From 23371b1d95849b7f55a33cad9ba00f81e822c5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 24 Feb 2009 18:48:10 +0000 Subject: [PATCH 001/544] svn:eol-style is missing from these files From 9ab1052dcdca9be06dcec8abc37103a70e358e73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Tue, 24 Feb 2009 18:49:27 +0000 Subject: [PATCH 002/544] Vendor import of OpenSSH 5.2p1 --- ChangeLog | 4332 ++++--------------------------- Makefile.in | 6 +- PROTOCOL | 13 +- README | 4 +- addrmatch.c | 7 +- auth-options.c | 6 +- auth.c | 2 +- auth.h | 6 +- auth2-chall.c | 10 +- auth2-jpake.c | 557 ++++ auth2.c | 12 +- canohost.c | 4 +- canohost.h | 4 +- channels.c | 187 +- channels.h | 8 +- cipher.c | 47 +- cipher.h | 3 +- clientloop.c | 44 +- compat.c | 5 +- compat.h | 3 +- config.guess | 155 +- config.h.in | 9 + config.sub | 191 +- configure | 426 ++- configure.ac | 42 +- contrib/caldera/openssh.spec | 8 +- contrib/caldera/ssh-host-keygen | 10 +- contrib/caldera/sshd.pam | 2 +- contrib/cygwin/Makefile | 4 +- contrib/cygwin/ssh-host-config | 227 +- contrib/redhat/openssh.spec | 4 +- contrib/redhat/sshd.pam | 2 +- contrib/ssh-copy-id | 4 +- contrib/ssh-copy-id.1 | 4 +- contrib/sshd.pam.generic | 2 +- contrib/suse/openssh.spec | 4 +- contrib/suse/rc.sshd | 6 +- defines.h | 8 +- dispatch.c | 3 +- jpake.c | 604 +++++ jpake.h | 134 + kex.c | 2 +- kexgexs.c | 27 +- key.c | 7 +- loginrec.c | 145 +- misc.c | 27 +- moduli.0 | 2 +- monitor.c | 231 +- monitor.h | 9 +- monitor_fdpass.c | 29 +- monitor_wrap.c | 167 +- monitor_wrap.h | 22 +- myproposal.h | 9 +- nchan.c | 12 +- openbsd-compat/bsd-poll.c | 5 +- openbsd-compat/port-uw.c | 4 +- openbsd-compat/xcrypt.c | 2 +- openbsd-compat/xmmap.c | 5 +- packet.c | 75 +- pathnames.h | 10 +- readconf.c | 130 +- readconf.h | 9 +- regress/conch-ciphers.sh | 3 +- regress/putty-ciphers.sh | 7 +- regress/putty-kex.sh | 3 +- regress/putty-transfer.sh | 3 +- schnorr.c | 409 +++ scp.0 | 2 +- scp.c | 4 +- servconf.c | 55 +- servconf.h | 10 +- serverloop.c | 18 +- session.c | 18 +- sftp-server-main.c | 5 +- sftp-server.0 | 2 +- sftp.0 | 8 +- sftp.1 | 15 +- sftp.c | 81 +- ssh-add.0 | 2 +- ssh-agent.0 | 2 +- ssh-keygen.0 | 4 +- ssh-keygen.1 | 5 +- ssh-keygen.c | 18 +- ssh-keyscan.0 | 6 +- ssh-keyscan.1 | 8 +- ssh-keyscan.c | 9 +- ssh-keysign.0 | 2 +- ssh-rand-helper.0 | 2 +- ssh.0 | 20 +- ssh.1 | 25 +- ssh.c | 58 +- ssh2.h | 9 +- ssh_config | 5 +- ssh_config.0 | 25 +- ssh_config.5 | 28 +- sshconnect.c | 10 +- sshconnect2.c | 321 ++- sshd.0 | 5 +- sshd.8 | 6 +- sshd.c | 5 +- sshd_config.0 | 21 +- sshd_config.5 | 14 +- sshpty.c | 9 + ttymodes.c | 7 +- uidswap.c | 10 + version.h | 4 +- 106 files changed, 4664 insertions(+), 4657 deletions(-) create mode 100644 auth2-jpake.c create mode 100644 jpake.c create mode 100644 jpake.h create mode 100644 schnorr.c diff --git a/ChangeLog b/ChangeLog index 3d08a80d3c9c..f802c0d7fc4d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,497 @@ +20090223 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2009/02/22 23:50:57 + [ssh_config.5 sshd_config.5] + don't advertise experimental options + - djm@cvs.openbsd.org 2009/02/22 23:59:25 + [sshd_config.5] + missing period + - djm@cvs.openbsd.org 2009/02/23 00:06:15 + [version.h] + openssh-5.2 + - (djm) [README] update for 5.2 + - (djm) Release openssh-5.2p1 + +20090222 + - (djm) OpenBSD CVS Sync + - tobias@cvs.openbsd.org 2009/02/21 19:32:04 + [misc.c sftp-server-main.c ssh-keygen.c] + Added missing newlines in error messages. + ok dtucker + +20090221 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2009/02/17 01:28:32 + [ssh_config] + sync with revised default ciphers; pointed out by dkrause@ + - djm@cvs.openbsd.org 2009/02/18 04:31:21 + [schnorr.c] + signature should hash over the entire group, not just the generator + (this is still disabled code) + - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] + [contrib/suse/openssh.spec] Prepare for 5.2p1 + +20090216 + - (djm) [regress/conch-ciphers.sh regress/putty-ciphers.sh] + [regress/putty-kex.sh regress/putty-transfer.sh] Downgrade disabled + interop tests from FATAL error to a warning. Allows some interop + tests to proceed if others are missing necessary prerequisites. + - (djm) [configure.ac] support GNU/kFreeBSD and GNU/kOpensolaris + systems; patch from Aurelien Jarno via rmh AT aybabtu.com + +20090214 + - (djm) OpenBSD CVS Sync + - dtucker@cvs.openbsd.org 2009/02/02 11:15:14 + [sftp.c] + Initialize a few variables to prevent spurious "may be used + uninitialized" warnings from newer gcc's. ok djm@ + - djm@cvs.openbsd.org 2009/02/12 03:00:56 + [canohost.c canohost.h channels.c channels.h clientloop.c readconf.c] + [readconf.h serverloop.c ssh.c] + support remote port forwarding with a zero listen port (-R0:...) to + dyamically allocate a listen port at runtime (this is actually + specified in rfc4254); bz#1003 ok markus@ + - djm@cvs.openbsd.org 2009/02/12 03:16:01 + [serverloop.c] + tighten check for -R0:... forwarding: only allow dynamic allocation + if want_reply is set in the packet + - djm@cvs.openbsd.org 2009/02/12 03:26:22 + [monitor.c] + some paranoia: check that the serialised key is really KEY_RSA before + diddling its internals + - djm@cvs.openbsd.org 2009/02/12 03:42:09 + [ssh.1] + document -R0:... usage + - djm@cvs.openbsd.org 2009/02/12 03:44:25 + [ssh.1] + consistency: Dq => Ql + - djm@cvs.openbsd.org 2009/02/12 03:46:17 + [ssh_config.5] + document RemoteForward usage with 0 listen port + - jmc@cvs.openbsd.org 2009/02/12 07:34:20 + [ssh_config.5] + kill trailing whitespace; + - markus@cvs.openbsd.org 2009/02/13 11:50:21 + [packet.c] + check for enc !=NULL in packet_start_discard + - djm@cvs.openbsd.org 2009/02/14 06:35:49 + [PROTOCOL] + mention that eow and no-more-sessions extensions are sent only to + OpenSSH peers + +20090212 + - (djm) [sshpty.c] bz#1419: OSX uses cloning ptys that automagically + set ownership and modes, so avoid explicitly setting them + - (djm) [configure.ac loginrec.c] bz#1421: fix lastlog support for OSX. + OSX provides a getlastlogxbyname function that automates the reading of + a lastlog file. Also, the pututxline function will update lastlog so + there is no need for loginrec.c to do it explicitly. Collapse some + overly verbose code while I'm in there. + +20090201 + - (dtucker) [defines.h sshconnect.c] INET6_ADDRSTRLEN is now needed in + channels.c too, so move the definition for non-IP6 platforms to defines.h + where it can be shared. + +20090129 + - (tim) [contrib/cygwin/ssh-host-config] Patch from Corinna Vinschen. + If the CYGWIN environment variable is empty, the installer script + should not install the service with an empty CYGWIN variable, but + rather without setting CYGWNI entirely. + - (tim) [contrib/cygwin/ssh-host-config] Whitespace cleanup. No code changes. + +20090128 + - (tim) [contrib/cygwin/ssh-host-config] Patch from Corinna Vinschen. + Changes to work on Cygwin 1.5.x as well as on the new Cygwin 1.7.x. + The information given for the setting of the CYGWIN environment variable + is wrong for both releases so I just removed it, together with the + unnecessary (Cygwin 1.5.x) or wrong (Cygwin 1.7.x) default setting. + +20081228 + - (djm) OpenBSD CVS Sync + - stevesk@cvs.openbsd.org 2008/12/09 03:20:42 + [channels.c servconf.c] + channel_print_adm_permitted_opens() should deal with all the printing + for that config option. suggested by markus@; ok markus@ djm@ + dtucker@ + - djm@cvs.openbsd.org 2008/12/09 04:32:22 + [auth2-chall.c] + replace by-hand string building with xasprinf(); ok deraadt@ + - sobrado@cvs.openbsd.org 2008/12/09 15:35:00 + [sftp.1 sftp.c] + update for the synopses displayed by the 'help' command, there are a + few missing flags; add 'bye' to the output of 'help'; sorting and spacing. + jmc@ suggested replacing .Oo/.Oc with a single .Op macro. + ok jmc@ + - stevesk@cvs.openbsd.org 2008/12/09 22:37:33 + [clientloop.c] + fix typo in error message + - stevesk@cvs.openbsd.org 2008/12/10 03:55:20 + [addrmatch.c] + o cannot be NULL here but use xfree() to be consistent; ok djm@ + - stevesk@cvs.openbsd.org 2008/12/29 01:12:36 + [ssh-keyscan.1] + fix example, default key type is rsa for 3+ years; from + frederic.perrin@resel.fr + - stevesk@cvs.openbsd.org 2008/12/29 02:23:26 + [pathnames.h] + no need to escape single quotes in comments + - okan@cvs.openbsd.org 2008/12/30 00:46:56 + [sshd_config.5] + add AllowAgentForwarding to available Match keywords list + ok djm + - djm@cvs.openbsd.org 2009/01/01 21:14:35 + [channels.c] + call channel destroy callbacks on receipt of open failure messages. + fixes client hangs when connecting to a server that has MaxSessions=0 + set spotted by imorgan AT nas.nasa.gov; ok markus@ + - djm@cvs.openbsd.org 2009/01/01 21:17:36 + [kexgexs.c] + fix hash calculation for KEXGEX: hash over the original client-supplied + values and not the sanity checked versions that we acutally use; + bz#1540 reported by john.smith AT arrows.demon.co.uk + ok markus@ + - djm@cvs.openbsd.org 2009/01/14 01:38:06 + [channels.c] + support SOCKS4A protocol, from dwmw2 AT infradead.org via bz#1482; + "looks ok" markus@ + - stevesk@cvs.openbsd.org 2009/01/15 17:38:43 + [readconf.c] + 1) use obsolete instead of alias for consistency + 2) oUserKnownHostsFile not obsolete but oGlobalKnownHostsFile2 is + so move the comment. + 3) reorder so like options are together + ok djm@ + - djm@cvs.openbsd.org 2009/01/22 09:46:01 + [channels.c channels.h session.c] + make Channel->path an allocated string, saving a few bytes here and + there and fixing bz#1380 in the process; ok markus@ + - djm@cvs.openbsd.org 2009/01/22 09:49:57 + [channels.c] + oops! I committed the wrong version of the Channel->path diff, + it was missing some tweaks suggested by stevesk@ + - djm@cvs.openbsd.org 2009/01/22 10:02:34 + [clientloop.c misc.c readconf.c readconf.h servconf.c servconf.h] + [serverloop.c ssh-keyscan.c ssh.c sshd.c] + make a2port() return -1 when it encounters an invalid port number + rather than 0, which it will now treat as valid (needed for future work) + adjust current consumers of a2port() to check its return value is <= 0, + which in turn required some things to be converted from u_short => int + make use of int vs. u_short consistent in some other places too + feedback & ok markus@ + - djm@cvs.openbsd.org 2009/01/22 10:09:16 + [auth-options.c] + another chunk of a2port() diff that got away. wtfdjm?? + - djm@cvs.openbsd.org 2009/01/23 07:58:11 + [myproposal.h] + prefer CTR modes and revised arcfour (i.e w/ discard) modes to CBC + modes; ok markus@ + - naddy@cvs.openbsd.org 2009/01/24 17:10:22 + [ssh_config.5 sshd_config.5] + sync list of preferred ciphers; ok djm@ + - markus@cvs.openbsd.org 2009/01/26 09:58:15 + [cipher.c cipher.h packet.c] + Work around the CPNI-957037 Plaintext Recovery Attack by always + reading 256K of data on packet size or HMAC errors (in CBC mode only). + Help, feedback and ok djm@ + Feedback from Martin Albrecht and Paterson Kenny + +20090107 + - (djm) [uidswap.c] bz#1412: Support >16 supplemental groups in OS X. + Patch based on one from vgiffin AT apple.com; ok dtucker@ + - (djm) [channels.c] bz#1419: support "on demand" X11 forwarding via + launchd on OS X; patch from vgiffin AT apple.com, slightly tweaked; + ok dtucker@ + - (djm) [contrib/ssh-copy-id.1 contrib/ssh-copy-id] bz#1492: Make + ssh-copy-id copy id_rsa.pub by default (instead of the legacy "identity" + key). Patch from cjwatson AT debian.org + +20090107 + - (tim) [configure.ac defines.h openbsd-compat/port-uw.c + openbsd-compat/xcrypt.c] Add SECUREWARE support to OpenServer 6 SVR5 ABI. + OK djm@ dtucker@ + - (tim) [configure.ac] Move check_for_libcrypt_later=1 in *-*-sysv5*) section. + OpenServer 6 doesn't need libcrypt. + +20081209 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/12/09 02:38:18 + [clientloop.c] + The ~C escape handler does not work correctly for multiplexed sessions - + it opens a commandline on the master session, instead of on the slave + that requested it. Disable it on slave sessions until such time as it + is fixed; bz#1543 report from Adrian Bridgett via Colin Watson + ok markus@ + - djm@cvs.openbsd.org 2008/12/09 02:39:59 + [sftp.c] + Deal correctly with failures in remote stat() operation in sftp, + correcting fail-on-error behaviour in batchmode. bz#1541 report and + fix from anedvedicky AT gmail.com; ok markus@ + - djm@cvs.openbsd.org 2008/12/09 02:58:16 + [readconf.c] + don't leave junk (free'd) pointers around in Forward *fwd argument on + failure; avoids double-free in ~C -L handler when given an invalid + forwarding specification; bz#1539 report from adejong AT debian.org + via Colin Watson; ok markus@ dtucker@ + - djm@cvs.openbsd.org 2008/12/09 03:02:37 + [sftp.1 sftp.c] + correct sftp(1) and corresponding usage syntax; + bz#1518 patch from imorgan AT nas.nasa.gov; ok deraadt@ improved diff jmc@ + +20081208 + - (djm) [configure.ac] bz#1538: better test for ProPolice/SSP: actually + use some stack in main(). + Report and suggested fix from vapier AT gentoo.org + - (djm) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2008/12/02 19:01:07 + [clientloop.c] + we have to use the recipient's channel number (RFC 4254) for + SSH2_MSG_CHANNEL_SUCCESS/SSH2_MSG_CHANNEL_FAILURE messages, + otherwise we trigger 'Non-public channel' error messages on sshd + systems with clientkeepalive enabled; noticed by sturm; ok djm; + - markus@cvs.openbsd.org 2008/12/02 19:08:59 + [serverloop.c] + backout 1.149, since it's not necessary and openssh clients send + broken CHANNEL_FAILURE/SUCCESS messages since about 2004; ok djm@ + - markus@cvs.openbsd.org 2008/12/02 19:09:38 + [channels.c] + s/remote_id/id/ to be more consistent with other code; ok djm@ + +20081201 + - (dtucker) [contrib/cygwin/{Makefile,ssh-host-config}] Add new doc files + and tweak the is-sshd-running check in ssh-host-config. Patch from + vinschen at redhat com. + - (dtucker) OpenBSD CVS Sync + - markus@cvs.openbsd.org 2008/11/21 15:47:38 + [packet.c] + packet_disconnect() on padding error, too. should reduce the success + probability for the CPNI-957037 Plaintext Recovery Attack to 2^-18 + ok djm@ + - dtucker@cvs.openbsd.org 2008/11/30 11:59:26 + [monitor_fdpass.c] + Retry sendmsg/recvmsg on EAGAIN and EINTR; ok djm@ + +20081123 + - (dtucker) [monitor_fdpass.c] Reduce diff vs OpenBSD by moving some + declarations, removing an unnecessary union member and adding whitespace. + cmsgbuf.tmp thing spotted by des at des no, ok djm some time ago. + +20081118 + - (tim) [addrmatch.c configure.ac] Some platforms do not have sin6_scope_id + member of sockaddr_in6. Also reported in Bug 1491 by David Leonard. OK and + feedback by djm@ + +20081111 + - (dtucker) OpenBSD CVS Sync + - jmc@cvs.openbsd.org 2008/11/05 11:22:54 + [servconf.c] + passord -> password; + fixes user/5975 from Rene Maroufi + - stevesk@cvs.openbsd.org 2008/11/07 00:42:12 + [ssh-keygen.c] + spelling/typo in comment + - stevesk@cvs.openbsd.org 2008/11/07 18:50:18 + [nchan.c] + add space to some log/debug messages for readability; ok djm@ markus@ + - dtucker@cvs.openbsd.org 2008/11/07 23:34:48 + [auth2-jpake.c] + Move JPAKE define to make life easier for portable. ok djm@ + - tobias@cvs.openbsd.org 2008/11/09 12:34:47 + [session.c ssh.1] + typo fixed (overriden -> overridden) + ok espie, jmc + - stevesk@cvs.openbsd.org 2008/11/11 02:58:09 + [servconf.c] + USE_AFS not referenced so remove #ifdef. fixes sshd -T not printing + kerberosgetafstoken. ok dtucker@ + (Id sync only, we still want the ifdef in portable) + - stevesk@cvs.openbsd.org 2008/11/11 03:55:11 + [channels.c] + for sshd -T print 'permitopen any' vs. 'permitopen' for case of no + permitopen's; ok and input dtucker@ + - djm@cvs.openbsd.org 2008/11/10 02:06:35 + [regress/putty-ciphers.sh] + PuTTY supports AES CTR modes, so interop test against them too + +20081105 + - OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/11/03 08:59:41 + [servconf.c] + include MaxSessions in sshd -T output; patch from imorgan AT nas.nasa.gov + - djm@cvs.openbsd.org 2008/11/04 07:58:09 + [auth.c] + need unistd.h for close() prototype + (ID sync only) + - djm@cvs.openbsd.org 2008/11/04 08:22:13 + [auth.h auth2.c monitor.c monitor.h monitor_wrap.c monitor_wrap.h] + [readconf.c readconf.h servconf.c servconf.h ssh2.h ssh_config.5] + [sshconnect2.c sshd_config.5 jpake.c jpake.h schnorr.c auth2-jpake.c] + [Makefile.in] + Add support for an experimental zero-knowledge password authentication + method using the J-PAKE protocol described in F. Hao, P. Ryan, + "Password Authenticated Key Exchange by Juggling", 16th Workshop on + Security Protocols, Cambridge, April 2008. + + This method allows password-based authentication without exposing + the password to the server. Instead, the client and server exchange + cryptographic proofs to demonstrate of knowledge of the password while + revealing nothing useful to an attacker or compromised endpoint. + + This is experimental, work-in-progress code and is presently + compiled-time disabled (turn on -DJPAKE in Makefile.inc). + + "just commit it. It isn't too intrusive." deraadt@ + - stevesk@cvs.openbsd.org 2008/11/04 19:18:00 + [readconf.c] + because parse_forward() is now used to parse all forward types (DLR), + and it malloc's space for host variables, we don't need to malloc + here. fixes small memory leaks. + + previously dynamic forwards were not parsed in parse_forward() and + space was not malloc'd in that case. + + ok djm@ + - stevesk@cvs.openbsd.org 2008/11/05 03:23:09 + [clientloop.c ssh.1] + add dynamic forward escape command line; ok djm@ + +20081103 + - OpenBSD CVS Sync + - sthen@cvs.openbsd.org 2008/07/24 23:55:30 + [ssh-keygen.1] + Add "ssh-keygen -F -l" to synopsis (displays fingerprint from + known_hosts). ok djm@ + - grunk@cvs.openbsd.org 2008/07/25 06:56:35 + [ssh_config] + Add VisualHostKey to example file, ok djm@ + - grunk@cvs.openbsd.org 2008/07/25 07:05:16 + [key.c] + In random art visualization, make sure to use the end marker only at the + end. Initial diff by Dirk Loss, tweaks and ok djm@ + - markus@cvs.openbsd.org 2008/07/31 14:48:28 + [sshconnect2.c] + don't allocate space for empty banners; report t8m at centrum.cz; + ok deraadt + - krw@cvs.openbsd.org 2008/08/02 04:29:51 + [ssh_config.5] + whitepsace -> whitespace. From Matthew Clarke via bugs@. + - djm@cvs.openbsd.org 2008/08/21 04:09:57 + [session.c] + allow ForceCommand internal-sftp with arguments. based on patch from + michael.barabanov AT gmail.com; ok markus@ + - djm@cvs.openbsd.org 2008/09/06 12:24:13 + [kex.c] + OpenSSL 0.9.8h supplies a real EVP_sha256 so we do not need our + replacement anymore + (ID sync only for portable - we still need this) + - markus@cvs.openbsd.org 2008/09/11 14:22:37 + [compat.c compat.h nchan.c ssh.c] + only send eow and no-more-sessions requests to openssh 5 and newer; + fixes interop problems with broken ssh v2 implementations; ok djm@ + - millert@cvs.openbsd.org 2008/10/02 14:39:35 + [session.c] + Convert an unchecked strdup to xstrdup. OK deraadt@ + - jmc@cvs.openbsd.org 2008/10/03 13:08:12 + [sshd.8] + do not give an example of how to chmod files: we can presume the user + knows that. removes an ambiguity in the permission of authorized_keys; + ok deraadt + - deraadt@cvs.openbsd.org 2008/10/03 23:56:28 + [sshconnect2.c] + Repair strnvis() buffersize of 4*n+1, with termination gauranteed by the + function. + spotted by des@freebsd, who commited an incorrect fix to the freebsd tree + and (as is fairly typical) did not report the problem to us. But this fix + is correct. + ok djm + - djm@cvs.openbsd.org 2008/10/08 23:34:03 + [ssh.1 ssh.c] + Add -y option to force logging via syslog rather than stderr. + Useful for daemonised ssh connection (ssh -f). Patch originally from + and ok'd by markus@ + - djm@cvs.openbsd.org 2008/10/09 03:50:54 + [servconf.c sshd_config.5] + support setting PermitEmptyPasswords in a Match block + requested in PR3891; ok dtucker@ + - jmc@cvs.openbsd.org 2008/10/09 06:54:22 + [ssh.c] + add -y to usage(); + - stevesk@cvs.openbsd.org 2008/10/10 04:55:16 + [scp.c] + spelling in comment; ok djm@ + - stevesk@cvs.openbsd.org 2008/10/10 05:00:12 + [key.c] + typo in error message; ok djm@ + - stevesk@cvs.openbsd.org 2008/10/10 16:43:27 + [ssh_config.5] + use 'Privileged ports can be forwarded only when logging in as root on + the remote machine.' for RemoteForward just like ssh.1 -R. + ok djm@ jmc@ + - stevesk@cvs.openbsd.org 2008/10/14 18:11:33 + [sshconnect.c] + use #define ROQUIET here; no binary change. ok dtucker@ + - stevesk@cvs.openbsd.org 2008/10/17 18:36:24 + [ssh_config.5] + correct and clarify VisualHostKey; ok jmc@ + - stevesk@cvs.openbsd.org 2008/10/30 19:31:16 + [clientloop.c sshd.c] + don't need to #include "monitor_fdpass.h" + - stevesk@cvs.openbsd.org 2008/10/31 15:05:34 + [dispatch.c] + remove unused #define DISPATCH_MIN; ok markus@ + - djm@cvs.openbsd.org 2008/11/01 04:50:08 + [sshconnect2.c] + sprinkle ARGSUSED on dispatch handlers + nuke stale unusued prototype + - stevesk@cvs.openbsd.org 2008/11/01 06:43:33 + [channels.c] + fix some typos in log messages; ok djm@ + - sobrado@cvs.openbsd.org 2008/11/01 11:14:36 + [ssh-keyscan.1 ssh-keyscan.c] + the ellipsis is not an optional argument; while here, improve spacing. + - stevesk@cvs.openbsd.org 2008/11/01 17:40:33 + [clientloop.c readconf.c readconf.h ssh.c] + merge dynamic forward parsing into parse_forward(); + 'i think this is OK' djm@ + - stevesk@cvs.openbsd.org 2008/11/02 00:16:16 + [ttymodes.c] + protocol 2 tty modes support is now 7.5 years old so remove these + debug3()s; ok deraadt@ + - stevesk@cvs.openbsd.org 2008/11/03 01:07:02 + [readconf.c] + remove valueless comment + - stevesk@cvs.openbsd.org 2008/11/03 02:44:41 + [readconf.c] + fix comment + - (djm) [contrib/caldera/ssh-host-keygen contrib/suse/rc.sshd] + Make example scripts generate keys with default sizes rather than fixed, + non-default 1024 bits; patch from imorgan AT nas.nasa.gov + - (djm) [contrib/sshd.pam.generic contrib/caldera/sshd.pam] + [contrib/redhat/sshd.pam] Move pam_nologin to account group from + incorrect auth group in example files; + patch from imorgan AT nas.nasa.gov + +20080906 + - (dtucker) [config.guess config.sub] Update to latest versions from + http://git.savannah.gnu.org/gitweb/ (2008-04-14 and 2008-06-16 + respectively). + +20080830 + - (dtucker) [openbsd-compat/bsd-poll.c] correctly check for number of FDs + larger than FD_SETSIZE (OpenSSH only ever uses poll with one fd). Patch + from Nicholas Marriott. + +20080721 + - (djm) OpenBSD CVS Sync + - djm@cvs.openbsd.org 2008/07/23 07:36:55 + [servconf.c] + do not try to print options that have been compile-time disabled + in config test mode (sshd -T); report from nix-corp AT esperi.org.uk + ok dtucker@ + - (djm) [servconf.c] Print UsePAM option in config test mode (when it + has been compiled in); report from nix-corp AT esperi.org.uk + ok dtucker@ + 20080721 - (djm) OpenBSD CVS Sync - jmc@cvs.openbsd.org 2008/07/18 22:51:01 @@ -873,3841 +1367,3 @@ [contrib/suse/openssh.spec] Crank version numbers in RPM spec files - (djm) [README] Update link to release notes - (djm) Release 5.0p1 - -20080315 - - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are - empty; report and patch from Peter Stuge - - (djm) [regress/test-exec.sh] Silence noise from detection of putty - commands; report from Peter Stuge - - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing - crashes when used with ChrootDirectory - - -20080327 - - (dtucker) Cache selinux status earlier so we know if it's enabled after a - chroot. Allows ChrootDirectory to work with selinux support compiled in - but not enabled. Using it with selinux enabled will require some selinux - support inside the chroot. "looks sane" djm@ - - (djm) Fix RCS ident in sftp-server-main.c - - (djm) OpenBSD CVS sync: - - jmc@cvs.openbsd.org 2008/02/11 07:58:28 - [ssh.1 sshd.8 sshd_config.5] - bump Mdocdate for pages committed in "febuary", necessary because - of a typo in rcs.c; - - deraadt@cvs.openbsd.org 2008/03/13 01:49:53 - [monitor_fdpass.c] - Correct CMSG_SPACE and CMSG_LEN usage everywhere in the tree. Due to - an extensive discussion with otto, kettenis, millert, and hshoexer - - deraadt@cvs.openbsd.org 2008/03/15 16:19:02 - [monitor_fdpass.c] - Repair the simple cases for msg_controllen where it should just be - CMSG_SIZE(sizeof(int)), not sizeof(buffer) which may be larger because - of alignment; ok kettenis hshoexer - - djm@cvs.openbsd.org 2008/03/23 12:54:01 - [sftp-client.c] - prefer POSIX-style file renaming over filexfer rename behaviour if the - server supports the posix-rename@openssh.com extension. - Note that the old (filexfer) behaviour would refuse to clobber an - existing file. Users who depended on this should adjust their sftp(1) - usage. - ok deraadt@ markus@ - - deraadt@cvs.openbsd.org 2008/03/24 16:11:07 - [monitor_fdpass.c] - msg_controllen has to be CMSG_SPACE so that the kernel can account for - each cmsg_len (ie. msg_controllen = sum of CMSG_ALIGN(cmsg_len). This - works now that kernel fd passing has been fixed to accept a bit of - sloppiness because of this ABI repair. - lots of discussion with kettenis - - djm@cvs.openbsd.org 2008/03/25 11:58:02 - [session.c sshd_config.5] - ignore ~/.ssh/rc if a sshd_config ForceCommand is specified; - from dtucker@ ok deraadt@ djm@ - - djm@cvs.openbsd.org 2008/03/25 23:01:41 - [session.c] - last patch had backwards test; spotted by termim AT gmail.com - - djm@cvs.openbsd.org 2008/03/26 21:28:14 - [auth-options.c auth-options.h session.c sshd.8] - add no-user-rc authorized_keys option to disable execution of ~/.ssh/rc - - djm@cvs.openbsd.org 2008/03/27 00:16:49 - [version.h] - openssh-4.9 - - djm@cvs.openbsd.org 2008/03/24 21:46:54 - [regress/sftp-badcmds.sh] - disable no-replace rename test now that we prefer a POSIX rename; spotted - by dkrause@ - - (djm) [configure.ac] fix alignment of --without-stackprotect description - - (djm) [configure.ac] --with-selinux too - - (djm) [regress/Makefile] cleanup PuTTY interop test droppings - - (djm) [README] Update link to release notes - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Crank version numbers in RPM spec files - - (djm) Release 4.9p1 - -20080315 - - (djm) [regress/test-exec.sh] Quote putty-related variables in case they are - empty; report and patch from Peter Stuge - - (djm) [regress/test-exec.sh] Silence noise from detection of putty - commands; report from Peter Stuge - - (djm) [session.c] Relocate incorrectly-placed closefrom() that was causing - crashes when used with ChrootDirectory - -20080314 - - (tim) [regress/sftp-cmds.sh] s/cd/lcd/ in lls test. Reported by - vinschen at redhat.com. Add () to put echo commands in subshell for lls test - I mistakenly left out of last commit. - - (tim) [regress/localcommand.sh] Shell portability fix. Reported by imorgan at - nas.nasa.gov - -20080313 - - (djm) [Makefile.in regress/Makefile] Fix interop-tests target (note to - self: make changes to Makefile.in next time, not the generated Makefile). - - (djm) [Makefile.in regress/test-exec.sh] Find installed plink(1) and - puttygen(1) by $PATH - - (tim) [scp.c] Use poll.h if available, fall back to sys/poll.h if not. Patch - by vinschen at redhat.com. - - (tim) [regress/sftp-cmds.sh regress/ssh2putty.sh] Shell portability fixes - from vinschen at redhat.com and imorgan at nas.nasa.gov - -20080312 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/10/29 06:57:13 - [regress/Makefile regress/localcommand.sh] - Add simple regress test for LocalCommand; ok djm@ - - jmc@cvs.openbsd.org 2007/11/25 15:35:09 - [regress/agent-getpeereid.sh regress/agent.sh] - more existant -> existent, from Martynas Venckus; - pfctl changes: ok henning - ssh changes: ok deraadt - - djm@cvs.openbsd.org 2007/12/12 05:04:03 - [regress/sftp-cmds.sh] - unbreak lls command and add a regress test that would have caught the - breakage; spotted by mouring@ - NB. sftp code change already committed. - - djm@cvs.openbsd.org 2007/12/21 04:13:53 - [regress/Makefile regress/test-exec.sh regress/putty-ciphers.sh] - [regress/putty-kex.sh regress/putty-transfer.sh regress/ssh2putty.sh] - basic (crypto, kex and transfer) interop regression tests against putty - To run these, install putty and run "make interop-tests" from the build - directory - the tests aren't run by default yet. - -20080311 - - (dtucker) [auth-pam.c monitor.c session.c sshd.c] Bug #926: Move - pam_open_session and pam_close_session into the privsep monitor, which - will ensure that pam_session_close is called as root. Patch from Tomas - Mraz. - -20080309 - - (dtucker) [configure.ac] It turns out gcc's -fstack-protector-all doesn't - always work for all platforms and versions, so test what we can and - add a configure flag to turn it of if needed. ok djm@ - - (dtucker) [openbsd-compat/port-aix.{c,h}] Remove AIX specific initgroups - implementation. It's not needed to fix bug #1081 and breaks the build - on some AIX configurations. - - (dtucker) [openbsd-compat/regress/strtonumtest.c] Bug #1347: Use platform's - equivalent of LLONG_MAX for the compat regression tests, which makes them - run on AIX and HP-UX. Patch from David Leonard. - - (dtucker) [configure.ac] Run stack-protector tests with -Werror to catch - platforms where gcc understands the option but it's not supported (and - thus generates a warning). - -20080307 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2008/02/11 07:58:28 - [ssh.1 sshd.8 sshd_config.5] - bump Mdocdate for pages committed in "febuary", necessary because - of a typo in rcs.c; - - djm@cvs.openbsd.org 2008/02/13 22:38:17 - [servconf.h session.c sshd.c] - rekey arc4random and OpenSSL RNG in postauth child - closefrom fds > 2 before shell/command execution - ok markus@ - - mbalmer@cvs.openbsd.org 2008/02/14 13:10:31 - [sshd.c] - When started in configuration test mode (-t) do not check that sshd is - being started with an absolute path. - ok djm - - markus@cvs.openbsd.org 2008/02/20 15:25:26 - [session.c] - correct boolean encoding for coredump; der Mouse via dugsong - - djm@cvs.openbsd.org 2008/02/22 05:58:56 - [session.c] - closefrom() call was too early, delay it until just before we execute - the user's rc files (if any). - - dtucker@cvs.openbsd.org 2008/02/22 20:44:02 - [clientloop.c packet.c packet.h serverloop.c] - Allow all SSH2 packet types, including UNIMPLEMENTED to reset the - keepalive timer (bz #1307). ok markus@ - - djm@cvs.openbsd.org 2008/02/27 20:21:15 - [sftp-server.c] - add an extension method "posix-rename@openssh.com" to perform POSIX atomic - rename() operations. based on patch from miklos AT szeredi.hu in bz#1400; - ok dtucker@ markus@ - - deraadt@cvs.openbsd.org 2008/03/02 18:19:35 - [monitor_fdpass.c] - use a union to ensure alignment of the cmsg (pay attention: various other - parts of the tree need this treatment too); ok djm - - deraadt@cvs.openbsd.org 2008/03/04 21:15:42 - [version.h] - crank version; from djm - - (tim) [regress/sftp-glob.sh] Shell portability fix. - -20080302 - - (dtucker) [configure.ac] FreeBSD's glob() doesn't behave the way we expect - either, so use our own. - -20080229 - - (dtucker) [openbsd-compat/bsd-poll.c] We don't check for select(2) in - configure (and there's not much point, as openssh won't work without it) - so HAVE_SELECT is not defined and the poll(2) compat code doesn't get - built in. Remove HAVE_SELECT so we can build on platforms without poll. - - (dtucker) [scp.c] Include sys/poll.h inside HAVE_SYS_POLL_H. - - (djm) [contrib/gnome-ssh-askpass2.h] Keep askpass windown on top. From - Debian patch via bernd AT openbsd.org - -20080228 - - (dtucker) [configure.ac] Add -fstack-protector to LDFLAGS too, fixes - linking problems on AIX with gcc 4.1.x. - - (dtucker) [includes.h ssh-add.c ssh-agent.c ssh-keygen.c ssh.c sshd.c - openbsd-compat/openssl-compat.{c,h}] Bug #1437 Move the OpenSSL compat - header to after OpenSSL headers, since some versions of OpenSSL have - SSLeay_add_all_algorithms as a macro already. - - (dtucker) [key.c defines.h openbsd-compat/openssl-compat.h] Move old OpenSSL - compat glue into openssl-compat.h. - - (dtucker) [configure.ac openbsd-compat/port-aix.{c,h}] Bug #1081: Implement - getgrouplist via getgrset on AIX, rather than iterating over getgrent. - This allows, eg, Match and AllowGroups directives to work with NIS and - LDAP groups. - - (dtucker) [sshd.c] Bug #1042: make log messages for tcpwrappers use the - same SyslogFacility as the rest of sshd. Patch from William Knox, - ok djm@. - -20080225 - - (dtucker) [openbsd-compat/fake-rfc2553.h] rename ssh_gai_strerror hack - since it now conflicts with the helper function in misc.c. From - vinschen AT redhat.com. - - (dtucker) [configure.ac audit-bsm.c] Bug #1420: Add a local implementation - of aug_get_machine for systems that don't have their own (eg OS X, FreeBSD). - Help and testing from csjp at FreeBSD org, vgiffin at apple com. ok djm@ - - (dtucker) [includes.h openbsd-compat/openssl-compat.c] Bug #1437: reshuffle - headers so ./configure --with-ssl-engine actually works. Patch from - Ian Lister. - -20080224 - - (tim) [contrib/cygwin/ssh-host-config] - Grammar changes on SYSCONFDIR LOCALSTATEDIR messages. - Check more thoroughly that it's possible to create the /var/empty directory. - Patch by vinschen AT redhat.com - -20080210 - - OpenBSD CVS Sync - - chl@cvs.openbsd.org 2008/01/11 07:22:28 - [sftp-client.c sftp-client.h] - disable unused functions - initially from tobias@, but disabled them by placing them in - "#ifdef notyet" which was asked by djm@ - ok djm@ tobias@ - - djm@cvs.openbsd.org 2008/01/19 19:13:28 - [ssh.1] - satisfy the pedants: -q does not suppress all diagnostic messages (e.g. - some commandline parsing warnings go unconditionally to stdout). - - djm@cvs.openbsd.org 2008/01/19 20:48:53 - [clientloop.c] - fd leak on session multiplexing error path. Report and patch from - gregory_shively AT fanniemae.com - - djm@cvs.openbsd.org 2008/01/19 20:51:26 - [ssh.c] - ignore SIGPIPE in multiplex client mode - we can receive this if the - server runs out of fds on us midway. Report and patch from - gregory_shively AT fanniemae.com - - djm@cvs.openbsd.org 2008/01/19 22:04:57 - [sftp-client.c] - fix remote handle leak in do_download() local file open error path; - report and fix from sworley AT chkno.net - - djm@cvs.openbsd.org 2008/01/19 22:22:58 - [ssh-keygen.c] - when hashing individual hosts (ssh-keygen -Hf hostname), make sure we - hash just the specified hostname and not the entire hostspec from the - keyfile. It may be of the form "hostname,ipaddr", which would lead to - a hash that never matches. report and fix from jp AT devnull.cz - - djm@cvs.openbsd.org 2008/01/19 22:37:19 - [ssh-keygen.c] - unbreak line numbering (broken in revision 1.164), fix error message - - djm@cvs.openbsd.org 2008/01/19 23:02:40 - [channels.c] - When we added support for specified bind addresses for port forwards, we - added a quirk SSH_OLD_FORWARD_ADDR. There is a bug in our handling of - this for -L port forwards that causes the client to listen on both v4 - and v6 addresses when connected to a server with this quirk, despite - having set 0.0.0.0 as a bind_address. - report and patch from Jan.Pechanec AT Sun.COM; ok dtucker@ - - djm@cvs.openbsd.org 2008/01/19 23:09:49 - [readconf.c readconf.h sshconnect2.c] - promote rekeylimit to a int64 so it can hold the maximum useful limit - of 2^32; report and patch from Jan.Pechanec AT Sun.COM, ok dtucker@ - - djm@cvs.openbsd.org 2008/01/20 00:38:30 - [sftp.c] - When uploading, correctly handle the case of an unquoted filename with - glob metacharacters that match a file exactly but not as a glob, e.g. a - file called "[abcd]". report and test cases from duncan2nd AT gmx.de - - djm@cvs.openbsd.org 2008/01/21 17:24:30 - [sftp-server.c] - Remove the fixed 100 handle limit in sftp-server and allocate as many - as we have available file descriptors. Patch from miklos AT szeredi.hu; - ok dtucker@ markus@ - - djm@cvs.openbsd.org 2008/01/21 19:20:17 - [sftp-client.c] - when a remote write error occurs during an upload, ensure that ACKs for - all issued requests are properly drained. patch from t8m AT centrum.cz - - dtucker@cvs.openbsd.org 2008/01/23 01:56:54 - [clientloop.c packet.c serverloop.c] - Revert the change for bz #1307 as it causes connection aborts if an IGNORE - packet arrives while we're waiting in packet_read_expect (and possibly - elsewhere). - - jmc@cvs.openbsd.org 2008/01/31 20:06:50 - [scp.1] - explain how to handle local file names containing colons; - requested by Tamas TEVESZ - ok dtucker - - markus@cvs.openbsd.org 2008/02/04 21:53:00 - [session.c sftp-server.c sftp.h] - link sftp-server into sshd; feedback and ok djm@ - - mcbride@cvs.openbsd.org 2008/02/09 12:15:43 - [ssh.1 sshd.8] - Document the correct permissions for the ~/.ssh/ directory. - ok jmc - - djm@cvs.openbsd.org 2008/02/10 09:55:37 - [sshd_config.5] - mantion that "internal-sftp" is useful with ForceCommand too - - djm@cvs.openbsd.org 2008/02/10 10:54:29 - [servconf.c session.c] - delay ~ expansion for ChrootDirectory so it expands to the logged-in user's - home, rather than the user who starts sshd (probably root) - -20080119 - - (djm) Silence noice from expr in ssh-copy-id; patch from - mikel AT mikelward.com - - (djm) Only listen for IPv6 connections on AF_INET6 sockets; patch from - tsr2600 AT gmail.com - -20080102 - - (dtucker) [configure.ac] Fix message for -fstack-protector-all test. - -20080101 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/12/31 10:41:31 - [readconf.c servconf.c] - Prevent strict-aliasing warnings on newer gcc versions. bz #1355, patch - from Dmitry V. Levin, ok djm@ - - dtucker@cvs.openbsd.org 2007/12/31 15:27:04 - [sshd.c] - When in inetd mode, have sshd generate a Protocol 1 ephemeral server - key only for connections where the client chooses Protocol 1 as opposed - to when it's enabled in the server's config. Speeds up Protocol 2 - connections to inetd-mode servers that also allow Protocol 1. bz #440, - based on a patch from bruno at wolff.to, ok markus@ - - dtucker@cvs.openbsd.org 2008/01/01 08:47:04 - [misc.c] - spaces -> tabs from my previous commit - - dtucker@cvs.openbsd.org 2008/01/01 09:06:39 - [scp.c] - If scp -p encounters a pre-epoch timestamp, use the epoch which is - as close as we can get given that it's used unsigned. Add a little - debugging while there. bz #828, ok djm@ - - dtucker@cvs.openbsd.org 2008/01/01 09:27:33 - [sshd_config.5 servconf.c] - Allow PermitRootLogin in a Match block. Allows for, eg, permitting root - only from the local network. ok markus@, man page bit ok jmc@ - - dtucker@cvs.openbsd.org 2008/01/01 08:51:20 - [moduli] - Updated moduli file; ok djm@ - -20071231 - - (dtucker) [configure.ac openbsd-compat/glob.{c,h}] Bug #1407: force use of - builtin glob implementation on Mac OS X. Based on a patch from - vgiffin at apple. - -20071229 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/12/12 05:04:03 - [sftp.c] - unbreak lls command and add a regress test that would have caught the - breakage; spotted by mouring@ - - dtucker@cvs.openbsd.org 2007/12/27 14:22:08 - [servconf.c canohost.c misc.c channels.c sshconnect.c misc.h ssh-keyscan.c - sshd.c] - Add a small helper function to consistently handle the EAI_SYSTEM error - code of getaddrinfo. Prompted by vgiffin at apple com via bz #1417. - ok markus@ stevesk@ - - dtucker@cvs.openbsd.org 2007/12/28 15:32:24 - [clientloop.c serverloop.c packet.c] - Make SSH2_MSG_UNIMPLEMENTED and SSH2_MSG_IGNORE messages reset the - ServerAlive and ClientAlive timers. Prevents dropping a connection - when these are enabled but the peer does not support our keepalives. - bz #1307, ok djm@. - - dtucker@cvs.openbsd.org 2007/12/28 22:34:47 - [clientloop.c] - Use the correct packet maximum sizes for remote port and agent forwarding. - Prevents the server from killing the connection if too much data is queued - and an excessively large packet gets sent. bz #1360, ok djm@. - -20071202 - - (dtucker) [configure.ac] Enable -fstack-protector-all on systems where - gcc supports it. ok djm@ - - (dtucker) [scp.c] Update $OpenBSD tag missing from rev 1.175 and remove - leftover debug code. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/10/29 00:52:45 - [auth2-gss.c] - Allow build without -DGSSAPI; ok deraadt@ - (Id sync only, Portable already has the ifdefs) - - dtucker@cvs.openbsd.org 2007/10/29 01:55:04 - [ssh.c] - Plug tiny mem leaks in ControlPath and ProxyCommand option processing; - ok djm@ - - dtucker@cvs.openbsd.org 2007/10/29 04:08:08 - [monitor_wrap.c monitor.c] - Send config block back to slave for invalid users too so options - set by a Match block (eg Banner) behave the same for non-existent - users. Found by and ok djm@ - - dtucker@cvs.openbsd.org 2007/10/29 06:51:59 - [ssh_config.5] - ProxyCommand and LocalCommand use the user's shell, not /bin/sh; ok djm@ - - dtucker@cvs.openbsd.org 2007/10/29 06:54:50 - [ssh.c] - Make LocalCommand work for Protocol 1 too; ok djm@ - - jmc@cvs.openbsd.org 2007/10/29 07:48:19 - [ssh_config.5] - clean up after previous macro removal; - - djm@cvs.openbsd.org 2007/11/03 00:36:14 - [clientloop.c] - fix memory leak in process_cmdline(), patch from Jan.Pechanec AT Sun.COM; - ok dtucker@ - - deraadt@cvs.openbsd.org 2007/11/03 01:24:06 - [ssh.c] - bz #1377: getpwuid results were being clobbered by another getpw* call - inside tilde_expand_filename(); save the data we need carefully - ok djm - - dtucker@cvs.openbsd.org 2007/11/03 02:00:32 - [ssh.c] - Use xstrdup/xfree when saving pwname and pwdir; ok deraadt@ - - deraadt@cvs.openbsd.org 2007/11/03 02:03:49 - [ssh.c] - avoid errno trashing in signal handler; ok dtucker - -20071030 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/10/29 23:49:41 - [openbsd-compat/sys-tree.h] - remove extra backslash at the end of RB_PROTOTYPE, report from - Jan.Pechanec AT Sun.COM; ok deraadt@ - -20071026 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2007/09/11 23:49:09 - [sshpty.c] - remove #if defined block not needed; ok markus@ dtucker@ - (NB. RCD ID sync only for portable) - - djm@cvs.openbsd.org 2007/09/21 03:05:23 - [ssh_config.5] - document KbdInteractiveAuthentication in ssh_config.5; - patch from dkg AT fifthhorseman.net - - djm@cvs.openbsd.org 2007/09/21 08:15:29 - [auth-bsdauth.c auth-passwd.c auth.c auth.h auth1.c auth2-chall.c] - [monitor.c monitor_wrap.c] - unifdef -DBSD_AUTH - unifdef -USKEY - These options have been in use for some years; - ok markus@ "no objection" millert@ - (NB. RCD ID sync only for portable) - - canacar@cvs.openbsd.org 2007/09/25 23:48:57 - [ssh-agent.c] - When adding a key that already exists, update the properties - (time, confirm, comment) instead of discarding them. ok djm@ markus@ - - ray@cvs.openbsd.org 2007/09/27 00:15:57 - [dh.c] - Don't return -1 on error in dh_pub_is_valid(), since it evaluates - to true. - Also fix a typo. - Initial diff from Matthew Dempsky, input from djm. - OK djm, markus. - - dtucker@cvs.openbsd.org 2007/09/29 00:25:51 - [auth2.c] - Remove unused prototype. ok djm@ - - chl@cvs.openbsd.org 2007/10/02 17:49:58 - [ssh-keygen.c] - handles zero-sized strings that fgets can return - properly removes trailing newline - removes an unused variable - correctly counts line number - "looks ok" ray@ markus@ - - markus@cvs.openbsd.org 2007/10/22 19:10:24 - [readconf.c] - make sure that both the local and remote port are correct when - parsing -L; Jan Pechanec (bz #1378) - - djm@cvs.openbsd.org 2007/10/24 03:30:02 - [sftp.c] - rework argument splitting and parsing to cope correctly with common - shell escapes and make handling of escaped characters consistent - with sh(1) and between sftp commands (especially between ones that - glob their arguments and ones that don't). - parse command flags using getopt(3) rather than hand-rolled parsers. - ok dtucker@ - - djm@cvs.openbsd.org 2007/10/24 03:44:02 - [scp.c] - factor out network read/write into an atomicio()-like function, and - use it to handle short reads, apply bandwidth limits and update - counters. make network IO non-blocking, so a small trickle of - reads/writes has a chance of updating the progress meter; bz #799 - ok dtucker@ - - djm@cvs.openbsd.org 2006/08/29 09:44:00 - [regress/sftp-cmds.sh] - clean up our mess - - markus@cvs.openbsd.org 2006/11/06 09:27:43 - [regress/cfgmatch.sh] - fix quoting for non-(c)sh login shells. - - dtucker@cvs.openbsd.org 2006/12/13 08:36:36 - [regress/cfgmatch.sh] - Additional test for multiple PermitOpen entries. ok djm@ - - pvalchev@cvs.openbsd.org 2007/06/07 19:41:46 - [regress/cipher-speed.sh regress/try-ciphers.sh] - test umac-64@openssh.com - ok djm@ - - djm@cvs.openbsd.org 2007/10/24 03:32:35 - [regress/sftp-cmds.sh regress/sftp-glob.sh regress/test-exec.sh] - comprehensive tests for sftp escaping its interaction with globbing; - ok dtucker@ - - djm@cvs.openbsd.org 2007/10/26 05:30:01 - [regress/sftp-glob.sh regress/test-exec.sh] - remove "echo -E" crap that I added in last commit and use printf(1) for - cases where we strictly require echo not to reprocess escape characters. - - deraadt@cvs.openbsd.org 2005/11/28 17:50:12 - [openbsd-compat/glob.c] - unused arg in internal static API - - jakob@cvs.openbsd.org 2007/10/11 18:36:41 - [openbsd-compat/getrrsetbyname.c openbsd-compat/getrrsetbyname.h] - use RRSIG instead of SIG for DNSSEC. ok djm@ - - otto@cvs.openbsd.org 2006/10/21 09:55:03 - [openbsd-compat/base64.c] - remove calls to abort(3) that can't happen anyway; from - ; ok millert@ deraadt@ - - frantzen@cvs.openbsd.org 2004/04/24 18:11:46 - [openbsd-compat/sys-tree.h] - sync to Niels Provos' version. avoid unused variable warning in - RB_NEXT() - - tdeval@cvs.openbsd.org 2004/11/24 18:10:42 - [openbsd-compat/sys-tree.h] - typo - - grange@cvs.openbsd.org 2004/05/04 16:59:32 - [openbsd-compat/sys-queue.h] - Remove useless ``elm'' argument from the SIMPLEQ_REMOVE_HEAD macro. - This matches our SLIST behaviour and NetBSD's SIMPLEQ as well. - ok millert krw deraadt - - deraadt@cvs.openbsd.org 2005/02/25 13:29:30 - [openbsd-compat/sys-queue.h] - minor white spacing - - otto@cvs.openbsd.org 2005/10/17 20:19:42 - [openbsd-compat/sys-queue.h] - Performing certain operations on queue.h data structurs produced - funny results. An example is calling LIST_REMOVE on the same - element twice. This will not fail, but result in a data structure - referencing who knows what. Prevent these accidents by NULLing some - fields on remove and replace. This way, either a panic or segfault - will be produced on the faulty operation. - - otto@cvs.openbsd.org 2005/10/24 20:25:14 - [openbsd-compat/sys-queue.h] - Partly backout. NOLIST, used in LISTs is probably interfering. - requested by deraadt@ - - otto@cvs.openbsd.org 2005/10/25 06:37:47 - [openbsd-compat/sys-queue.h] - Some uvm problem is being exposed with the more strict macros. - Revert until we've found out what's causing the panics. - - otto@cvs.openbsd.org 2005/11/25 08:06:25 - [openbsd-compat/sys-queue.h] - Introduce debugging aid for queue macros. Disabled by default; but - developers are encouraged to run with this enabled. - ok krw@ fgsch@ deraadt@ - - otto@cvs.openbsd.org 2007/04/30 18:42:34 - [openbsd-compat/sys-queue.h] - Enable QUEUE_MACRO_DEBUG on DIAGNOSTIC kernels. - Input and okays from krw@, millert@, otto@, deraadt@, miod@. - - millert@cvs.openbsd.org 2004/10/07 16:56:11 - GLOB_NOESCAPE is POSIX so move it out of the #ifndef _POSIX_SOURCE - block. - (NB. mostly an RCS ID sync, as portable strips out the conditionals) - - (djm) [regress/sftp-cmds.sh] - Use more restrictive glob to pick up test files from /bin - some platforms - ship broken symlinks there which could spoil the test. - - (djm) [openbsd-compat/bindresvport.c] - Sync RCS ID after irrelevant (for portable OpenSSH) header shuffling - -20070927 - - (dtucker) [configure.ac atomicio.c] Fall back to including if - we don't have (eq QNX). From bacon at cs nyu edu. - - (dtucker) [configure.ac defines.h] Shadow expiry does not work on QNX6 - so disable it for that platform. From bacon at cs nyu edu. - -20070921 - - (djm) [atomicio.c] Fix spin avoidance for platforms that define - EWOULDBLOCK; patch from ben AT psc.edu - -20070917 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/08/23 02:49:43 - [auth-passwd.c auth.c session.c] - unifdef HAVE_LOGIN_CAP; ok deraadt@ millert@ - NB. RCS ID sync only for portable - - djm@cvs.openbsd.org 2007/08/23 02:55:51 - [auth-passwd.c auth.c session.c] - missed include bits from last commit - NB. RCS ID sync only for portable - - djm@cvs.openbsd.org 2007/08/23 03:06:10 - [auth.h] - login_cap.h doesn't belong here - NB. RCS ID sync only for portable - - djm@cvs.openbsd.org 2007/08/23 03:22:16 - [auth2-none.c sshd_config sshd_config.5] - Support "Banner=none" to disable displaying of the pre-login banner; - ok dtucker@ deraadt@ - - djm@cvs.openbsd.org 2007/08/23 03:23:26 - [sshconnect.c] - Execute ProxyCommands with $SHELL rather than /bin/sh unconditionally - - djm@cvs.openbsd.org 2007/09/04 03:21:03 - [clientloop.c monitor.c monitor_fdpass.c monitor_fdpass.h] - [monitor_wrap.c ssh.c] - make file descriptor passing code return an error rather than call fatal() - when it encounters problems, and use this to make session multiplexing - masters survive slaves failing to pass all stdio FDs; ok markus@ - - djm@cvs.openbsd.org 2007/09/04 11:15:56 - [ssh.c sshconnect.c sshconnect.h] - make ssh(1)'s ConnectTimeout option apply to both the TCP connection and - SSH banner exchange (previously it just covered the TCP connection). - This allows callers of ssh(1) to better detect and deal with stuck servers - that accept a TCP connection but don't progress the protocol, and also - makes ConnectTimeout useful for connections via a ProxyCommand; - feedback and "looks ok" markus@ - - sobrado@cvs.openbsd.org 2007/09/09 11:38:01 - [ssh-add.c ssh-agent.1 ssh-agent.c ssh-keygen.c] - sort synopsis and options in ssh-agent(1); usage is lowercase - ok jmc@ - - stevesk@cvs.openbsd.org 2007/09/11 04:36:29 - [sshpty.c] - sort #include - NB. RCS ID sync only - - gilles@cvs.openbsd.org 2007/09/11 15:47:17 - [session.c ssh-keygen.c sshlogin.c] - use strcspn to properly overwrite '\n' in fgets returned buffer - ok pyr@, ray@, millert@, moritz@, chl@ - - stevesk@cvs.openbsd.org 2007/09/11 23:49:09 - [sshpty.c] - remove #if defined block not needed; ok markus@ dtucker@ - NB. RCS ID sync only - - stevesk@cvs.openbsd.org 2007/09/12 19:39:19 - [umac.c] - use xmalloc() and xfree(); ok markus@ pvalchev@ - - djm@cvs.openbsd.org 2007/09/13 04:39:04 - [sftp-server.c] - fix incorrect test when setting syslog facility; from Jan Pechanec - - djm@cvs.openbsd.org 2007/09/16 00:55:52 - [sftp-client.c] - use off_t instead of u_int64_t for file offsets, matching what the - progressmeter code expects; bz #842 - - (tim) [defines.h] Fix regression in long password support on OpenServer 6. - Problem report and additional testing rac AT tenzing.org. - -20070914 - - (dtucker) [openbsd-compat/bsd-asprintf.c] Plug mem leak in error path. - Patch from Jan.Pechanec at sun com. - -20070910 - - (dtucker) [openbsd-compat/regress/closefromtest.c] Bug #1358: Always - return 0 on successful test. From David.Leonard at quest com. - - (tim) [configure.ac] Autoconf didn't define HAVE_LIBIAF because we - did a AC_CHECK_FUNCS within the AC_CHECK_LIB test. - -20070817 - - (dtucker) [sshd.8] Many Linux variants use a single "!" to denote locked - accounts and that's what the code looks for, so make man page and code - agree. Pointed out by Roumen Petrov. - - (dtucker) [INSTALL] Group the parts describing random options and PAM - implementations together which is hopefully more coherent. - - (dtucker) [INSTALL] the pid file is sshd.pid not ssh.pid. - - (dtucker) [INSTALL] Give PAM its own heading. - - (dtucker) [INSTALL] Link to tcpwrappers. - -20070816 - - (dtucker) [session.c] Call PAM cleanup functions for unauthenticated - connections too. Based on a patch from Sandro Wefel, with & ok djm@ - -20070815 - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2007/08/15 08:14:46 - [clientloop.c] - do NOT fall back to the trused x11 cookie if generation of an untrusted - cookie fails; from Jan Pechanec, via security-alert at sun.com; - ok dtucker - - markus@cvs.openbsd.org 2007/08/15 08:16:49 - [version.h] - openssh 4.7 - - stevesk@cvs.openbsd.org 2007/08/15 12:13:41 - [ssh_config.5] - tun device forwarding now honours ExitOnForwardFailure; ok markus@ - - (dtucker) [openbsd-compat/bsd-cray.c] Remove debug from signal handler. - ok djm@ - - (dtucker) [README contrib/caldera/openssh.spec contrib/redhat/openssh.spec - contrib/suse/openssh.spec] Crank version. - -20070813 - - (dtucker) [session.c] Bug #1339: ensure that pam_setcred() is always - called with PAM_ESTABLISH_CRED at least once, which resolves a problem - with pam_dhkeys. Patch from David Leonard, ok djm@ - -20070810 - - (dtucker) [auth-pam.c] Use sigdie here too. ok djm@ - - (dtucker) [configure.ac] Bug #1343: Set DISABLE_FD_PASSING for QNX6. From - Matt Kraai, ok djm@ - -20070809 - - (dtucker) [openbsd-compat/port-aix.c] Comment typo. - - (dtucker) [README.platform] Document the interaction between PermitRootLogin - and the AIX native login restrictions. - - (dtucker) [defines.h] Remove _PATH_{CSHELL,SHELLS} which aren't - used anywhere and are a potential source of warnings. - -20070808 - - (djm) OpenBSD CVS Sync - - ray@cvs.openbsd.org 2007/07/12 05:48:05 - [key.c] - Delint: remove some unreachable statements, from Bret Lambert. - OK markus@ and dtucker@. - - sobrado@cvs.openbsd.org 2007/08/06 19:16:06 - [scp.1 scp.c] - the ellipsis is not an optional argument; while here, sync the usage - and synopsis of commands - lots of good ideas by jmc@ - ok jmc@ - - djm@cvs.openbsd.org 2007/08/07 07:32:53 - [clientloop.c clientloop.h ssh.c] - bz#1232: ensure that any specified LocalCommand is executed after the - tunnel device is opened. Also, make failures to open a tunnel device - fatal when ExitOnForwardFailure is active. - Reported by h.goebel AT goebel-consult.de; ok dtucker markus reyk deraadt - -20070724 - - (tim) [openssh.xml.in] make FMRI match what package scripts use. - - (tim) [openbsd-compat/regress/closefromtest.c] Bug 1345: fix open() call. - Report/patch by David.Leonard AT quest.com (and Bernhard Simon) - - (tim) [buildpkg.sh.in openssh.xml.in] Allow more flexibility where smf(5) - - (tim) [buildpkg.sh.in] s|$FAKE_ROOT/${sysconfdir}|$FAKE_ROOT${sysconfdir}| - -20070628 - - (djm) bz#1325: Fix SELinux in permissive mode where it would - incorrectly fatal() on errors. patch from cjwatson AT debian.org; - ok dtucker - -20070625 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/06/13 00:21:27 - [scp.c] - don't ftruncate() non-regular files; bz#1236 reported by wood AT - xmission.com; ok dtucker@ - - djm@cvs.openbsd.org 2007/06/14 21:43:25 - [ssh.c] - handle EINTR when waiting for mux exit status properly - - djm@cvs.openbsd.org 2007/06/14 22:48:05 - [ssh.c] - when waiting for the multiplex exit status, read until the master end - writes an entire int of data *and* closes the client_fd; fixes mux - regression spotted by dtucker, ok dtucker@ - - djm@cvs.openbsd.org 2007/06/19 02:04:43 - [atomicio.c] - if the fd passed to atomicio/atomiciov() is non blocking, then poll() to - avoid a spin if it is not yet ready for reading/writing; ok dtucker@ - - dtucker@cvs.openbsd.org 2007/06/25 08:20:03 - [channels.c] - Correct test for window updates every three packets; prevents sending - window updates for every single packet. ok markus@ - - dtucker@cvs.openbsd.org 2007/06/25 12:02:27 - [atomicio.c] - Include like the man page says rather than . ok djm@ - - (dtucker) [atomicio.c] Test for EWOULDBLOCK in atomiciov to match - atomicio. - - (dtucker) [atomicio.c configure.ac openbsd-compat/Makefile.in - openbsd-compat/bsd-poll.{c,h} openbsd-compat/openbsd-compat.h] - Add an implementation of poll() built on top of select(2). Code from - OpenNTPD with changes suggested by djm. ok djm@ - -20070614 - - (dtucker) [cipher-ctr.c umac.c openbsd-compat/openssl-compat.h] Move the - USE_BUILTIN_RIJNDAEL compat goop to openssl-compat.h so it can be - shared with umac.c. Allows building with OpenSSL 0.9.5 again including - umac support. With tim@ djm@, ok djm. - - (dtucker) [openbsd-compat/openssl-compat.h] Merge USE_BUILTIN_RIJNDAEL - sections. Fixes builds with early OpenSSL 0.9.6 versions. - - (dtucker) [openbsd-compat/openssl-compat.h] Remove redundant definition - of USE_BUILTIN_RIJNDAEL since the <0.9.6 test is covered by the - subsequent <0.9.7 test. - -20070612 - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2007/06/11 09:14:00 - [channels.h] - increase default channel windows; ok djm - - djm@cvs.openbsd.org 2007/06/12 07:41:00 - [ssh-add.1] - better document ssh-add's -d option (delete identies from agent), bz#1224 - new text based on some provided by andrewmc-debian AT celt.dias.ie; - ok dtucker@ - - djm@cvs.openbsd.org 2007/06/12 08:20:00 - [ssh-gss.h gss-serv.c gss-genr.c] - relocate server-only GSSAPI code from libssh to server; bz #1225 - patch from simon AT sxw.org.uk; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2007/06/12 08:24:20 - [scp.c] - make scp try to skip FIFOs rather than blocking when nothing is listening. - depends on the platform supporting sane O_NONBLOCK semantics for open - on FIFOs (apparently POSIX does not mandate this), which OpenBSD does. - bz #856; report by cjwatson AT debian.org; ok markus@ - - djm@cvs.openbsd.org 2007/06/12 11:11:08 - [ssh.c] - fix slave exit value when a control master goes away without passing the - full exit status by ensuring that the slave reads a full int. bz#1261 - reported by frekko AT gmail.com; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2007/06/12 11:15:17 - [ssh.c ssh.1] - Add "-K" flag for ssh to set GSSAPIAuthentication=yes and - GSSAPIDelegateCredentials=yes. This is symmetric with -k (disable GSSAPI) - and is useful for hosts with /home on Kerberised NFS; bz #1312 - patch from Markus.Kuhn AT cl.cam.ac.uk; ok dtucker@ markus@ - - djm@cvs.openbsd.org 2007/06/12 11:45:27 - [ssh.c] - improved exit message from multiplex slave sessions; bz #1262 - reported by alexandre.nunes AT gmail.com; ok dtucker@ - - dtucker@cvs.openbsd.org 2007/06/12 11:56:15 - [gss-genr.c] - Pass GSS OID to gss_display_status to provide better information in - error messages. Patch from Simon Wilkinson via bz 1220. ok djm@ - - jmc@cvs.openbsd.org 2007/06/12 13:41:03 - [ssh-add.1] - identies -> identities; - - jmc@cvs.openbsd.org 2007/06/12 13:43:55 - [ssh.1] - add -K to SYNOPSIS; - - dtucker@cvs.openbsd.org 2007/06/12 13:54:28 - [scp.c] - Encode filename with strnvis if the name contains a newline (which can't - be represented in the scp protocol), from bz #891. ok markus@ - -20070611 - - (djm) Bugzilla #1306: silence spurious error messages from hang-on-exit - fix; tested by dtucker@ and jochen.kirn AT gmail.com - - pvalchev@cvs.openbsd.org 2007/06/07 19:37:34 - [kex.h mac.c mac.h monitor_wrap.c myproposal.h packet.c ssh.1] - [ssh_config.5 sshd.8 sshd_config.5] - Add a new MAC algorithm for data integrity, UMAC-64 (not default yet, - must specify umac-64@openssh.com). Provides about 20% end-to-end speedup - compared to hmac-md5. Represents a different approach to message - authentication to that of HMAC that may be beneficial if HMAC based on - one of its underlying hash algorithms is found to be vulnerable to a - new attack. http://www.ietf.org/rfc/rfc4418.txt - in conjunction with and OK djm@ - - pvalchev@cvs.openbsd.org 2007/06/08 04:40:40 - [ssh_config] - Add a "MACs" line after "Ciphers" with the default MAC algorithms, - to ease people who want to tweak both (eg. for performance reasons). - ok deraadt@ djm@ dtucker@ - - jmc@cvs.openbsd.org 2007/06/08 07:43:46 - [ssh_config.5] - put the MAC list into a display, like we do for ciphers, - since groff has trouble handling wide lines; - - jmc@cvs.openbsd.org 2007/06/08 07:48:09 - [sshd_config.5] - oops, here too: put the MAC list into a display, like we do for - ciphers, since groff has trouble with wide lines; - - markus@cvs.openbsd.org 2007/06/11 08:04:44 - [channels.c] - send 'window adjust' messages every tree packets and do not wait - until 50% of the window is consumed. ok djm dtucker - - (djm) [configure.ac umac.c] If platform doesn't provide swap32(3), then - fallback to provided bit-swizzing functions - - (dtucker) [openbsd-compat/bsd-misc.c] According to the spec the "remainder" - argument to nanosleep may be NULL. Currently this never happens in OpenSSH, - but check anyway in case this changes or the code gets used elsewhere. - - (dtucker) [includes.h] Bug #1243: HAVE_PATHS -> HAVE_PATHS_H. Should - prevent warnings about redefinitions of various things in paths.h. - Spotted by cartmanltd at hotmail.com. - -20070605 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/05/22 10:18:52 - [sshd.c] - zap double include; from p_nowaczyk AT o2.pl - (not required in -portable, Id sync only) - - djm@cvs.openbsd.org 2007/05/30 05:58:13 - [kex.c] - tidy: KNF, ARGSUSED and u_int - - jmc@cvs.openbsd.org 2007/05/31 19:20:16 - [scp.1 ssh_config.5 sftp-server.8 ssh-agent.1 sshd_config.5 sftp.1 - ssh-keygen.1 ssh-keyscan.1 ssh-add.1 sshd.8 ssh.1 ssh-keysign.8] - convert to new .Dd format; - (We will need to teach mdoc2man.awk to understand this too.) - - djm@cvs.openbsd.org 2007/05/31 23:34:29 - [packet.c] - gc unreachable code; spotted by Tavis Ormandy - - djm@cvs.openbsd.org 2007/06/02 09:04:58 - [bufbn.c] - memory leak on error path; from arnaud.lacombe.1 AT ulaval.ca - - djm@cvs.openbsd.org 2007/06/05 06:52:37 - [kex.c monitor_wrap.c packet.c mac.h kex.h mac.c] - Preserve MAC ctx between packets, saving 2xhash calls per-packet. - Yields around a 12-16% end-to-end speedup for arcfour256/hmac-md5 - patch from markus@ tested dtucker@ and myself, ok markus@ and me (I'm - committing at his request) - - (dtucker) [mdoc2man.awk] Teach it to deal with $Mdocdate tags that - OpenBSD's cvs now adds. - - (dtucker) [mdoc2man.awk] Remove trailing "$" from Mdocdate regex so - mindrot's cvs doesn't expand it on us. - - (dtucker) [mdoc2man.awk] Add support for %R references, used for RFCs. - -20070520 - - (dtucker) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2007/04/14 22:01:58 - [auth2.c] - remove unused macro; from Dmitry V. Levin - - stevesk@cvs.openbsd.org 2007/04/18 01:12:43 - [sftp-server.c] - cast "%llu" format spec to (unsigned long long); do not assume a - u_int64_t arg is the same as 'unsigned long long'. - from Dmitry V. Levin - ok markus@ 'Yes, that looks correct' millert@ - - dtucker@cvs.openbsd.org 2007/04/23 10:15:39 - [servconf.c] - Remove debug() left over from development. ok deraadt@ - - djm@cvs.openbsd.org 2007/05/17 07:50:31 - [log.c] - save and restore errno when logging; ok deraadt@ - - djm@cvs.openbsd.org 2007/05/17 07:55:29 - [sftp-server.c] - bz#1286 stop reading and processing commands when input or output buffer - is nearly full, otherwise sftp-server would happily try to grow the - input/output buffers past the maximum supported by the buffer API and - promptly fatal() - based on patch from Thue Janus Kristensen; feedback & ok dtucker@ - - djm@cvs.openbsd.org 2007/05/17 20:48:13 - [sshconnect2.c] - fall back to gethostname() when the outgoing connection is not - on a socket, such as is the case when ProxyCommand is used. - Gives hostbased auth an opportunity to work; bz#616, report - and feedback stuart AT kaloram.com; ok markus@ - - djm@cvs.openbsd.org 2007/05/17 20:52:13 - [monitor.c] - pass received SIGINT from monitor to postauth child so it can clean - up properly. bz#1196, patch from senthilkumar_sen AT hotpop.com; - ok markus@ - - jolan@cvs.openbsd.org 2007/05/17 23:53:41 - [sshconnect2.c] - djm owes me a vb and a tism cd for breaking ssh compilation - - (dtucker) [auth-pam.c] malloc+memset -> calloc. Patch from - ldv at altlinux.org. - - (dtucker) [auth-pam.c] Return empty string if fgets fails in - sshpam_tty_conv. Patch from ldv at altlinux.org. - -20070509 - - (tim) [configure.ac] Bug #1287: Add missing test for ucred.h. - -20070429 - - (dtucker) [openbsd-compat/bsd-misc.c] Include unistd.h and sys/types.h - for select(2) prototype. - - (dtucker) [auth-shadow.c loginrec.c] Include time.h for time(2) prototype. - - (dtucker) [configure.ac openbsd-compat/getrrsetbyname.c] Bug #1299: Use the - platform's _res if it has one. Should fix problem of DNSSEC record lookups - on NetBSD as reported by Curt Sampson. - - (dtucker) [openbsd-compat/xmmap.c] Include stdlib.h for mkstemp prototype. - - (dtucker) [configure.ac defines.h] Have configure check for MAXSYMLINKS - so we don't get redefinition warnings. - - (dtucker) [openbsd-compat/xmmap.c] Include stdlib.h for mkstemp prototype. - - (dtucker) [configure.ac defines.h] Prevent warnings about __attribute__ - __nonnull__ for versions of GCC that don't support it. - - (dtucker) [configure.ac defines.h] Have configure check for offsetof - to prevent redefinition warnings. - -20070406 - - (dtucker) [INSTALL] Update the systems that have PAM as standard. Link - to OpenPAM too. - - (dtucker) [INSTALL] prngd lives at sourceforge these days. - -20070326 - - (tim) [auth.c configure.ac defines.h session.c openbsd-compat/port-uw.c - openbsd-compat/port-uw.h openbsd-compat/xcrypt.c] Rework libiaf test/defines - to account for IRIX having libiaf but not set_id(). Patch with & ok dtucker@ - -20070325 - - (dtucker) [Makefile.in configure.ac] Replace single-purpose LIBSELINUX, - LIBWRAP and LIBPAM variables in Makefile with the general-purpose - SSHDLIBS. "I like" djm@ - -20070321 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/03/09 05:20:06 - [servconf.c sshd.c] - Move C/R -> kbdint special case to after the defaults have been - loaded, which makes ChallengeResponse default to yes again. This - was broken by the Match changes and not fixed properly subsequently. - Found by okan at demirmen.com, ok djm@ "please do it" deraadt@ - - djm@cvs.openbsd.org 2007/03/19 01:01:29 - [sshd_config] - Disable the legacy SSH protocol 1 for new installations via - a configuration override. In the future, we will change the - server's default itself so users who need the legacy protocol - will need to turn it on explicitly - - dtucker@cvs.openbsd.org 2007/03/19 12:16:42 - [ssh-agent.c] - Remove the signal handler that checks if the agent's parent process - has gone away, instead check when the select loop returns. Record when - the next key will expire when scanning for expired keys. Set the select - timeout to whichever of these two things happens next. With djm@, with & - ok deraadt@ markus@ - - tedu@cvs.openbsd.org 2007/03/20 03:56:12 - [readconf.c clientloop.c] - remove some bogus *p tests from charles longeau - ok deraadt millert - - jmc@cvs.openbsd.org 2007/03/20 15:57:15 - [sshd.8] - - let synopsis and description agree for -f - - sort FILES - - +.Xr ssh-keyscan 1 , - from Igor Sobrado - - (dtucker) [configure.ac openbsd-compat/bsd-getpeereid.c] Bug #1287: Use - getpeerucred to implement getpeereid (currently only Solaris 10 and up). - Patch by Jan.Pechanec at Sun. - - (dtucker) [regress/agent-getpeereid.sh] Do peereid test if we have - HAVE_GETPEERUCRED too. Also from Jan Pechanec. - -20070313 - - (dtucker) [entropy.c scard-opensc.c ssh-rand-helper.c] Bug #1294: include - string.h to prevent warnings, from vapier at gentoo.org. - - (dtucker) [LICENCE] Add Daniel Walsh as a copyright holder for the - selinux bits in -portable. - - (dtucker) [cipher-3des1.c cipher-bf1.c] The OpenSSL 0.9.8e problem in - bug #1291 also affects Protocol 1 3des. While at it, use compat-openssl.h - in cipher-bf1.c. Patch from Juan Gallego. - - (dtucker) [README.platform] Info about blibpath on AIX. - -20070306 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2007/03/01 16:19:33 - [sshd_config.5] - sort the `match' keywords; - - djm@cvs.openbsd.org 2007/03/06 10:13:14 - [version.h] - openssh-4.6; "please" deraadt@ - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] crank spec files for release - - (djm) [README] correct link to release notes - - (djm) Release 4.6p1 - -20070304 - - (djm) [configure.ac] add a --without-openssl-header-check option to - configure, as some platforms (OS X) ship OpenSSL headers whose version - does not match that of the shipping library. ok dtucker@ - - (dtucker) [openbsd-compat/openssl-compat.h] Bug #1291: Work around a - bug in OpenSSL 0.9.8e that prevents aes256-ctr, aes192-ctr and arcfour256 - ciphers from working correctly (disconnects with "Bad packet length" - errors) as found by Ben Harris. ok djm@ - -20070303 - - (dtucker) [regress/agent-ptrace.sh] Make ttrace gdb error a little more - general to cover newer gdb versions on HP-UX. - -20070302 - - (dtucker) [configure.ac] For Cygwin, read files in textmode (which allows - CRLF as well as LF lineendings) and write in binary mode. Patch from - vinschen at redhat.com. - - (dtucker) [INSTALL] Update to autoconf-2.61. - -20070301 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/03/01 10:28:02 - [auth2.c sshd_config.5 servconf.c] - Remove ChallengeResponseAuthentication support inside a Match - block as its interaction with KbdInteractive makes it difficult to - support. Also, relocate the CR/kbdint option special-case code into - servconf. "please commit" djm@, ok markus@ for the relocation. - - (tim) [buildpkg.sh.in openssh.xml.in] Clean up Solaris 10 smf(5) bits. - "Looks sane" dtucker@ - -20070228 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2007/02/28 00:55:30 - [ssh-agent.c] - Remove expired keys periodically so they don't remain in memory when - the agent is entirely idle, as noted by David R. Piegdon. This is the - simple fix, a more efficient one will be done later. With markus, - deraadt, with & ok djm. - -20070225 - - (dtucker) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2007/02/20 10:25:14 - [clientloop.c] - set maximum packet and window sizes the same for multiplexed clients - as normal connections; ok markus@ - - dtucker@cvs.openbsd.org 2007/02/21 11:00:05 - [sshd.c] - Clear alarm() before restarting sshd on SIGHUP. Without this, if there's - a SIGALRM pending (for SSH1 key regeneration) when sshd is SIGHUP'ed, the - newly exec'ed sshd will get the SIGALRM and not have a handler for it, - and the default action will terminate the listening sshd. Analysis and - patch from andrew at gaul.org. - - dtucker@cvs.openbsd.org 2007/02/22 12:58:40 - [servconf.c] - Check activep so Match and GatewayPorts work together; ok markus@ - - ray@cvs.openbsd.org 2007/02/24 03:30:11 - [moduli.c] - - strlen returns size_t, not int. - - Pass full buffer size to fgets. - OK djm@, millert@, and moritz@. - -20070219 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2007/01/10 13:23:22 - [ssh_config.5] - do not use a list for SYNOPSIS; - this is actually part of a larger report sent by eric s. raymond - and forwarded by brad, but i only read half of it. spotted by brad. - - jmc@cvs.openbsd.org 2007/01/12 20:20:41 - [ssh-keygen.1 ssh-keygen.c] - more secsh -> rfc 4716 updates; - spotted by wiz@netbsd - ok markus - - dtucker@cvs.openbsd.org 2007/01/17 23:22:52 - [readconf.c] - Honour activep for times (eg ServerAliveInterval) while parsing - ssh_config and ~/.ssh/config so they work properly with Host directives. - From mario.lorenz@wincor-nixdorf.com via bz #1275. ok markus@ - - stevesk@cvs.openbsd.org 2007/01/21 01:41:54 - [auth-skey.c kex.c ssh-keygen.c session.c clientloop.c] - spaces - - stevesk@cvs.openbsd.org 2007/01/21 01:45:35 - [readconf.c] - spaces - - djm@cvs.openbsd.org 2007/01/22 11:32:50 - [sftp-client.c] - return error from do_upload() when a write fails. fixes bz#1252: zero - exit status from sftp when uploading to a full device. report from - jirkat AT atlas.cz; ok dtucker@ - - djm@cvs.openbsd.org 2007/01/22 13:06:21 - [scp.c] - fix detection of whether we should show progress meter or not: scp - tested isatty(stderr) but wrote the progress meter to stdout. This patch - makes it test stdout. bz#1265 reported by junkmail AT bitsculpture.com; - of dtucker@ - - stevesk@cvs.openbsd.org 2007/02/14 14:32:00 - [bufbn.c] - typos in comments; ok jmc@ - - dtucker@cvs.openbsd.org 2007/02/19 10:45:58 - [monitor_wrap.c servconf.c servconf.h monitor.c sshd_config.5] - Teach Match how handle config directives that are used before - authentication. This allows configurations such as permitting password - authentication from the local net only while requiring pubkey from - offsite. ok djm@, man page bits ok jmc@ - - (dtucker) [contrib/findssl.sh] Add "which" as a shell function since some - platforms don't have it. Patch from dleonard at vintela.com. - - (dtucker) [openbsd-compat/getrrsetbyname.c] Don't attempt to calloc - an array for signatures when there are none since "calloc(0, n) returns - NULL on some platforms (eg Tru64), which is explicitly permitted by - POSIX. Diagnosis and patch by svallet genoscope.cns.fr. - -20070128 - - (djm) [channels.c serverloop.c] Fix so-called "hang on exit" (bz #52) - when closing a tty session when a background process still holds tty - fds open. Great detective work and patch by Marc Aurele La France, - slightly tweaked by me; ok dtucker@ - -20070123 - - (dtucker) [openbsd-compat/bsd-snprintf.c] Static declarations for public - library interfaces aren't very helpful. Fix up the DOPR_OUTCH macro - so it works properly and modify its callers so that they don't pre or - post decrement arguments that are conditionally evaluated. While there, - put SNPRINTF_CONST back as it prevents build failures in some - configurations. ok djm@ (for most of it) - -20070122 - - (djm) [ssh-rand-helper.8] manpage nits; - from dleonard AT vintela.com (bz#1529) - -20070117 - - (dtucker) [packet.c] Re-remove in_systm.h since it's already in includes.h - and multiple including it causes problems on old IRIXes. (It snuck back - in during a sync.) Found (again) by Georg Schwarz. - -20070114 - - (dtucker) [ssh-keygen.c] av -> argv to match earlier sync. - - (djm) [openbsd-compat/bsd-snprintf.c] Fix integer overflow in return - value of snprintf replacement, similar to bugs in various libc - implementations. This overflow is not exploitable in OpenSSH. - While I'm fiddling with it, make it a fair bit faster by inlining the - append-char routine; ok dtucker@ - -20070105 - - (djm) OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2006/11/14 19:41:04 - [ssh-keygen.c] - use argc and argv not some made up short form - - ray@cvs.openbsd.org 2006/11/23 01:35:11 - [misc.c sftp.c] - Don't access buf[strlen(buf) - 1] for zero-length strings. - ``ok by me'' djm@. - - markus@cvs.openbsd.org 2006/12/11 21:25:46 - [ssh-keygen.1 ssh.1] - add rfc 4716 (public key format); ok jmc - - djm@cvs.openbsd.org 2006/12/12 03:58:42 - [channels.c compat.c compat.h] - bz #1019: some ssh.com versions apparently can't cope with the - remote port forwarding bind_address being a hostname, so send - them an address for cases where they are not explicitly - specified (wildcard or localhost bind). reported by daveroth AT - acm.org; ok dtucker@ deraadt@ - - dtucker@cvs.openbsd.org 2006/12/13 08:34:39 - [servconf.c] - Make PermitOpen work with multiple values like the man pages says. - bz #1267 with details from peter at dmtz.com, with & ok djm@ - - dtucker@cvs.openbsd.org 2006/12/14 10:01:14 - [servconf.c] - Make "PermitOpen all" first-match within a block to match the way other - options work. ok markus@ djm@ - - jmc@cvs.openbsd.org 2007/01/02 09:57:25 - [sshd_config.5] - do not use lists for SYNOPSIS; - from eric s. raymond via brad - - stevesk@cvs.openbsd.org 2007/01/03 00:53:38 - [ssh-keygen.c] - remove small dead code; arnaud.lacombe.1@ulaval.ca via Coverity scan - - stevesk@cvs.openbsd.org 2007/01/03 03:01:40 - [auth2-chall.c channels.c dns.c sftp.c ssh-keygen.c ssh.c] - spaces - - stevesk@cvs.openbsd.org 2007/01/03 04:09:15 - [sftp.c] - ARGSUSED for lint - - stevesk@cvs.openbsd.org 2007/01/03 07:22:36 - [sftp-server.c] - spaces - -20061205 - - (djm) [auth.c] Fix NULL pointer dereference in fakepw(). Crash would - occur if the server did not have the privsep user and an invalid user - tried to login and both privsep and krb5 auth are disabled; ok dtucker@ - - (djm) [bsd-asprintf.c] Better test for bad vsnprintf lengths; ok dtucker@ - -20061108 - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2006/11/07 13:02:07 - [dh.c] - BN_hex2bn returns int; from dtucker@ - -20061107 - - (dtucker) [sshd.c] Use privsep_pw if we have it, but only require it - if we absolutely need it. Pointed out by Corinna, ok djm@ - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2006/11/06 21:25:28 - [auth-rsa.c kexgexc.c kexdhs.c key.c ssh-dss.c sshd.c kexgexs.c - ssh-keygen.c bufbn.c moduli.c scard.c kexdhc.c sshconnect1.c dh.c rsa.c] - add missing checks for openssl return codes; with & ok djm@ - - markus@cvs.openbsd.org 2006/11/07 10:31:31 - [monitor.c version.h] - correctly check for bad signatures in the monitor, otherwise the monitor - and the unpriv process can get out of sync. with dtucker@, ok djm@, - dtucker@ - - (dtucker) [README contrib/{caldera,redhat,contrib}/openssh.spec] Bump - versions. - - (dtucker) Release 4.5p1. - -20061105 - - (djm) OpenBSD CVS Sync - - otto@cvs.openbsd.org 2006/10/28 18:08:10 - [ssh.1] - correct/expand example of usage of -w; ok jmc@ stevesk@ - - markus@cvs.openbsd.org 2006/10/31 16:33:12 - [kexdhc.c kexdhs.c kexgexc.c kexgexs.c] - check DH_compute_key() for -1 even if it should not happen because of - earlier calls to dh_pub_is_valid(); report krahmer at suse.de; ok djm - -20061101 - - (dtucker) [openbsd-compat/port-solaris.c] Bug #1255: Make only hwerr - events fatal in Solaris process contract support and tell it to signal - only processes in the same process group when something happens. - Based on information from andrew.benham at thus.net and similar to - a patch from Chad Mynhier. ok djm@ - -20061027 -- (djm) [auth.c] gc some dead code - -20061023 - - (djm) OpenBSD CVS Sync - - ray@cvs.openbsd.org 2006/09/30 17:48:22 - [sftp.c] - Clear errno before calling the strtol functions. - From Paul Stoeber . - OK deraadt@. - - djm@cvs.openbsd.org 2006/10/06 02:29:19 - [ssh-agent.c ssh-keyscan.c ssh.c] - sys/resource.h needs sys/time.h; prompted by brad@ - (NB. Id sync only for portable) - - djm@cvs.openbsd.org 2006/10/09 23:36:11 - [session.c] - xmalloc -> xcalloc that was missed previously, from portable - (NB. Id sync only for portable, obviously) - - markus@cvs.openbsd.org 2006/10/10 10:12:45 - [sshconnect.c] - sleep before retrying (not after) since sleep changes errno; fixes - pr 5250; rad@twig.com; ok dtucker djm - - markus@cvs.openbsd.org 2006/10/11 12:38:03 - [clientloop.c serverloop.c] - exit instead of doing a blocking tcp send if we detect a client/server - timeout, since the tcp sendqueue might be already full (of alive - requests); ok dtucker, report mpf - - djm@cvs.openbsd.org 2006/10/22 02:25:50 - [sftp-client.c] - cancel progress meter when upload write fails; ok deraadt@ - - (tim) [Makefile.in scard/Makefile.in] Add datarootdir= lines to keep - autoconf 2.60 from complaining. - -20061018 - - (dtucker) OpenBSD CVS Sync - - ray@cvs.openbsd.org 2006/09/25 04:55:38 - [ssh-keyscan.1 ssh.1] - Change "a SSH" to "an SSH". Hurray, I'm not the only one who - pronounces "SSH" as "ess-ess-aich". - OK jmc@ and stevesk@. - - (dtucker) [sshd.c] Reshuffle storing of pw struct; prevents warnings - on older versions of OS X. ok djm@ - -20061016 - - (dtucker) [monitor_fdpass.c] Include sys/in.h, required for cmsg macros - on older (2.0) Linuxes. Based on patch from thmo-13 at gmx de. - -20061006 - - (tim) [buildpkg.sh.in] Use uname -r instead of -v in OS_VER for Solaris. - Differentiate between OpenServer 5 and OpenServer 6 - - (dtucker) [configure.ac] Set put -lselinux into $LIBS while testing for - SELinux functions so they're detected correctly. Patch from pebenito at - gentoo.org. - - (tim) [buildpkg.sh.in] Some systems have really limited nawk (OpenServer). - Allow setting alternate awk in openssh-config.local. - -20061003 - - (tim) [configure.ac] Move CHECK_HEADERS test before platform specific - section so additional platform specific CHECK_HEADER tests will work - correctly. Fixes " on FreeBSD" problem report by des AT des.no - Feedback and "seems like a good idea" dtucker@ - -20061001 - - (dtucker) [audit-bsm.c] Include errno.h. Pointed out by des at des.no. - -20060929 - - (dtucker) [configure.ac] Bug #1239: Fix configure test for OpenSSH engine - support. Patch from andrew.benham at thus net. - -20060928 - - (dtucker) [entropy.c] Bug #1238: include signal.h to fix compilation error - on Solaris 8 w/out /dev/random or prngd. Patch from rl at - math.technion.ac.il. - -20060926 - - (dtucker) [bufaux.h] nuke bufaux.h; it's already gone from OpenBSD and not - referenced any more. ok djm@ - - (dtucker) [sftp-server.8] Resync; spotted by djm@ - - (dtucker) Release 4.4p1. - -20060924 - - (tim) [configure.ac] Remove CFLAGS hack for UnixWare 1.x/2.x (added - to rev 1.308) to work around broken gcc 2.x header file. - -20060923 - - (dtucker) [configure.ac] Bug #1234: Put opensc libs into $LIBS rather than - $LDFLAGS. Patch from vapier at gentoo org. - -20060922 - - (dtucker) [packet.c canohost.c] Include arpa/inet.h for htonl macros on - some platforms (eg HP-UX 11.00). From santhi.amirta at gmail com. - -20060921 - - (dtucker) OpenBSD CVS Sync - - otto@cvs.openbsd.org 2006/09/19 05:52:23 - [sftp.c] - Use S_IS* macros insted of masking with S_IF* flags. The latter may - have multiple bits set, which lead to surprising results. Spotted by - Paul Stoeber, more to come. ok millert@ pedro@ jaredy@ djm@ - - markus@cvs.openbsd.org 2006/09/19 21:14:08 - [packet.c] - client NULL deref on protocol error; Tavis Ormandy, Google Security Team - - (dtucker) [defines.h] Include unistd.h before defining getpgrp; fixes - build error on Ultrix. From Bernhard Simon. - -20060918 - - (dtucker) [configure.ac] On AIX, check to see if the compiler will allow - macro redefinitions, and if not, remove "-qlanglvl=ansi" from the flags. - Allows build out of the box with older VAC and XLC compilers. Found by - David Bronder and Bernhard Simon. - - (dtucker) [openbsd-compat/port-aix.{c,h}] Reduce scope of includes. - Prevents macro redefinition warnings of "RDONLY". - -20060916 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/09/16 19:53:37 - [deattack.c deattack.h packet.c] - limit maximum work performed by the CRC compensation attack detector, - problem reported by Tavis Ormandy, Google Security Team; - ok markus@ deraadt@ - - (djm) Add openssh.xml to .cvsignore and sort it - - (dtucker) [auth-pam.c] Propogate TZ environment variable to PAM auth - process so that any logging it does is with the right timezone. From - Scott Strickler, ok djm@. - - (dtucker) [monitor.c] Correctly handle auditing of single commands when - using Protocol 1. From jhb at freebsd. - - (djm) [sshd.c] Fix warning/API abuse; ok dtucker@ - - (dtucker) [INSTALL] Add info about audit support. - -20060912 - - (djm) [Makefile.in buildpkg.sh.in configure.ac openssh.xml.in] - Support SMF in Solaris Packages if enabled by configure. Patch from - Chad Mynhier, tested by dtucker@ - -20060911 - - (dtucker) [cipher-aes.c] Include string.h for memcpy and friends. Noted - by Pekka Savola. - -20060910 - - (dtucker) [contrib/aix/buildbff.sh] Ensure that perl is available. - - (dtucker) [configure.ac] Add -lcrypt to let DragonFly build OOTB. - -20060909 - - (dtucker) [openbsd-compat/bsd-snprintf.c] Add stdarg.h. - - (dtucker) [contrib/aix/buildbff.sh] Always create privsep user. - - (dtucker) [buildpkg.sh.in] Always create privsep user. ok djm@ - -20060908 - - (dtucker) [auth-sia.c] Add includes required for build on Tru64. Patch - from Chris Adams. - - (dtucker) [configure.ac] The BSM header test needs time.h in some cases. - -20060907 - - (djm) [sshd.c auth.c] Set up fakepw() with privsep uid/gid, so it can - be used to drop privilege to; fixes Solaris GSSAPI crash reported by - Magnus Abrante; suggestion and feedback dtucker@ - NB. this change will require that the privilege separation user must - exist on all the time, not just when UsePrivilegeSeparation=yes - - (tim) [configure.ac] s/BROKEN_UPDWTMP/BROKEN_UPDWTMPX/ on SCO OSR6 - - (dtucker) [loginrec.c] Wrap paths.h in HAVE_PATHS_H. - - (dtucker) [regress/cfgmatch.sh] stop_client is racy, so give us a better - chance of winning. - -20060905 - - (dtucker) [configure.ac] s/AC_DEFINES/AC_DEFINE/ spotted by Roumen Petrov. - - (dtucker) [loginrec.c] Include paths.h for _PATH_BTMP. - -20060904 - - (dtucker) [configure.ac] Define BROKEN_UPDWTMP on SCO OSR6 as the native - updwdtmp seems to generate invalid wtmp entries. From Roger Cornelius, - ok djm@ - -20060903 - - (dtucker) [configure.ac openbsd-compat/openbsd-compat.h] Check for - declaration of writev(2) and declare it ourselves if necessary. Makes - the atomiciov() calls build on really old systems. ok djm@ - -20060902 - - (dtucker) [openbsd-compat/port-irix.c] Add errno.h, found by Iain Morgan. - - (dtucker) [ssh-keyscan.c ssh-rand-helper.c ssh.c sshconnect.c - openbsd-compat/bindresvport.c openbsd-compat/getrrsetbyname.c - openbsd-compat/port-tun.c openbsd-compat/rresvport.c] Include - for hton* and ntoh* macros. Required on (at least) HP-UX since we define - _XOPEN_SOURCE_EXTENDED. Found by santhi.amirta at gmail com. - -20060901 - - (djm) [audit-bsm.c audit.c auth-bsdauth.c auth-chall.c auth-pam.c] - [auth-rsa.c auth-shadow.c auth-sia.c auth1.c auth2-chall.c] - [auth2-gss.c auth2-kbdint.c auth2-none.c authfd.c authfile.c] - [cipher-3des1.c cipher-aes.c cipher-bf1.c cipher-ctr.c clientloop.c] - [dh.c dns.c entropy.c gss-serv-krb5.c gss-serv.c hostfile.c kex.c] - [kexdhc.c kexdhs.c kexgexc.c kexgexs.c key.c loginrec.c mac.c] - [md5crypt.c monitor.c monitor_wrap.c readconf.c rsa.c] - [scard-opensc.c scard.c session.c ssh-add.c ssh-agent.c ssh-dss.c] - [ssh-keygen.c ssh-keysign.c ssh-rsa.c ssh.c sshconnect.c] - [sshconnect1.c sshconnect2.c sshd.c] - [openbsd-compat/bsd-cray.c openbsd-compat/port-aix.c] - [openbsd-compat/port-linux.c openbsd-compat/port-solaris.c] - [openbsd-compat/port-uw.c] - Lots of headers for SCO OSR6, mainly adding stdarg.h for log.h; - compile problems reported by rac AT tenzing.org - - (djm) [includes.h monitor.c openbsd-compat/bindresvport.c] - [openbsd-compat/rresvport.c] Some more headers: netinet/in.h - sys/socket.h and unistd.h in various places - - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Fix implict declaration - warnings for binary_open and binary_close. Patch from Corinna Vinschen. - - (dtucker) [configure.ac includes.h openbsd-compat/glob.{c,h}] Explicitly - test for GLOB_NOMATCH and use our glob functions if it's not found. - Stops sftp from segfaulting when attempting to get a nonexistent file on - Cygwin (previous versions of OpenSSH didn't use the native glob). Partly - from and tested by Corinna Vinschen. - - (dtucker) [README contrib/{caldera,redhat,suse}/openssh.spec] Crank - versions. - -20060831 - - (djm) [CREDITS LICENCE Makefile.in auth.c configure.ac includes.h ] - [platform.c platform.h sshd.c openbsd-compat/Makefile.in] - [openbsd-compat/openbsd-compat.h openbsd-compat/port-solaris.c] - [openbsd-compat/port-solaris.h] Add support for Solaris process - contracts, enabled with --use-solaris-contracts. Patch from Chad - Mynhier, tweaked by dtucker@ and myself; ok dtucker@ - - (dtucker) [contrib/cygwin/ssh-host-config] Add SeTcbPrivilege privilege - while setting up the ssh service account. Patch from Corinna Vinschen. - -20060830 - - (djm) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2006/08/21 08:14:01 - [sshd_config.5] - Document HostbasedUsesNameFromPacketOnly. Corrections from jmc@, - ok jmc@ djm@ - - dtucker@cvs.openbsd.org 2006/08/21 08:15:57 - [sshd.8] - Add more detail about what permissions are and aren't accepted for - authorized_keys files. Corrections jmc@, ok djm@, "looks good" jmc@ - - djm@cvs.openbsd.org 2006/08/29 10:40:19 - [channels.c session.c] - normalise some inconsistent (but harmless) NULL pointer checks - spotted by the Stanford SATURN tool, via Isil Dillig; - ok markus@ deraadt@ - - dtucker@cvs.openbsd.org 2006/08/29 12:02:30 - [gss-genr.c] - Work around a problem in Heimdal that occurs when KRB5CCNAME file is - missing, by checking whether or not kerberos allocated us a context - before attempting to free it. Patch from Simon Wilkinson, tested by - biorn@, ok djm@ - - dtucker@cvs.openbsd.org 2006/08/30 00:06:51 - [sshconnect2.c] - Fix regression where SSH2 banner is printed at loglevels ERROR and FATAL - where previously it weren't. bz #1221, found by Dean Kopesky, ok djm@ - - djm@cvs.openbsd.org 2006/08/30 00:14:37 - [version.h] - crank to 4.4 - - (djm) [openbsd-compat/xcrypt.c] needs unistd.h - - (dtucker) [auth.c openbsd-compat/port-aix.c] Bug #1207: always call - loginsuccess on AIX immediately after authentication to clear the failed - login count. Previously this would only happen when an interactive - session starts (ie when a pty is allocated) but this means that accounts - that have primarily non-interactive sessions (eg scp's) may gradually - accumulate enough failures to lock out an account. This change may have - a side effect of creating two audit records, one with a tty of "ssh" - corresponding to the authentication and one with the allocated pty per - interactive session. - -20060824 - - (dtucker) [openbsd-compat/basename.c] Include errno.h. - - (dtucker) [openbsd-compat/bsd-misc.c] Add includes needed for select(2) on - older systems. - - (dtucker) [openbsd-compat/bsd-misc.c] Include for select(2) - on POSIX systems. - - (dtucker) [openbsd-compat/bsd-openpty.c] Include for ioctl(2). - - (dtucker) [openbsd-compat/rresvport.c] Include for malloc. - - (dtucker) [openbsd-compat/xmmap.c] Move #define HAVE_MMAP to prevent - unused variable warning when we have a broken or missing mmap(2). - -20060822 - - (dtucker) [Makefile.in] Bug #1177: fix incorrect path for sshrc in - Makefile. Patch from santhi.amirta at gmail, ok djm. - -20060820 - - (dtucker) [log.c] Move ifdef to prevent unused variable warning. - - (dtucker) [configure.ac] Save $LIBS during PAM library tests and restore - afterward. Removes the need to mangle $LIBS later to remove -lpam and -ldl. - - (dtucker) [configure.ac] Relocate --with-pam parts in preparation for - fixing bug #1181. No changes yet. - - (dtucker) [configure.ac] Bug #1181: Explicitly test to see if OpenSSL - (0.9.8a and presumably newer) requires -ldl to successfully link. - - (dtucker) [configure.ac] Remove errant "-". - -20060819 - - (djm) OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/08/18 22:41:29 - [gss-genr.c] - GSSAPI error code should be 0 and not -1; from simon@sxw.org.uk - - (dtucker) [openbsd-compat/regress/Makefile.in] Add $(EXEEXT) and add a - single rule for the test progs. - -20060818 - - (dtucker) [configure.ac openbsd-compat/bsd-closefrom.c] Resync with - closefrom.c from sudo. - - (dtucker) [openbsd-compat/bsd-closefrom.c] Comment out rcsid. - - (dtucker) [openbsd-compat/regress/snprintftest.c] Newline on error. - - (dtucker) [openbsd-compat/regress/Makefile.in] Use implicit rules for the - test progs instead; they work better than what we have. - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2006/08/06 01:13:32 - [compress.c monitor.c monitor_wrap.c] - "zlib.h" can be ; ok djm@ markus@ - - miod@cvs.openbsd.org 2006/08/12 20:46:46 - [monitor.c monitor_wrap.c] - Revert previous include file ordering change, for ssh to compile under - gcc2 (or until openssl include files are cleaned of parameter names - in function prototypes) - - dtucker@cvs.openbsd.org 2006/08/14 12:40:25 - [servconf.c servconf.h sshd_config.5] - Add ability to match groups to Match keyword in sshd_config. Feedback - djm@, stevesk@, ok stevesk@. - - djm@cvs.openbsd.org 2006/08/16 11:47:15 - [sshd.c] - factor inetd connection, TCP listen and main TCP accept loop out of - main() into separate functions to improve readability; ok markus@ - - deraadt@cvs.openbsd.org 2006/08/18 09:13:26 - [log.c log.h sshd.c] - make signal handler termination path shorter; risky code pointed out by - mark dowd; ok djm markus - - markus@cvs.openbsd.org 2006/08/18 09:15:20 - [auth.h session.c sshd.c] - delay authentication related cleanups until we're authenticated and - all alarms have been cancelled; ok deraadt - - djm@cvs.openbsd.org 2006/08/18 10:27:16 - [misc.h] - reorder so prototypes are sorted by the files they refer to; no - binary change - - djm@cvs.openbsd.org 2006/08/18 13:54:54 - [gss-genr.c ssh-gss.h sshconnect2.c] - bz #1218 - disable SPNEGO as per RFC4462; diff from simon AT sxw.org.uk - ok markus@ - - djm@cvs.openbsd.org 2006/08/18 14:40:34 - [gss-genr.c ssh-gss.h] - constify host argument to match the rest of the GSSAPI functions and - unbreak compilation with -Werror - - (djm) Disable sigdie() for platforms that cannot safely syslog inside - a signal handler (basically all of them, excepting OpenBSD); - ok dtucker@ - -20060817 - - (dtucker) [openbsd-compat/fake-rfc2553.c openbsd-compat/setproctitle.c] - Include stdlib.h for malloc and friends. - - (dtucker) [configure.ac openbsd-compat/bsd-closefrom.c] Use F_CLOSEM fcntl - for closefrom() on AIX. Pointed out by William Ahern. - - (dtucker) [openbsd-compat/regress/{Makefile.in,closefromtest.c}] Regress - test for closefrom() in compat code. - -20060816 - - (djm) [audit-bsm.c] Sprinkle in some headers - -20060815 - - (dtucker) [LICENCE] Add Reyk to the list for the compat dir. - -20060806 - - (djm) [openbsd-compat/bsd-getpeereid.c] Add some headers to quiet warnings - on Solaris 10 - -20060806 - - (dtucker) [defines.h] With the includes.h changes we no longer get the - name clash on "YES" so we can remove the workaround for it. - - (dtucker) [openbsd-compat/{bsd-asprintf.c,bsd-openpty.c,bsd-snprintf.c, - glob.c}] Include stdlib.h for malloc and friends in compat code. - -20060805 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2006/07/24 13:58:22 - [sshconnect.c] - disable tunnel forwarding when no strict host key checking - and key changed; ok djm@ markus@ dtucker@ - - stevesk@cvs.openbsd.org 2006/07/25 02:01:34 - [scard.c] - need #include - - stevesk@cvs.openbsd.org 2006/07/25 02:59:21 - [channels.c clientloop.c packet.c scp.c serverloop.c sftp-client.c] - [sftp-server.c ssh-agent.c ssh-keyscan.c sshconnect.c sshd.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/26 02:35:17 - [atomicio.c auth.c dh.c authfile.c buffer.c clientloop.c kex.c] - [groupaccess.c gss-genr.c kexgexs.c misc.c monitor.c monitor_mm.c] - [packet.c scp.c serverloop.c session.c sftp-client.c sftp-common.c] - [sftp-server.c sftp.c ssh-add.c ssh-agent.c ssh-keygen.c sshlogin.c] - [uidswap.c xmalloc.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/26 13:57:17 - [authfd.c authfile.c dh.c canohost.c channels.c clientloop.c compat.c] - [hostfile.c kex.c log.c misc.c moduli.c monitor.c packet.c readpass.c] - [scp.c servconf.c session.c sftp-server.c sftp.c ssh-add.c ssh-agent.c] - [ssh-keygen.c ssh-keyscan.c ssh-keysign.c ssh.c sshconnect.c] - [sshconnect1.c sshd.c xmalloc.c] - move #include out of includes.h - - jmc@cvs.openbsd.org 2006/07/27 08:00:50 - [ssh_config.5] - avoid confusing wording in HashKnownHosts: - originally spotted by alan amesbury; - ok deraadt - - jmc@cvs.openbsd.org 2006/07/27 08:00:50 - [ssh_config.5] - avoid confusing wording in HashKnownHosts: - originally spotted by alan amesbury; - ok deraadt - - dtucker@cvs.openbsd.org 2006/08/01 11:34:36 - [sshconnect.c] - Allow fallback to known_hosts entries without port qualifiers for - non-standard ports too, so that all existing known_hosts entries will be - recognised. Requested by, feedback and ok markus@ - - stevesk@cvs.openbsd.org 2006/08/01 23:22:48 - [auth-passwd.c auth-rhosts.c auth-rsa.c auth.c auth.h auth1.c] - [auth2-chall.c auth2-pubkey.c authfile.c buffer.c canohost.c] - [channels.c clientloop.c dh.c dns.c dns.h hostfile.c kex.c kexdhc.c] - [kexgexc.c kexgexs.c key.c key.h log.c misc.c misc.h moduli.c] - [monitor_wrap.c packet.c progressmeter.c readconf.c readpass.c scp.c] - [servconf.c session.c sftp-client.c sftp-common.c sftp-server.c sftp.c] - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh.c sshconnect.c] - [sshconnect1.c sshconnect2.c sshd.c sshlogin.c sshtty.c uuencode.c] - [uuencode.h xmalloc.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/08/01 23:36:12 - [authfile.c channels.c progressmeter.c scard.c servconf.c ssh.c] - clean extra spaces - - deraadt@cvs.openbsd.org 2006/08/03 03:34:42 - [OVERVIEW atomicio.c atomicio.h auth-bsdauth.c auth-chall.c auth-krb5.c] - [auth-options.c auth-options.h auth-passwd.c auth-rh-rsa.c auth-rhosts.c] - [auth-rsa.c auth-skey.c auth.c auth.h auth1.c auth2-chall.c auth2-gss.c] - [auth2-hostbased.c auth2-kbdint.c auth2-none.c auth2-passwd.c ] - [auth2-pubkey.c auth2.c authfd.c authfd.h authfile.c bufaux.c bufbn.c] - [buffer.c buffer.h canohost.c channels.c channels.h cipher-3des1.c] - [cipher-bf1.c cipher-ctr.c cipher.c cleanup.c clientloop.c compat.c] - [compress.c deattack.c dh.c dispatch.c dns.c dns.h fatal.c groupaccess.c] - [groupaccess.h gss-genr.c gss-serv-krb5.c gss-serv.c hostfile.c kex.c] - [kex.h kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c key.c] - [key.h log.c log.h mac.c match.c md-sha256.c misc.c misc.h moduli.c] - [monitor.c monitor_fdpass.c monitor_mm.c monitor_mm.h monitor_wrap.c] - [monitor_wrap.h msg.c nchan.c packet.c progressmeter.c readconf.c] - [readconf.h readpass.c rsa.c scard.c scard.h scp.c servconf.c servconf.h] - [serverloop.c session.c session.h sftp-client.c sftp-common.c] - [sftp-common.h sftp-glob.c sftp-server.c sftp.c ssh-add.c ssh-agent.c] - [ssh-dss.c ssh-gss.h ssh-keygen.c ssh-keyscan.c ssh-keysign.c ssh-rsa.c] - [ssh.c ssh.h sshconnect.c sshconnect.h sshconnect1.c sshconnect2.c] - [sshd.c sshlogin.c sshlogin.h sshpty.c sshpty.h sshtty.c ttymodes.c] - [uidswap.c uidswap.h uuencode.c uuencode.h xmalloc.c xmalloc.h] - [loginrec.c loginrec.h openbsd-compat/port-aix.c openbsd-compat/port-tun.h] - almost entirely get rid of the culture of ".h files that include .h files" - ok djm, sort of ok stevesk - makes the pain stop in one easy step - NB. portable commit contains everything *except* removing includes.h, as - that will take a fair bit more work as we move headers that are required - for portability workarounds to defines.h. (also, this step wasn't "easy") - - stevesk@cvs.openbsd.org 2006/08/04 20:46:05 - [monitor.c session.c ssh-agent.c] - spaces - - (djm) [auth-pam.c defines.h] Move PAM related bits to auth-pam.c - - (djm) [auth-pam.c auth.c bufaux.h entropy.c openbsd-compat/port-tun.c] - remove last traces of bufaux.h - it was merged into buffer.h in the big - includes.h commit - - (djm) [auth.c loginrec.c] Missing netinet/in.h for loginrec - - (djm) [openbsd-compat/regress/snprintftest.c] - [openbsd-compat/regress/strduptest.c] Add missing includes so they pass - compilation with "-Wall -Werror" - - (djm) [auth-pam.c auth-shadow.c auth2-none.c cleanup.c sshd.c] - [openbsd-compat/port-tun.c openbsd-compat/port-tun.h] Sprinkle more - includes for Linux in - - (dtucker) [cleanup.c] Need defines.h for __dead. - - (dtucker) [auth2-gss.c] We still need the #ifdef GSSAPI in -portable. - - (dtucker) [openbsd-compat/{bsd-arc4random.c,port-tun.c,xmmap.c}] Lots of - #include stdarg.h, needed for log.h. - - (dtucker) [entropy.c] Needs unistd.h too. - - (dtucker) [ssh-rand-helper.c] Needs stdarg.h for log.h. - - (dtucker) [openbsd-compat/getrrsetbyname.c] Nees stdlib.h for malloc. - - (dtucker) [openbsd-compat/strtonum.c] Include stdlib.h for strtoll, - otherwise it is implicitly declared as returning an int. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2006/08/05 07:52:52 - [auth2-none.c sshd.c monitor_wrap.c] - Add headers required to build with KERBEROS5=no. ok djm@ - - dtucker@cvs.openbsd.org 2006/08/05 08:00:33 - [auth-skey.c] - Add headers required to build with -DSKEY. ok djm@ - - dtucker@cvs.openbsd.org 2006/08/05 08:28:24 - [monitor_wrap.c auth-skey.c auth2-chall.c] - Zap unused variables in -DSKEY code. ok djm@ - - dtucker@cvs.openbsd.org 2006/08/05 08:34:04 - [packet.c] - Typo in comment - - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Add headers required to compile - on Cygwin. - - (dtucker) [openbsd-compat/fake-rfc2553.c] Add headers needed for inet_ntoa. - - (dtucker) [auth-skey.c] monitor_wrap.h needs ssh-gss.h. - - (dtucker) [audit.c audit.h] Repair headers. - - (dtucker) [audit-bsm.c] Add additional headers now required. - -20060804 - - (dtucker) [configure.ac] The "crippled AES" test does not work on recent - versions of Solaris, so use AC_LINK_IFELSE to actually link the test program - rather than just compiling it. Spotted by dlg@. - -20060802 - - (dtucker) [openbsd-compat/daemon.c] Add unistd.h for fork() prototype. - -20060725 - - (dtucker) [openbsd-compat/xmmap.c] Need fcntl.h for O_RDRW. - -20060724 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/07/12 13:39:55 - [sshd_config.5] - - new sentence, new line - - s/The the/The/ - - kill a bad comma - - stevesk@cvs.openbsd.org 2006/07/12 22:28:52 - [auth-options.c canohost.c channels.c includes.h readconf.c] - [servconf.c ssh-keyscan.c ssh.c sshconnect.c sshd.c] - move #include out of includes.h; ok djm@ - - stevesk@cvs.openbsd.org 2006/07/12 22:42:32 - [includes.h ssh.c ssh-rand-helper.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/14 01:15:28 - [monitor_wrap.h] - don't need incompletely-typed 'struct passwd' now with - #include ; ok markus@ - - stevesk@cvs.openbsd.org 2006/07/17 01:31:10 - [authfd.c authfile.c channels.c cleanup.c clientloop.c groupaccess.c] - [includes.h log.c misc.c msg.c packet.c progressmeter.c readconf.c] - [readpass.c scp.c servconf.c sftp-client.c sftp-server.c sftp.c] - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c ssh.c] - [sshconnect.c sshlogin.c sshpty.c uidswap.c] - move #include out of includes.h - - dtucker@cvs.openbsd.org 2006/07/17 12:02:24 - [auth-options.c] - Use '\0' rather than 0 to terminates strings; ok djm@ - - dtucker@cvs.openbsd.org 2006/07/17 12:06:00 - [channels.c channels.h servconf.c sshd_config.5] - Add PermitOpen directive to sshd_config which is equivalent to the - "permitopen" key option. Allows server admin to allow TCP port - forwarding only two specific host/port pairs. Useful when combined - with Match. - If permitopen is used in both sshd_config and a key option, both - must allow a given connection before it will be permitted. - Note that users can still use external forwarders such as netcat, - so to be those must be controlled too for the limits to be effective. - Feedback & ok djm@, man page corrections & ok jmc@. - - jmc@cvs.openbsd.org 2006/07/18 07:50:40 - [sshd_config.5] - tweak; ok dtucker - - jmc@cvs.openbsd.org 2006/07/18 07:56:28 - [scp.1] - replace DIAGNOSTICS with .Ex; - - jmc@cvs.openbsd.org 2006/07/18 08:03:09 - [ssh-agent.1 sshd_config.5] - mark up angle brackets; - - dtucker@cvs.openbsd.org 2006/07/18 08:22:23 - [sshd_config.5] - Clarify description of Match, with minor correction from jmc@ - - stevesk@cvs.openbsd.org 2006/07/18 22:27:55 - [dh.c] - remove unneeded includes; ok djm@ - - dtucker@cvs.openbsd.org 2006/07/19 08:56:41 - [servconf.c sshd_config.5] - Add support for X11Forwaring, X11DisplayOffset and X11UseLocalhost to - Match. ok djm@ - - dtucker@cvs.openbsd.org 2006/07/19 13:07:10 - [servconf.c servconf.h session.c sshd.8 sshd_config sshd_config.5] - Add ForceCommand keyword to sshd_config, equivalent to the "command=" - key option, man page entry and example in sshd_config. - Feedback & ok djm@, man page corrections & ok jmc@ - - stevesk@cvs.openbsd.org 2006/07/20 15:26:15 - [auth1.c serverloop.c session.c sshconnect2.c] - missed some needed #include when KERBEROS5=no; issue from - massimo@cedoc.mo.it - - dtucker@cvs.openbsd.org 2006/07/21 12:43:36 - [channels.c channels.h servconf.c servconf.h sshd_config.5] - Make PermitOpen take a list of permitted ports and act more like most - other keywords (ie the first match is the effective setting). This - also makes it easier to override a previously set PermitOpen. ok djm@ - - stevesk@cvs.openbsd.org 2006/07/21 21:13:30 - [channels.c] - more ARGSUSED (lint) for dispatch table-driven functions; ok djm@ - - stevesk@cvs.openbsd.org 2006/07/21 21:26:55 - [progressmeter.c] - ARGSUSED for signal handler - - stevesk@cvs.openbsd.org 2006/07/22 19:08:54 - [includes.h moduli.c progressmeter.c scp.c sftp-common.c] - [sftp-server.c ssh-agent.c sshlogin.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/22 20:48:23 - [atomicio.c auth-options.c auth-passwd.c auth-rhosts.c auth-rsa.c] - [auth.c auth1.c auth2-chall.c auth2-hostbased.c auth2-passwd.c auth2.c] - [authfd.c authfile.c bufaux.c bufbn.c buffer.c canohost.c channels.c] - [cipher-3des1.c cipher-bf1.c cipher-ctr.c cipher.c clientloop.c] - [compat.c deattack.c dh.c dns.c gss-genr.c gss-serv.c hostfile.c] - [includes.h kex.c kexdhc.c kexdhs.c kexgexc.c kexgexs.c key.c log.c] - [mac.c match.c md-sha256.c misc.c moduli.c monitor.c monitor_fdpass.c] - [monitor_mm.c monitor_wrap.c msg.c nchan.c packet.c rsa.c] - [progressmeter.c readconf.c readpass.c scp.c servconf.c serverloop.c] - [session.c sftp-client.c sftp-common.c sftp-glob.c sftp-server.c sftp.c] - [ssh-add.c ssh-agent.c ssh-dss.c ssh-keygen.c ssh-keyscan.c] - [ssh-keysign.c ssh-rsa.c ssh.c sshconnect.c sshconnect1.c sshconnect2.c] - [sshd.c sshlogin.c sshpty.c ttymodes.c uidswap.c xmalloc.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/23 01:11:05 - [auth.h dispatch.c kex.h sftp-client.c] - #include for sig_atomic_t; need this prior to - move - - (djm) [acss.c auth-krb5.c auth-options.c auth-pam.c auth-shadow.c] - [canohost.c channels.c cipher-acss.c defines.h dns.c gss-genr.c] - [gss-serv-krb5.c gss-serv.c log.h loginrec.c logintest.c readconf.c] - [servconf.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c ssh-rand-helper.c] - [ssh.c sshconnect.c sshd.c openbsd-compat/bindresvport.c] - [openbsd-compat/bsd-arc4random.c openbsd-compat/bsd-misc.c] - [openbsd-compat/getrrsetbyname.c openbsd-compat/glob.c] - [openbsd-compat/mktemp.c openbsd-compat/port-linux.c] - [openbsd-compat/port-tun.c openbsd-compat/readpassphrase.c] - [openbsd-compat/setproctitle.c openbsd-compat/xmmap.c] - make the portable tree compile again - sprinkle unistd.h and string.h - back in. Don't redefine __unused, as it turned out to be used in - headers on Linux, and replace its use in auth-pam.c with ARGSUSED - - (djm) [openbsd-compat/glob.c] - Move get_arg_max() into the ifdef HAVE_GLOB block so that it compiles - on OpenBSD (or other platforms with a decent glob implementation) with - -Werror - - (djm) [uuencode.c] - Add resolv.h, is it contains the prototypes for __b64_ntop/__b64_pton on - some platforms - - (djm) [session.c] - fix compile error with -Werror -Wall: 'path' is only used in - do_setup_env() if HAVE_LOGIN_CAP is not defined - - (djm) [openbsd-compat/basename.c openbsd-compat/bsd-closefrom.c] - [openbsd-compat/bsd-cray.c openbsd-compat/bsd-openpty.c] - [openbsd-compat/bsd-snprintf.c openbsd-compat/fake-rfc2553.c] - [openbsd-compat/port-aix.c openbsd-compat/port-irix.c] - [openbsd-compat/rresvport.c] - These look to need string.h and/or unistd.h (based on a grep for function - names) - - (djm) [Makefile.in] - Remove generated openbsd-compat/regress/Makefile in distclean target - - (djm) [regress/Makefile regress/agent-getpeereid.sh regress/cfgmatch.sh] - [regress/cipher-speed.sh regress/forcecommand.sh regress/forwarding.sh] - Sync regress tests to -current; include dtucker@'s new cfgmatch and - forcecommand tests. Add cipher-speed.sh test (not linked in yet) - - (dtucker) [cleanup.c] Since config.h defines _LARGE_FILES on AIX, including - system headers before defines.h will cause conflicting definitions. - - (dtucker) [regress/forcecommand.sh] Portablize. - -20060713 - - (dtucker) [auth-krb5.c auth-pam.c] Still more errno.h - -20060712 - - (dtucker) [configure.ac defines.h] Only define SHUT_RD (and friends) and - O_NONBLOCK if they're really needed. Fixes build errors on HP-UX, old - Linuxes and probably more. - - (dtucker) [configure.ac] OpenBSD needs before - for SHUT_RD. - - (dtucker) [openbsd-compat/port-tun.c] OpenBSD needs before - . - - (dtucker) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2006/07/10 16:01:57 - [sftp-glob.c sftp-common.h sftp.c] - buffer.h only needed in sftp-common.h and remove some unneeded - user includes; ok djm@ - - jmc@cvs.openbsd.org 2006/07/10 16:04:21 - [sshd.8] - s/and and/and/ - - stevesk@cvs.openbsd.org 2006/07/10 16:37:36 - [readpass.c log.h scp.c fatal.c xmalloc.c includes.h ssh-keyscan.c misc.c - auth.c packet.c log.c] - move #include out of includes.h; ok markus@ - - dtucker@cvs.openbsd.org 2006/07/11 10:12:07 - [ssh.c] - Only copy the part of environment variable that we actually use. Prevents - ssh bailing when SendEnv is used and an environment variable with a really - long value exists. ok djm@ - - markus@cvs.openbsd.org 2006/07/11 18:50:48 - [clientloop.c ssh.1 ssh.c channels.c ssh_config.5 readconf.h session.c - channels.h readconf.c] - add ExitOnForwardFailure: terminate the connection if ssh(1) - cannot set up all requested dynamic, local, and remote port - forwardings. ok djm, dtucker, stevesk, jmc - - stevesk@cvs.openbsd.org 2006/07/11 20:07:25 - [scp.c auth.c monitor.c serverloop.c sftp-server.c sshpty.c readpass.c - sshd.c monitor_wrap.c monitor_fdpass.c ssh-agent.c ttymodes.c atomicio.c - includes.h session.c sshlogin.c monitor_mm.c packet.c sshconnect2.c - sftp-client.c nchan.c clientloop.c sftp.c misc.c canohost.c channels.c - ssh-keygen.c progressmeter.c uidswap.c msg.c readconf.c sshconnect.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/07/11 20:16:43 - [ssh.c] - cast asterisk field precision argument to int to remove warning; - ok markus@ - - stevesk@cvs.openbsd.org 2006/07/11 20:27:56 - [authfile.c ssh.c] - need here also (it's also included in ) - - dtucker@cvs.openbsd.org 2006/07/12 11:34:58 - [sshd.c servconf.h servconf.c sshd_config.5 auth.c] - Add support for conditional directives to sshd_config via a "Match" - keyword, which works similarly to the "Host" directive in ssh_config. - Lines after a Match line override the default set in the main section - if the condition on the Match line is true, eg - AllowTcpForwarding yes - Match User anoncvs - AllowTcpForwarding no - will allow port forwarding by all users except "anoncvs". - Currently only a very small subset of directives are supported. - ok djm@ - - (dtucker) [loginrec.c openbsd-compat/xmmap.c openbsd-compat/bindresvport.c - openbsd-compat/glob.c openbsd-compat/mktemp.c openbsd-compat/port-tun.c - openbsd-compat/readpassphrase.c openbsd-compat/strtonum.c] Include . - - (dtucker) [openbsd-compat/setproctitle.c] Include stdarg.h. - - (dtucker) [ssh-keyscan.c ssh-rand-helper.c] More errno.h here too. - - (dtucker) [openbsd-compat/openbsd-compat.h] v*printf needs stdarg.h. - - (dtucker) [openbsd-compat/bsd-asprintf.c openbsd-compat/port-aix.c - openbsd-compat/rresvport.c] More errno.h. - -20060711 - - (dtucker) [configure.ac ssh-keygen.c openbsd-compat/bsd-openpty.c - openbsd-compat/daemon.c] Add includes needed by open(2). Conditionally - include paths.h. Fixes build error on Solaris. - - (dtucker) [entropy.c] More fcntl.h, this time on AIX (and probably - others). - -20060710 - - (dtucker) [INSTALL] New autoconf version: 2.60. - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/06/14 10:50:42 - [sshconnect.c] - limit the number of pre-banner characters we will accept; ok markus@ - - djm@cvs.openbsd.org 2006/06/26 10:36:15 - [clientloop.c] - mention optional bind_address in runtime port forwarding setup - command-line help. patch from santhi.amirta AT gmail.com - - stevesk@cvs.openbsd.org 2006/07/02 17:12:58 - [ssh.1 ssh.c ssh_config.5 sshd_config.5] - more details and clarity for tun(4) device forwarding; ok and help - jmc@ - - stevesk@cvs.openbsd.org 2006/07/02 18:36:47 - [gss-serv-krb5.c gss-serv.c] - no "servconf.h" needed here - (gss-serv-krb5.c change not applied, portable needs the server options) - - stevesk@cvs.openbsd.org 2006/07/02 22:45:59 - [groupaccess.c groupaccess.h includes.h session.c sftp-common.c sshpty.c] - move #include out of includes.h - (portable needed uidswap.c too) - - stevesk@cvs.openbsd.org 2006/07/02 23:01:55 - [clientloop.c ssh.1] - use -KR[bind_address:]port here; ok djm@ - - stevesk@cvs.openbsd.org 2006/07/03 08:54:20 - [includes.h ssh.c sshconnect.c sshd.c] - move #include "version.h" out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/07/03 17:59:32 - [channels.c includes.h] - move #include out of includes.h; old ok djm@ - (portable needed session.c too) - - stevesk@cvs.openbsd.org 2006/07/05 02:42:09 - [canohost.c hostfile.c includes.h misc.c packet.c readconf.c] - [serverloop.c sshconnect.c uuencode.c] - move #include out of includes.h; ok deraadt@ - (also ssh-rand-helper.c logintest.c loginrec.c) - - djm@cvs.openbsd.org 2006/07/06 10:47:05 - [servconf.c servconf.h session.c sshd_config.5] - support arguments to Subsystem commands; ok markus@ - - djm@cvs.openbsd.org 2006/07/06 10:47:57 - [sftp-server.8 sftp-server.c] - add commandline options to enable logging of transactions; ok markus@ - - stevesk@cvs.openbsd.org 2006/07/06 16:03:53 - [auth-options.c auth-options.h auth-passwd.c auth-rh-rsa.c] - [auth-rhosts.c auth-rsa.c auth.c auth.h auth2-hostbased.c] - [auth2-pubkey.c auth2.c includes.h misc.c misc.h monitor.c] - [monitor_wrap.c monitor_wrap.h scp.c serverloop.c session.c] - [session.h sftp-common.c ssh-add.c ssh-keygen.c ssh-keysign.c] - [ssh.c sshconnect.c sshconnect.h sshd.c sshpty.c sshpty.h uidswap.c] - [uidswap.h] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/07/06 16:22:39 - [ssh-keygen.c] - move #include "dns.h" up - - stevesk@cvs.openbsd.org 2006/07/06 17:36:37 - [monitor_wrap.h] - typo in comment - - stevesk@cvs.openbsd.org 2006/07/08 21:47:12 - [authfd.c canohost.c clientloop.c dns.c dns.h includes.h] - [monitor_fdpass.c nchan.c packet.c servconf.c sftp.c ssh-agent.c] - [ssh-keyscan.c ssh.c sshconnect.h sshd.c sshlogin.h] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/08 21:48:53 - [monitor.c session.c] - missed these from last commit: - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/08 23:30:06 - [log.c] - move user includes after /usr/include files - - stevesk@cvs.openbsd.org 2006/07/09 15:15:11 - [auth2-none.c authfd.c authfile.c includes.h misc.c monitor.c] - [readpass.c scp.c serverloop.c sftp-client.c sftp-server.c] - [ssh-add.c ssh-agent.c ssh-keygen.c ssh-keysign.c ssh.c sshd.c] - [sshlogin.c sshpty.c] - move #include out of includes.h - - stevesk@cvs.openbsd.org 2006/07/09 15:27:59 - [ssh-add.c] - use O_RDONLY vs. 0 in open(); no binary change - - djm@cvs.openbsd.org 2006/07/10 11:24:54 - [sftp-server.c] - remove optind - it isn't used here - - djm@cvs.openbsd.org 2006/07/10 11:25:53 - [sftp-server.c] - don't log variables that aren't yet set - - (djm) [loginrec.c ssh-rand-helper.c sshd.c openbsd-compat/glob.c] - [openbsd-compat/mktemp.c openbsd-compat/openbsd-compat.h] - [openbsd-compat/port-tun.c openbsd-compat/readpassphrase.c] - [openbsd-compat/xcrypt.c] Fix includes.h fallout, mainly fcntl.h - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/07/10 12:03:20 - [scp.c] - duplicate argv at the start of main() because it gets modified later; - pointed out by deraadt@ ok markus@ - - djm@cvs.openbsd.org 2006/07/10 12:08:08 - [channels.c] - fix misparsing of SOCKS 5 packets that could result in a crash; - reported by mk@ ok markus@ - - dtucker@cvs.openbsd.org 2006/07/10 12:46:51 - [misc.c misc.h sshd.8 sshconnect.c] - Add port identifier to known_hosts for non-default ports, based originally - on a patch from Devin Nate in bz#910. - For any connection using the default port or using a HostKeyAlias the - format is unchanged, otherwise the host name or address is enclosed - within square brackets in the same format as sshd's ListenAddress. - Tested by many, ok markus@. - - (dtucker) [openbsd-compat/openbsd-compat.h] Need to include - for struct sockaddr on platforms that use the fake-rfc stuff. - -20060706 - - (dtucker) [configure.ac] Try AIX blibpath test in different order when - compiling with gcc. gcc 4.1.x will accept (but ignore) -b flags so - configure would not select the correct libpath linker flags. - - (dtucker) [INSTALL] A bit more info on autoconf. - -20060705 - - (dtucker) [ssh-rand-helper.c] Don't exit if mkdir fails because the - target already exists. - -20060630 - - (dtucker) [openbsd-compat/openbsd-compat.h] SNPRINTF_CONST for snprintf - declaration too. Patch from russ at sludge.net. - - (dtucker) [openbsd-compat/getrrsetbyname.c] Undef _res before defining it, - prevents warnings on platforms where _res is in the system headers. - - (dtucker) [INSTALL] Bug #1202: Note when autoconf is required and which - version. - -20060627 - - (dtucker) [configure.ac] Bug #1203: Add missing '[', which causes problems - with autoconf 2.60. Patch from vapier at gentoo.org. - -20060625 - - (dtucker) [channels.c serverloop.c] Apply the bug #1102 workaround to ptys - only, otherwise sshd can hang exiting non-interactive sessions. - -20060624 - - (dtucker) [configure.ac] Bug #1193: Define PASSWD_NEEDS_USERNAME on Solaris. - Works around limitation in Solaris' passwd program for changing passwords - where the username is longer than 8 characters. ok djm@ - - (dtucker) [serverloop.c] Get ifdef/ifndef the right way around for the bug - #1102 workaround. - -20060623 - - (dtucker) [README.platform configure.ac openbsd-compat/port-tun.c] Add - tunnel support for Mac OS X/Darwin via a third-party tun driver. Patch - from reyk@, tested by anil@ - - (dtucker) [channels.c configure.ac serverloop.c] Bug #1102: Around AIX - 4.3.3 ML3 or so, the AIX pty layer starting passing zero-length writes - on the pty slave as zero-length reads on the pty master, which sshd - interprets as the descriptor closing. Since most things don't do zero - length writes this rarely matters, but occasionally it happens, and when - it does the SSH pty session appears to hang, so we add a special case for - this condition. ok djm@ - -20060613 - - (djm) [getput.h] This file has been replaced by functions in misc.c - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/05/08 10:49:48 - [sshconnect2.c] - uint32_t -> u_int32_t (which we use everywhere else) - (Id sync only - portable already had this) - - markus@cvs.openbsd.org 2006/05/16 09:00:00 - [clientloop.c] - missing free; from Kylene Hall - - markus@cvs.openbsd.org 2006/05/17 12:43:34 - [scp.c sftp.c ssh-agent.c ssh-keygen.c sshconnect.c] - fix leak; coverity via Kylene Jo Hall - - miod@cvs.openbsd.org 2006/05/18 21:27:25 - [kexdhc.c kexgexc.c] - paramter -> parameter - - dtucker@cvs.openbsd.org 2006/05/29 12:54:08 - [ssh_config.5] - Add gssapi-with-mic to PreferredAuthentications default list; ok jmc - - dtucker@cvs.openbsd.org 2006/05/29 12:56:33 - [ssh_config] - Add GSSAPIAuthentication and GSSAPIDelegateCredentials to examples in - sample ssh_config. ok markus@ - - jmc@cvs.openbsd.org 2006/05/29 16:10:03 - [ssh_config.5] - oops - previous was too long; split the list of auths up - - mk@cvs.openbsd.org 2006/05/30 11:46:38 - [ssh-add.c] - Sync usage() with man page and reality. - ok deraadt dtucker - - jmc@cvs.openbsd.org 2006/05/29 16:13:23 - [ssh.1] - add GSSAPI to the list of authentication methods supported; - - mk@cvs.openbsd.org 2006/05/30 11:46:38 - [ssh-add.c] - Sync usage() with man page and reality. - ok deraadt dtucker - - markus@cvs.openbsd.org 2006/06/01 09:21:48 - [sshd.c] - call get_remote_ipaddr() early; fixes logging after client disconnects; - report mpf@; ok dtucker@ - - markus@cvs.openbsd.org 2006/06/06 10:20:20 - [readpass.c sshconnect.c sshconnect.h sshconnect2.c uidswap.c] - replace remaining setuid() calls with permanently_set_uid() and - check seteuid() return values; report Marcus Meissner; ok dtucker djm - - markus@cvs.openbsd.org 2006/06/08 14:45:49 - [readpass.c sshconnect.c sshconnect2.c uidswap.c uidswap.h] - do not set the gid, noted by solar; ok djm - - djm@cvs.openbsd.org 2006/06/13 01:18:36 - [ssh-agent.c] - always use a format string, even when printing a constant - - djm@cvs.openbsd.org 2006/06/13 02:17:07 - [ssh-agent.c] - revert; i am on drugs. spotted by alexander AT beard.se - -20060521 - - (dtucker) [auth.c monitor.c] Now that we don't log from both the monitor - and slave, we can remove the special-case handling in the audit hook in - auth_log. - -20060517 - - (dtucker) [ssh-rand-helper.c] Check return code of mkdir and fix file - pointer leak. From kjhall at us.ibm.com, found by coverity. - -20060515 - - (dtucker) [openbsd-compat/getrrsetbyname.c] Use _compat_res instead of - _res, prevents problems on some platforms that have _res as a global but - don't have getrrsetbyname(), eg IRIX 5.3. Found and tested by - georg.schwarz at freenet.de, ok djm@. - - (dtucker) [defines.h] Find a value for IOV_MAX or use a conservative - default. Patch originally from tim@, ok djm - - (dtucker) [auth-pam.c] Bug #1188: pass result of do_pam_account back and - do not allow kbdint again after the PAM account check fails. ok djm@ - -20060506 - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2006/04/25 08:02:27 - [authfile.c authfile.h sshconnect2.c ssh.c sshconnect1.c] - Prevent ssh from trying to open private keys with bad permissions more than - once or prompting for their passphrases (which it subsequently ignores - anyway), similar to a previous change in ssh-add. bz #1186, ok djm@ - - djm@cvs.openbsd.org 2006/05/04 14:55:23 - [dh.c] - tighter DH exponent checks here too; feedback and ok markus@ - - djm@cvs.openbsd.org 2006/04/01 05:37:46 - [OVERVIEW] - $OpenBSD$ in here too - - dtucker@cvs.openbsd.org 2006/05/06 08:35:40 - [auth-krb5.c] - Add $OpenBSD$ in comment here too - -20060504 - - (dtucker) [auth-pam.c groupaccess.c monitor.c monitor_wrap.c scard-opensc.c - session.c ssh-rand-helper.c sshd.c openbsd-compat/bsd-cygwin_util.c - openbsd-compat/setproctitle.c] Convert malloc(foo*bar) -> calloc(foo,bar) - in Portable-only code; since calloc zeros, remove now-redundant memsets. - Also add a couple of sanity checks. With & ok djm@ - -20060503 - - (dtucker) [packet.c] Remove in_systm.h since it's also in includes.h - and double including it on IRIX 5.3 causes problems. From Georg Schwarz, - "no objections" tim@ - -20060423 - - (djm) OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2006/04/01 05:42:20 - [scp.c] - minimal lint cleanup (unused crud, and some size_t); ok djm - - djm@cvs.openbsd.org 2006/04/01 05:50:29 - [scp.c] - xasprintification; ok deraadt@ - - djm@cvs.openbsd.org 2006/04/01 05:51:34 - [atomicio.c] - ANSIfy; requested deraadt@ - - dtucker@cvs.openbsd.org 2006/04/02 08:34:52 - [ssh-keysign.c] - sessionid can be 32 bytes now too when sha256 kex is used; ok djm@ - - djm@cvs.openbsd.org 2006/04/03 07:10:38 - [gss-genr.c] - GSSAPI buffers shouldn't be nul-terminated, spotted in bugzilla #1066 - by dleonard AT vintela.com. use xasprintf() to simplify code while in - there; "looks right" deraadt@ - - djm@cvs.openbsd.org 2006/04/16 00:48:52 - [buffer.c buffer.h channels.c] - Fix condition where we could exit with a fatal error when an input - buffer became too large and the remote end had advertised a big window. - The problem was a mismatch in the backoff math between the channels code - and the buffer code, so make a buffer_check_alloc() function that the - channels code can use to propsectivly check whether an incremental - allocation will succeed. bz #1131, debugged with the assistance of - cove AT wildpackets.com; ok dtucker@ deraadt@ - - djm@cvs.openbsd.org 2006/04/16 00:52:55 - [atomicio.c atomicio.h] - introduce atomiciov() function that wraps readv/writev to retry - interrupted transfers like atomicio() does for read/write; - feedback deraadt@ dtucker@ stevesk@ ok deraadt@ - - djm@cvs.openbsd.org 2006/04/16 00:54:10 - [sftp-client.c] - avoid making a tiny 4-byte write to send the packet length of sftp - commands, which would result in a separate tiny packet on the wire by - using atomiciov(writev, ...) to write the length and the command in one - pass; ok deraadt@ - - djm@cvs.openbsd.org 2006/04/16 07:59:00 - [atomicio.c] - reorder sanity test so that it cannot dereference past the end of the - iov array; well spotted canacar@! - - dtucker@cvs.openbsd.org 2006/04/18 10:44:28 - [bufaux.c bufbn.c Makefile.in] - Move Buffer bignum functions into their own file, bufbn.c. This means - that sftp and sftp-server (which use the Buffer functions in bufaux.c - but not the bignum ones) no longer need to be linked with libcrypto. - ok markus@ - - djm@cvs.openbsd.org 2006/04/20 09:27:09 - [auth.h clientloop.c dispatch.c dispatch.h kex.h] - replace the last non-sig_atomic_t flag used in a signal handler with a - sig_atomic_t, unfortunately with some knock-on effects in other (non- - signal) contexts in which it is used; ok markus@ - - markus@cvs.openbsd.org 2006/04/20 09:47:59 - [sshconnect.c] - simplify; ok djm@ - - djm@cvs.openbsd.org 2006/04/20 21:53:44 - [includes.h session.c sftp.c] - Switch from using pipes to socketpairs for communication between - sftp/scp and ssh, and between sshd and its subprocesses. This saves - a file descriptor per session and apparently makes userland ppp over - ssh work; ok markus@ deraadt@ (ID Sync only - portable makes this - decision on a per-platform basis) - - djm@cvs.openbsd.org 2006/04/22 04:06:51 - [uidswap.c] - use setres[ug]id() to permanently revoke privileges; ok deraadt@ - (ID Sync only - portable already uses setres[ug]id() whenever possible) - - stevesk@cvs.openbsd.org 2006/04/22 18:29:33 - [crc32.c] - remove extra spaces - - (djm) [auth.h dispatch.h kex.h] sprinkle in signal.h to get - sig_atomic_t - -20060421 - - (djm) [Makefile.in configure.ac session.c sshpty.c] - [contrib/redhat/sshd.init openbsd-compat/Makefile.in] - [openbsd-compat/openbsd-compat.h openbsd-compat/port-linux.c] - [openbsd-compat/port-linux.h] Add support for SELinux, setting - the execution and TTY contexts. based on patch from Daniel Walsh, - bz #880; ok dtucker@ - -20060418 - - (djm) [canohost.c] Reorder IP options check so that it isn't broken - by mapped addresses; bz #1179 reported by markw wtech-llc.com; - ok dtucker@ - -20060331 - - OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2006/03/27 01:21:18 - [xmalloc.c] - we can do the size & nmemb check before the integer overflow check; - evol - - deraadt@cvs.openbsd.org 2006/03/27 13:03:54 - [dh.c] - use strtonum() instead of atoi(), limit dhg size to 64k; ok djm - - djm@cvs.openbsd.org 2006/03/27 23:15:46 - [sftp.c] - always use a format string for addargs; spotted by mouring@ - - deraadt@cvs.openbsd.org 2006/03/28 00:12:31 - [README.tun ssh.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/28 01:52:28 - [channels.c] - do not accept unreasonable X ports numbers; ok djm - - deraadt@cvs.openbsd.org 2006/03/28 01:53:43 - [ssh-agent.c] - use strtonum() to parse the pid from the file, and range check it - better; ok djm - - djm@cvs.openbsd.org 2006/03/30 09:41:25 - [channels.c] - ARGSUSED for dispatch table-driven functions - - djm@cvs.openbsd.org 2006/03/30 09:58:16 - [authfd.c bufaux.c deattack.c gss-serv.c mac.c misc.c misc.h] - [monitor_wrap.c msg.c packet.c sftp-client.c sftp-server.c ssh-agent.c] - replace {GET,PUT}_XXBIT macros with functionally similar functions, - silencing a heap of lint warnings. also allows them to use - __bounded__ checking which can't be applied to macros; requested - by and feedback from deraadt@ - - djm@cvs.openbsd.org 2006/03/30 10:41:25 - [ssh.c ssh_config.5] - add percent escape chars to the IdentityFile option, bz #1159 based - on a patch by imaging AT math.ualberta.ca; feedback and ok dtucker@ - - dtucker@cvs.openbsd.org 2006/03/30 11:05:17 - [ssh-keygen.c] - Correctly handle truncated files while converting keys; ok djm@ - - dtucker@cvs.openbsd.org 2006/03/30 11:40:21 - [auth.c monitor.c] - Prevent duplicate log messages when privsep=yes; ok djm@ - - jmc@cvs.openbsd.org 2006/03/31 09:09:30 - [ssh_config.5] - kill trailing whitespace; - - djm@cvs.openbsd.org 2006/03/31 09:13:56 - [ssh_config.5] - remote user escape is %r not %h; spotted by jmc@ - -20060326 - - OpenBSD CVS Sync - - jakob@cvs.openbsd.org 2006/03/15 08:46:44 - [ssh-keygen.c] - if no key file are given when printing the DNS host record, use the - host key file(s) as default. ok djm@ - - biorn@cvs.openbsd.org 2006/03/16 10:31:45 - [scp.c] - Try to display errormessage even if remout == -1 - ok djm@, markus@ - - djm@cvs.openbsd.org 2006/03/17 22:31:50 - [authfd.c] - another unreachable found by lint - - djm@cvs.openbsd.org 2006/03/17 22:31:11 - [authfd.c] - unreachanble statement, found by lint - - djm@cvs.openbsd.org 2006/03/19 02:22:32 - [serverloop.c] - memory leaks detected by Coverity via elad AT netbsd.org; - ok deraadt@ dtucker@ - - djm@cvs.openbsd.org 2006/03/19 02:22:56 - [sftp.c] - more memory leaks detected by Coverity via elad AT netbsd.org; - deraadt@ ok - - djm@cvs.openbsd.org 2006/03/19 02:23:26 - [hostfile.c] - FILE* leak detected by Coverity via elad AT netbsd.org; - ok deraadt@ - - djm@cvs.openbsd.org 2006/03/19 02:24:05 - [dh.c readconf.c servconf.c] - potential NULL pointer dereferences detected by Coverity - via elad AT netbsd.org; ok deraadt@ - - djm@cvs.openbsd.org 2006/03/19 07:41:30 - [sshconnect2.c] - memory leaks detected by Coverity via elad AT netbsd.org; - deraadt@ ok - - dtucker@cvs.openbsd.org 2006/03/19 11:51:52 - [servconf.c] - Correct strdelim null test; ok djm@ - - deraadt@cvs.openbsd.org 2006/03/19 18:52:11 - [auth1.c authfd.c channels.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/19 18:53:12 - [kex.c kex.h monitor.c myproposal.h session.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/19 18:56:41 - [clientloop.c progressmeter.c serverloop.c sshd.c] - ARGSUSED for signal handlers - - deraadt@cvs.openbsd.org 2006/03/19 18:59:49 - [ssh-keyscan.c] - please lint - - deraadt@cvs.openbsd.org 2006/03/19 18:59:30 - [ssh.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/19 18:59:09 - [authfile.c] - whoever thought that break after return was a good idea needs to - get their head examimed - - djm@cvs.openbsd.org 2006/03/20 04:09:44 - [monitor.c] - memory leaks detected by Coverity via elad AT netbsd.org; - deraadt@ ok - that should be all of them now - - djm@cvs.openbsd.org 2006/03/20 11:38:46 - [key.c] - (really) last of the Coverity diffs: avoid possible NULL deref in - key_free. via elad AT netbsd.org; markus@ ok - - deraadt@cvs.openbsd.org 2006/03/20 17:10:19 - [auth.c key.c misc.c packet.c ssh-add.c] - in a switch (), break after return or goto is stupid - - deraadt@cvs.openbsd.org 2006/03/20 17:13:16 - [key.c] - djm did a typo - - deraadt@cvs.openbsd.org 2006/03/20 17:17:23 - [ssh-rsa.c] - in a switch (), break after return or goto is stupid - - deraadt@cvs.openbsd.org 2006/03/20 18:14:02 - [channels.c clientloop.c monitor_wrap.c monitor_wrap.h serverloop.c] - [ssh.c sshpty.c sshpty.h] - sprinkle u_int throughout pty subsystem, ok markus - - deraadt@cvs.openbsd.org 2006/03/20 18:17:20 - [auth1.c auth2.c sshd.c] - sprinkle some ARGSUSED for table driven functions (which sometimes - must ignore their args) - - deraadt@cvs.openbsd.org 2006/03/20 18:26:55 - [channels.c monitor.c session.c session.h ssh-agent.c ssh-keygen.c] - [ssh-rsa.c ssh.c sshlogin.c] - annoying spacing fixes getting in the way of real diffs - - deraadt@cvs.openbsd.org 2006/03/20 18:27:50 - [monitor.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/20 18:35:12 - [channels.c] - x11_fake_data is only ever used as u_char * - - deraadt@cvs.openbsd.org 2006/03/20 18:41:43 - [dns.c] - cast xstrdup to propert u_char * - - deraadt@cvs.openbsd.org 2006/03/20 18:42:27 - [canohost.c match.c ssh.c sshconnect.c] - be strict with tolower() casting - - deraadt@cvs.openbsd.org 2006/03/20 18:48:34 - [channels.c fatal.c kex.c packet.c serverloop.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/20 21:11:53 - [ttymodes.c] - spacing - - djm@cvs.openbsd.org 2006/03/25 00:05:41 - [auth-bsdauth.c auth-skey.c auth.c auth2-chall.c channels.c] - [clientloop.c deattack.c gss-genr.c kex.c key.c misc.c moduli.c] - [monitor.c monitor_wrap.c packet.c scard.c sftp-server.c ssh-agent.c] - [ssh-keyscan.c ssh.c sshconnect.c sshconnect2.c sshd.c uuencode.c] - [xmalloc.c xmalloc.h] - introduce xcalloc() and xasprintf() failure-checked allocations - functions and use them throughout openssh - - xcalloc is particularly important because malloc(nmemb * size) is a - dangerous idiom (subject to integer overflow) and it is time for it - to die - - feedback and ok deraadt@ - - djm@cvs.openbsd.org 2006/03/25 01:13:23 - [buffer.c channels.c deattack.c misc.c scp.c session.c sftp-client.c] - [sftp-server.c ssh-agent.c ssh-rsa.c xmalloc.c xmalloc.h auth-pam.c] - [uidswap.c] - change OpenSSH's xrealloc() function from being xrealloc(p, new_size) - to xrealloc(p, new_nmemb, new_itemsize). - - realloc is particularly prone to integer overflows because it is - almost always allocating "n * size" bytes, so this is a far safer - API; ok deraadt@ - - djm@cvs.openbsd.org 2006/03/25 01:30:23 - [sftp.c] - "abormally" is a perfectly cromulent word, but "abnormally" is better - - djm@cvs.openbsd.org 2006/03/25 13:17:03 - [atomicio.c auth-bsdauth.c auth-chall.c auth-options.c auth-passwd.c] - [auth-rh-rsa.c auth-rhosts.c auth-rsa.c auth-skey.c auth.c auth1.c] - [auth2-chall.c auth2-hostbased.c auth2-kbdint.c auth2-none.c] - [auth2-passwd.c auth2-pubkey.c auth2.c authfd.c authfile.c bufaux.c] - [buffer.c canohost.c channels.c cipher-3des1.c cipher-bf1.c] - [cipher-ctr.c cipher.c cleanup.c clientloop.c compat.c compress.c] - [deattack.c dh.c dispatch.c fatal.c groupaccess.c hostfile.c kex.c] - [kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c key.c log.c] - [mac.c match.c md-sha256.c misc.c monitor.c monitor_fdpass.c] - [monitor_mm.c monitor_wrap.c msg.c nchan.c packet.c progressmeter.c] - [readconf.c readpass.c rsa.c scard.c scp.c servconf.c serverloop.c] - [session.c sftp-client.c sftp-common.c sftp-glob.c sftp-server.c] - [sftp.c ssh-add.c ssh-agent.c ssh-dss.c ssh-keygen.c ssh-keyscan.c] - [ssh-keysign.c ssh-rsa.c ssh.c sshconnect.c sshconnect1.c] - [sshconnect2.c sshd.c sshlogin.c sshpty.c sshtty.c ttymodes.c] - [uidswap.c uuencode.c xmalloc.c] - Put $OpenBSD$ tags back (as comments) to replace the RCSID()s that - Theo nuked - our scripts to sync -portable need them in the files - - deraadt@cvs.openbsd.org 2006/03/25 18:29:35 - [auth-rsa.c authfd.c packet.c] - needed casts (always will be needed) - - deraadt@cvs.openbsd.org 2006/03/25 18:30:55 - [clientloop.c serverloop.c] - spacing - - deraadt@cvs.openbsd.org 2006/03/25 18:36:15 - [sshlogin.c sshlogin.h] - nicer size_t and time_t types - - deraadt@cvs.openbsd.org 2006/03/25 18:40:14 - [ssh-keygen.c] - cast strtonum() result to right type - - deraadt@cvs.openbsd.org 2006/03/25 18:41:45 - [ssh-agent.c] - mark two more signal handlers ARGSUSED - - deraadt@cvs.openbsd.org 2006/03/25 18:43:30 - [channels.c] - use strtonum() instead of atoi() [limit X screens to 400, sorry] - - deraadt@cvs.openbsd.org 2006/03/25 18:56:55 - [bufaux.c channels.c packet.c] - remove (char *) casts to a function that accepts void * for the arg - - deraadt@cvs.openbsd.org 2006/03/25 18:58:10 - [channels.c] - delete cast not required - - djm@cvs.openbsd.org 2006/03/25 22:22:43 - [atomicio.h auth-options.h auth.h auth2-gss.c authfd.h authfile.h] - [bufaux.h buffer.h canohost.h channels.h cipher.h clientloop.h] - [compat.h compress.h crc32.c crc32.h deattack.h dh.h dispatch.h] - [dns.c dns.h getput.h groupaccess.h gss-genr.c gss-serv-krb5.c] - [gss-serv.c hostfile.h includes.h kex.h key.h log.h mac.h match.h] - [misc.h monitor.h monitor_fdpass.h monitor_mm.h monitor_wrap.h msg.h] - [myproposal.h packet.h pathnames.h progressmeter.h readconf.h rsa.h] - [scard.h servconf.h serverloop.h session.h sftp-common.h sftp.h] - [ssh-gss.h ssh.h ssh1.h ssh2.h sshconnect.h sshlogin.h sshpty.h] - [ttymodes.h uidswap.h uuencode.h xmalloc.h] - standardise spacing in $OpenBSD$ tags; requested by deraadt@ - - deraadt@cvs.openbsd.org 2006/03/26 01:31:48 - [uuencode.c] - typo - -20060325 - - OpenBSD CVS Sync - - djm@cvs.openbsd.org 2006/03/16 04:24:42 - [ssh.1] - Add RFC4419 (Diffie-Hellman group exchange KEX) to the list of SSH RFCs - that OpenSSH supports - - deraadt@cvs.openbsd.org 2006/03/19 18:51:18 - [atomicio.c auth-bsdauth.c auth-chall.c auth-krb5.c auth-options.c] - [auth-pam.c auth-passwd.c auth-rh-rsa.c auth-rhosts.c auth-rsa.c] - [auth-shadow.c auth-skey.c auth.c auth1.c auth2-chall.c] - [auth2-hostbased.c auth2-kbdint.c auth2-none.c auth2-passwd.c] - [auth2-pubkey.c auth2.c authfd.c authfile.c bufaux.c buffer.c] - [canohost.c channels.c cipher-3des1.c cipher-acss.c cipher-aes.c] - [cipher-bf1.c cipher-ctr.c cipher.c cleanup.c clientloop.c compat.c] - [compress.c deattack.c dh.c dispatch.c dns.c entropy.c fatal.c] - [groupaccess.c hostfile.c includes.h kex.c kexdh.c kexdhc.c] - [kexdhs.c kexgex.c kexgexc.c kexgexs.c key.c log.c loginrec.c] - [loginrec.h logintest.c mac.c match.c md-sha256.c md5crypt.c misc.c] - [monitor.c monitor_fdpass.c monitor_mm.c monitor_wrap.c msg.c] - [nchan.c packet.c progressmeter.c readconf.c readpass.c rsa.c] - [scard.c scp.c servconf.c serverloop.c session.c sftp-client.c] - [sftp-common.c sftp-glob.c sftp-server.c sftp.c ssh-add.c] - [ssh-agent.c ssh-dss.c ssh-keygen.c ssh-keyscan.c ssh-keysign.c] - [ssh-rand-helper.c ssh-rsa.c ssh.c sshconnect.c sshconnect1.c] - [sshconnect2.c sshd.c sshlogin.c sshpty.c sshtty.c ttymodes.c] - [uidswap.c uuencode.c xmalloc.c openbsd-compat/bsd-arc4random.c] - [openbsd-compat/bsd-closefrom.c openbsd-compat/bsd-cygwin_util.c] - [openbsd-compat/bsd-getpeereid.c openbsd-compat/bsd-misc.c] - [openbsd-compat/bsd-nextstep.c openbsd-compat/bsd-snprintf.c] - [openbsd-compat/bsd-waitpid.c openbsd-compat/fake-rfc2553.c] - RCSID() can die - - deraadt@cvs.openbsd.org 2006/03/19 18:53:12 - [kex.h myproposal.h] - spacing - - djm@cvs.openbsd.org 2006/03/20 04:07:22 - [auth2-gss.c] - GSSAPI related leaks detected by Coverity via elad AT netbsd.org; - reviewed by simon AT sxw.org.uk; deraadt@ ok - - djm@cvs.openbsd.org 2006/03/20 04:07:49 - [gss-genr.c] - more GSSAPI related leaks detected by Coverity via elad AT netbsd.org; - reviewed by simon AT sxw.org.uk; deraadt@ ok - - djm@cvs.openbsd.org 2006/03/20 04:08:18 - [gss-serv.c] - last lot of GSSAPI related leaks detected by Coverity via - elad AT netbsd.org; reviewed by simon AT sxw.org.uk; deraadt@ ok - - deraadt@cvs.openbsd.org 2006/03/20 18:14:02 - [monitor_wrap.h sshpty.h] - sprinkle u_int throughout pty subsystem, ok markus - - deraadt@cvs.openbsd.org 2006/03/20 18:26:55 - [session.h] - annoying spacing fixes getting in the way of real diffs - - deraadt@cvs.openbsd.org 2006/03/20 18:41:43 - [dns.c] - cast xstrdup to propert u_char * - - jakob@cvs.openbsd.org 2006/03/22 21:16:24 - [ssh.1] - simplify SSHFP example; ok jmc@ - - djm@cvs.openbsd.org 2006/03/22 21:27:15 - [deattack.c deattack.h] - remove IV support from the CRC attack detector, OpenSSH has never used - it - it only applied to IDEA-CFB, which we don't support. - prompted by NetBSD Coverity report via elad AT netbsd.org; - feedback markus@ "nuke it" deraadt@ - -20060318 - - (djm) [auth-pam.c] Fix memleak in error path, from Coverity via - elad AT NetBSD.org - - (dtucker) [openbsd-compat/bsd-snprintf.c] Bug #1173: make fmtint() take - a LLONG rather than a long. Fixes scp'ing of large files on platforms - with missing/broken snprintfs. Patch from e.borovac at bom.gov.au. - -20060316 - - (dtucker) [entropy.c] Add headers for WIFEXITED and friends. - - (dtucker) [configure.ac md-sha256.c] NetBSD has sha2.h in - /usr/include/crypto. Hint from djm@. - - (tim) [kex.c myproposal.h md-sha256.c openbsd-compat/sha2.c,h] - Disable sha256 when openssl < 0.9.7. Patch from djm@. - - (djm) [kex.c] Slightly more clean deactivation of dhgex-sha256 on old - OpenSSL; ok tim - -20060315 - - (djm) OpenBSD CVS Sync: - - msf@cvs.openbsd.org 2006/02/06 15:54:07 - [ssh.1] - - typo fix - ok jmc@ - - jmc@cvs.openbsd.org 2006/02/06 21:44:47 - [ssh.1] - make this a little less ambiguous... - - stevesk@cvs.openbsd.org 2006/02/07 01:08:04 - [auth-rhosts.c includes.h] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/07 01:18:09 - [includes.h ssh-agent.c ssh-keyscan.c sshconnect2.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/07 01:42:00 - [channels.c clientloop.c clientloop.h includes.h packet.h] - [serverloop.c sshpty.c sshpty.h sshtty.c ttymodes.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/07 01:52:50 - [sshtty.c] - "log.h" not needed - - stevesk@cvs.openbsd.org 2006/02/07 03:47:05 - [hostfile.c] - "packet.h" not needed - - stevesk@cvs.openbsd.org 2006/02/07 03:59:20 - [deattack.c] - duplicate #include - - stevesk@cvs.openbsd.org 2006/02/08 12:15:27 - [auth.c clientloop.c includes.h misc.c monitor.c readpass.c] - [session.c sftp.c ssh-agent.c ssh-keysign.c ssh.c sshconnect.c] - [sshd.c sshpty.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/08 12:32:49 - [includes.h misc.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/08 13:15:44 - [gss-serv.c monitor.c] - small KNF - - stevesk@cvs.openbsd.org 2006/02/08 14:16:59 - [sshconnect.c] - not needed - - stevesk@cvs.openbsd.org 2006/02/08 14:31:30 - [includes.h ssh-agent.c ssh-keyscan.c ssh.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/08 14:38:18 - [includes.h packet.c] - move #include and out of - includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/08 23:51:24 - [includes.h scp.c sftp-glob.c sftp-server.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/09 00:32:07 - [includes.h] - #include not needed; ok djm@ - NB. ID Sync only - we still need this (but it may move later) - - jmc@cvs.openbsd.org 2006/02/09 10:10:47 - [sshd.8] - - move some text into a CAVEATS section - - merge the COMMAND EXECUTION... section into AUTHENTICATION - - stevesk@cvs.openbsd.org 2006/02/10 00:27:13 - [channels.c clientloop.c includes.h misc.c progressmeter.c sftp.c] - [ssh.c sshd.c sshpty.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/10 01:44:27 - [includes.h monitor.c readpass.c scp.c serverloop.c session.c] - [sftp.c sshconnect.c sshconnect2.c sshd.c] - move #include out of includes.h; ok markus@ - - otto@cvs.openbsd.org 2006/02/11 19:31:18 - [atomicio.c] - type correctness; from Ray Lai in PR 5011; ok millert@ - - djm@cvs.openbsd.org 2006/02/12 06:45:34 - [ssh.c ssh_config.5] - add a %l expansion code to the ControlPath, which is filled in with the - local hostname at runtime. Requested by henning@ to avoid some problems - with /home on NFS; ok dtucker@ - - djm@cvs.openbsd.org 2006/02/12 10:44:18 - [readconf.c] - raise error when the user specifies a RekeyLimit that is smaller than 16 - (the smallest of our cipher's blocksize) or big enough to cause integer - wraparound; ok & feedback dtucker@ - - jmc@cvs.openbsd.org 2006/02/12 10:49:44 - [ssh_config.5] - slight rewording; ok djm - - jmc@cvs.openbsd.org 2006/02/12 10:52:41 - [sshd.8] - rework the description of authorized_keys a little; - - jmc@cvs.openbsd.org 2006/02/12 17:57:19 - [sshd.8] - sort the list of options permissable w/ authorized_keys; - ok djm dtucker - - jmc@cvs.openbsd.org 2006/02/13 10:16:39 - [sshd.8] - no need to subsection the authorized_keys examples - instead, convert - this to look like an actual file. also use proto 2 keys, and use IETF - example addresses; - - jmc@cvs.openbsd.org 2006/02/13 10:21:25 - [sshd.8] - small tweaks for the ssh_known_hosts section; - - jmc@cvs.openbsd.org 2006/02/13 11:02:26 - [sshd.8] - turn this into an example ssh_known_hosts file; ok djm - - jmc@cvs.openbsd.org 2006/02/13 11:08:43 - [sshd.8] - - avoid nasty line split - - `*' does not need to be escaped - - jmc@cvs.openbsd.org 2006/02/13 11:27:25 - [sshd.8] - sort FILES and use a -compact list; - - david@cvs.openbsd.org 2006/02/15 05:08:24 - [sftp-client.c] - typo in comment; ok djm@ - - jmc@cvs.openbsd.org 2006/02/15 16:53:20 - [ssh.1] - remove the IETF draft references and replace them with some updated RFCs; - - jmc@cvs.openbsd.org 2006/02/15 16:55:33 - [sshd.8] - remove ietf draft references; RFC list now maintained in ssh.1; - - jmc@cvs.openbsd.org 2006/02/16 09:05:34 - [sshd.8] - sync some of the FILES entries w/ ssh.1; - - jmc@cvs.openbsd.org 2006/02/19 19:52:10 - [sshd.8] - move the sshrc stuff out of FILES, and into its own section: - FILES is not a good place to document how stuff works; - - jmc@cvs.openbsd.org 2006/02/19 20:02:17 - [sshd.8] - sync the (s)hosts.equiv FILES entries w/ those from ssh.1; - - jmc@cvs.openbsd.org 2006/02/19 20:05:00 - [sshd.8] - grammar; - - jmc@cvs.openbsd.org 2006/02/19 20:12:25 - [ssh_config.5] - add some vertical space; - - stevesk@cvs.openbsd.org 2006/02/20 16:36:15 - [authfd.c channels.c includes.h session.c ssh-agent.c ssh.c] - move #include out of includes.h; ok djm@ - - stevesk@cvs.openbsd.org 2006/02/20 17:02:44 - [clientloop.c includes.h monitor.c progressmeter.c scp.c] - [serverloop.c session.c sftp.c ssh-agent.c ssh.c sshd.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/20 17:19:54 - [auth-rhosts.c auth-rsa.c auth.c auth2-none.c auth2-pubkey.c] - [authfile.c clientloop.c includes.h readconf.c scp.c session.c] - [sftp-client.c sftp-common.c sftp-common.h sftp-glob.c] - [sftp-server.c sftp.c ssh-add.c ssh-keygen.c ssh.c sshconnect.c] - [sshconnect2.c sshd.c sshpty.c] - move #include out of includes.h; ok markus@ - - stevesk@cvs.openbsd.org 2006/02/22 00:04:45 - [canohost.c clientloop.c includes.h match.c readconf.c scp.c ssh.c] - [sshconnect.c] - move #include out of includes.h; ok djm@ - - jmc@cvs.openbsd.org 2006/02/24 10:25:14 - [ssh_config.5] - add section on patterns; - from dtucker + myself - - jmc@cvs.openbsd.org 2006/02/24 10:33:54 - [sshd_config.5] - signpost to PATTERNS; - - jmc@cvs.openbsd.org 2006/02/24 10:37:07 - [ssh_config.5] - tidy up the refs to PATTERNS; - - jmc@cvs.openbsd.org 2006/02/24 10:39:52 - [sshd.8] - signpost to PATTERNS section; - - jmc@cvs.openbsd.org 2006/02/24 20:22:16 - [ssh-keysign.8 ssh_config.5 sshd_config.5] - some consistency fixes; - - jmc@cvs.openbsd.org 2006/02/24 20:31:31 - [ssh.1 ssh_config.5 sshd.8 sshd_config.5] - more consistency fixes; - - jmc@cvs.openbsd.org 2006/02/24 23:20:07 - [ssh_config.5] - some grammar/wording fixes; - - jmc@cvs.openbsd.org 2006/02/24 23:43:57 - [sshd_config.5] - some grammar/wording fixes; - - jmc@cvs.openbsd.org 2006/02/24 23:51:17 - [sshd_config.5] - oops - bits i missed; - - jmc@cvs.openbsd.org 2006/02/25 12:26:17 - [ssh_config.5] - document the possible values for KbdInteractiveDevices; - help/ok dtucker - - jmc@cvs.openbsd.org 2006/02/25 12:28:34 - [sshd_config.5] - document the order in which allow/deny directives are processed; - help/ok dtucker - - jmc@cvs.openbsd.org 2006/02/26 17:17:18 - [ssh_config.5] - move PATTERNS to the end of the main body; requested by dtucker - - jmc@cvs.openbsd.org 2006/02/26 18:01:13 - [sshd_config.5] - subsection is pointless here; - - jmc@cvs.openbsd.org 2006/02/26 18:03:10 - [ssh_config.5] - comma; - - djm@cvs.openbsd.org 2006/02/28 01:10:21 - [session.c] - fix logout recording when privilege separation is disabled, analysis and - patch from vinschen at redhat.com; tested by dtucker@ ok deraadt@ - NB. ID sync only - patch already in portable - - djm@cvs.openbsd.org 2006/03/04 04:12:58 - [serverloop.c] - move a debug() outside of a signal handler; ok markus@ a little while back - - djm@cvs.openbsd.org 2006/03/12 04:23:07 - [ssh.c] - knf nit - - djm@cvs.openbsd.org 2006/03/13 08:16:00 - [sshd.c] - don't log that we are listening on a socket before the listen() call - actually succeeds, bz #1162 reported by Senthil Kumar; ok dtucker@ - - dtucker@cvs.openbsd.org 2006/03/13 08:33:00 - [packet.c] - Set TCP_NODELAY for all connections not just "interactive" ones. Fixes - poor performance and protocol stalls under some network conditions (mindrot - bugs #556 and #981). Patch originally from markus@, ok djm@ - - dtucker@cvs.openbsd.org 2006/03/13 08:43:16 - [ssh-keygen.c] - Make ssh-keygen handle CR and CRLF line termination when converting IETF - format keys, in adition to vanilla LF. mindrot #1157, tested by Chris - Pepper, ok djm@ - - dtucker@cvs.openbsd.org 2006/03/13 10:14:29 - [misc.c ssh_config.5 sshd_config.5] - Allow config directives to contain whitespace by surrounding them by double - quotes. mindrot #482, man page help from jmc@, ok djm@ - - dtucker@cvs.openbsd.org 2006/03/13 10:26:52 - [authfile.c authfile.h ssh-add.c] - Make ssh-add check file permissions before attempting to load private - key files multiple times; it will fail anyway and this prevents confusing - multiple prompts and warnings. mindrot #1138, ok djm@ - - djm@cvs.openbsd.org 2006/03/14 00:15:39 - [canohost.c] - log the originating address and not just the name when a reverse - mapping check fails, requested by linux AT linuon.com - - markus@cvs.openbsd.org 2006/03/14 16:32:48 - [ssh_config.5 sshd_config.5] - *AliveCountMax applies to protcol v2 only; ok dtucker, djm - - djm@cvs.openbsd.org 2006/03/07 09:07:40 - [kex.c kex.h monitor.c myproposal.h ssh-keyscan.c sshconnect2.c sshd.c] - Implement the diffie-hellman-group-exchange-sha256 key exchange method - using the SHA256 code in libc (and wrapper to make it into an OpenSSL - EVP), interop tested against CVS PuTTY - NB. no portability bits committed yet - - (djm) [configure.ac defines.h kex.c md-sha256.c] - [openbsd-compat/sha2.h openbsd-compat/openbsd-compat.h] - [openbsd-compat/sha2.c] First stab at portability glue for SHA256 - KEX support, should work with libc SHA256 support or OpenSSL - EVP_sha256 if present - - (djm) [includes.h] Restore accidentally dropped netinet/in.h - - (djm) [Makefile.in openbsd-compat/Makefile.in] Add added files - - (djm) [md-sha256.c configure.ac] md-sha256.c needs sha2.h if present - - (djm) [regress/.cvsignore] Ignore Makefile here - - (djm) [loginrec.c] Need stat.h - - (djm) [openbsd-compat/sha2.h] Avoid include macro clash with - system sha2.h - - (djm) [ssh-rand-helper.c] Needs a bunch of headers - - (djm) [ssh-agent.c] Restore dropped stat.h - - (djm) [openbsd-compat/sha2.h openbsd-compat/sha2.c] Comment out - SHA384, which we don't need and doesn't compile without tweaks - - (djm) [auth-pam.c clientloop.c includes.h monitor.c session.c] - [sftp-client.c ssh-keysign.c ssh.c sshconnect.c sshconnect2.c] - [sshd.c openbsd-compat/bsd-misc.c openbsd-compat/bsd-openpty.c] - [openbsd-compat/glob.c openbsd-compat/mktemp.c] - [openbsd-compat/readpassphrase.c] Lots of include fixes for - OpenSolaris - - (tim) [includes.h] put sys/stat.h back in to quiet some "macro redefined:" - - (tim) [openssh/sshpty.c openssh/openbsd-compat/port-tun.c] put in some - includes removed from includes.h - - (dtucker) [configure.ac] Fix glob test conversion to AC_TRY_COMPILE - - (djm) [includes.h] Put back paths.h, it is needed in defines.h - - (dtucker) [openbsd-compat/openbsd-compat.h] AIX (at least) needs - sys/ioctl.h for struct winsize. - - (dtucker) [configure.ac] login_cap.h requires sys/types.h on NetBSD. - -20060313 - - (dtucker) [configure.ac] Bug #1171: Don't use printf("%lld", longlong) - since not all platforms support it. Instead, use internal equivalent while - computing LLONG_MIN and LLONG_MAX. Remove special case for alpha-dec-osf* - as it's no longer required. Tested by Bernhard Simon, ok djm@ - -20060304 - - (dtucker) [contrib/cygwin/ssh-host-config] Require use of lastlog as a - file rather than directory, required as Cygwin will be importing lastlog(1). - Also tightens up permissions on the file. Patch from vinschen@redhat.com. - - (dtucker) [gss-serv-krb5.c] Bug #1166: Correct #ifdefs for gssapi_krb5.h - includes. Patch from gentoo.riverrat at gmail.com. - -20060226 - - (dtucker) [configure.ac] Bug #1156: QNX apparently needs SSHD_ACQUIRES_CTTY - patch from kraai at ftbfs.org. - -20060223 - - (dtucker) [sshd_config sshd_config.5] Update UsePAM to reflect current - reality. Pointed out by tryponraj at gmail.com. - -20060222 - - (dtucker) [openbsd-compat/openssl-compat.{c,h}] Minor tidy up: only - compile in compat code if required. - -20060221 - - (dtucker) [openbsd-compat/openssl-compat.h] Prevent warning about - redefinition of SSLeay_add_all_algorithms. - -20060220 - - (dtucker) [INSTALL configure.ac openbsd-compat/openssl-compat.{c,h}] - Add optional enabling of OpenSSL's (hardware) Engine support, via - configure --with-ssl-engine. Based in part on a diff by michal at - logix.cz. - -20060219 - - (dtucker) [Makefile.in configure.ac, added openbsd-compat/regress/] - Add first attempt at regress tests for compat library. ok djm@ - -20060214 - - (tim) [buildpkg.sh.in] Make the names consistent. - s/pkg_post_make_install_fixes.sh/pkg-post-make-install-fixes.sh/ OK dtucker@ - -20060212 - - (dtucker) [openbsd-compat/bsd-cygwin_util.c] Make loop counter unsigned - to silence compiler warning, from vinschen at redhat.com. - - (tim) [configure.ac] Bug #1149. Disable /etc/default/login check for QNX. - - (dtucker) [README version.h contrib/caldera/openssh.spec - contrib/redhat/openssh.spec contrib/suse/openssh.spec] Bump version - strings to match 4.3p2 release. - -20060208 - - (tim) [session.c] Logout records were not updated on systems with - post auth privsep disabled due to bug 1086 changes. Analysis and patch - by vinschen at redhat.com. OK tim@, dtucker@. - - (dtucker) [configure.ac] Typo in Ultrix and NewsOS sections (NEED_SETPRGP - -> NEED_SETPGRP), reported by Bernhard Simon. ok tim@ - -20060206 - - (tim) [configure.ac] Remove unnecessary tests for net/if.h and - netinet/in_systm.h. OK dtucker@. - -20060205 - - (tim) [configure.ac] Add AC_REVISION. Add sys/time.h to lastlog.h test - for Solaris. OK dtucker@. - - (tim) [configure.ac] Bug #1149. Changes in QNX section only. Patch by - kraai at ftbfs.org. - -20060203 - - (tim) [configure.ac] test for egrep (AC_PROG_EGREP) before first - AC_CHECK_HEADERS test. Without it, if AC_CHECK_HEADERS is first run - by a platform specific check, builtin standard includes tests will be - skipped on the other platforms. - Analysis and suggestion by vinschen at redhat.com, patch by dtucker@. - OK tim@, djm@. - -20060202 - - (dtucker) [configure.ac] Bug #1148: Fix "crippled AES" test so that it - works with picky compilers. Patch from alex.kiernan at thus.net. - -20060201 - - (djm) [regress/test-exec.sh] Try 'logname' as well as 'whoami' to - determine the user's login name - needed for regress tests on Solaris - 10 and OpenSolaris - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/02/01 09:06:50 - [sshd.8] - - merge sections on protocols 1 and 2 into a single section - - remove configuration file section - ok markus - - jmc@cvs.openbsd.org 2006/02/01 09:11:41 - [sshd.8] - small tweak; - - (djm) [contrib/caldera/openssh.spec contrib/redhat/openssh.spec] - [contrib/suse/openssh.spec] Update versions ahead of release - - markus@cvs.openbsd.org 2006/02/01 11:27:22 - [version.h] - openssh 4.3 - - (djm) Release OpenSSH 4.3p1 - -20060131 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/01/20 11:21:45 - [ssh_config.5] - - word change, agreed w/ markus - - consistency fixes - - jmc@cvs.openbsd.org 2006/01/25 09:04:34 - [sshd.8] - move the options description up the page, and a few additional tweaks - whilst in here; - ok markus - - jmc@cvs.openbsd.org 2006/01/25 09:07:22 - [sshd.8] - move subsections to full sections; - - jmc@cvs.openbsd.org 2006/01/26 08:47:56 - [ssh.1] - add a section on verifying host keys in dns; - written with a lot of help from jakob; - feedback dtucker/markus; - ok markus - - reyk@cvs.openbsd.org 2006/01/30 12:22:22 - [channels.c] - mark channel as write failed or dead instead of read failed on error - of the channel output filter. - ok markus@ - - jmc@cvs.openbsd.org 2006/01/30 13:37:49 - [ssh.1] - remove an incorrect sentence; - reported by roumen petrov; - ok djm markus - - djm@cvs.openbsd.org 2006/01/31 10:19:02 - [misc.c misc.h scp.c sftp.c] - fix local arbitrary command execution vulnerability on local/local and - remote/remote copies (CVE-2006-0225, bz #1094), patch by - t8m AT centrum.cz, polished by dtucker@ and myself; ok markus@ - - djm@cvs.openbsd.org 2006/01/31 10:35:43 - [scp.c] - "scp a b c" shouldn't clobber "c" when it is not a directory, report and - fix from biorn@; ok markus@ - - (djm) Sync regress tests to OpenBSD: - - dtucker@cvs.openbsd.org 2005/03/10 10:20:39 - [regress/forwarding.sh] - Regress test for ClearAllForwardings (bz #994); ok markus@ - - dtucker@cvs.openbsd.org 2005/04/25 09:54:09 - [regress/multiplex.sh] - Don't call cleanup in multiplex as test-exec will cleanup anyway - found by tim@, ok djm@ - NB. ID sync only, we already had this - - djm@cvs.openbsd.org 2005/05/20 23:14:15 - [regress/test-exec.sh] - force addressfamily=inet for tests, unbreaking dynamic-forward regress for - recently committed nc SOCKS5 changes - - djm@cvs.openbsd.org 2005/05/24 04:10:54 - [regress/try-ciphers.sh] - oops, new arcfour modes here too - - markus@cvs.openbsd.org 2005/06/30 11:02:37 - [regress/scp.sh] - allow SUDO=sudo; from Alexander Bluhm - - grunk@cvs.openbsd.org 2005/11/14 21:25:56 - [regress/agent-getpeereid.sh] - all other scripts in this dir use $SUDO, not 'sudo', so pull this even - ok markus@ - - dtucker@cvs.openbsd.org 2005/12/14 04:36:39 - [regress/scp-ssh-wrapper.sh] - Fix assumption about how many args scp will pass; ok djm@ - NB. ID sync only, we already had this - - djm@cvs.openbsd.org 2006/01/27 06:49:21 - [scp.sh] - regress test for local to local scp copies; ok dtucker@ - - djm@cvs.openbsd.org 2006/01/31 10:23:23 - [scp.sh] - regression test for CVE-2006-0225 written by dtucker@ - - djm@cvs.openbsd.org 2006/01/31 10:36:33 - [scp.sh] - regress test for "scp a b c" where "c" is not a directory - -20060129 - - (dtucker) [configure.ac opensshd.init.in] Bug #1144: Use /bin/sh for the - opensshd.init script interpretter if /sbin/sh does not exist. ok tim@ - -20060120 - - (dtucker) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/01/15 17:37:05 - [ssh.1] - correction from deraadt - - jmc@cvs.openbsd.org 2006/01/18 10:53:29 - [ssh.1] - add a section on ssh-based vpn, based on reyk's README.tun; - - dtucker@cvs.openbsd.org 2006/01/20 00:14:55 - [scp.1 ssh.1 ssh_config.5 sftp.1] - Document RekeyLimit. Based on patch from jan.iven at cern.ch from mindrot - #1056 with feedback from jmc, djm and markus; ok jmc@ djm@ - -20060114 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/01/06 13:27:32 - [ssh.1] - weed out some duplicate info in the known_hosts FILES entries; - ok djm - - jmc@cvs.openbsd.org 2006/01/06 13:29:10 - [ssh.1] - final round of whacking FILES for duplicate info, and some consistency - fixes; - ok djm - - jmc@cvs.openbsd.org 2006/01/12 14:44:12 - [ssh.1] - split sections on tcp and x11 forwarding into two sections. - add an example in the tcp section, based on sth i wrote for ssh faq; - help + ok: djm markus dtucker - - jmc@cvs.openbsd.org 2006/01/12 18:48:48 - [ssh.1] - refer to `TCP' rather than `TCP/IP' in the context of connection - forwarding; - ok markus - - jmc@cvs.openbsd.org 2006/01/12 22:20:00 - [sshd.8] - refer to TCP forwarding, rather than TCP/IP forwarding; - - jmc@cvs.openbsd.org 2006/01/12 22:26:02 - [ssh_config.5] - refer to TCP forwarding, rather than TCP/IP forwarding; - - jmc@cvs.openbsd.org 2006/01/12 22:34:12 - [ssh.1] - back out a sentence - AUTHENTICATION already documents this; - -20060109 - - (dtucker) [contrib/cygwin/ssh-host-config] Make sshd service depend on - tcpip service so it's always started after IP is up. Patch from - vinschen at redhat.com. - -20060106 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/01/03 16:31:10 - [ssh.1] - move FILES to a -compact list, and make each files an item in that list. - this avoids nastly line wrap when we have long pathnames, and treats - each file as a separate item; - remove the .Pa too, since it is useless. - - jmc@cvs.openbsd.org 2006/01/03 16:35:30 - [ssh.1] - use a larger width for the ENVIRONMENT list; - - jmc@cvs.openbsd.org 2006/01/03 16:52:36 - [ssh.1] - put FILES in some sort of order: sort by pathname - - jmc@cvs.openbsd.org 2006/01/03 16:55:18 - [ssh.1] - tweak the description of ~/.ssh/environment - - jmc@cvs.openbsd.org 2006/01/04 18:42:46 - [ssh.1] - chop out some duplication in the .{r,s}hosts/{h,sh}osts.equiv FILES - entries; - ok markus - - jmc@cvs.openbsd.org 2006/01/04 18:45:01 - [ssh.1] - remove .Xr's to rsh(1) and telnet(1): they are hardly needed; - - jmc@cvs.openbsd.org 2006/01/04 19:40:24 - [ssh.1] - +.Xr ssh-keyscan 1 , - - jmc@cvs.openbsd.org 2006/01/04 19:50:09 - [ssh.1] - -.Xr gzip 1 , - - djm@cvs.openbsd.org 2006/01/05 23:43:53 - [misc.c] - check that stdio file descriptors are actually closed before clobbering - them in sanitise_stdfd(). problems occurred when a lower numbered fd was - closed, but higher ones weren't. spotted by, and patch tested by - Frédéric Olivié - -20060103 - - (djm) [channels.c] clean up harmless merge error, from reyk@ - -20060103 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2006/01/02 17:09:49 - [ssh_config.5 sshd_config.5] - some corrections from michael knudsen; - -20060102 - - (djm) [README.tun] Add README.tun, missed during sync of tun(4) support - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2005/12/31 10:46:17 - [ssh.1] - merge the "LOGIN SESSION AND REMOTE EXECUTION" and "SERVER - AUTHENTICATION" sections into "AUTHENTICATION"; - some rewording done to make the text read better, plus some - improvements from djm; - ok djm - - jmc@cvs.openbsd.org 2005/12/31 13:44:04 - [ssh.1] - clean up ENVIRONMENT a little; - - jmc@cvs.openbsd.org 2005/12/31 13:45:19 - [ssh.1] - .Nm does not require an argument; - - stevesk@cvs.openbsd.org 2006/01/01 08:59:27 - [includes.h misc.c] - move ; ok djm@ - - stevesk@cvs.openbsd.org 2006/01/01 10:08:48 - [misc.c] - no trailing "\n" for debug() - - djm@cvs.openbsd.org 2006/01/02 01:20:31 - [sftp-client.c sftp-common.h sftp-server.c] - use a common max. packet length, no binary change - - reyk@cvs.openbsd.org 2006/01/02 07:53:44 - [misc.c] - clarify tun(4) opening - set the mode and bring the interface up. also - (re)sets the tun(4) layer 2 LINK0 flag for existing tunnel interfaces. - suggested and ok by djm@ - - jmc@cvs.openbsd.org 2006/01/02 12:31:06 - [ssh.1] - start to cut some duplicate info from FILES; - help/ok djm - -20060101 - - (djm) [Makefile.in configure.ac includes.h misc.c] - [openbsd-compat/port-tun.c openbsd-compat/port-tun.h] Add support - for tunnel forwarding for FreeBSD and NetBSD. NetBSD's support is - limited to IPv4 tunnels only, and most versions don't support the - tap(4) device at all. - - (djm) [configure.ac] Fix linux/if_tun.h test - - (djm) [openbsd-compat/port-tun.c] Linux needs linux/if.h too - -20051229 - - (djm) OpenBSD CVS Sync - - stevesk@cvs.openbsd.org 2005/12/28 22:46:06 - [canohost.c channels.c clientloop.c] - use 'break-in' for consistency; ok deraadt@ ok and input jmc@ - - reyk@cvs.openbsd.org 2005/12/30 15:56:37 - [channels.c channels.h clientloop.c] - add channel output filter interface. - ok djm@, suggested by markus@ - - jmc@cvs.openbsd.org 2005/12/30 16:59:00 - [sftp.1] - do not suggest that interactive authentication will work - with the -b flag; - based on a diff from john l. scarfone; - ok djm - - stevesk@cvs.openbsd.org 2005/12/31 01:38:45 - [ssh.1] - document -MM; ok djm@ - - (djm) [openbsd-compat/port-tun.c openbsd-compat/port-tun.h configure.ac] - [serverloop.c ssh.c openbsd-compat/Makefile.in] - [openbsd-compat/openbsd-compat.h] Implement tun(4) forwarding - compatability support for Linux, diff from reyk@ - - (djm) [configure.ac] Disable Linux tun(4) compat code if linux/tun.h does - not exist - - (djm) [configure.ac] oops, make that linux/if_tun.h - -20051229 - - (tim) [buildpkg.sh.in] grep for $SSHDUID instead of $SSHDGID on /etc/passwd - -20051224 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2005/12/20 21:59:43 - [ssh.1] - merge the sections on protocols 1 and 2 into one section on - authentication; - feedback djm dtucker - ok deraadt markus dtucker - - jmc@cvs.openbsd.org 2005/12/20 22:02:50 - [ssh.1] - .Ss -> .Sh: subsections have not made this page more readable - - jmc@cvs.openbsd.org 2005/12/20 22:09:41 - [ssh.1] - move info on ssh return values and config files up into the main - description; - - jmc@cvs.openbsd.org 2005/12/21 11:48:16 - [ssh.1] - -L and -R descriptions are now above, not below, ~C description; - - jmc@cvs.openbsd.org 2005/12/21 11:57:25 - [ssh.1] - options now described `above', rather than `later'; - - jmc@cvs.openbsd.org 2005/12/21 12:53:31 - [ssh.1] - -Y does X11 forwarding too; - ok markus - - stevesk@cvs.openbsd.org 2005/12/21 22:44:26 - [sshd.8] - clarify precedence of -p, Port, ListenAddress; ok and help jmc@ - - jmc@cvs.openbsd.org 2005/12/22 10:31:40 - [ssh_config.5] - put the description of "UsePrivilegedPort" in the correct place; - - jmc@cvs.openbsd.org 2005/12/22 11:23:42 - [ssh.1] - expand the description of -w somewhat; - help/ok reyk - - jmc@cvs.openbsd.org 2005/12/23 14:55:53 - [ssh.1] - - sync the description of -e w/ synopsis - - simplify the description of -I - - note that -I is only available if support compiled in, and that it - isn't by default - feedback/ok djm@ - - jmc@cvs.openbsd.org 2005/12/23 23:46:23 - [ssh.1] - less mark up for -c; - - djm@cvs.openbsd.org 2005/12/24 02:27:41 - [session.c sshd.c] - eliminate some code duplicated in privsep and non-privsep paths, and - explicitly clear SIGALRM handler; "groovy" deraadt@ - -20051220 - - (dtucker) OpenBSD CVS Sync - - reyk@cvs.openbsd.org 2005/12/13 15:03:02 - [serverloop.c] - if forced_tun_device is not set, it is -1 and not SSH_TUNID_ANY - - jmc@cvs.openbsd.org 2005/12/16 18:07:08 - [ssh.1] - move the option descriptions up the page: start of a restructure; - ok markus deraadt - - jmc@cvs.openbsd.org 2005/12/16 18:08:53 - [ssh.1] - simplify a sentence; - - jmc@cvs.openbsd.org 2005/12/16 18:12:22 - [ssh.1] - make the description of -c a little nicer; - - jmc@cvs.openbsd.org 2005/12/16 18:14:40 - [ssh.1] - signpost the protocol sections; - - stevesk@cvs.openbsd.org 2005/12/17 21:13:05 - [ssh_config.5 session.c] - spelling: fowarding, fowarded - - stevesk@cvs.openbsd.org 2005/12/17 21:36:42 - [ssh_config.5] - spelling: intented -> intended - - dtucker@cvs.openbsd.org 2005/12/20 04:41:07 - [ssh.c] - exit(255) on error to match description in ssh(1); bz #1137; ok deraadt@ - -20051219 - - (dtucker) [cipher-aes.c cipher-ctr.c cipher.c configure.ac - openbsd-compat/openssl-compat.h] Check for and work around broken AES - ciphers >128bit on (some) Solaris 10 systems. ok djm@ - -20051217 - - (dtucker) [defines.h] HP-UX system headers define "YES" and "NO" which - scp.c also uses, so undef them here. - - (dtucker) [configure.ac openbsd-compat/bsd-snprintf.c] Bug #1133: Our - snprintf replacement can have a conflicting declaration in HP-UX's system - headers (const vs. no const) so we now check for and work around it. Patch - from the dynamic duo of David Leonard and Ted Percival. - -20051214 - - (dtucker) OpenBSD CVS Sync (regress/) - - dtucker@cvs.openbsd.org 2005/12/30 04:36:39 - [regress/scp-ssh-wrapper.sh] - Fix assumption about how many args scp will pass; ok djm@ - -20051213 - - (djm) OpenBSD CVS Sync - - jmc@cvs.openbsd.org 2005/11/30 11:18:27 - [ssh.1] - timezone -> time zone - - jmc@cvs.openbsd.org 2005/11/30 11:45:20 - [ssh.1] - avoid ambiguities in describing TZ; - ok djm@ - - reyk@cvs.openbsd.org 2005/12/06 22:38:28 - [auth-options.c auth-options.h channels.c channels.h clientloop.c] - [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h] - [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c] - [sshconnect.h sshd.8 sshd_config sshd_config.5] - Add support for tun(4) forwarding over OpenSSH, based on an idea and - initial channel code bits by markus@. This is a simple and easy way to - use OpenSSH for ad hoc virtual private network connections, e.g. - administrative tunnels or secure wireless access. It's based on a new - ssh channel and works similar to the existing TCP forwarding support, - except that it depends on the tun(4) network interface on both ends of - the connection for layer 2 or layer 3 tunneling. This diff also adds - support for LocalCommand in the ssh(1) client. - ok djm@, markus@, jmc@ (manpages), tested and discussed with others - - djm@cvs.openbsd.org 2005/12/07 03:52:22 - [clientloop.c] - reyk forgot to compile with -Werror (missing header) - - jmc@cvs.openbsd.org 2005/12/07 10:52:13 - [ssh.1] - - avoid line split in SYNOPSIS - - add args to -w - - kill trailing whitespace - - jmc@cvs.openbsd.org 2005/12/08 14:59:44 - [ssh.1 ssh_config.5] - make `!command' a little clearer; - ok reyk - - jmc@cvs.openbsd.org 2005/12/08 15:06:29 - [ssh_config.5] - keep options in order; - - reyk@cvs.openbsd.org 2005/12/08 18:34:11 - [auth-options.c includes.h misc.c misc.h readconf.c servconf.c] - [serverloop.c ssh.c ssh_config.5 sshd_config.5 configure.ac] - two changes to the new ssh tunnel support. this breaks compatibility - with the initial commit but is required for a portable approach. - - make the tunnel id u_int and platform friendly, use predefined types. - - support configuration of layer 2 (ethernet) or layer 3 - (point-to-point, default) modes. configuration is done using the - Tunnel (yes|point-to-point|ethernet|no) option is ssh_config(5) and - restricted by the PermitTunnel (yes|point-to-point|ethernet|no) option - in sshd_config(5). - ok djm@, man page bits by jmc@ - - jmc@cvs.openbsd.org 2005/12/08 21:37:50 - [ssh_config.5] - new sentence, new line; - - markus@cvs.openbsd.org 2005/12/12 13:46:18 - [channels.c channels.h session.c] - make sure protocol messages for internal channels are ignored. - allow adjust messages for non-open channels; with and ok djm@ - - (djm) [misc.c] Disable tunnel code for non-OpenBSD (for now), enable - again by providing a sys_tun_open() function for your platform and - setting the CUSTOM_SYS_TUN_OPEN define. More work is required to match - OpenBSD's tunnel protocol, which prepends the address family to the - packet - -20051201 - - (djm) [envpass.sh] Remove regress script that was accidentally committed - in top level directory and not noticed for over a year :) - -20051129 - - (tim) [ssh-keygen.c] Move DSA length test after setting default when - bits == 0. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2005/11/29 02:04:55 - [ssh-keygen.c] - Populate default key sizes before checking them; from & ok tim@ - - (tim) [configure.ac sshd.8] Enable locked account check (a "*LK*" string) - for UnixWare. - -20051128 - - (dtucker) [regress/yes-head.sh] Work around breakage caused by some - versions of GNU head. Based on patch from zappaman at buraphalinux.org - - (dtucker) [includes.h] Bug #1122: __USE_GNU is a glibc internal macro, use - _GNU_SOURCE instead. Patch from t8m at centrum.cz. - - (dtucker) OpenBSD CVS Sync - - dtucker@cvs.openbsd.org 2005/11/28 05:16:53 - [ssh-keygen.1 ssh-keygen.c] - Enforce DSA key length of exactly 1024 bits to comply with FIPS-186-2, - increase minumum RSA key size to 768 bits and update man page to reflect - these. Patch originally bz#1119 (senthilkumar_sen at hotpop.com), - ok djm@, grudging ok deraadt@. - - dtucker@cvs.openbsd.org 2005/11/28 06:02:56 - [ssh-agent.1] - Update agent socket path templates to reflect reality, correct xref for - time formats. bz#1121, patch from openssh at roumenpetrov.info, ok djm@ - -20051126 - - (dtucker) [configure.ac] Bug #1126: AIX 5.2 and 5.3 (and presumably newer, - when they're available) need the real UID set otherwise pam_chauthtok will - set ADMCHG after changing the password, forcing the user to change it - again immediately. - -20051125 - - (dtucker) [configure.ac] Apply tim's fix for older systems where the - resolver state in resolv.h is "state" not "__res_state". With slight - modification by me to also work on old AIXes. ok djm@ - - (dtucker) [progressmeter.c scp.c sftp-server.c] Use correct casts for - snprintf formats, fixes warnings on some 64 bit platforms. Patch from - shaw at vranix.com, ok djm@ - -20051124 - - (djm) [configure.ac openbsd-compat/Makefile.in openbsd-compat/bsd-asprintf.c - openbsd-compat/bsd-snprintf.c openbsd-compat/openbsd-compat.h] Add an - asprintf() implementation, after syncing our {v,}snprintf() implementation - with some extra fixes from Samba's version. With help and debugging from - dtucker and tim; ok dtucker@ - - (dtucker) [configure.ac] Fix typos in comments and AC_SEARCH_LIB argument - order in Reliant Unix block. Patch from johane at lysator.liu.se. - - (dtucker) [regress/test-exec.sh] Use 1024 bit keys since we generate so - many and use them only once. Speeds up testing on older/slower hardware. - -20051122 - - (dtucker) OpenBSD CVS Sync - - deraadt@cvs.openbsd.org 2005/11/12 18:37:59 - [ssh-add.c] - space - - deraadt@cvs.openbsd.org 2005/11/12 18:38:15 - [scp.c] - avoid close(-1), as in rcp; ok cloder - - millert@cvs.openbsd.org 2005/11/15 11:59:54 - [includes.h] - Include sys/queue.h explicitly instead of assuming some other header - will pull it in. At the moment it gets pulled in by sys/select.h - (which ssh has no business including) via event.h. OK markus@ - (ID sync only in -portable) - - dtucker@cvs.openbsd.org 2005/11/21 09:42:10 - [auth-krb5.c] - Perform Kerberos calls even for invalid users to prevent leaking - information about account validity. bz #975, patch originally from - Senthil Kumar, sanity checked by Simon Wilkinson, tested by djm@, biorn@, - ok markus@ - - dtucker@cvs.openbsd.org 2005/11/22 03:36:03 - [hostfile.c] - Correct format/arguments to debug call; spotted by shaw at vranix.com - ok djm@ - - (dtucker) [loginrec.c] Add casts to prevent compiler warnings, patch - from shaw at vranix.com. - -20051120 - - (dtucker) [openbsd-compat/openssl-compat.h] Add comment explaining what - is going on. - -20051112 - - (dtucker) [openbsd-compat/getrrsetbyname.c] Restore Portable-specific - ifdef lost during sync. Spotted by tim@. - - (dtucker) [openbsd-compat/{realpath.c,stroll.c,rresvport.c}] $OpenBSD tag. - - (dtucker) [configure.ac] Use "$AWK" instead of "awk" in gcc version test. - - (dtucker) [configure.ac] Remove duplicate utimes() check. ok djm@ - - (dtucker) [regress/reconfigure.sh] Fix potential race in the reconfigure - test: if sshd takes too long to reconfigure the subsequent connection will - fail. Zap pidfile before HUPing sshd which will rewrite it when it's ready. - -20051110 - - (dtucker) [openbsd-compat/setenv.c] Merge changes for __findenv from - OpenBSD getenv.c revs 1.4 - 1.8 (ANSIfication of arguments, removal of - "register"). - - (dtucker) [openbsd-compat/setenv.c] Make __findenv static, remove - unnecessary prototype. - - (dtucker) [openbsd-compat/setenv.c] Sync changes from OpenBSD setenv.c - revs 1.7 - 1.9. - - (dtucker) [auth-krb5.c] Fix -Wsign-compare warning in non-Heimdal path. - Patch from djm@. - - (dtucker) [configure.ac] Disable pointer-sign warnings on gcc 4.0+ - since they're not useful right now. Patch from djm@. - - (dtucker) [openbsd-compat/getgrouplist.c] Sync OpenBSD revs 1.10 - 1.2 (ANSI - prototypes, removal of "register"). - - (dtucker) [openbsd-compat/strlcat.c] Sync OpenBSD revs 1.11 - 1.12 (removal - of "register"). - - (dtucker) [openbsd-compat/{LOTS}] Move the "OPENBSD ORIGINAL" markers to - after the copyright notices. Having them at the top next to the CVSIDs - guarantees a conflict for each and every sync. - - (dtucker) [openbsd-compat/strlcpy.c] Update from OpenBSD 1.8 -> 1.10. - - (dtucker) [openbsd-compat/sigact.h] Add "OPENBSD ORIGINAL" marker. - - (dtucker) [openbsd-compat/strmode.c] Update from OpenBSD 1.5 -> 1.7. - Removal of rcsid, "whiteout" inode type. - - (dtucker) [openbsd-compat/basename.c] Update from OpenBSD 1.11 -> 1.14. - Removal of rcsid, will no longer strlcpy parts of the string. - - (dtucker) [openbsd-compat/strtoll.c] Update from OpenBSD 1.4 -> 1.5. - - (dtucker) [openbsd-compat/strtoul.c] Update from OpenBSD 1.5 -> 1.7. - - (dtucker) [openbsd-compat/readpassphrase.c] Update from OpenBSD 1.16 -> 1.18. - - (dtucker) [openbsd-compat/readpassphrase.h] Update from OpenBSD 1.3 -> 1.5. - - (dtucker) [openbsd-compat/glob.c] Update from OpenBSD 1.22 -> 1.25. - - (dtucker) [openbsd-compat/glob.h] Update from OpenBSD 1.8 -> 1.9. - - (dtucker) [openbsd-compat/getcwd.c] Update from OpenBSD 1.9 -> 1.14. - - (dtucker) [openbsd-compat/getcwd.c] Replace lstat with fstat to match up - with OpenBSD code since we don't support platforms without fstat any more. - - (dtucker) [openbsd-compat/inet_aton.c] Update from OpenBSD 1.7 -> 1.9. - - (dtucker) [openbsd-compat/inet_ntoa.c] Update from OpenBSD 1.4 -> 1.6. - - (dtucker) [openbsd-compat/inet_ntop.c] Update from OpenBSD 1.5 -> 1.7. - - (dtucker) [openbsd-compat/daemon.c] Update from OpenBSD 1.5 -> 1.6. - - (dtucker) [openbsd-compat/strsep.c] Update from OpenBSD 1.5 -> 1.6. - - (dtucker) [openbsd-compat/daemon.c] Update from OpenBSD 1.10 -> 1.13. - - (dtucker) [openbsd-compat/mktemp.c] Update from OpenBSD 1.17 -> 1.19. - - (dtucker) [openbsd-compat/rresvport.c] Update from OpenBSD 1.6 -> 1.8. - - (dtucker) [openbsd-compat/bindresvport.c] Add "OPENBSD ORIGINAL" marker. - - (dtucker) [openbsd-compat/bindresvport.c] Update from OpenBSD 1.16 -> 1.17. - - (dtucker) [openbsd-compat/sigact.c] Update from OpenBSD 1.3 -> 1.4. - Id and copyright sync only, there were no substantial changes we need. - - (dtucker) [openbsd-compat/bsd-closefrom.c openbsd-compat/base64.c] - -Wsign-compare fixes from djm. - - (dtucker) [openbsd-compat/sigact.h] Update from OpenBSD 1.2 -> 1.3. - Id and copyright sync only, there were no substantial changes we need. - - (dtucker) [configure.ac] Try to get the gcc version number in a way that - doesn't change between versions, and use a safer default. - -20051105 - - (djm) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2005/10/07 11:13:57 - [ssh-keygen.c] - change DSA default back to 1024, as it's defined for 1024 bits only - and this causes interop problems with other clients. moreover, - in order to improve the security of DSA you need to change more - components of DSA key generation (e.g. the internal SHA1 hash); - ok deraadt - - djm@cvs.openbsd.org 2005/10/10 10:23:08 - [channels.c channels.h clientloop.c serverloop.c session.c] - fix regression I introduced in 4.2: X11 forwardings initiated after - a session has exited (e.g. "(sleep 5; xterm) &") would not start. - bz #1086 reported by t8m AT centrum.cz; ok markus@ dtucker@ - - djm@cvs.openbsd.org 2005/10/11 23:37:37 - [channels.c] - bz #1076 set SO_REUSEADDR on X11 forwarding listner sockets, preventing - bind() failure when a previous connection's listeners are in TIME_WAIT, - reported by plattner AT inf.ethz.ch; ok dtucker@ - - stevesk@cvs.openbsd.org 2005/10/13 14:03:01 - [auth2-gss.c gss-genr.c gss-serv.c] - remove unneeded #includes; ok markus@ - - stevesk@cvs.openbsd.org 2005/10/13 14:20:37 - [gss-serv.c] - spelling in comments - - stevesk@cvs.openbsd.org 2005/10/13 19:08:08 - [gss-serv-krb5.c gss-serv.c] - unused declarations; ok deraadt@ - (id sync only for gss-serv-krb5.c) - - stevesk@cvs.openbsd.org 2005/10/13 19:13:41 - [dns.c] - unneeded #include, unused declaration, little knf; ok deraadt@ - - stevesk@cvs.openbsd.org 2005/10/13 22:24:31 - [auth2-gss.c gss-genr.c gss-serv.c monitor.c] - KNF; ok djm@ - - stevesk@cvs.openbsd.org 2005/10/14 02:17:59 - [ssh-keygen.c ssh.c sshconnect2.c] - no trailing "\n" for log functions; ok djm@ - - stevesk@cvs.openbsd.org 2005/10/14 02:29:37 - [channels.c clientloop.c] - free()->xfree(); ok djm@ - - stevesk@cvs.openbsd.org 2005/10/15 15:28:12 - [sshconnect.c] - make external definition static; ok deraadt@ - - stevesk@cvs.openbsd.org 2005/10/17 13:45:05 - [dns.c] - fix memory leaks from 2 sources: - 1) key_fingerprint_raw() - 2) malloc in dns_read_rdata() - ok jakob@ - - stevesk@cvs.openbsd.org 2005/10/17 14:01:28 - [dns.c] - remove #ifdef LWRES; ok jakob@ - - stevesk@cvs.openbsd.org 2005/10/17 14:13:35 - [dns.c dns.h] - more cleanups; ok jakob@ - - djm@cvs.openbsd.org 2005/10/30 01:23:19 - [ssh_config.5] - mention control socket fallback behaviour, reported by - tryponraj AT gmail.com - - djm@cvs.openbsd.org 2005/10/30 04:01:03 - [ssh-keyscan.c] - make ssh-keygen discard junk from server before SSH- ident, spotted by - dave AT cirt.net; ok dtucker@ - - djm@cvs.openbsd.org 2005/10/30 04:03:24 - [ssh.c] - fix misleading debug message; ok dtucker@ - - dtucker@cvs.openbsd.org 2005/10/30 08:29:29 - [canohost.c sshd.c] - Check for connections with IP options earlier and drop silently. ok djm@ - - jmc@cvs.openbsd.org 2005/10/30 08:43:47 - [ssh_config.5] - remove trailing whitespace; - - djm@cvs.openbsd.org 2005/10/30 08:52:18 - [clientloop.c packet.c serverloop.c session.c ssh-agent.c ssh-keygen.c] - [ssh.c sshconnect.c sshconnect1.c sshd.c] - no need to escape single quotes in comments, no binary change - - dtucker@cvs.openbsd.org 2005/10/31 06:15:04 - [sftp.c] - Fix sorting with "ls -1" command. From Robert Tsai, "looks right" deraadt@ - - djm@cvs.openbsd.org 2005/10/31 11:12:49 - [ssh-keygen.1 ssh-keygen.c] - generate a protocol 2 RSA key by default - - djm@cvs.openbsd.org 2005/10/31 11:48:29 - [serverloop.c] - make sure we clean up wtmp, etc. file when we receive a SIGTERM, - SIGINT or SIGQUIT when running without privilege separation (the - normal privsep case is already OK). Patch mainly by dtucker@ and - senthilkumar_sen AT hotpop.com; ok dtucker@ - - jmc@cvs.openbsd.org 2005/10/31 19:55:25 - [ssh-keygen.1] - grammar; - - dtucker@cvs.openbsd.org 2005/11/03 13:38:29 - [canohost.c] - Cache reverse lookups with and without DNS separately; ok markus@ - - djm@cvs.openbsd.org 2005/11/04 05:15:59 - [kex.c kex.h kexdh.c kexdhc.c kexdhs.c kexgex.c kexgexc.c kexgexs.c] - remove hardcoded hash lengths in key exchange code, allowing - implementation of KEX methods with different hashes (e.g. SHA-256); - ok markus@ dtucker@ stevesk@ - - djm@cvs.openbsd.org 2005/11/05 05:01:15 - [bufaux.c] - Fix leaks in error paths, bz #1109 and #1110 reported by kremenek AT - cs.stanford.edu; ok dtucker@ - - (dtucker) [README.platform] Add PAM section. - - (djm) [openbsd-compat/getrrsetbyname.c] Sync to latest OpenBSD version, - resolving memory leak bz#1111 reported by kremenek AT cs.stanford.edu; - ok dtucker@ - -20051102 - - (dtucker) [openbsd-compat/bsd-misc.c] Bug #1108: fix broken strdup(). - Reported by olavi at ipunplugged.com and antoine.brodin at laposte.net - via FreeBSD. - -20051030 - - (djm) [contrib/suse/openssh.spec contrib/suse/rc. - sshd contrib/suse/sysconfig.ssh] Bug #1106: Updated SuSE spec and init - files from imorgan AT nas.nasa.gov - - (dtucker) [session.c] Bug #1045do not check /etc/nologin when PAM is - enabled, instead allow PAM to handle it. Note that on platforms using PAM, - the pam_nologin module should be added to sshd's session stack in order to - maintain exising behaviour. Based on patch and discussion from t8m at - centrum.cz, ok djm@ - -20051025 - - (dtucker) [configure.ac] Relocate LLONG_MAX calculation to after the - sizeof(long long) checks, to make fixing bug #1104 easier (no changes - yet). - - (dtucker) [configure.ac] Bug #1104: Tru64's printf family doesn't - understand "%lld", even though the compiler has "long long", so handle - it as a special case. Patch tested by mcaskill.scott at epa.gov. - - (dtucker) [contrib/cygwin/ssh-user-config] Remove duplicate yes/no - prompt. Patch from vinschen at redhat.com. - -20051017 - - (dtucker) [configure.ac] Bug #1097: Fix configure for cross-compiling. - /etc/default/login report and testing from aabaker at iee.org, corrections - from tim@. - -20051009 - - (dtucker) [configure.ac defines.h openbsd-compat/vis.{c,h}] Sync current - versions from OpenBSD. ok djm@ - -20051008 - - (dtucker) [configure.ac] Bug #1098: define $MAIL for HP-UX; report from - brian.smith at agilent com. - - (djm) [configure.ac] missing 'test' call for -with-Werror test - -20051005 - - (dtucker) [configure.ac sshd.8] Enable locked account check (a prepended - "*LOCKED*" string) for FreeBSD. Patch jeremie at le-hen.org and - senthilkumar_sen at hotpop.com. - -20051003 - - (dtucker) OpenBSD CVS Sync - - markus@cvs.openbsd.org 2005/09/07 08:53:53 - [channels.c] - enforce chanid != NULL; ok djm - - markus@cvs.openbsd.org 2005/09/09 19:18:05 - [clientloop.c] - typo; from mark at mcs.vuw.ac.nz, bug #1082 - - djm@cvs.openbsd.org 2005/09/13 23:40:07 - [sshd.c ssh.c misc.h sftp.c ssh-keygen.c ssh-keysign.c sftp-server.c - scp.c misc.c ssh-keyscan.c ssh-add.c ssh-agent.c] - ensure that stdio fds are attached; ok deraadt@ - - djm@cvs.openbsd.org 2005/09/19 11:37:34 - [ssh_config.5 ssh.1] - mention ability to specify bind_address for DynamicForward and -D options; - bz#1077 spotted by Haruyama Seigo - - djm@cvs.openbsd.org 2005/09/19 11:47:09 - [sshd.c] - stop connection abort on rekey with delayed compression enabled when - post-auth privsep is disabled (e.g. when root is logged in); ok dtucker@ - - djm@cvs.openbsd.org 2005/09/19 11:48:10 - [gss-serv.c] - typo - - jmc@cvs.openbsd.org 2005/09/19 15:38:27 - [ssh.1] - some more .Bk/.Ek to avoid ugly line split; - - jmc@cvs.openbsd.org 2005/09/19 15:42:44 - [ssh.c] - update -D usage here too; - - djm@cvs.openbsd.org 2005/09/19 23:31:31 - [ssh.1] - spelling nit from stevesk@ - - djm@cvs.openbsd.org 2005/09/21 23:36:54 - [sshd_config.5] - aquire -> acquire, from stevesk@ - - djm@cvs.openbsd.org 2005/09/21 23:37:11 - [sshd.c] - change label at markus@'s request - - jaredy@cvs.openbsd.org 2005/09/30 20:34:26 - [ssh-keyscan.1] - deploy .An -nosplit; ok jmc - - dtucker@cvs.openbsd.org 2005/10/03 07:44:42 - [canohost.c] - Relocate check_ip_options call to prevent logging of garbage for - connections with IP options set. bz#1092 from David Leonard, - "looks good" deraadt@ - - (dtucker) [regress/README.regress] Bug #989: Document limitation that scp - is required in the system path for the multiplex test to work. - -20050930 - - (dtucker) [openbsd-compat/openbsd-compat.h] Bug #1096: Add prototype - for strtoll. Patch from o.flebbe at science-computing.de. - - (dtucker) [monitor.c] Bug #1087: Send loginmsg to preauth privsep - child during PAM account check without clearing it. This restores the - post-login warnings such as LDAP password expiry. Patch from Tomas Mraz - with help from several others. - -20050929 - - (dtucker) [monitor_wrap.c] Remove duplicate definition of loginmsg - introduced during sync. - -20050928 - - (dtucker) [entropy.c] Use u_char for receiving RNG seed for consistency. - - (dtucker) [auth-pam.c] Bug #1028: send final non-query messages from - PAM via keyboard-interactive. Patch tested by the folks at Vintela. - -20050927 - - (dtucker) [entropy.c] Remove unnecessary tests for getuid and geteuid - calls, since they can't possibly fail. ok djm@ - - (dtucker) [entropy.c entropy.h sshd.c] Pass RNG seed to the reexec'ed - process when sshd relies on ssh-random-helper. Should result in faster - logins on systems without a real random device or prngd. ok djm@ - -20050924 - - (dtucker) [auth2.c] Move start_pam() calls out of if-else block to remove - duplicate call. ok djm@ - -20050922 - - (dtucker) [configure.ac] Use -R linker flag for libedit too; patch from - skeleten at shillest.net. - - (dtucker) [configure.ac] Fix help for --with-opensc; patch from skeleten at - shillest.net. - -20050919 - - (tim) [aclocal.m4 configure.ac] Delete acconfig.h and add templates to - AC_DEFINE and AC_DEFINE_UNQUOTED to quiet autoconf 2.59 warning messages. - ok dtucker@ - -20050912 - - (tim) [configure.ac] Bug 1078. Fix --without-kerberos5. Reported by - Mike Frysinger. - -20050908 - - (tim) [defines.h openbsd-compat/port-uw.c] Add long password support to - OpenServer 6 and add osr5bigcrypt support so when someone migrates - passwords between UnixWare and OpenServer they will still work. OK dtucker@ - -$Id: ChangeLog,v 1.5095 2008/07/21 08:22:25 djm Exp $ diff --git a/Makefile.in b/Makefile.in index c1b7ab5a642d..312b8d2b12da 100644 --- a/Makefile.in +++ b/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.297 2008/07/08 14:21:12 djm Exp $ +# $Id: Makefile.in,v 1.298 2008/11/05 05:20:46 djm Exp $ # uncomment if you run a non bourne compatable shell. Ie. csh #SHELL = @SH@ @@ -71,7 +71,7 @@ LIBSSH_OBJS=acss.o authfd.o authfile.o bufaux.o bufbn.o buffer.o \ atomicio.o key.o dispatch.o kex.o mac.o uidswap.o uuencode.o misc.o \ monitor_fdpass.o rijndael.o ssh-dss.o ssh-rsa.o dh.o kexdh.o \ kexgex.o kexdhc.o kexgexc.o scard.o msg.o progressmeter.o dns.o \ - entropy.o scard-opensc.o gss-genr.o umac.o + entropy.o scard-opensc.o gss-genr.o umac.o jpake.o schnorr.o SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \ sshconnect.o sshconnect1.o sshconnect2.o mux.o @@ -81,7 +81,7 @@ SSHDOBJS=sshd.o auth-rhosts.o auth-passwd.o auth-rsa.o auth-rh-rsa.o \ auth.o auth1.o auth2.o auth-options.o session.o \ auth-chall.o auth2-chall.o groupaccess.o \ auth-skey.o auth-bsdauth.o auth2-hostbased.o auth2-kbdint.o \ - auth2-none.o auth2-passwd.o auth2-pubkey.o \ + auth2-none.o auth2-passwd.o auth2-pubkey.o auth2-jpake.o \ monitor_mm.o monitor.o monitor_wrap.o kexdhs.o kexgexs.o \ auth-krb5.o \ auth2-gss.o gss-serv.o gss-serv-krb5.o \ diff --git a/PROTOCOL b/PROTOCOL index 37fd536d9817..5aada630ddd4 100644 --- a/PROTOCOL +++ b/PROTOCOL @@ -64,6 +64,12 @@ remain open after a "eow@openssh.com" has been sent and more data may still be sent in the other direction. This message does not consume window space and may be sent even if no window space is available. +NB. due to certain broken SSH implementations aborting upon receipt +of this message (in contravention of RFC4254 section 5.4), this +message is only sent to OpenSSH peers (identified by banner). +Other SSH implementations may be whitelisted to receive this message +upon request. + 4. connection: disallow additional sessions extension "no-more-sessions@openssh.com" @@ -87,6 +93,11 @@ connection. Note that this is not a general defence against compromised clients (that is impossible), but it thwarts a simple attack. +NB. due to certain broken SSH implementations aborting upon receipt +of this message, the no-more-sessions request is only sent to OpenSSH +servers (identified by banner). Other SSH implementations may be +whitelisted to receive this message upon request. + 5. connection: Tunnel forward extension "tun@openssh.com" OpenSSH supports layer 2 and layer 3 tunnelling via the "tun@openssh.com" @@ -240,4 +251,4 @@ The values of the f_flag bitmask are as follows: Both the "statvfs@openssh.com" and "fstatvfs@openssh.com" extensions are advertised in the SSH_FXP_VERSION hello with version "2". -$OpenBSD: PROTOCOL,v 1.11 2008/07/05 05:16:01 djm Exp $ +$OpenBSD: PROTOCOL,v 1.12 2009/02/14 06:35:49 djm Exp $ diff --git a/README b/README index 183d92f70e15..9de00c093352 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -See http://www.openssh.com/txt/release-5.1 for the release notes. +See http://www.openssh.com/txt/release-5.2 for the release notes. - A Japanese translation of this document and of the OpenSSH FAQ is - available at http://www.unixuser.org/~haruyama/security/openssh/index.html @@ -62,4 +62,4 @@ References - [6] http://www.openbsd.org/cgi-bin/man.cgi?query=style&sektion=9 [7] http://www.openssh.com/faq.html -$Id: README,v 1.69 2008/07/21 08:21:52 djm Exp $ +$Id: README,v 1.70 2009/02/23 00:11:57 djm Exp $ diff --git a/addrmatch.c b/addrmatch.c index 2086afe84f4b..d39885b7bdeb 100644 --- a/addrmatch.c +++ b/addrmatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: addrmatch.c,v 1.3 2008/06/10 23:06:19 djm Exp $ */ +/* $OpenBSD: addrmatch.c,v 1.4 2008/12/10 03:55:20 stevesk Exp $ */ /* * Copyright (c) 2004-2008 Damien Miller @@ -31,6 +31,7 @@ #include "match.h" #include "log.h" +#include "xmalloc.h" struct xaddr { sa_family_t af; @@ -97,7 +98,9 @@ addr_sa_to_xaddr(struct sockaddr *sa, socklen_t slen, struct xaddr *xa) return -1; xa->af = AF_INET6; memcpy(&xa->v6, &in6->sin6_addr, sizeof(xa->v6)); +#ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID xa->scope_id = in6->sin6_scope_id; +#endif break; default: return -1; @@ -415,7 +418,7 @@ addr_match_list(const char *addr, const char *_list) goto foundit; } } - free(o); + xfree(o); return ret; } diff --git a/auth-options.c b/auth-options.c index 25361455e5ac..ab085c2339cc 100644 --- a/auth-options.c +++ b/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.43 2008/06/10 23:06:19 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.44 2009/01/22 10:09:16 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -255,7 +255,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) cp = "permitopen=\""; if (strncasecmp(opts, cp, strlen(cp)) == 0) { char *host, *p; - u_short port; + int port; char *patterns = xmalloc(strlen(opts) + 1); opts += strlen(cp); @@ -293,7 +293,7 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum) goto bad_option; } host = cleanhostname(host); - if (p == NULL || (port = a2port(p)) == 0) { + if (p == NULL || (port = a2port(p)) <= 0) { debug("%.100s, line %lu: Bad permitopen port " "<%.100s>", file, linenum, p ? p : ""); auth_debug_add("%.100s, line %lu: " diff --git a/auth.c b/auth.c index 2370e5c2c714..3585daadc1c6 100644 --- a/auth.c +++ b/auth.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.c,v 1.79 2008/07/02 12:03:51 dtucker Exp $ */ +/* $OpenBSD: auth.c,v 1.80 2008/11/04 07:58:09 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * diff --git a/auth.h b/auth.h index 6a70f0eb6a37..3a70f4421346 100644 --- a/auth.h +++ b/auth.h @@ -1,4 +1,4 @@ -/* $OpenBSD: auth.h,v 1.61 2008/07/02 12:03:51 dtucker Exp $ */ +/* $OpenBSD: auth.h,v 1.62 2008/11/04 08:22:12 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -59,6 +59,7 @@ struct Authctxt { struct passwd *pw; /* set if 'valid' */ char *style; void *kbdintctxt; + void *jpake_ctx; #ifdef BSD_AUTH auth_session_t *as; #endif @@ -156,6 +157,9 @@ int bsdauth_respond(void *, u_int, char **); int skey_query(void *, char **, char **, u_int *, char ***, u_int **); int skey_respond(void *, u_int, char **); +void auth2_jpake_get_pwdata(Authctxt *, BIGNUM **, char **, char **); +void auth2_jpake_stop(Authctxt *); + int allowed_user(struct passwd *); struct passwd * getpwnamallow(const char *user); diff --git a/auth2-chall.c b/auth2-chall.c index d816578c6243..e6dbffe22b91 100644 --- a/auth2-chall.c +++ b/auth2-chall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2-chall.c,v 1.33 2007/09/21 08:15:29 djm Exp $ */ +/* $OpenBSD: auth2-chall.c,v 1.34 2008/12/09 04:32:22 djm Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. * Copyright (c) 2001 Per Allansson. All rights reserved. @@ -281,7 +281,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) { Authctxt *authctxt = ctxt; KbdintAuthctxt *kbdintctxt; - int authenticated = 0, res, len; + int authenticated = 0, res; u_int i, nresp; char **response = NULL, *method; @@ -330,11 +330,7 @@ input_userauth_info_response(int type, u_int32_t seq, void *ctxt) break; } - len = strlen("keyboard-interactive") + 2 + - strlen(kbdintctxt->device->name); - method = xmalloc(len); - snprintf(method, len, "keyboard-interactive/%s", - kbdintctxt->device->name); + xasprintf(&method, "keyboard-interactive/%s", kbdintctxt->device->name); if (!authctxt->postponed) { if (authenticated) { diff --git a/auth2-jpake.c b/auth2-jpake.c new file mode 100644 index 000000000000..efe7ff2a396f --- /dev/null +++ b/auth2-jpake.c @@ -0,0 +1,557 @@ +/* $OpenBSD: auth2-jpake.c,v 1.2 2008/11/07 23:34:48 dtucker Exp $ */ +/* + * Copyright (c) 2008 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Server side of zero-knowledge password auth using J-PAKE protocol + * as described in: + * + * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", + * 16th Workshop on Security Protocols, Cambridge, April 2008 + * + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + */ + +#ifdef JPAKE + +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "xmalloc.h" +#include "ssh2.h" +#include "key.h" +#include "hostfile.h" +#include "buffer.h" +#include "auth.h" +#include "packet.h" +#include "dispatch.h" +#include "log.h" +#include "servconf.h" +#include "auth-options.h" +#include "canohost.h" +#ifdef GSSAPI +#include "ssh-gss.h" +#endif +#include "monitor_wrap.h" + +#include "jpake.h" + +/* + * XXX options->permit_empty_passwd (at the moment, they will be refused + * anyway because they will mismatch on fake salt. + */ + +/* Dispatch handlers */ +static void input_userauth_jpake_client_step1(int, u_int32_t, void *); +static void input_userauth_jpake_client_step2(int, u_int32_t, void *); +static void input_userauth_jpake_client_confirm(int, u_int32_t, void *); + +static int auth2_jpake_start(Authctxt *); + +/* import */ +extern ServerOptions options; +extern u_char *session_id2; +extern u_int session_id2_len; + +/* + * Attempt J-PAKE authentication. + */ +static int +userauth_jpake(Authctxt *authctxt) +{ + int authenticated = 0; + + packet_check_eom(); + + debug("jpake-01@openssh.com requested"); + + if (authctxt->user != NULL) { + if (authctxt->jpake_ctx == NULL) + authctxt->jpake_ctx = jpake_new(); + if (options.zero_knowledge_password_authentication) + authenticated = auth2_jpake_start(authctxt); + } + + return authenticated; +} + +Authmethod method_jpake = { + "jpake-01@openssh.com", + userauth_jpake, + &options.zero_knowledge_password_authentication +}; + +/* Clear context and callbacks */ +void +auth2_jpake_stop(Authctxt *authctxt) +{ + /* unregister callbacks */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); + if (authctxt->jpake_ctx != NULL) { + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + } +} + +/* Returns 1 if 'c' is a valid crypt(3) salt character, 0 otherwise */ +static int +valid_crypt_salt(int c) +{ + if (c >= 'A' && c <= 'Z') + return 1; + if (c >= 'a' && c <= 'z') + return 1; + if (c >= '.' && c <= '9') + return 1; + return 0; +} + +/* + * Derive fake salt as H(username || first_private_host_key) + * This provides relatively stable fake salts for non-existent + * users and avoids the jpake method becoming an account validity + * oracle. + */ +static void +derive_rawsalt(const char *username, u_char *rawsalt, u_int len) +{ + u_char *digest; + u_int digest_len; + Buffer b; + Key *k; + + buffer_init(&b); + buffer_put_cstring(&b, username); + if ((k = get_hostkey_by_index(0)) == NULL || + (k->flags & KEY_FLAG_EXT)) + fatal("%s: no hostkeys", __func__); + switch (k->type) { + case KEY_RSA1: + case KEY_RSA: + if (k->rsa->p == NULL || k->rsa->q == NULL) + fatal("%s: RSA key missing p and/or q", __func__); + buffer_put_bignum2(&b, k->rsa->p); + buffer_put_bignum2(&b, k->rsa->q); + break; + case KEY_DSA: + if (k->dsa->priv_key == NULL) + fatal("%s: DSA key missing priv_key", __func__); + buffer_put_bignum2(&b, k->dsa->priv_key); + break; + default: + fatal("%s: unknown key type %d", __func__, k->type); + } + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), + &digest, &digest_len) != 0) + fatal("%s: hash_buffer", __func__); + buffer_free(&b); + if (len > digest_len) + fatal("%s: not enough bytes for rawsalt (want %u have %u)", + __func__, len, digest_len); + memcpy(rawsalt, digest, len); + bzero(digest, digest_len); + xfree(digest); +} + +/* ASCII an integer [0, 64) for inclusion in a password/salt */ +static char +pw_encode64(u_int i64) +{ + const u_char e64[] = + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + return e64[i64 % 64]; +} + +/* Generate ASCII salt bytes for user */ +static char * +makesalt(u_int want, const char *user) +{ + u_char rawsalt[32]; + static char ret[33]; + u_int i; + + if (want > sizeof(ret) - 1) + fatal("%s: want %u", __func__, want); + + derive_rawsalt(user, rawsalt, sizeof(rawsalt)); + bzero(ret, sizeof(ret)); + for (i = 0; i < want; i++) + ret[i] = pw_encode64(rawsalt[i]); + bzero(rawsalt, sizeof(rawsalt)); + + return ret; +} + +/* + * Select the system's default password hashing scheme and generate + * a stable fake salt under it for use by a non-existent account. + * Prevents jpake method being used to infer the validity of accounts. + */ +static void +fake_salt_and_scheme(Authctxt *authctxt, char **salt, char **scheme) +{ + char *rounds_s, *style; + long long rounds; + login_cap_t *lc; + + + if ((lc = login_getclass(authctxt->pw->pw_class)) == NULL && + (lc = login_getclass(NULL)) == NULL) + fatal("%s: login_getclass failed", __func__); + style = login_getcapstr(lc, "localcipher", NULL, NULL); + if (style == NULL) + style = xstrdup("blowfish,6"); + login_close(lc); + + if ((rounds_s = strchr(style, ',')) != NULL) + *rounds_s++ = '\0'; + rounds = strtonum(rounds_s, 1, 1<<31, NULL); + + if (strcmp(style, "md5") == 0) { + xasprintf(salt, "$1$%s$", makesalt(8, authctxt->user)); + *scheme = xstrdup("md5"); + } else if (strcmp(style, "old") == 0) { + *salt = xstrdup(makesalt(2, authctxt->user)); + *scheme = xstrdup("crypt"); + } else if (strcmp(style, "newsalt") == 0) { + rounds = MAX(rounds, 7250); + rounds = MIN(rounds, (1<<24) - 1); + xasprintf(salt, "_%c%c%c%c%s", + pw_encode64(rounds), pw_encode64(rounds >> 6), + pw_encode64(rounds >> 12), pw_encode64(rounds >> 18), + makesalt(4, authctxt->user)); + *scheme = xstrdup("crypt-extended"); + } else { + /* Default to blowfish */ + rounds = MAX(rounds, 3); + rounds = MIN(rounds, 31); + xasprintf(salt, "$2a$%02lld$%s", rounds, + makesalt(22, authctxt->user)); + *scheme = xstrdup("bcrypt"); + } + xfree(style); + debug3("%s: fake %s salt for user %s: %s", + __func__, *scheme, authctxt->user, *salt); +} + +/* + * Fetch password hashing scheme, password salt and derive shared secret + * for user. If user does not exist, a fake but stable and user-unique + * salt will be returned. + */ +void +auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, + char **hash_scheme, char **salt) +{ + char *cp; + u_char *secret; + u_int secret_len, salt_len; + +#ifdef JPAKE_DEBUG + debug3("%s: valid %d pw %.5s...", __func__, + authctxt->valid, authctxt->pw->pw_passwd); +#endif + + *salt = NULL; + *hash_scheme = NULL; + if (authctxt->valid) { + if (strncmp(authctxt->pw->pw_passwd, "$2$", 3) == 0 && + strlen(authctxt->pw->pw_passwd) > 28) { + /* + * old-variant bcrypt: + * "$2$", 2 digit rounds, "$", 22 bytes salt + */ + salt_len = 3 + 2 + 1 + 22 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("bcrypt"); + } else if (strncmp(authctxt->pw->pw_passwd, "$2a$", 4) == 0 && + strlen(authctxt->pw->pw_passwd) > 29) { + /* + * current-variant bcrypt: + * "$2a$", 2 digit rounds, "$", 22 bytes salt + */ + salt_len = 4 + 2 + 1 + 22 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("bcrypt"); + } else if (strncmp(authctxt->pw->pw_passwd, "$1$", 3) == 0 && + strlen(authctxt->pw->pw_passwd) > 5) { + /* + * md5crypt: + * "$1$", salt until "$" + */ + cp = strchr(authctxt->pw->pw_passwd + 3, '$'); + if (cp != NULL) { + salt_len = (cp - authctxt->pw->pw_passwd) + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, + salt_len); + *hash_scheme = xstrdup("md5crypt"); + } + } else if (strncmp(authctxt->pw->pw_passwd, "_", 1) == 0 && + strlen(authctxt->pw->pw_passwd) > 9) { + /* + * BSDI extended crypt: + * "_", 4 digits count, 4 chars salt + */ + salt_len = 1 + 4 + 4 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("crypt-extended"); + } else if (strlen(authctxt->pw->pw_passwd) == 13 && + valid_crypt_salt(authctxt->pw->pw_passwd[0]) && + valid_crypt_salt(authctxt->pw->pw_passwd[1])) { + /* + * traditional crypt: + * 2 chars salt + */ + salt_len = 2 + 1; + *salt = xmalloc(salt_len); + strlcpy(*salt, authctxt->pw->pw_passwd, salt_len); + *hash_scheme = xstrdup("crypt"); + } + if (*salt == NULL) { + debug("%s: unrecognised crypt scheme for user %s", + __func__, authctxt->pw->pw_name); + } + } + if (*salt == NULL) + fake_salt_and_scheme(authctxt, salt, hash_scheme); + + if (hash_buffer(authctxt->pw->pw_passwd, + strlen(authctxt->pw->pw_passwd), EVP_sha256(), + &secret, &secret_len) != 0) + fatal("%s: hash_buffer", __func__); + if ((*s = BN_bin2bn(secret, secret_len, NULL)) == NULL) + fatal("%s: BN_bin2bn (secret)", __func__); +#ifdef JPAKE_DEBUG + debug3("%s: salt = %s (len %u)", __func__, + *salt, (u_int)strlen(*salt)); + debug3("%s: scheme = %s", __func__, *hash_scheme); + JPAKE_DEBUG_BN((*s, "%s: s = ", __func__)); +#endif + bzero(secret, secret_len); + xfree(secret); +} + +/* + * Being authentication attempt. + * Note, sets authctxt->postponed while in subprotocol + */ +static int +auth2_jpake_start(Authctxt *authctxt) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x3_proof, *x4_proof; + u_int x3_proof_len, x4_proof_len; + char *salt, *hash_scheme; + + debug("%s: start", __func__); + + PRIVSEP(jpake_step1(pctx->grp, + &pctx->server_id, &pctx->server_id_len, + &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, + &x3_proof, &x3_proof_len, + &x4_proof, &x4_proof_len)); + + PRIVSEP(auth2_jpake_get_pwdata(authctxt, &pctx->s, + &hash_scheme, &salt)); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); + + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1); + packet_put_cstring(hash_scheme); + packet_put_cstring(salt); + packet_put_string(pctx->server_id, pctx->server_id_len); + packet_put_bignum2(pctx->g_x3); + packet_put_bignum2(pctx->g_x4); + packet_put_string(x3_proof, x3_proof_len); + packet_put_string(x4_proof, x4_proof_len); + packet_send(); + packet_write_wait(); + + bzero(hash_scheme, strlen(hash_scheme)); + bzero(salt, strlen(salt)); + xfree(hash_scheme); + xfree(salt); + bzero(x3_proof, x3_proof_len); + bzero(x4_proof, x4_proof_len); + xfree(x3_proof); + xfree(x4_proof); + + /* Expect step 1 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, + input_userauth_jpake_client_step1); + + authctxt->postponed = 1; + return 0; +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_step1(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x1_proof, *x2_proof, *x4_s_proof; + u_int x1_proof_len, x2_proof_len, x4_s_proof_len; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1, NULL); + + /* Fetch step 1 values */ + if ((pctx->g_x1 = BN_new()) == NULL || + (pctx->g_x2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + pctx->client_id = packet_get_string(&pctx->client_id_len); + packet_get_bignum2(pctx->g_x1); + packet_get_bignum2(pctx->g_x2); + x1_proof = packet_get_string(&x1_proof_len); + x2_proof = packet_get_string(&x2_proof_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); + + PRIVSEP(jpake_step2(pctx->grp, pctx->s, pctx->g_x3, + pctx->g_x1, pctx->g_x2, pctx->x4, + pctx->client_id, pctx->client_id_len, + pctx->server_id, pctx->server_id_len, + x1_proof, x1_proof_len, + x2_proof, x2_proof_len, + &pctx->b, + &x4_s_proof, &x4_s_proof_len)); + + bzero(x1_proof, x1_proof_len); + bzero(x2_proof, x2_proof_len); + xfree(x1_proof); + xfree(x2_proof); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); + + /* Send values for step 2 */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2); + packet_put_bignum2(pctx->b); + packet_put_string(x4_s_proof, x4_s_proof_len); + packet_send(); + packet_write_wait(); + + bzero(x4_s_proof, x4_s_proof_len); + xfree(x4_s_proof); + + /* Expect step 2 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, + input_userauth_jpake_client_step2); +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_step2(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x2_s_proof; + u_int x2_s_proof_len; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2, NULL); + + if ((pctx->a = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Fetch step 2 values */ + packet_get_bignum2(pctx->a); + x2_s_proof = packet_get_string(&x2_s_proof_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); + + /* Derive shared key and calculate confirmation hash */ + PRIVSEP(jpake_key_confirm(pctx->grp, pctx->s, pctx->a, + pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, + pctx->server_id, pctx->server_id_len, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + x2_s_proof, x2_s_proof_len, + &pctx->k, + &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len)); + + bzero(x2_s_proof, x2_s_proof_len); + xfree(x2_s_proof); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); + + /* Send key confirmation proof */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM); + packet_put_string(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + packet_send(); + packet_write_wait(); + + /* Expect confirmation from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, + input_userauth_jpake_client_confirm); +} + +/* ARGSUSED */ +static void +input_userauth_jpake_client_confirm(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + int authenticated = 0; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM, NULL); + + pctx->h_k_cid_sessid = packet_get_string(&pctx->h_k_cid_sessid_len); + packet_check_eom(); + + if (!use_privsep) + JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); + + /* Verify expected confirmation hash */ + if (PRIVSEP(jpake_check_confirm(pctx->k, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len)) == 1) + authenticated = authctxt->valid ? 1 : 0; + else + debug("%s: confirmation mismatch", __func__); + + /* done */ + authctxt->postponed = 0; + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + userauth_finish(authctxt, authenticated, method_jpake.name); +} + +#endif /* JPAKE */ + diff --git a/auth2.c b/auth2.c index a835abfc6c33..ecf8570526ed 100644 --- a/auth2.c +++ b/auth2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth2.c,v 1.119 2008/07/04 23:30:16 djm Exp $ */ +/* $OpenBSD: auth2.c,v 1.120 2008/11/04 08:22:12 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -71,12 +71,18 @@ extern Authmethod method_hostbased; #ifdef GSSAPI extern Authmethod method_gssapi; #endif +#ifdef JPAKE +extern Authmethod method_jpake; +#endif Authmethod *authmethods[] = { &method_none, &method_pubkey, #ifdef GSSAPI &method_gssapi, +#endif +#ifdef JPAKE + &method_jpake, #endif &method_passwd, &method_kbdint, @@ -257,8 +263,12 @@ input_userauth_request(int type, u_int32_t seq, void *ctxt) } /* reset state */ auth2_challenge_stop(authctxt); +#ifdef JPAKE + auth2_jpake_stop(authctxt); +#endif #ifdef GSSAPI + /* XXX move to auth2_gssapi_stop() */ dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_TOKEN, NULL); dispatch_set(SSH2_MSG_USERAUTH_GSSAPI_EXCHANGE_COMPLETE, NULL); #endif diff --git a/canohost.c b/canohost.c index 42011fd0acf2..7138f48d0f41 100644 --- a/canohost.c +++ b/canohost.c @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.c,v 1.63 2008/06/12 00:03:49 dtucker Exp $ */ +/* $OpenBSD: canohost.c,v 1.64 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -342,7 +342,7 @@ get_remote_name_or_ip(u_int utmp_len, int use_dns) /* Returns the local/remote port for the socket. */ -static int +int get_sock_port(int sock, int local) { struct sockaddr_storage from; diff --git a/canohost.h b/canohost.h index e33e8941b2cb..d9b41ffe5449 100644 --- a/canohost.h +++ b/canohost.h @@ -1,4 +1,4 @@ -/* $OpenBSD: canohost.h,v 1.9 2006/03/25 22:22:42 djm Exp $ */ +/* $OpenBSD: canohost.h,v 1.10 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen @@ -23,5 +23,7 @@ char *get_local_name(int); int get_remote_port(void); int get_local_port(void); +int get_sock_port(int, int); + void ipv64_normalise_mapped(struct sockaddr_storage *, socklen_t *); diff --git a/channels.c b/channels.c index 69c99c9b2f77..dea60ba24e77 100644 --- a/channels.c +++ b/channels.c @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.c,v 1.286 2008/07/16 11:52:19 djm Exp $ */ +/* $OpenBSD: channels.c,v 1.295 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -296,6 +296,7 @@ channel_new(char *ctype, int type, int rfd, int wfd, int efd, buffer_init(&c->input); buffer_init(&c->output); buffer_init(&c->extended); + c->path = NULL; c->ostate = CHAN_OUTPUT_OPEN; c->istate = CHAN_INPUT_OPEN; c->flags = 0; @@ -402,6 +403,10 @@ channel_free(Channel *c) xfree(c->remote_name); c->remote_name = NULL; } + if (c->path) { + xfree(c->path); + c->path = NULL; + } while ((cc = TAILQ_FIRST(&c->status_confirms)) != NULL) { if (cc->abandon_cb != NULL) cc->abandon_cb(c, cc->ctx); @@ -691,7 +696,7 @@ channel_register_open_confirm(int id, channel_callback_fn *fn, void *ctx) Channel *c = channel_lookup(id); if (c == NULL) { - logit("channel_register_open_comfirm: %d: bad id", id); + logit("channel_register_open_confirm: %d: bad id", id); return; } c->open_confirm = fn; @@ -980,7 +985,7 @@ static int channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) { char *p, *host; - u_int len, have, i, found; + u_int len, have, i, found, need; char username[256]; struct { u_int8_t version; @@ -996,10 +1001,20 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) if (have < len) return 0; p = buffer_ptr(&c->input); + + need = 1; + /* SOCKS4A uses an invalid IP address 0.0.0.x */ + if (p[4] == 0 && p[5] == 0 && p[6] == 0 && p[7] != 0) { + debug2("channel %d: socks4a request", c->self); + /* ... and needs an extra string (the hostname) */ + need = 2; + } + /* Check for terminating NUL on the string(s) */ for (found = 0, i = len; i < have; i++) { if (p[i] == '\0') { - found = 1; - break; + found++; + if (found == need) + break; } if (i > 1024) { /* the peer is probably sending garbage */ @@ -1008,7 +1023,7 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) return -1; } } - if (!found) + if (found < need) return 0; buffer_get(&c->input, (char *)&s4_req.version, 1); buffer_get(&c->input, (char *)&s4_req.command, 1); @@ -1018,23 +1033,46 @@ channel_decode_socks4(Channel *c, fd_set *readset, fd_set *writeset) p = buffer_ptr(&c->input); len = strlen(p); debug2("channel %d: decode socks4: user %s/%d", c->self, p, len); + len++; /* trailing '\0' */ if (len > have) fatal("channel %d: decode socks4: len %d > have %d", c->self, len, have); strlcpy(username, p, sizeof(username)); buffer_consume(&c->input, len); - buffer_consume(&c->input, 1); /* trailing '\0' */ - host = inet_ntoa(s4_req.dest_addr); - strlcpy(c->path, host, sizeof(c->path)); + if (c->path != NULL) { + xfree(c->path); + c->path = NULL; + } + if (need == 1) { /* SOCKS4: one string */ + host = inet_ntoa(s4_req.dest_addr); + c->path = xstrdup(host); + } else { /* SOCKS4A: two strings */ + have = buffer_len(&c->input); + p = buffer_ptr(&c->input); + len = strlen(p); + debug2("channel %d: decode socks4a: host %s/%d", + c->self, p, len); + len++; /* trailing '\0' */ + if (len > have) + fatal("channel %d: decode socks4a: len %d > have %d", + c->self, len, have); + if (len > NI_MAXHOST) { + error("channel %d: hostname \"%.100s\" too long", + c->self, p); + return -1; + } + c->path = xstrdup(p); + buffer_consume(&c->input, len); + } c->host_port = ntohs(s4_req.dest_port); debug2("channel %d: dynamic request: socks4 host %s port %u command %u", - c->self, host, c->host_port, s4_req.command); + c->self, c->path, c->host_port, s4_req.command); if (s4_req.command != 1) { - debug("channel %d: cannot handle: socks4 cn %d", - c->self, s4_req.command); + debug("channel %d: cannot handle: %s cn %d", + c->self, need == 1 ? "SOCKS4" : "SOCKS4A", s4_req.command); return -1; } s4_rsp.version = 0; /* vn: 0 for reply */ @@ -1065,7 +1103,7 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) u_int8_t atyp; } s5_req, s5_rsp; u_int16_t dest_port; - u_char *p, dest_addr[255+1]; + u_char *p, dest_addr[255+1], ntop[INET6_ADDRSTRLEN]; u_int have, need, i, found, nmethods, addrlen, af; debug2("channel %d: decode socks5", c->self); @@ -1138,10 +1176,22 @@ channel_decode_socks5(Channel *c, fd_set *readset, fd_set *writeset) buffer_get(&c->input, (char *)&dest_addr, addrlen); buffer_get(&c->input, (char *)&dest_port, 2); dest_addr[addrlen] = '\0'; - if (s5_req.atyp == SSH_SOCKS5_DOMAIN) - strlcpy(c->path, (char *)dest_addr, sizeof(c->path)); - else if (inet_ntop(af, dest_addr, c->path, sizeof(c->path)) == NULL) - return -1; + if (c->path != NULL) { + xfree(c->path); + c->path = NULL; + } + if (s5_req.atyp == SSH_SOCKS5_DOMAIN) { + if (addrlen >= NI_MAXHOST) { + error("channel %d: dynamic request: socks5 hostname " + "\"%.100s\" too long", c->self, dest_addr); + return -1; + } + c->path = xstrdup(dest_addr); + } else { + if (inet_ntop(af, dest_addr, ntop, sizeof(ntop)) == NULL) + return -1; + c->path = xstrdup(ntop); + } c->host_port = ntohs(dest_port); debug2("channel %d: dynamic request: socks5 host %s port %u command %u", @@ -1370,7 +1420,8 @@ channel_post_port_listener(Channel *c, fd_set *readset, fd_set *writeset) c->local_window_max, c->local_maxpacket, 0, rtype, 1); nc->listening_port = c->listening_port; nc->host_port = c->host_port; - strlcpy(nc->path, c->path, sizeof(nc->path)); + if (c->path != NULL) + nc->path = xstrdup(c->path); if (nextstate == SSH_CHANNEL_DYNAMIC) { /* @@ -2311,8 +2362,8 @@ channel_input_open_failure(int type, u_int32_t seq, void *ctxt) xfree(lang); } packet_check_eom(); - /* Free the channel. This will also close the socket. */ - channel_free(c); + /* Schedule the channel for cleanup/deletion. */ + chan_mark_dead(c); } /* ARGSUSED */ @@ -2377,18 +2428,18 @@ channel_input_status_confirm(int type, u_int32_t seq, void *ctxt) { Channel *c; struct channel_confirm *cc; - int remote_id; + int id; /* Reset keepalive timeout */ keep_alive_timeouts = 0; - remote_id = packet_get_int(); + id = packet_get_int(); packet_check_eom(); - debug2("channel_input_confirm: type %d id %d", type, remote_id); + debug2("channel_input_status_confirm: type %d id %d", type, id); - if ((c = channel_lookup(remote_id)) == NULL) { - logit("channel_input_success_failure: %d: unknown", remote_id); + if ((c = channel_lookup(id)) == NULL) { + logit("channel_input_status_confirm: %d: unknown", id); return; } ; @@ -2409,7 +2460,8 @@ channel_set_af(int af) } static int -channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_port, +channel_setup_fwd_listener(int type, const char *listen_addr, + u_short listen_port, int *allocated_listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports) { Channel *c; @@ -2417,6 +2469,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por struct addrinfo hints, *ai, *aitop; const char *host, *addr; char ntop[NI_MAXHOST], strport[NI_MAXSERV]; + in_port_t *lport_p; host = (type == SSH_CHANNEL_RPORT_LISTENER) ? listen_addr : host_to_connect; @@ -2426,7 +2479,7 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por error("No forward host name."); return 0; } - if (strlen(host) > SSH_CHANNEL_PATH_LEN - 1) { + if (strlen(host) >= NI_MAXHOST) { error("Forward host name too long."); return 0; } @@ -2485,10 +2538,29 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por } return 0; } - + if (allocated_listen_port != NULL) + *allocated_listen_port = 0; for (ai = aitop; ai; ai = ai->ai_next) { - if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) + switch (ai->ai_family) { + case AF_INET: + lport_p = &((struct sockaddr_in *)ai->ai_addr)-> + sin_port; + break; + case AF_INET6: + lport_p = &((struct sockaddr_in6 *)ai->ai_addr)-> + sin6_port; + break; + default: continue; + } + /* + * If allocating a port for -R forwards, then use the + * same port for all address families. + */ + if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && + allocated_listen_port != NULL && *allocated_listen_port > 0) + *lport_p = htons(*allocated_listen_port); + if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop, sizeof(ntop), strport, sizeof(strport), NI_NUMERICHOST|NI_NUMERICSERV) != 0) { error("channel_setup_fwd_listener: getnameinfo failed"); @@ -2504,7 +2576,8 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por channel_set_reuseaddr(sock); - debug("Local forwarding listening on %s port %s.", ntop, strport); + debug("Local forwarding listening on %s port %s.", + ntop, strport); /* Bind the socket to the address. */ if (bind(sock, ai->ai_addr, ai->ai_addrlen) < 0) { @@ -2523,11 +2596,24 @@ channel_setup_fwd_listener(int type, const char *listen_addr, u_short listen_por close(sock); continue; } + + /* + * listen_port == 0 requests a dynamically allocated port - + * record what we got. + */ + if (type == SSH_CHANNEL_RPORT_LISTENER && listen_port == 0 && + allocated_listen_port != NULL && + *allocated_listen_port == 0) { + *allocated_listen_port = get_sock_port(sock, 1); + debug("Allocated listen port %d", + *allocated_listen_port); + } + /* Allocate a channel number for the socket. */ c = channel_new("port listener", type, sock, sock, -1, CHAN_TCP_WINDOW_DEFAULT, CHAN_TCP_PACKET_DEFAULT, 0, "port listener", 1); - strlcpy(c->path, host, sizeof(c->path)); + c->path = xstrdup(host); c->host_port = port_to_connect; c->listening_port = listen_port; success = 1; @@ -2549,8 +2635,7 @@ channel_cancel_rport_listener(const char *host, u_short port) Channel *c = channels[i]; if (c != NULL && c->type == SSH_CHANNEL_RPORT_LISTENER && - strncmp(c->path, host, sizeof(c->path)) == 0 && - c->listening_port == port) { + strcmp(c->path, host) == 0 && c->listening_port == port) { debug2("%s: close channel %d", __func__, i); channel_free(c); found = 1; @@ -2566,17 +2651,18 @@ channel_setup_local_fwd_listener(const char *listen_host, u_short listen_port, const char *host_to_connect, u_short port_to_connect, int gateway_ports) { return channel_setup_fwd_listener(SSH_CHANNEL_PORT_LISTENER, - listen_host, listen_port, host_to_connect, port_to_connect, + listen_host, listen_port, NULL, host_to_connect, port_to_connect, gateway_ports); } /* protocol v2 remote port fwd, used by sshd */ int channel_setup_remote_fwd_listener(const char *listen_address, - u_short listen_port, int gateway_ports) + u_short listen_port, int *allocated_listen_port, int gateway_ports) { return channel_setup_fwd_listener(SSH_CHANNEL_RPORT_LISTENER, - listen_address, listen_port, NULL, 0, gateway_ports); + listen_address, listen_port, allocated_listen_port, + NULL, 0, gateway_ports); } /* @@ -2791,10 +2877,16 @@ channel_print_adm_permitted_opens(void) { int i; + printf("permitopen"); + if (num_adm_permitted_opens == 0) { + printf(" any\n"); + return; + } for (i = 0; i < num_adm_permitted_opens; i++) if (permitted_adm_opens[i].host_to_connect != NULL) printf(" %s:%d", permitted_adm_opens[i].host_to_connect, permitted_adm_opens[i].port_to_connect); + printf("\n"); } /* Try to start non-blocking connect to next host in cctx list */ @@ -3074,7 +3166,7 @@ x11_create_display_inet(int x11_display_offset, int x11_use_localhost, } static int -connect_local_xsocket(u_int dnr) +connect_local_xsocket_path(const char *pathname) { int sock; struct sockaddr_un addr; @@ -3084,7 +3176,7 @@ connect_local_xsocket(u_int dnr) error("socket: %.100s", strerror(errno)); memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; - snprintf(addr.sun_path, sizeof addr.sun_path, _PATH_UNIX_X, dnr); + strlcpy(addr.sun_path, pathname, sizeof addr.sun_path); if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) return sock; close(sock); @@ -3092,6 +3184,14 @@ connect_local_xsocket(u_int dnr) return -1; } +static int +connect_local_xsocket(u_int dnr) +{ + char buf[1024]; + snprintf(buf, sizeof buf, _PATH_UNIX_X, dnr); + return connect_local_xsocket_path(buf); +} + int x11_connect_display(void) { @@ -3113,6 +3213,17 @@ x11_connect_display(void) * connection to the real X server. */ + /* Check if the display is from launchd. */ +#ifdef __APPLE__ + if (strncmp(display, "/tmp/launch", 11) == 0) { + sock = connect_local_xsocket_path(display); + if (sock < 0) + return -1; + + /* OK, we now have a connection to the display. */ + return sock; + } +#endif /* * Check if it is a unix domain socket. Unix domain displays are in * one of the following formats: unix:d[.s], :d[.s], ::d[.s] diff --git a/channels.h b/channels.h index 108b360681d6..1488ed7e59ab 100644 --- a/channels.h +++ b/channels.h @@ -1,4 +1,4 @@ -/* $OpenBSD: channels.h,v 1.96 2008/06/15 20:06:26 djm Exp $ */ +/* $OpenBSD: channels.h,v 1.98 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen @@ -55,8 +55,6 @@ #define SSH_CHANNEL_ZOMBIE 14 /* Almost dead. */ #define SSH_CHANNEL_MAX_TYPE 15 -#define SSH_CHANNEL_PATH_LEN 256 - struct Channel; typedef struct Channel Channel; @@ -105,7 +103,7 @@ struct Channel { Buffer output; /* data received over encrypted connection for * send on socket */ Buffer extended; - char path[SSH_CHANNEL_PATH_LEN]; + char *path; /* path for unix domain sockets, or host name for forwards */ int listening_port; /* port being listened for forwards */ int host_port; /* remote port to connect for forwards */ @@ -247,7 +245,7 @@ int channel_request_remote_forwarding(const char *, u_short, int channel_setup_local_fwd_listener(const char *, u_short, const char *, u_short, int); void channel_request_rforward_cancel(const char *host, u_short port); -int channel_setup_remote_fwd_listener(const char *, u_short, int); +int channel_setup_remote_fwd_listener(const char *, u_short, int *, int); int channel_cancel_rport_listener(const char *, u_short); /* x11 forwarding */ diff --git a/cipher.c b/cipher.c index b264063c4031..bb5c0ac3a2c2 100644 --- a/cipher.c +++ b/cipher.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.c,v 1.81 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -63,31 +63,32 @@ struct Cipher { u_int block_size; u_int key_len; u_int discard_len; + u_int cbc_mode; const EVP_CIPHER *(*evptype)(void); } ciphers[] = { - { "none", SSH_CIPHER_NONE, 8, 0, 0, EVP_enc_null }, - { "des", SSH_CIPHER_DES, 8, 8, 0, EVP_des_cbc }, - { "3des", SSH_CIPHER_3DES, 8, 16, 0, evp_ssh1_3des }, - { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, evp_ssh1_bf }, + { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null }, + { "des", SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc }, + { "3des", SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des }, + { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf }, - { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, EVP_des_ede3_cbc }, - { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_bf_cbc }, - { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, EVP_cast5_cbc }, - { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, EVP_rc4 }, - { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, EVP_rc4 }, - { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, EVP_rc4 }, - { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, EVP_aes_128_cbc }, - { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, EVP_aes_192_cbc }, - { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc }, + { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc }, + { "blowfish-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc }, + { "cast128-cbc", SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc }, + { "arcfour", SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 }, + { "arcfour128", SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 }, + { "arcfour256", SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 }, + { "aes128-cbc", SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc }, + { "aes192-cbc", SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc }, + { "aes256-cbc", SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, { "rijndael-cbc@lysator.liu.se", - SSH_CIPHER_SSH2, 16, 32, 0, EVP_aes_256_cbc }, - { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, evp_aes_128_ctr }, - { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, evp_aes_128_ctr }, - { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, evp_aes_128_ctr }, + SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc }, + { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr }, + { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr }, + { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr }, #ifdef USE_CIPHER_ACSS - { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, EVP_acss }, + { "acss@openssh.org", SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss }, #endif - { NULL, SSH_CIPHER_INVALID, 0, 0, 0, NULL } + { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL } }; /*--*/ @@ -110,6 +111,12 @@ cipher_get_number(const Cipher *c) return (c->number); } +u_int +cipher_is_cbc(const Cipher *c) +{ + return (c->cbc_mode); +} + u_int cipher_mask_ssh1(int client) { diff --git a/cipher.h b/cipher.h index 49bbc1682b97..3dd2270bbe9e 100644 --- a/cipher.h +++ b/cipher.h @@ -1,4 +1,4 @@ -/* $OpenBSD: cipher.h,v 1.36 2006/03/25 22:22:42 djm Exp $ */ +/* $OpenBSD: cipher.h,v 1.37 2009/01/26 09:58:15 markus Exp $ */ /* * Author: Tatu Ylonen @@ -81,6 +81,7 @@ void cipher_cleanup(CipherContext *); void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); u_int cipher_blocksize(const Cipher *); u_int cipher_keylen(const Cipher *); +u_int cipher_is_cbc(const Cipher *); u_int cipher_get_number(const Cipher *); void cipher_get_keyiv(CipherContext *, u_char *, u_int); diff --git a/clientloop.c b/clientloop.c index f10fab7698cf..a2d2d1d07465 100644 --- a/clientloop.c +++ b/clientloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: clientloop.c,v 1.201 2008/07/16 11:51:14 djm Exp $ */ +/* $OpenBSD: clientloop.c,v 1.209 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -107,7 +107,6 @@ #include "atomicio.h" #include "sshpty.h" #include "misc.h" -#include "monitor_fdpass.h" #include "match.h" #include "msg.h" @@ -765,8 +764,8 @@ process_cmdline(void) void (*handler)(int); char *s, *cmd, *cancel_host; int delete = 0; - int local = 0; - u_short cancel_port; + int local = 0, remote = 0, dynamic = 0; + int cancel_port; Forward fwd; bzero(&fwd, sizeof(fwd)); @@ -790,6 +789,8 @@ process_cmdline(void) "Request local forward"); logit(" -R[bind_address:]port:host:hostport " "Request remote forward"); + logit(" -D[bind_address:]port " + "Request dynamic forward"); logit(" -KR[bind_address:]port " "Cancel remote forward"); if (!options.permit_local_command) @@ -809,17 +810,22 @@ process_cmdline(void) delete = 1; s++; } - if (*s != 'L' && *s != 'R') { + if (*s == 'L') + local = 1; + else if (*s == 'R') + remote = 1; + else if (*s == 'D') + dynamic = 1; + else { logit("Invalid command."); goto out; } - if (*s == 'L') - local = 1; - if (local && delete) { + + if ((local || dynamic) && delete) { logit("Not supported."); goto out; } - if ((!local || delete) && !compat20) { + if (remote && delete && !compat20) { logit("Not supported for SSH protocol version 1."); goto out; } @@ -837,17 +843,17 @@ process_cmdline(void) cancel_port = a2port(cancel_host); cancel_host = NULL; } - if (cancel_port == 0) { + if (cancel_port <= 0) { logit("Bad forwarding close port"); goto out; } channel_request_rforward_cancel(cancel_host, cancel_port); } else { - if (!parse_forward(&fwd, s)) { + if (!parse_forward(&fwd, s, dynamic, remote)) { logit("Bad forwarding specification."); goto out; } - if (local) { + if (local || dynamic) { if (channel_setup_local_fwd_listener(fwd.listen_host, fwd.listen_port, fwd.connect_host, fwd.connect_port, options.gateway_ports) < 0) { @@ -1036,7 +1042,6 @@ process_escapes(Channel *c, Buffer *bin, Buffer *bout, Buffer *berr, Supported escape sequences:\r\n\ %c. - terminate session\r\n\ %cB - send a BREAK to the remote system\r\n\ - %cC - open a command line\r\n\ %cR - Request rekey (SSH protocol 2 only)\r\n\ %c# - list forwarded connections\r\n\ %c? - this message\r\n\ @@ -1045,8 +1050,7 @@ Supported escape sequences:\r\n\ escape_char, escape_char, escape_char, escape_char, escape_char, escape_char, - escape_char, escape_char, - escape_char); + escape_char, escape_char); } else { snprintf(string, sizeof string, "%c?\r\n\ @@ -1081,6 +1085,8 @@ Supported escape sequences:\r\n\ continue; case 'C': + if (c && c->ctl_fd != -1) + goto noescape; process_cmdline(); continue; @@ -1632,7 +1638,7 @@ client_request_forwarded_tcpip(const char *request_type, int rchan) { Channel *c = NULL; char *listen_address, *originator_address; - int listen_port, originator_port; + u_short listen_port, originator_port; /* Get rest of the packet */ listen_address = packet_get_string(NULL); @@ -1658,7 +1664,7 @@ client_request_x11(const char *request_type, int rchan) { Channel *c = NULL; char *originator; - int originator_port; + u_short originator_port; int sock; if (!options.forward_x11) { @@ -1722,7 +1728,7 @@ client_request_tun_fwd(int tun_mode, int local_tun, int remote_tun) return 0; if (!compat20) { - error("Tunnel forwarding is not support for protocol 1"); + error("Tunnel forwarding is not supported for protocol 1"); return -1; } @@ -1846,7 +1852,7 @@ client_input_channel_req(int type, u_int32_t seq, void *ctxt) if (reply) { packet_start(success ? SSH2_MSG_CHANNEL_SUCCESS : SSH2_MSG_CHANNEL_FAILURE); - packet_put_int(id); + packet_put_int(c->remote_id); packet_send(); } xfree(rtype); diff --git a/compat.c b/compat.c index bc113158144b..df3541df70ef 100644 --- a/compat.c +++ b/compat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.c,v 1.77 2006/12/12 03:58:42 djm Exp $ */ +/* $OpenBSD: compat.c,v 1.78 2008/09/11 14:22:37 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -91,7 +91,8 @@ compat_datafellows(const char *version) "OpenSSH_3.1*", SSH_BUG_EXTEOF|SSH_OLD_FORWARD_ADDR}, { "OpenSSH_3.*", SSH_OLD_FORWARD_ADDR }, { "Sun_SSH_1.0*", SSH_BUG_NOREKEY|SSH_BUG_EXTEOF}, - { "OpenSSH*", 0 }, + { "OpenSSH_4*", 0 }, + { "OpenSSH*", SSH_NEW_OPENSSH }, { "*MindTerm*", 0 }, { "2.1.0*", SSH_BUG_SIGBLOB|SSH_BUG_HMAC| SSH_OLD_SESSIONID|SSH_BUG_DEBUG| diff --git a/compat.h b/compat.h index 4d8ebc908a42..16cf282a7aec 100644 --- a/compat.h +++ b/compat.h @@ -1,4 +1,4 @@ -/* $OpenBSD: compat.h,v 1.41 2006/12/12 03:58:42 djm Exp $ */ +/* $OpenBSD: compat.h,v 1.42 2008/09/11 14:22:37 markus Exp $ */ /* * Copyright (c) 1999, 2000, 2001 Markus Friedl. All rights reserved. @@ -57,6 +57,7 @@ #define SSH_BUG_FIRSTKEX 0x00800000 #define SSH_OLD_FORWARD_ADDR 0x01000000 #define SSH_BUG_RFWD_ADDR 0x02000000 +#define SSH_NEW_OPENSSH 0x04000000 void enable_compat13(void); void enable_compat20(void); diff --git a/config.guess b/config.guess index 6d71f752f91a..c7607c74f1b8 100755 --- a/config.guess +++ b/config.guess @@ -1,9 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. -timestamp='2005-05-27' +timestamp='2008-04-14' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -55,8 +56,8 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -106,7 +107,7 @@ set_cc_for_build=' trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; : ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d -q "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || + { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; @@ -125,7 +126,7 @@ case $CC_FOR_BUILD,$HOST_CC,$CC in ;; ,,*) CC_FOR_BUILD=$CC ;; ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ;' +esac ; set_cc_for_build= ;' # This is needed to find uname on a Pyramid OSx when run in the BSD universe. # (ghazi@noc.rutgers.edu 1994-08-24) @@ -160,6 +161,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in arm*) machine=arm-unknown ;; sh3el) machine=shl-unknown ;; sh3eb) machine=sh-unknown ;; + sh5el) machine=sh5le-unknown ;; *) machine=${UNAME_MACHINE_ARCH}-unknown ;; esac # The Operating System including object format, if it has switched @@ -199,50 +201,18 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. echo "${machine}-${os}${release}" exit ;; - amd64:OpenBSD:*:*) - echo x86_64-unknown-openbsd${UNAME_RELEASE} - exit ;; - amiga:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit ;; - cats:OpenBSD:*:*) - echo arm-unknown-openbsd${UNAME_RELEASE} - exit ;; - hp300:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit ;; - luna88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit ;; - mac68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit ;; - macppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit ;; - mvme68k:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit ;; - mvme88k:OpenBSD:*:*) - echo m88k-unknown-openbsd${UNAME_RELEASE} - exit ;; - mvmeppc:OpenBSD:*:*) - echo powerpc-unknown-openbsd${UNAME_RELEASE} - exit ;; - sgi:OpenBSD:*:*) - echo mips64-unknown-openbsd${UNAME_RELEASE} - exit ;; - sun3:OpenBSD:*:*) - echo m68k-unknown-openbsd${UNAME_RELEASE} - exit ;; *:OpenBSD:*:*) - echo ${UNAME_MACHINE}-unknown-openbsd${UNAME_RELEASE} + UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` + echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} exit ;; *:ekkoBSD:*:*) echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} exit ;; + *:SolidBSD:*:*) + echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} + exit ;; macppc:MirBSD:*:*) - echo powerppc-unknown-mirbsd${UNAME_RELEASE} + echo powerpc-unknown-mirbsd${UNAME_RELEASE} exit ;; *:MirBSD:*:*) echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} @@ -360,7 +330,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; - i86pc:SunOS:5.*:*) + i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*) echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` exit ;; sun4*:SunOS:6*:*) @@ -562,7 +532,7 @@ EOF echo rs6000-ibm-aix3.2 fi exit ;; - *:AIX:*:[45]) + *:AIX:*:[456]) IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then IBM_ARCH=rs6000 @@ -658,8 +628,7 @@ EOF esac if [ ${HP_ARCH} = "hppa2.0w" ] then - # avoid double evaluation of $set_cc_for_build - test -n "$CC_FOR_BUILD" || eval $set_cc_for_build + eval $set_cc_for_build # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler @@ -800,12 +769,19 @@ EOF echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} exit ;; *:FreeBSD:*:*) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + case ${UNAME_MACHINE} in + pc98) + echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + amd64) + echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + *) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; + esac exit ;; i*:CYGWIN*:*) echo ${UNAME_MACHINE}-pc-cygwin exit ;; - i*:MINGW*:*) + *:MINGW*:*) echo ${UNAME_MACHINE}-pc-mingw32 exit ;; i*:windows32*:*) @@ -815,9 +791,18 @@ EOF i*:PW*:*) echo ${UNAME_MACHINE}-pc-pw32 exit ;; - x86:Interix*:[34]*) - echo i586-pc-interix${UNAME_RELEASE}|sed -e 's/\..*//' - exit ;; + *:Interix*:[3456]*) + case ${UNAME_MACHINE} in + x86) + echo i586-pc-interix${UNAME_RELEASE} + exit ;; + EM64T | authenticamd) + echo x86_64-unknown-interix${UNAME_RELEASE} + exit ;; + IA64) + echo ia64-unknown-interix${UNAME_RELEASE} + exit ;; + esac ;; [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) echo i${UNAME_MACHINE}-pc-mks exit ;; @@ -830,7 +815,7 @@ EOF i*:UWIN*:*) echo ${UNAME_MACHINE}-pc-uwin exit ;; - amd64:CYGWIN*:*:*) + amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) echo x86_64-unknown-cygwin exit ;; p*:CYGWIN*:*) @@ -851,6 +836,16 @@ EOF echo ${UNAME_MACHINE}-pc-minix exit ;; arm*:Linux:*:*) + eval $set_cc_for_build + if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep -q __ARM_EABI__ + then + echo ${UNAME_MACHINE}-unknown-linux-gnu + else + echo ${UNAME_MACHINE}-unknown-linux-gnueabi + fi + exit ;; + avr32*:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; cris:Linux:*:*) @@ -887,7 +882,11 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; mips64:Linux:*:*) @@ -906,9 +905,16 @@ EOF #endif #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^CPU=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^CPU/{ + s: ::g + p + }'`" test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } ;; + or32:Linux:*:*) + echo or32-unknown-linux-gnu + exit ;; ppc:Linux:*:*) echo powerpc-unknown-linux-gnu exit ;; @@ -952,9 +958,15 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) echo ${UNAME_MACHINE}-unknown-linux-gnu exit ;; + vax:Linux:*:*) + echo ${UNAME_MACHINE}-dec-linux-gnu + exit ;; x86_64:Linux:*:*) echo x86_64-unknown-linux-gnu exit ;; + xtensa*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit ;; i*86:Linux:*:*) # The BFD linker knows what the default object file format is, so # first see if it will tell us. cd to the root directory to prevent @@ -973,9 +985,6 @@ EOF a.out-i386-linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; "") # Either a pre-BFD a.out linker (linux-gnuoldld) or # one that does not give us useful --help. @@ -997,7 +1006,7 @@ EOF LIBC=gnulibc1 # endif #else - #ifdef __INTEL_COMPILER + #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) LIBC=gnu #else LIBC=gnuaout @@ -1007,7 +1016,11 @@ EOF LIBC=dietlibc #endif EOF - eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep ^LIBC=` + eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' + /^LIBC/{ + s: ::g + p + }'`" test x"${LIBC}" != x && { echo "${UNAME_MACHINE}-pc-linux-${LIBC}" exit @@ -1200,6 +1213,9 @@ EOF BePC:BeOS:*:*) # BeOS running on Intel PC compatible. echo i586-pc-beos exit ;; + BePC:Haiku:*:*) # Haiku running on Intel PC compatible. + echo i586-pc-haiku + exit ;; SX-4:SUPER-UX:*:*) echo sx4-nec-superux${UNAME_RELEASE} exit ;; @@ -1209,6 +1225,15 @@ EOF SX-6:SUPER-UX:*:*) echo sx6-nec-superux${UNAME_RELEASE} exit ;; + SX-7:SUPER-UX:*:*) + echo sx7-nec-superux${UNAME_RELEASE} + exit ;; + SX-8:SUPER-UX:*:*) + echo sx8-nec-superux${UNAME_RELEASE} + exit ;; + SX-8R:SUPER-UX:*:*) + echo sx8r-nec-superux${UNAME_RELEASE} + exit ;; Power*:Rhapsody:*:*) echo powerpc-apple-rhapsody${UNAME_RELEASE} exit ;; @@ -1218,7 +1243,6 @@ EOF *:Darwin:*:*) UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown case $UNAME_PROCESSOR in - *86) UNAME_PROCESSOR=i686 ;; unknown) UNAME_PROCESSOR=powerpc ;; esac echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} @@ -1297,6 +1321,9 @@ EOF i*86:skyos:*:*) echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' exit ;; + i*86:rdos:*:*) + echo ${UNAME_MACHINE}-pc-rdos + exit ;; esac #echo '(No uname command or uname output not recognized.)' 1>&2 @@ -1457,9 +1484,9 @@ This script, last modified $timestamp, has failed to recognize the operating system you are using. It is advised that you download the most up to date version of the config scripts from - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.guess + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD and - http://savannah.gnu.org/cgi-bin/viewcvs/*checkout*/config/config/config.sub + http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD If the version you run ($0) is already up to date, please send the following data and any information you think might be diff --git a/config.h.in b/config.h.in index a650bdba8b0a..84967a46126f 100644 --- a/config.h.in +++ b/config.h.in @@ -380,6 +380,9 @@ /* Define to 1 if you have the `getgrset' function. */ #undef HAVE_GETGRSET +/* Define to 1 if you have the `getlastlogxbyname' function. */ +#undef HAVE_GETLASTLOGXBYNAME + /* Define to 1 if you have the `getluid' function. */ #undef HAVE_GETLUID @@ -897,6 +900,9 @@ /* define if you have struct sockaddr_in6 data type */ #undef HAVE_STRUCT_SOCKADDR_IN6 +/* Define to 1 if `sin6_scope_id' is member of `struct sockaddr_in6'. */ +#undef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID + /* define if you have struct sockaddr_storage data type */ #undef HAVE_STRUCT_SOCKADDR_STORAGE @@ -1158,6 +1164,9 @@ /* Define if you want Kerberos 5 support */ #undef KRB5 +/* Define if pututxline updates lastlog too */ +#undef LASTLOG_WRITE_PUTUTXLINE + /* Define if you want TCP Wrappers support */ #undef LIBWRAP diff --git a/config.sub b/config.sub index 519f2cd0066c..a649350a6ca7 100755 --- a/config.sub +++ b/config.sub @@ -1,9 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. +# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 +# Free Software Foundation, Inc. -timestamp='2005-05-12' +timestamp='2008-06-16' # This file is (in principle) common to ALL GNU software. # The presence of a machine in this file suggests that SOME GNU software @@ -71,8 +72,8 @@ Report bugs and patches to ." version="\ GNU config.sub ($timestamp) -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -119,8 +120,9 @@ esac # Here we must recognize all the valid KERNEL-OS combinations. maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \ - kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*) + nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ + uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ + storm-chaos* | os2-emx* | rtmk-nova*) os=-$maybe_os basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` ;; @@ -171,6 +173,10 @@ case $os in -hiux*) os=-hiuxwe2 ;; + -sco6) + os=-sco5v6 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco5) os=-sco3.2v5 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -187,6 +193,10 @@ case $os in # Don't forget version if it is 3.2v4 or newer. basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` ;; + -sco5v6*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; -sco*) os=-sco3.2v2 basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` @@ -231,23 +241,27 @@ case $basic_machine in | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr \ + | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ | bfin \ | c4x | clipper \ | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ + | fido | fr30 | frv \ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ | i370 | i860 | i960 | ia64 \ | ip2k | iq2000 \ - | m32r | m32rle | m68000 | m68k | m88k | maxq | mcore \ + | m32c | m32r | m32rle | m68000 | m68k | m88k \ + | maxq | mb | microblaze | mcore | mep | metag \ | mips | mipsbe | mipseb | mipsel | mipsle \ | mips16 \ | mips64 | mips64el \ - | mips64vr | mips64vrel \ + | mips64octeon | mips64octeonel \ | mips64orion | mips64orionel \ + | mips64r5900 | mips64r5900el \ + | mips64vr | mips64vrel \ | mips64vr4100 | mips64vr4100el \ | mips64vr4300 | mips64vr4300el \ | mips64vr5000 | mips64vr5000el \ + | mips64vr5900 | mips64vr5900el \ | mipsisa32 | mipsisa32el \ | mipsisa32r2 | mipsisa32r2el \ | mipsisa64 | mipsisa64el \ @@ -256,21 +270,24 @@ case $basic_machine in | mipsisa64sr71k | mipsisa64sr71kel \ | mipstx39 | mipstx39el \ | mn10200 | mn10300 \ + | mt \ | msp430 \ + | nios | nios2 \ | ns16k | ns32k \ - | openrisc | or32 \ + | or32 \ | pdp10 | pdp11 | pj | pjl \ | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ | pyramid \ - | sh | sh[1234] | sh[23]e | sh[34]eb | shbe | shle | sh[1234]le | sh3ele \ + | score \ + | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b \ - | strongarm \ + | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ + | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ + | spu | strongarm \ | tahoe | thumb | tic4x | tic80 | tron \ | v850 | v850e \ | we32k \ - | x86 | xscale | xscalee[bl] | xstormy16 | xtensa \ + | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ | z8k) basic_machine=$basic_machine-unknown ;; @@ -281,6 +298,9 @@ case $basic_machine in ;; m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) ;; + ms1) + basic_machine=mt-unknown + ;; # We use `pc' rather than `unknown' # because (1) that's what they normally are, and @@ -300,28 +320,31 @@ case $basic_machine in | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* \ + | avr-* | avr32-* \ | bfin-* | bs2000-* \ | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ | clipper-* | craynv-* | cydra-* \ | d10v-* | d30v-* | dlx-* \ | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ + | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \ | h8300-* | h8500-* \ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ | i*86-* | i860-* | i960-* | ia64-* \ | ip2k-* | iq2000-* \ - | m32r-* | m32rle-* \ + | m32c-* | m32r-* | m32rle-* \ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ + | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ | mips16-* \ | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ + | mips64octeon-* | mips64octeonel-* \ | mips64orion-* | mips64orionel-* \ + | mips64r5900-* | mips64r5900el-* \ + | mips64vr-* | mips64vrel-* \ | mips64vr4100-* | mips64vr4100el-* \ | mips64vr4300-* | mips64vr4300el-* \ | mips64vr5000-* | mips64vr5000el-* \ + | mips64vr5900-* | mips64vr5900el-* \ | mipsisa32-* | mipsisa32el-* \ | mipsisa32r2-* | mipsisa32r2el-* \ | mipsisa64-* | mipsisa64el-* \ @@ -330,28 +353,34 @@ case $basic_machine in | mipsisa64sr71k-* | mipsisa64sr71kel-* \ | mipstx39-* | mipstx39el-* \ | mmix-* \ + | mt-* \ | msp430-* \ + | nios-* | nios2-* \ | none-* | np1-* | ns16k-* | ns32k-* \ | orion-* \ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ | pyramid-* \ | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[23]e-* | sh[34]eb-* | shbe-* \ + | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc86x-* | sparclet-* \ + | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | strongarm-* | sv1-* | sx?-* \ + | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ + | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \ | tron-* \ | v850-* | v850e-* | vax-* \ | we32k-* \ - | x86-* | x86_64-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ + | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ + | xstormy16-* | xtensa*-* \ | ymp-* \ | z8k-*) ;; + # Recognize the basic CPU types without company name, with glob match. + xtensa*) + basic_machine=$basic_machine-unknown + ;; # Recognize the various machine names and aliases which stand # for a CPU type and a company and sometimes even an OS. 386bsd) @@ -422,10 +451,22 @@ case $basic_machine in basic_machine=ns32k-sequent os=-dynix ;; + blackfin) + basic_machine=bfin-unknown + os=-linux + ;; + blackfin-*) + basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; c90) basic_machine=c90-cray os=-unicos ;; + cegcc) + basic_machine=arm-unknown + os=-cegcc + ;; convex-c1) basic_machine=c1-convex os=-bsd @@ -454,8 +495,8 @@ case $basic_machine in basic_machine=craynv-cray os=-unicosmp ;; - cr16c) - basic_machine=cr16c-unknown + cr16) + basic_machine=cr16-unknown os=-elf ;; crds | unos) @@ -493,6 +534,10 @@ case $basic_machine in basic_machine=m88k-motorola os=-sysv3 ;; + dicos) + basic_machine=i686-pc + os=-dicos + ;; djgpp) basic_machine=i586-pc os=-msdosdjgpp @@ -647,6 +692,14 @@ case $basic_machine in basic_machine=m68k-isi os=-sysv ;; + m68knommu) + basic_machine=m68k-unknown + os=-linux + ;; + m68knommu-*) + basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; m88k-omron*) basic_machine=m88k-omron ;; @@ -662,6 +715,10 @@ case $basic_machine in basic_machine=i386-pc os=-mingw32 ;; + mingw32ce) + basic_machine=arm-unknown + os=-mingw32ce + ;; miniframe) basic_machine=m68000-convergent ;; @@ -687,6 +744,9 @@ case $basic_machine in basic_machine=i386-pc os=-msdos ;; + ms1-*) + basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` + ;; mvs) basic_machine=i370-ibm os=-mvs @@ -762,9 +822,8 @@ case $basic_machine in basic_machine=hppa1.1-oki os=-proelf ;; - or32 | or32-*) + openrisc | openrisc-*) basic_machine=or32-unknown - os=-coff ;; os400) basic_machine=powerpc-ibm @@ -786,6 +845,14 @@ case $basic_machine in basic_machine=i860-intel os=-osf ;; + parisc) + basic_machine=hppa-unknown + os=-linux + ;; + parisc-*) + basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'` + os=-linux + ;; pbd) basic_machine=sparc-tti ;; @@ -795,6 +862,12 @@ case $basic_machine in pc532 | pc532-*) basic_machine=ns32k-pc532 ;; + pc98) + basic_machine=i386-pc + ;; + pc98-*) + basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; pentium | p5 | k5 | k6 | nexgen | viac3) basic_machine=i586-pc ;; @@ -851,6 +924,10 @@ case $basic_machine in basic_machine=i586-unknown os=-pw32 ;; + rdos) + basic_machine=i386-pc + os=-rdos + ;; rom68k) basic_machine=m68k-rom68k os=-coff @@ -877,6 +954,10 @@ case $basic_machine in sb1el) basic_machine=mipsisa64sb1el-unknown ;; + sde) + basic_machine=mipsisa32-sde + os=-elf + ;; sei) basic_machine=mips-sei os=-seiux @@ -888,6 +969,9 @@ case $basic_machine in basic_machine=sh-hitachi os=-hms ;; + sh5el) + basic_machine=sh5le-unknown + ;; sh64) basic_machine=sh64-unknown ;; @@ -977,6 +1061,10 @@ case $basic_machine in basic_machine=tic6x-unknown os=-coff ;; + tile*) + basic_machine=tile-unknown + os=-linux-gnu + ;; tx39) basic_machine=mipstx39-unknown ;; @@ -1090,13 +1178,10 @@ case $basic_machine in we32k) basic_machine=we32k-att ;; - sh3 | sh4 | sh[34]eb | sh[1234]le | sh[23]ele) + sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) basic_machine=sh-unknown ;; - sh64) - basic_machine=sh64-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b) + sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) basic_machine=sparc-sun ;; cydra) @@ -1169,20 +1254,23 @@ case $os in | -aos* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* | -openbsd* \ + | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ + | -openbsd* | -solidbsd* \ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ + | -chorusos* | -chorusrdb* | -cegcc* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ + | -uxpv* | -beos* | -mpeix* | -udk* \ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* | -skyos*) + | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ + | -skyos* | -haiku* | -rdos* | -toppers* | -drops*) # Remember, each alternative MUST END IN *, to match a version number. ;; -qnx*) @@ -1200,7 +1288,7 @@ case $os in os=`echo $os | sed -e 's|nto|nto-qnx|'` ;; -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) ;; -mac*) @@ -1312,6 +1400,9 @@ case $os in -zvmoe) os=-zvmoe ;; + -dicos*) + os=-dicos + ;; -none) ;; *) @@ -1334,6 +1425,12 @@ else # system, and we'll never get to this point. case $basic_machine in + score-*) + os=-elf + ;; + spu-*) + os=-elf + ;; *-acorn) os=-riscix1.2 ;; @@ -1343,9 +1440,9 @@ case $basic_machine in arm*-semi) os=-aout ;; - c4x-* | tic4x-*) - os=-coff - ;; + c4x-* | tic4x-*) + os=-coff + ;; # This must come before the *-dec entry. pdp10-*) os=-tops20 @@ -1371,6 +1468,9 @@ case $basic_machine in m68*-cisco) os=-aout ;; + mep-*) + os=-elf + ;; mips*-cisco) os=-elf ;; @@ -1389,6 +1489,9 @@ case $basic_machine in *-be) os=-beos ;; + *-haiku) + os=-haiku + ;; *-ibm) os=-aix ;; diff --git a/configure b/configure index 19cc20c84473..0b757c6a44fc 100755 --- a/configure +++ b/configure @@ -1,5 +1,5 @@ #! /bin/sh -# From configure.ac Revision: 1.409 . +# From configure.ac Revision: 1.415 . # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61 for OpenSSH Portable. # @@ -203,7 +203,7 @@ if as_func_ret_failure; then echo as_func_ret_failure succeeded. fi -if (set x; as_func_ret_success y && test x = \"\$1\" ); then +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 @@ -407,7 +407,7 @@ if as_func_ret_failure; then echo as_func_ret_failure succeeded. fi -if (set x; as_func_ret_success y && test x = \"\$1\" ); then +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 @@ -5461,7 +5461,7 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ # -fstack-protector-all doesn't always work for some GCC versions # and/or platforms, so we test if we can. If it's not supported - # on a give platform gcc will emit a warning so we use -Werror. + # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then for t in -fstack-protector-all -fstack-protector; do { echo "$as_me:$LINENO: checking if $CC supports $t" >&5 @@ -5477,8 +5477,8 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include -int main(void){return 0;} +#include +int main(void){char x[256]; snprintf(x, sizeof(x), "XXX"); return 0;} _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext @@ -5518,8 +5518,8 @@ cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ -#include -int main(void){exit(0);} +#include +int main(void){char x[256]; snprintf(x, sizeof(x), "XXX"); return 0;} _ACEOF rm -f conftest$ac_exeext @@ -7365,6 +7365,11 @@ _ACEOF #include +cat >>confdefs.h <<\_ACEOF +#define LASTLOG_WRITE_PUTUTXLINE 1 +_ACEOF + + fi ;; @@ -7678,6 +7683,31 @@ _ACEOF cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" +_ACEOF + + ;; +*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) + check_for_libcrypt_later=1 + cat >>confdefs.h <<\_ACEOF +#define PAM_TTY_KLUDGE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define LOCKED_PASSWD_PREFIX "!" +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define SPT_TYPE SPT_REUSEARGV +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define _PATH_BTMP "/var/log/btmp" +_ACEOF + + +cat >>confdefs.h <<\_ACEOF +#define USE_BTMP 1 _ACEOF ;; @@ -8744,7 +8774,6 @@ _ACEOF ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) - check_for_libcrypt_later=1 cat >>confdefs.h <<\_ACEOF #define UNIXWARE_LONG_PASSWORDS 1 @@ -8782,11 +8811,181 @@ _ACEOF #define BROKEN_UPDWTMPX 1 _ACEOF + { echo "$as_me:$LINENO: checking for getluid in -lprot" >&5 +echo $ECHO_N "checking for getluid in -lprot... $ECHO_C" >&6; } +if test "${ac_cv_lib_prot_getluid+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lprot $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char getluid (); +int +main () +{ +return getluid (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + ac_cv_lib_prot_getluid=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_lib_prot_getluid=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_prot_getluid" >&5 +echo "${ECHO_T}$ac_cv_lib_prot_getluid" >&6; } +if test $ac_cv_lib_prot_getluid = yes; then + LIBS="$LIBS -lprot" + + +for ac_func in getluid setluid +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + cat >>confdefs.h <<\_ACEOF +#define HAVE_SECUREWARE 1 +_ACEOF + + cat >>confdefs.h <<\_ACEOF +#define DISABLE_SHADOW 1 +_ACEOF + + +fi + ;; *) cat >>confdefs.h <<\_ACEOF #define LOCKED_PASSWD_STRING "*LK*" _ACEOF + check_for_libcrypt_later=1 ;; esac ;; @@ -14775,6 +14974,100 @@ fi done +for ac_func in getlastlogxbyname +do +as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for $ac_func" >&5 +echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +/* Define $ac_func to an innocuous variant, in case declares $ac_func. + For example, HP-UX 11i declares gettimeofday. */ +#define $ac_func innocuous_$ac_func + +/* System header to define __stub macros and hopefully few prototypes, + which can conflict with char $ac_func (); below. + Prefer to if __STDC__ is defined, since + exists even on freestanding compilers. */ + +#ifdef __STDC__ +# include +#else +# include +#endif + +#undef $ac_func + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char $ac_func (); +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined __stub_$ac_func || defined __stub___$ac_func +choke me +#endif + +int +main () +{ +return $ac_func (); + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + eval "$as_ac_var=yes" +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + eval "$as_ac_var=no" +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext +fi +ac_res=`eval echo '${'$as_ac_var'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_var'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +_ACEOF + +fi +done + + { echo "$as_me:$LINENO: checking for daemon" >&5 echo $ECHO_N "checking for daemon... $ECHO_C" >&6; } if test "${ac_cv_func_daemon+set}" = set; then @@ -22501,6 +22794,121 @@ cat >>confdefs.h <<\_ACEOF #define HAVE_STRUCT_IN6_ADDR 1 _ACEOF + + { echo "$as_me:$LINENO: checking for struct sockaddr_in6.sin6_scope_id" >&5 +echo $ECHO_N "checking for struct sockaddr_in6.sin6_scope_id... $ECHO_C" >&6; } +if test "${ac_cv_member_struct_sockaddr_in6_sin6_scope_id+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + + +int +main () +{ +static struct sockaddr_in6 ac_aggr; +if (ac_aggr.sin6_scope_id) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_sockaddr_in6_sin6_scope_id=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + + +int +main () +{ +static struct sockaddr_in6 ac_aggr; +if (sizeof ac_aggr.sin6_scope_id) +return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_member_struct_sockaddr_in6_sin6_scope_id=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_member_struct_sockaddr_in6_sin6_scope_id=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_member_struct_sockaddr_in6_sin6_scope_id" >&5 +echo "${ECHO_T}$ac_cv_member_struct_sockaddr_in6_sin6_scope_id" >&6; } +if test $ac_cv_member_struct_sockaddr_in6_sin6_scope_id = yes; then + +cat >>confdefs.h <<_ACEOF +#define HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID 1 +_ACEOF + + +fi + fi { echo "$as_me:$LINENO: checking for struct addrinfo" >&5 diff --git a/configure.ac b/configure.ac index fcf7e416b5cd..b33914daea20 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -# $Id: configure.ac,v 1.409 2008/07/09 11:07:19 djm Exp $ +# $Id: configure.ac,v 1.415 2009/02/16 04:37:03 djm Exp $ # # Copyright (c) 1999-2004 Damien Miller # @@ -15,7 +15,7 @@ # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. AC_INIT(OpenSSH, Portable, openssh-unix-dev@mindrot.org) -AC_REVISION($Revision: 1.409 $) +AC_REVISION($Revision: 1.415 $) AC_CONFIG_SRCDIR([ssh.c]) AC_CONFIG_HEADER(config.h) @@ -126,7 +126,7 @@ int main(void){char b[10]; memset(b, 0, sizeof(b));} # -fstack-protector-all doesn't always work for some GCC versions # and/or platforms, so we test if we can. If it's not supported - # on a give platform gcc will emit a warning so we use -Werror. + # on a given platform gcc will emit a warning so we use -Werror. if test "x$use_stack_protector" = "x1"; then for t in -fstack-protector-all -fstack-protector; do AC_MSG_CHECKING(if $CC supports $t) @@ -136,8 +136,8 @@ int main(void){char b[10]; memset(b, 0, sizeof(b));} LDFLAGS="$LDFLAGS $t -Werror" AC_LINK_IFELSE( [AC_LANG_SOURCE([ -#include -int main(void){return 0;} +#include +int main(void){char x[[256]]; snprintf(x, sizeof(x), "XXX"); return 0;} ])], [ AC_MSG_RESULT(yes) CFLAGS="$saved_CFLAGS $t" @@ -145,8 +145,8 @@ int main(void){return 0;} AC_MSG_CHECKING(if $t works) AC_RUN_IFELSE( [AC_LANG_SOURCE([ -#include -int main(void){exit(0);} +#include +int main(void){char x[[256]]; snprintf(x, sizeof(x), "XXX"); return 0;} ])], [ AC_MSG_RESULT(yes) break ], @@ -477,6 +477,8 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_CHECK_DECL(AU_IPv4, [], AC_DEFINE(AU_IPv4, 0, [System only supports IPv4 audit records]) [#include ] + AC_DEFINE(LASTLOG_WRITE_PUTUTXLINE, 1, + [Define if pututxline updates lastlog too]) ) ;; *-*-dragonfly*) @@ -561,6 +563,14 @@ main() { if (NSVersionOfRunTimeLibrary("System") >= (60 << 16)) AC_DEFINE(WITH_ABBREV_NO_TTY) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") ;; +*-*-k*bsd*-gnu | *-*-kopensolaris*-gnu) + check_for_libcrypt_later=1 + AC_DEFINE(PAM_TTY_KLUDGE) + AC_DEFINE(LOCKED_PASSWD_PREFIX, "!") + AC_DEFINE(SPT_TYPE,SPT_REUSEARGV) + AC_DEFINE(_PATH_BTMP, "/var/log/btmp", [log for bad login attempts]) + AC_DEFINE(USE_BTMP, 1, [Use btmp to log bad logins]) + ;; *-*-linux*) no_dev_ptmx=1 check_for_libcrypt_later=1 @@ -728,7 +738,6 @@ mips-sony-bsd|mips-sony-newsos4) ;; # UnixWare 7.x, OpenUNIX 8 *-*-sysv5*) - check_for_libcrypt_later=1 AC_DEFINE(UNIXWARE_LONG_PASSWORDS, 1, [Support passwords > 8 chars]) AC_DEFINE(USE_PIPES) AC_DEFINE(SETEUID_BREAKS_SETUID) @@ -741,8 +750,14 @@ mips-sony-bsd|mips-sony-newsos4) AC_DEFINE(BROKEN_LIBIAF, 1, [ia_uinfo routines not supported by OS yet]) AC_DEFINE(BROKEN_UPDWTMPX) + AC_CHECK_LIB(prot, getluid,[ LIBS="$LIBS -lprot" + AC_CHECK_FUNCS(getluid setluid,,,-lprot) + AC_DEFINE(HAVE_SECUREWARE) + AC_DEFINE(DISABLE_SHADOW) + ],,) ;; *) AC_DEFINE(LOCKED_PASSWD_STRING, "*LK*") + check_for_libcrypt_later=1 ;; esac ;; @@ -1503,6 +1518,8 @@ AC_CHECK_FUNCS(utmpname) dnl Checks for utmpx functions AC_CHECK_FUNCS(endutxent getutxent getutxid getutxline pututxline ) AC_CHECK_FUNCS(setutxent utmpxname) +dnl Checks for lastlog functions +AC_CHECK_FUNCS(getlastlogxbyname) AC_CHECK_FUNC(daemon, [AC_DEFINE(HAVE_DAEMON, 1, [Define if your libraries define daemon()])], @@ -2824,6 +2841,15 @@ AC_CACHE_CHECK([for struct in6_addr], ac_cv_have_struct_in6_addr, [ if test "x$ac_cv_have_struct_in6_addr" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_IN6_ADDR, 1, [define if you have struct in6_addr data type]) + +dnl Now check for sin6_scope_id + AC_CHECK_MEMBERS([struct sockaddr_in6.sin6_scope_id],,, + [ +#ifdef HAVE_SYS_TYPES_H +#include +#endif +#include + ]) fi AC_CACHE_CHECK([for struct addrinfo], ac_cv_have_struct_addrinfo, [ diff --git a/contrib/caldera/openssh.spec b/contrib/caldera/openssh.spec index 32d175d4bcd1..42dbcfeebcaa 100644 --- a/contrib/caldera/openssh.spec +++ b/contrib/caldera/openssh.spec @@ -17,11 +17,11 @@ #old cvs stuff. please update before use. may be deprecated. %define use_stable 1 %if %{use_stable} - %define version 5.1p1 + %define version 5.2p1 %define cvs %{nil} %define release 1 %else - %define version 5.1p1 + %define version 5.2p1 %define cvs cvs20050315 %define release 0r1 %endif @@ -251,7 +251,7 @@ install -m 0755 contrib/caldera/ssh-host-keygen $SKG # install remaining docs DocD="%{buildroot}%{_defaultdocdir}/%{name}-%{version}" mkdir -p $DocD/%{askpass} -cp -a CREDITS ChangeLog LICENCE OVERVIEW README* TODO $DocD +cp -a CREDITS ChangeLog LICENCE OVERVIEW README* TODO PROTOCOL* $DocD install -p -m 0444 %{SOURCE3} $DocD/faq.html cp -a %{askpass}/{README,ChangeLog,TODO,SshAskpass*.ad} $DocD/%{askpass} %if %{use_stable} @@ -358,4 +358,4 @@ fi * Mon Jan 01 1998 ... Template Version: 1.31 -$Id: openssh.spec,v 1.65 2008/07/21 08:21:53 djm Exp $ +$Id: openssh.spec,v 1.66 2009/02/21 07:03:05 djm Exp $ diff --git a/contrib/caldera/ssh-host-keygen b/contrib/caldera/ssh-host-keygen index 3c5c1718270a..86382ddfb43f 100755 --- a/contrib/caldera/ssh-host-keygen +++ b/contrib/caldera/ssh-host-keygen @@ -1,6 +1,6 @@ #! /bin/sh # -# $Id: ssh-host-keygen,v 1.2 2003/11/21 12:48:57 djm Exp $ +# $Id: ssh-host-keygen,v 1.3 2008/11/03 09:16:01 djm Exp $ # # This script is normally run only *once* for a given host # (in a given period of time) -- on updates/upgrades/recovery @@ -15,16 +15,16 @@ if [ -f $keydir/ssh_host_key -o \ -f $keydir/ssh_host_key.pub ]; then echo "You already have an SSH1 RSA host key in $keydir/ssh_host_key." else - echo "Generating 1024 bit SSH1 RSA host key." - $keygen -b 1024 -t rsa1 -f $keydir/ssh_host_key -C '' -N '' + echo "Generating SSH1 RSA host key." + $keygen -t rsa1 -f $keydir/ssh_host_key -C '' -N '' fi if [ -f $keydir/ssh_host_rsa_key -o \ -f $keydir/ssh_host_rsa_key.pub ]; then echo "You already have an SSH2 RSA host key in $keydir/ssh_host_rsa_key." else - echo "Generating 1024 bit SSH2 RSA host key." - $keygen -b 1024 -t rsa -f $keydir/ssh_host_rsa_key -C '' -N '' + echo "Generating SSH2 RSA host key." + $keygen -t rsa -f $keydir/ssh_host_rsa_key -C '' -N '' fi if [ -f $keydir/ssh_host_dsa_key -o \ diff --git a/contrib/caldera/sshd.pam b/contrib/caldera/sshd.pam index 26dcb34d9e94..f050a9aee648 100644 --- a/contrib/caldera/sshd.pam +++ b/contrib/caldera/sshd.pam @@ -1,6 +1,6 @@ #%PAM-1.0 auth required /lib/security/pam_pwdb.so shadow nodelay -auth required /lib/security/pam_nologin.so +account required /lib/security/pam_nologin.so account required /lib/security/pam_pwdb.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_pwdb.so shadow nullok use_authtok diff --git a/contrib/cygwin/Makefile b/contrib/cygwin/Makefile index 3e2d264041df..2ebd143dcdf9 100644 --- a/contrib/cygwin/Makefile +++ b/contrib/cygwin/Makefile @@ -38,11 +38,13 @@ install-sshdoc: $(INSTALL) -m 644 $(srcdir)/ChangeLog $(DESTDIR)$(sshdocdir)/ChangeLog $(INSTALL) -m 644 $(srcdir)/LICENCE $(DESTDIR)$(sshdocdir)/LICENCE $(INSTALL) -m 644 $(srcdir)/OVERVIEW $(DESTDIR)$(sshdocdir)/OVERVIEW + $(INSTALL) -m 644 $(srcdir)/PROTOCOL $(DESTDIR)$(sshdocdir)/PROTOCOL + $(INSTALL) -m 644 $(srcdir)/PROTOCOL.agent $(DESTDIR)$(sshdocdir)/PROTOCOL.agent $(INSTALL) -m 644 $(srcdir)/README $(DESTDIR)$(sshdocdir)/README $(INSTALL) -m 644 $(srcdir)/README.dns $(DESTDIR)$(sshdocdir)/README.dns + $(INSTALL) -m 644 $(srcdir)/README.platform $(DESTDIR)$(sshdocdir)/README.platform $(INSTALL) -m 644 $(srcdir)/README.privsep $(DESTDIR)$(sshdocdir)/README.privsep $(INSTALL) -m 644 $(srcdir)/README.smartcard $(DESTDIR)$(sshdocdir)/README.smartcard - $(INSTALL) -m 644 $(srcdir)/RFC.nroff $(DESTDIR)$(sshdocdir)/RFC.nroff $(INSTALL) -m 644 $(srcdir)/TODO $(DESTDIR)$(sshdocdir)/TODO $(INSTALL) -m 644 $(srcdir)/WARNING.RNG $(DESTDIR)$(sshdocdir)/WARNING.RNG diff --git a/contrib/cygwin/ssh-host-config b/contrib/cygwin/ssh-host-config index bbb6da4c4e76..57e728fbc6dd 100644 --- a/contrib/cygwin/ssh-host-config +++ b/contrib/cygwin/ssh-host-config @@ -25,7 +25,7 @@ source ${CSIH_SCRIPT} port_number=22 privsep_configured=no privsep_used=yes -cygwin_value="ntsec" +cygwin_value="" password_value= # ====================================================================== @@ -37,13 +37,13 @@ create_host_keys() { csih_inform "Generating ${SYSCONFDIR}/ssh_host_key" ssh-keygen -t rsa1 -f ${SYSCONFDIR}/ssh_host_key -N '' > /dev/null fi - + if [ ! -f "${SYSCONFDIR}/ssh_host_rsa_key" ] then csih_inform "Generating ${SYSCONFDIR}/ssh_host_rsa_key" ssh-keygen -t rsa -f ${SYSCONFDIR}/ssh_host_rsa_key -N '' > /dev/null fi - + if [ ! -f "${SYSCONFDIR}/ssh_host_dsa_key" ] then csih_inform "Generating ${SYSCONFDIR}/ssh_host_dsa_key" @@ -75,12 +75,12 @@ update_services_file() { _spaces=" # " fi _serv_tmp="${_my_etcdir}/srv.out.$$" - - mount -t -f "${_win_etcdir}" "${_my_etcdir}" - + + mount -o text -f "${_win_etcdir}" "${_my_etcdir}" + # Depends on the above mount _wservices=`cygpath -w "${_services}"` - + # Remove sshd 22/port from services if [ `grep -q 'sshd[ \t][ \t]*22' "${_services}"; echo $?` -eq 0 ] then @@ -89,16 +89,16 @@ update_services_file() { then if mv "${_serv_tmp}" "${_services}" then - csih_inform "Removing sshd from ${_wservices}" + csih_inform "Removing sshd from ${_wservices}" else - csih_warning "Removing sshd from ${_wservices} failed!" + csih_warning "Removing sshd from ${_wservices} failed!" fi rm -f "${_serv_tmp}" else csih_warning "Removing sshd from ${_wservices} failed!" fi fi - + # Add ssh 22/tcp and ssh 22/udp to services if [ `grep -q 'ssh[ \t][ \t]*22' "${_services}"; echo $?` -ne 0 ] then @@ -106,9 +106,9 @@ update_services_file() { then if mv "${_serv_tmp}" "${_services}" then - csih_inform "Added ssh to ${_wservices}" + csih_inform "Added ssh to ${_wservices}" else - csih_warning "Adding ssh to ${_wservices} failed!" + csih_warning "Adding ssh to ${_wservices} failed!" fi rm -f "${_serv_tmp}" else @@ -134,16 +134,16 @@ sshd_privsep() { csih_inform "For more info on privilege separation read /usr/share/doc/openssh/README.privsep." if csih_request "Should privilege separation be used?" then - privsep_used=yes - if ! csih_create_unprivileged_user sshd - then + privsep_used=yes + if ! csih_create_unprivileged_user sshd + then csih_warning "Couldn't create user 'sshd'!" - csih_warning "Privilege separation set to 'no' again!" - csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" + csih_warning "Privilege separation set to 'no' again!" + csih_warning "Check your ${SYSCONFDIR}/sshd_config file!" privsep_used=no - fi + fi else - privsep_used=no + privsep_used=no fi else # On 9x don't use privilege separation. Since security isn't @@ -151,7 +151,7 @@ sshd_privsep() { privsep_used=no fi fi - + # Create default sshd_config from skeleton files in /etc/defaults/etc or # modify to add the missing privsep configuration option if cmp "${SYSCONFDIR}/sshd_config" "${SYSCONFDIR}/defaults/${SYSCONFDIR}/sshd_config" >/dev/null 2>&1 @@ -161,8 +161,8 @@ sshd_privsep() { sed -e "s/^#UsePrivilegeSeparation yes/UsePrivilegeSeparation ${privsep_used}/ s/^#Port 22/Port ${port_number}/ s/^#StrictModes yes/StrictModes no/" \ - < ${SYSCONFDIR}/sshd_config \ - > "${sshdconfig_tmp}" + < ${SYSCONFDIR}/sshd_config \ + > "${sshdconfig_tmp}" mv "${sshdconfig_tmp}" ${SYSCONFDIR}/sshd_config elif [ "${privsep_configured}" != "yes" ] then @@ -193,19 +193,19 @@ update_inetd_conf() { # will be replaced by a file in inetd.d/ if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -eq 0 ] then - grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" - if [ -f "${_inetcnf_tmp}" ] - then - if mv "${_inetcnf_tmp}" "${_inetcnf}" - then + grep -v '^[# \t]*ssh' "${_inetcnf}" >> "${_inetcnf_tmp}" + if [ -f "${_inetcnf_tmp}" ] + then + if mv "${_inetcnf_tmp}" "${_inetcnf}" + then csih_inform "Removed ssh[d] from ${_inetcnf}" - else + else csih_warning "Removing ssh[d] from ${_inetcnf} failed!" - fi - rm -f "${_inetcnf_tmp}" - else - csih_warning "Removing ssh[d] from ${_inetcnf} failed!" - fi + fi + rm -f "${_inetcnf_tmp}" + else + csih_warning "Removing ssh[d] from ${_inetcnf} failed!" + fi fi fi @@ -214,13 +214,13 @@ update_inetd_conf() { then if [ "${_with_comment}" -eq 0 ] then - sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" + sed -e 's/@COMMENT@[ \t]*//' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" else - sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" + sed -e 's/@COMMENT@[ \t]*/# /' < "${_sshd_inetd_conf}" > "${_sshd_inetd_conf_tmp}" fi mv "${_sshd_inetd_conf_tmp}" "${_sshd_inetd_conf}" csih_inform "Updated ${_sshd_inetd_conf}" - fi + fi elif [ -f "${_inetcnf}" ] then @@ -233,26 +233,26 @@ update_inetd_conf() { grep -v '^[# \t]*sshd' "${_inetcnf}" >> "${_inetcnf_tmp}" if [ -f "${_inetcnf_tmp}" ] then - if mv "${_inetcnf_tmp}" "${_inetcnf}" - then + if mv "${_inetcnf_tmp}" "${_inetcnf}" + then csih_inform "Removed sshd from ${_inetcnf}" - else + else csih_warning "Removing sshd from ${_inetcnf} failed!" - fi - rm -f "${_inetcnf_tmp}" + fi + rm -f "${_inetcnf_tmp}" else - csih_warning "Removing sshd from ${_inetcnf} failed!" + csih_warning "Removing sshd from ${_inetcnf} failed!" fi fi - + # Add ssh line to inetd.conf if [ `grep -q '^[# \t]*ssh' "${_inetcnf}"; echo $?` -ne 0 ] then if [ "${_with_comment}" -eq 0 ] then - echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" + echo 'ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" else - echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" + echo '# ssh stream tcp nowait root /usr/sbin/sshd sshd -i' >> "${_inetcnf}" fi csih_inform "Added ssh to ${_inetcnf}" fi @@ -278,80 +278,83 @@ install_service() { echo -e "${_csih_QUERY_STR} Do you want to install sshd as a service?" if csih_request "(Say \"no\" if it is already installed as a service)" then - csih_inform "Note that the CYGWIN variable must contain at least \"ntsec\"" - csih_inform "for sshd to be able to change user context without password." - csih_get_cygenv "${cygwin_value}" + csih_get_cygenv "${cygwin_value}" - if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) - then - csih_inform "On Windows Server 2003, Windows Vista, and above, the" - csih_inform "SYSTEM account cannot setuid to other users -- a capability" - csih_inform "sshd requires. You need to have or to create a privileged" - csih_inform "account. This script will help you do so." - echo - if ! csih_create_privileged_user "${password_value}" - then - csih_error_recoverable "There was a serious problem creating a privileged user." - csih_request "Do you want to proceed anyway?" || exit 1 - fi - fi + if ( csih_is_nt2003 || [ "$csih_FORCE_PRIVILEGED_USER" = "yes" ] ) + then + csih_inform "On Windows Server 2003, Windows Vista, and above, the" + csih_inform "SYSTEM account cannot setuid to other users -- a capability" + csih_inform "sshd requires. You need to have or to create a privileged" + csih_inform "account. This script will help you do so." + echo + if ! csih_create_privileged_user "${password_value}" + then + csih_error_recoverable "There was a serious problem creating a privileged user." + csih_request "Do you want to proceed anyway?" || exit 1 + fi + fi - # never returns empty if NT or above - run_service_as=$(csih_service_should_run_as) + # never returns empty if NT or above + run_service_as=$(csih_service_should_run_as) - if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] - then - password="${csih_PRIVILEGED_PASSWORD}" - if [ -z "${password}" ] - then - csih_get_value "Please enter the password for user '${run_service_as}':" "-s" - password="${csih_value}" - fi - fi + if [ "${run_service_as}" = "${csih_PRIVILEGED_USERNAME}" ] + then + password="${csih_PRIVILEGED_PASSWORD}" + if [ -z "${password}" ] + then + csih_get_value "Please enter the password for user '${run_service_as}':" "-s" + password="${csih_value}" + fi + fi - # at this point, we either have $run_service_as = "system" and $password is empty, - # or $run_service_as is some privileged user and (hopefully) $password contains - # the correct password. So, from here out, we use '-z "${password}"' to discriminate - # the two cases. + # at this point, we either have $run_service_as = "system" and $password is empty, + # or $run_service_as is some privileged user and (hopefully) $password contains + # the correct password. So, from here out, we use '-z "${password}"' to discriminate + # the two cases. - csih_check_user "${run_service_as}" + csih_check_user "${run_service_as}" - if [ -z "${password}" ] - then - if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \ - -e CYGWIN="${csih_cygenv}" - then - echo - csih_inform "The sshd service has been installed under the LocalSystem" - csih_inform "account (also known as SYSTEM). To start the service now, call" - csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it" - csih_inform "will start automatically after the next reboot." - fi - else - if cygrunsrv -I sshd -d "CYGWIN sshd" -p /usr/sbin/sshd -a "-D" -y tcpip \ - -e CYGWIN="${csih_cygenv}" -u "${run_service_as}" -w "${password}" - then + if [ -n "${csih_cygenv}" ] + then + cygwin_env="-e CYGWIN=\"${csih_cygenv}\"" + fi + if [ -z "${password}" ] + then + if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \ + -a "-D" -y tcpip ${cygwin_env} + then + echo + csih_inform "The sshd service has been installed under the LocalSystem" + csih_inform "account (also known as SYSTEM). To start the service now, call" + csih_inform "\`net start sshd' or \`cygrunsrv -S sshd'. Otherwise, it" + csih_inform "will start automatically after the next reboot." + fi + else + if eval cygrunsrv -I sshd -d \"CYGWIN sshd\" -p /usr/sbin/sshd \ + -a "-D" -y tcpip ${cygwin_env} \ + -u "${run_service_as}" -w "${password}" + then echo csih_inform "The sshd service has been installed under the '${run_service_as}'" csih_inform "account. To start the service now, call \`net start sshd' or" - csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically" - csih_inform "after the next reboot." - fi - fi + csih_inform "\`cygrunsrv -S sshd'. Otherwise, it will start automatically" + csih_inform "after the next reboot." + fi + fi - # now, if successfully installed, set ownership of the affected files - if cygrunsrv -Q sshd >/dev/null 2>&1 - then - chown "${run_service_as}" ${SYSCONFDIR}/ssh* - chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty - chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog - if [ -f ${LOCALSTATEDIR}/log/sshd.log ] - then + # now, if successfully installed, set ownership of the affected files + if cygrunsrv -Q sshd >/dev/null 2>&1 + then + chown "${run_service_as}" ${SYSCONFDIR}/ssh* + chown "${run_service_as}".544 ${LOCALSTATEDIR}/empty + chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/lastlog + if [ -f ${LOCALSTATEDIR}/log/sshd.log ] + then chown "${run_service_as}".544 ${LOCALSTATEDIR}/log/sshd.log - fi - else - csih_warning "Something went wrong installing the sshd service." - fi + fi + else + csih_warning "Something went wrong installing the sshd service." + fi fi # user allowed us to install as service fi # service not yet installed fi # csih_is_nt @@ -456,7 +459,7 @@ done # Check for running ssh/sshd processes first. Refuse to do anything while # some ssh processes are still running -if ps -ef | grep -v grep | grep -q ssh +if ps -ef | grep -q '/sshd\?$' then echo csih_error "There are still ssh processes running. Please shut them down first." @@ -475,9 +478,9 @@ setfacl -m u:system:rwx "${LOCALSTATEDIR}/log" # Create /var/log/lastlog if not already exists if [ -e ${LOCALSTATEDIR}/log/lastlog -a ! -f ${LOCALSTATEDIR}/log/lastlog ] then - echo + echo csih_error_multi "${LOCALSTATEDIR}/log/lastlog exists, but is not a file." \ - "Cannot create ssh host configuration." + "Cannot create ssh host configuration." fi if [ ! -e ${LOCALSTATEDIR}/log/lastlog ] then @@ -520,7 +523,7 @@ sshd_privsep -update_services_file +update_services_file update_inetd_conf install_service diff --git a/contrib/redhat/openssh.spec b/contrib/redhat/openssh.spec index bb9e4d616c98..10bdc1989a34 100644 --- a/contrib/redhat/openssh.spec +++ b/contrib/redhat/openssh.spec @@ -1,4 +1,4 @@ -%define ver 5.1p1 +%define ver 5.2p1 %define rel 1 # OpenSSH privilege separation requires a user & group ID @@ -333,7 +333,7 @@ fi %files %defattr(-,root,root) -%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* RFC* TODO WARNING* +%doc CREDITS ChangeLog INSTALL LICENCE OVERVIEW README* PROTOCOL* TODO WARNING* %attr(0755,root,root) %{_bindir}/scp %attr(0644,root,root) %{_mandir}/man1/scp.1* %attr(0755,root,root) %dir %{_sysconfdir}/ssh diff --git a/contrib/redhat/sshd.pam b/contrib/redhat/sshd.pam index e486077661c1..ffa5adbe58e5 100644 --- a/contrib/redhat/sshd.pam +++ b/contrib/redhat/sshd.pam @@ -1,6 +1,6 @@ #%PAM-1.0 auth required pam_stack.so service=system-auth -auth required pam_nologin.so +account required pam_nologin.so account required pam_stack.so service=system-auth password required pam_stack.so service=system-auth session required pam_stack.so service=system-auth diff --git a/contrib/ssh-copy-id b/contrib/ssh-copy-id index acd36d398721..df74d25c8c0d 100644 --- a/contrib/ssh-copy-id +++ b/contrib/ssh-copy-id @@ -1,11 +1,11 @@ #!/bin/sh -# Shell script to install your identity.pub on a remote machine +# Shell script to install your public key on a remote machine # Takes the remote machine name as an argument. # Obviously, the remote machine must accept password authentication, # or one of the other keys in your ssh-agent, for this to work. -ID_FILE="${HOME}/.ssh/identity.pub" +ID_FILE="${HOME}/.ssh/id_rsa.pub" if [ "-i" = "$1" ]; then shift diff --git a/contrib/ssh-copy-id.1 b/contrib/ssh-copy-id.1 index b331fa149e9e..f25ed01f2a6e 100644 --- a/contrib/ssh-copy-id.1 +++ b/contrib/ssh-copy-id.1 @@ -18,7 +18,7 @@ the original English. .. .TH SSH-COPY-ID 1 "14 November 1999" "OpenSSH" .SH NAME -ssh-copy-id \- install your identity.pub in a remote machine's authorized_keys +ssh-copy-id \- install your public key in a remote machine's authorized_keys .SH SYNOPSIS .B ssh-copy-id [-i [identity_file]] .I "[user@]machine" @@ -42,7 +42,7 @@ set in its configuration). If the .B -i option is given then the identity file (defaults to -.BR ~/.ssh/identity.pub ) +.BR ~/.ssh/id_rsa.pub ) is used, regardless of whether there are any keys in your .BR ssh-agent . Otherwise, if this: diff --git a/contrib/sshd.pam.generic b/contrib/sshd.pam.generic index cf5af30248a9..215f0fe300a4 100644 --- a/contrib/sshd.pam.generic +++ b/contrib/sshd.pam.generic @@ -1,6 +1,6 @@ #%PAM-1.0 auth required /lib/security/pam_unix.so shadow nodelay -auth required /lib/security/pam_nologin.so +account required /lib/security/pam_nologin.so account required /lib/security/pam_unix.so password required /lib/security/pam_cracklib.so password required /lib/security/pam_unix.so shadow nullok use_authtok diff --git a/contrib/suse/openssh.spec b/contrib/suse/openssh.spec index 7bd9e05694c8..62f43e1374e7 100644 --- a/contrib/suse/openssh.spec +++ b/contrib/suse/openssh.spec @@ -13,7 +13,7 @@ Summary: OpenSSH, a free Secure Shell (SSH) protocol implementation Name: openssh -Version: 5.1p1 +Version: 5.2p1 URL: http://www.openssh.com/ Release: 1 Source0: openssh-%{version}.tar.gz @@ -200,7 +200,7 @@ fi %files %defattr(-,root,root) -%doc ChangeLog OVERVIEW README* +%doc ChangeLog OVERVIEW README* PROTOCOL* %doc TODO CREDITS LICENCE %attr(0755,root,root) %dir %{_sysconfdir}/ssh %attr(0644,root,root) %config(noreplace) %{_sysconfdir}/ssh/ssh_config diff --git a/contrib/suse/rc.sshd b/contrib/suse/rc.sshd index 573960bfa071..4d4880d7ed60 100644 --- a/contrib/suse/rc.sshd +++ b/contrib/suse/rc.sshd @@ -45,17 +45,17 @@ case "$1" in start) if ! test -f /etc/ssh/ssh_host_key ; then echo Generating /etc/ssh/ssh_host_key. - ssh-keygen -t rsa1 -b 1024 -f /etc/ssh/ssh_host_key -N '' + ssh-keygen -t rsa1 -f /etc/ssh/ssh_host_key -N '' fi if ! test -f /etc/ssh/ssh_host_dsa_key ; then echo Generating /etc/ssh/ssh_host_dsa_key. - ssh-keygen -t dsa -b 1024 -f /etc/ssh/ssh_host_dsa_key -N '' + ssh-keygen -t dsa -f /etc/ssh/ssh_host_dsa_key -N '' fi if ! test -f /etc/ssh/ssh_host_rsa_key ; then echo Generating /etc/ssh/ssh_host_rsa_key. - ssh-keygen -t rsa -b 1024 -f /etc/ssh/ssh_host_rsa_key -N '' + ssh-keygen -t rsa -f /etc/ssh/ssh_host_rsa_key -N '' fi echo -n "Starting SSH daemon" ## Start daemon with startproc(8). If this fails diff --git a/defines.h b/defines.h index a8203ebbbf06..536ec4978be5 100644 --- a/defines.h +++ b/defines.h @@ -25,7 +25,7 @@ #ifndef _DEFINES_H #define _DEFINES_H -/* $Id: defines.h,v 1.151 2008/07/04 13:10:49 djm Exp $ */ +/* $Id: defines.h,v 1.153 2009/02/01 11:19:54 dtucker Exp $ */ /* Constants */ @@ -698,7 +698,7 @@ struct winsize { # define CUSTOM_SYS_AUTH_PASSWD 1 #endif -#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) +#if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(HAVE_SECUREWARE) # define CUSTOM_SYS_AUTH_PASSWD 1 #endif #if defined(HAVE_LIBIAF) && defined(HAVE_SET_ID) && !defined(BROKEN_LIBIAF) @@ -738,4 +738,8 @@ struct winsize { # define EWOULDBLOCK EAGAIN #endif +#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ +#define INET6_ADDRSTRLEN 46 +#endif + #endif /* _DEFINES_H */ diff --git a/dispatch.c b/dispatch.c index d6b63be4b7ff..64bb80947427 100644 --- a/dispatch.c +++ b/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: dispatch.c,v 1.21 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: dispatch.c,v 1.22 2008/10/31 15:05:34 stevesk Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * @@ -37,7 +37,6 @@ #include "packet.h" #include "compat.h" -#define DISPATCH_MIN 0 #define DISPATCH_MAX 255 dispatch_fn *dispatch[DISPATCH_MAX]; diff --git a/jpake.c b/jpake.c new file mode 100644 index 000000000000..565f2e255089 --- /dev/null +++ b/jpake.c @@ -0,0 +1,604 @@ +/* $OpenBSD: jpake.c,v 1.1 2008/11/04 08:22:12 djm Exp $ */ +/* + * Copyright (c) 2008 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Shared components of zero-knowledge password auth using J-PAKE protocol + * as described in: + * + * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", + * 16th Workshop on Security Protocols, Cambridge, April 2008 + * + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + */ + +#include "includes.h" + +#include + +#include +#include +#include + +#include +#include + +#include "xmalloc.h" +#include "ssh2.h" +#include "key.h" +#include "hostfile.h" +#include "auth.h" +#include "buffer.h" +#include "packet.h" +#include "dispatch.h" +#include "log.h" + +#include "jpake.h" + +#ifdef JPAKE + +/* RFC3526 group 5, 1536 bits */ +#define JPAKE_GROUP_G "2" +#define JPAKE_GROUP_P \ + "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74" \ + "020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F1437" \ + "4FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" \ + "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF05" \ + "98DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB" \ + "9ED529077096966D670C354E4ABC9804F1746C08CA237327FFFFFFFFFFFFFFFF" + +struct jpake_group * +jpake_default_group(void) +{ + struct jpake_group *ret; + + ret = xmalloc(sizeof(*ret)); + ret->p = ret->q = ret->g = NULL; + if (BN_hex2bn(&ret->p, JPAKE_GROUP_P) == 0 || + BN_hex2bn(&ret->g, JPAKE_GROUP_G) == 0) + fatal("%s: BN_hex2bn", __func__); + /* Subgroup order is p/2 (p is a safe prime) */ + if ((ret->q = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + if (BN_rshift1(ret->q, ret->p) != 1) + fatal("%s: BN_rshift1", __func__); + + return ret; +} + +/* + * Generate uniformly distributed random number in range (1, high). + * Return number on success, NULL on failure. + */ +BIGNUM * +bn_rand_range_gt_one(const BIGNUM *high) +{ + BIGNUM *r, *tmp; + int success = -1; + + if ((tmp = BN_new()) == NULL) { + error("%s: BN_new", __func__); + return NULL; + } + if ((r = BN_new()) == NULL) { + error("%s: BN_new failed", __func__); + goto out; + } + if (BN_set_word(tmp, 2) != 1) { + error("%s: BN_set_word(tmp, 2)", __func__); + goto out; + } + if (BN_sub(tmp, high, tmp) == -1) { + error("%s: BN_sub failed (tmp = high - 2)", __func__); + goto out; + } + if (BN_rand_range(r, tmp) == -1) { + error("%s: BN_rand_range failed", __func__); + goto out; + } + if (BN_set_word(tmp, 2) != 1) { + error("%s: BN_set_word(tmp, 2)", __func__); + goto out; + } + if (BN_add(r, r, tmp) == -1) { + error("%s: BN_add failed (r = r + 2)", __func__); + goto out; + } + success = 0; + out: + BN_clear_free(tmp); + if (success == 0) + return r; + BN_clear_free(r); + return NULL; +} + +/* + * Hash contents of buffer 'b' with hash 'md'. Returns 0 on success, + * with digest via 'digestp' (caller to free) and length via 'lenp'. + * Returns -1 on failure. + */ +int +hash_buffer(const u_char *buf, u_int len, const EVP_MD *md, + u_char **digestp, u_int *lenp) +{ + u_char digest[EVP_MAX_MD_SIZE]; + u_int digest_len; + EVP_MD_CTX evp_md_ctx; + int success = -1; + + EVP_MD_CTX_init(&evp_md_ctx); + + if (EVP_DigestInit_ex(&evp_md_ctx, md, NULL) != 1) { + error("%s: EVP_DigestInit_ex", __func__); + goto out; + } + if (EVP_DigestUpdate(&evp_md_ctx, buf, len) != 1) { + error("%s: EVP_DigestUpdate", __func__); + goto out; + } + if (EVP_DigestFinal_ex(&evp_md_ctx, digest, &digest_len) != 1) { + error("%s: EVP_DigestFinal_ex", __func__); + goto out; + } + *digestp = xmalloc(digest_len); + *lenp = digest_len; + memcpy(*digestp, digest, *lenp); + success = 0; + out: + EVP_MD_CTX_cleanup(&evp_md_ctx); + bzero(digest, sizeof(digest)); + digest_len = 0; + return success; +} + +/* print formatted string followed by bignum */ +void +jpake_debug3_bn(const BIGNUM *n, const char *fmt, ...) +{ + char *out, *h; + va_list args; + + out = NULL; + va_start(args, fmt); + vasprintf(&out, fmt, args); + va_end(args); + if (out == NULL) + fatal("%s: vasprintf failed", __func__); + + if (n == NULL) + debug3("%s(null)", out); + else { + h = BN_bn2hex(n); + debug3("%s0x%s", out, h); + free(h); + } + free(out); +} + +/* print formatted string followed by buffer contents in hex */ +void +jpake_debug3_buf(const u_char *buf, u_int len, const char *fmt, ...) +{ + char *out, h[65]; + u_int i, j; + va_list args; + + out = NULL; + va_start(args, fmt); + vasprintf(&out, fmt, args); + va_end(args); + if (out == NULL) + fatal("%s: vasprintf failed", __func__); + + debug3("%s length %u%s", out, len, buf == NULL ? " (null)" : ""); + free(out); + if (buf == NULL) + return; + + *h = '\0'; + for (i = j = 0; i < len; i++) { + snprintf(h + j, sizeof(h) - j, "%02x", buf[i]); + j += 2; + if (j >= sizeof(h) - 1 || i == len - 1) { + debug3(" %s", h); + *h = '\0'; + j = 0; + } + } +} + +struct jpake_ctx * +jpake_new(void) +{ + struct jpake_ctx *ret; + + ret = xcalloc(1, sizeof(*ret)); + + ret->grp = jpake_default_group(); + + ret->s = ret->k = NULL; + ret->x1 = ret->x2 = ret->x3 = ret->x4 = NULL; + ret->g_x1 = ret->g_x2 = ret->g_x3 = ret->g_x4 = NULL; + ret->a = ret->b = NULL; + + ret->client_id = ret->server_id = NULL; + ret->h_k_cid_sessid = ret->h_k_sid_sessid = NULL; + + debug3("%s: alloc %p", __func__, ret); + + return ret; +} + + +void +jpake_free(struct jpake_ctx *pctx) +{ + debug3("%s: free %p", __func__, pctx); + +#define JPAKE_BN_CLEAR_FREE(v) \ + do { \ + if ((v) != NULL) { \ + BN_clear_free(v); \ + (v) = NULL; \ + } \ + } while (0) +#define JPAKE_BUF_CLEAR_FREE(v, l) \ + do { \ + if ((v) != NULL) { \ + bzero((v), (l)); \ + xfree(v); \ + (v) = NULL; \ + (l) = 0; \ + } \ + } while (0) + + JPAKE_BN_CLEAR_FREE(pctx->s); + JPAKE_BN_CLEAR_FREE(pctx->k); + JPAKE_BN_CLEAR_FREE(pctx->x1); + JPAKE_BN_CLEAR_FREE(pctx->x2); + JPAKE_BN_CLEAR_FREE(pctx->x3); + JPAKE_BN_CLEAR_FREE(pctx->x4); + JPAKE_BN_CLEAR_FREE(pctx->g_x1); + JPAKE_BN_CLEAR_FREE(pctx->g_x2); + JPAKE_BN_CLEAR_FREE(pctx->g_x3); + JPAKE_BN_CLEAR_FREE(pctx->g_x4); + JPAKE_BN_CLEAR_FREE(pctx->a); + JPAKE_BN_CLEAR_FREE(pctx->b); + + JPAKE_BUF_CLEAR_FREE(pctx->client_id, pctx->client_id_len); + JPAKE_BUF_CLEAR_FREE(pctx->server_id, pctx->server_id_len); + JPAKE_BUF_CLEAR_FREE(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); + JPAKE_BUF_CLEAR_FREE(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + +#undef JPAKE_BN_CLEAR_FREE +#undef JPAKE_BUF_CLEAR_FREE + + bzero(pctx, sizeof(pctx)); + xfree(pctx); +} + +/* dump entire jpake_ctx. NB. includes private values! */ +void +jpake_dump(struct jpake_ctx *pctx, const char *fmt, ...) +{ + char *out; + va_list args; + + out = NULL; + va_start(args, fmt); + vasprintf(&out, fmt, args); + va_end(args); + if (out == NULL) + fatal("%s: vasprintf failed", __func__); + + debug3("%s: %s (ctx at %p)", __func__, out, pctx); + if (pctx == NULL) { + free(out); + return; + } + +#define JPAKE_DUMP_BN(a) do { \ + if ((a) != NULL) \ + JPAKE_DEBUG_BN(((a), "%s = ", #a)); \ + } while (0) +#define JPAKE_DUMP_BUF(a, b) do { \ + if ((a) != NULL) \ + JPAKE_DEBUG_BUF((a, b, "%s", #a)); \ + } while (0) + + JPAKE_DUMP_BN(pctx->s); + JPAKE_DUMP_BN(pctx->k); + JPAKE_DUMP_BN(pctx->x1); + JPAKE_DUMP_BN(pctx->x2); + JPAKE_DUMP_BN(pctx->x3); + JPAKE_DUMP_BN(pctx->x4); + JPAKE_DUMP_BN(pctx->g_x1); + JPAKE_DUMP_BN(pctx->g_x2); + JPAKE_DUMP_BN(pctx->g_x3); + JPAKE_DUMP_BN(pctx->g_x4); + JPAKE_DUMP_BN(pctx->a); + JPAKE_DUMP_BN(pctx->b); + + JPAKE_DUMP_BUF(pctx->client_id, pctx->client_id_len); + JPAKE_DUMP_BUF(pctx->server_id, pctx->server_id_len); + JPAKE_DUMP_BUF(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); + JPAKE_DUMP_BUF(pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + + debug3("%s: %s done", __func__, out); + free(out); +} + +/* Shared parts of step 1 exchange calculation */ +void +jpake_step1(struct jpake_group *grp, + u_char **id, u_int *id_len, + BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, + u_char **priv1_proof, u_int *priv1_proof_len, + u_char **priv2_proof, u_int *priv2_proof_len) +{ + BN_CTX *bn_ctx; + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + + /* Random nonce to prevent replay */ + *id = xmalloc(KZP_ID_LEN); + *id_len = KZP_ID_LEN; + arc4random_buf(*id, *id_len); + + /* + * x1/x3 is a random element of Zq + * x2/x4 is a random element of Z*q + * We also exclude [1] from x1/x3 candidates and [0, 1] from + * x2/x4 candiates to avoid possible degeneracy (i.e. g^0, g^1). + */ + if ((*priv1 = bn_rand_range_gt_one(grp->q)) == NULL || + (*priv2 = bn_rand_range_gt_one(grp->q)) == NULL) + fatal("%s: bn_rand_range_gt_one", __func__); + + /* + * client: g_x1 = g^x1 mod p / server: g_x3 = g^x3 mod p + * client: g_x2 = g^x2 mod p / server: g_x4 = g^x4 mod p + */ + if ((*g_priv1 = BN_new()) == NULL || + (*g_priv2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + if (BN_mod_exp(*g_priv1, grp->g, *priv1, grp->p, bn_ctx) == -1) + fatal("%s: BN_mod_exp", __func__); + if (BN_mod_exp(*g_priv2, grp->g, *priv2, grp->p, bn_ctx) == -1) + fatal("%s: BN_mod_exp", __func__); + + /* Generate proofs for holding x1/x3 and x2/x4 */ + if (schnorr_sign(grp->p, grp->q, grp->g, + *priv1, *g_priv1, *id, *id_len, + priv1_proof, priv1_proof_len) != 0) + fatal("%s: schnorr_sign", __func__); + if (schnorr_sign(grp->p, grp->q, grp->g, + *priv2, *g_priv2, *id, *id_len, + priv2_proof, priv2_proof_len) != 0) + fatal("%s: schnorr_sign", __func__); + + BN_CTX_free(bn_ctx); +} + +/* Shared parts of step 2 exchange calculation */ +void +jpake_step2(struct jpake_group *grp, BIGNUM *s, + BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, + const u_char *theirid, u_int theirid_len, + const u_char *myid, u_int myid_len, + const u_char *theirpub1_proof, u_int theirpub1_proof_len, + const u_char *theirpub2_proof, u_int theirpub2_proof_len, + BIGNUM **newpub, + u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) +{ + BN_CTX *bn_ctx; + BIGNUM *tmp, *exponent; + + /* Validate peer's step 1 values */ + if (BN_cmp(theirpub1, BN_value_one()) <= 0) + fatal("%s: theirpub1 <= 1", __func__); + if (BN_cmp(theirpub2, BN_value_one()) <= 0) + fatal("%s: theirpub2 <= 1", __func__); + + if (schnorr_verify(grp->p, grp->q, grp->g, theirpub1, + theirid, theirid_len, theirpub1_proof, theirpub1_proof_len) != 1) + fatal("%s: schnorr_verify theirpub1 failed", __func__); + if (schnorr_verify(grp->p, grp->q, grp->g, theirpub2, + theirid, theirid_len, theirpub2_proof, theirpub2_proof_len) != 1) + fatal("%s: schnorr_verify theirpub2 failed", __func__); + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + + if ((*newpub = BN_new()) == NULL || + (tmp = BN_new()) == NULL || + (exponent = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* + * client: exponent = x2 * s mod p + * server: exponent = x4 * s mod p + */ + if (BN_mod_mul(exponent, mypriv2, s, grp->q, bn_ctx) != 1) + fatal("%s: BN_mod_mul (exponent = mypriv2 * s mod p)", + __func__); + + /* + * client: tmp = g^(x1 + x3 + x4) mod p + * server: tmp = g^(x1 + x2 + x3) mod p + */ + if (BN_mod_mul(tmp, mypub1, theirpub1, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = mypub1 * theirpub1 mod p)", + __func__); + if (BN_mod_mul(tmp, tmp, theirpub2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * theirpub2 mod p)", __func__); + + /* + * client: a = tmp^exponent = g^((x1+x3+x4) * x2 * s) mod p + * server: b = tmp^exponent = g^((x1+x2+x3) * x4 * s) mod p + */ + if (BN_mod_exp(*newpub, tmp, exponent, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (newpub = tmp^exponent mod p)", __func__); + + JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); + JPAKE_DEBUG_BN((exponent, "%s: exponent = ", __func__)); + + /* Note the generator here is 'tmp', not g */ + if (schnorr_sign(grp->p, grp->q, tmp, exponent, *newpub, + myid, myid_len, + newpub_exponent_proof, newpub_exponent_proof_len) != 0) + fatal("%s: schnorr_sign newpub", __func__); + + BN_clear_free(tmp); /* XXX stash for later use? */ + BN_clear_free(exponent); /* XXX stash for later use? (yes, in conf) */ + + BN_CTX_free(bn_ctx); +} + +/* Confirmation hash calculation */ +void +jpake_confirm_hash(const BIGNUM *k, + const u_char *endpoint_id, u_int endpoint_id_len, + const u_char *sess_id, u_int sess_id_len, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + Buffer b; + + /* + * Calculate confirmation proof: + * client: H(k || client_id || session_id) + * server: H(k || server_id || session_id) + */ + buffer_init(&b); + buffer_put_bignum2(&b, k); + buffer_put_string(&b, endpoint_id, endpoint_id_len); + buffer_put_string(&b, sess_id, sess_id_len); + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), + confirm_hash, confirm_hash_len) != 0) + fatal("%s: hash_buffer", __func__); + buffer_free(&b); +} + +/* Shared parts of key derivation and confirmation calculation */ +void +jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val, + BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, + BIGNUM *theirpub1, BIGNUM *theirpub2, + const u_char *my_id, u_int my_id_len, + const u_char *their_id, u_int their_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, + BIGNUM **k, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + BN_CTX *bn_ctx; + BIGNUM *tmp; + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + if ((tmp = BN_new()) == NULL || + (*k = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Validate step 2 values */ + if (BN_cmp(step2_val, BN_value_one()) <= 0) + fatal("%s: step2_val <= 1", __func__); + + /* + * theirpriv2_s_proof is calculated with a different generator: + * tmp = g^(mypriv1+mypriv2+theirpub1) = g^mypub1*g^mypub2*g^theirpub1 + * Calculate it here so we can check the signature. + */ + if (BN_mod_mul(tmp, mypub1, mypub2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = mypub1 * mypub2 mod p)", __func__); + if (BN_mod_mul(tmp, tmp, theirpub1, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * theirpub1 mod p)", __func__); + + JPAKE_DEBUG_BN((tmp, "%s: tmp = ", __func__)); + + if (schnorr_verify(grp->p, grp->q, tmp, step2_val, + their_id, their_id_len, + theirpriv2_s_proof, theirpriv2_s_proof_len) != 1) + fatal("%s: schnorr_verify theirpriv2_s_proof failed", __func__); + + /* + * Derive shared key: + * client: k = (b / g^(x2*x4*s))^x2 = g^((x1+x3)*x2*x4*s) + * server: k = (a / g^(x2*x4*s))^x4 = g^((x1+x3)*x2*x4*s) + * + * Computed as: + * client: k = (g_x4^(q - (x2 * s)) * b)^x2 mod p + * server: k = (g_x2^(q - (x4 * s)) * b)^x4 mod p + */ + if (BN_mul(tmp, mypriv2, s, bn_ctx) != 1) + fatal("%s: BN_mul (tmp = mypriv2 * s)", __func__); + if (BN_mod_sub(tmp, grp->q, tmp, grp->q, bn_ctx) != 1) + fatal("%s: BN_mod_sub (tmp = q - tmp mod q)", __func__); + if (BN_mod_exp(tmp, theirpub2, tmp, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_exp (tmp = theirpub2^tmp) mod p", __func__); + if (BN_mod_mul(tmp, tmp, step2_val, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_mul (tmp = tmp * step2_val) mod p", __func__); + if (BN_mod_exp(*k, tmp, mypriv2, grp->p, bn_ctx) != 1) + fatal("%s: BN_mod_exp (k = tmp^mypriv2) mod p", __func__); + + BN_CTX_free(bn_ctx); + BN_clear_free(tmp); + + jpake_confirm_hash(*k, my_id, my_id_len, sess_id, sess_id_len, + confirm_hash, confirm_hash_len); +} + +/* + * Calculate and check confirmation hash from peer. Returns 1 on success + * 0 on failure/mismatch. + */ +int +jpake_check_confirm(const BIGNUM *k, + const u_char *peer_id, u_int peer_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) +{ + u_char *expected_confirm_hash; + u_int expected_confirm_hash_len; + int success = 0; + + /* Calculate and verify expected confirmation hash */ + jpake_confirm_hash(k, peer_id, peer_id_len, sess_id, sess_id_len, + &expected_confirm_hash, &expected_confirm_hash_len); + + JPAKE_DEBUG_BUF((expected_confirm_hash, expected_confirm_hash_len, + "%s: expected confirm hash", __func__)); + JPAKE_DEBUG_BUF((peer_confirm_hash, peer_confirm_hash_len, + "%s: received confirm hash", __func__)); + + if (peer_confirm_hash_len != expected_confirm_hash_len) + error("%s: confirmation length mismatch (my %u them %u)", + __func__, expected_confirm_hash_len, peer_confirm_hash_len); + else if (memcmp(peer_confirm_hash, expected_confirm_hash, + expected_confirm_hash_len) == 0) + success = 1; + bzero(expected_confirm_hash, expected_confirm_hash_len); + xfree(expected_confirm_hash); + debug3("%s: success = %d", __func__, success); + return success; +} + +/* XXX main() function with tests */ + +#endif /* JPAKE */ + diff --git a/jpake.h b/jpake.h new file mode 100644 index 000000000000..a3d800cd3c41 --- /dev/null +++ b/jpake.h @@ -0,0 +1,134 @@ +/* $OpenBSD: jpake.h,v 1.1 2008/11/04 08:22:13 djm Exp $ */ +/* + * Copyright (c) 2008 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef JPAKE_H +#define JPAKE_H + +#include + +#include + +/* Set JPAKE_DEBUG in CFLAGS for privacy-violating debugging */ +#ifndef JPAKE_DEBUG +# define JPAKE_DEBUG_BN(a) +# define JPAKE_DEBUG_BUF(a) +# define JPAKE_DEBUG_CTX(a) +#else +# define JPAKE_DEBUG_BN(a) jpake_debug3_bn a +# define JPAKE_DEBUG_BUF(a) jpake_debug3_buf a +# define JPAKE_DEBUG_CTX(a) jpake_dump a +#endif /* SCHNORR_DEBUG */ + +struct jpake_group { + BIGNUM *p, *q, *g; +}; + +#define KZP_ID_LEN 16 /* Length of client and server IDs */ + +struct jpake_ctx { + /* Parameters */ + struct jpake_group *grp; + + /* Private values shared by client and server */ + BIGNUM *s; /* Secret (salted, crypted password) */ + BIGNUM *k; /* Derived key */ + + /* Client private values (NULL for server) */ + BIGNUM *x1; /* random in Zq */ + BIGNUM *x2; /* random in Z*q */ + + /* Server private values (NULL for server) */ + BIGNUM *x3; /* random in Zq */ + BIGNUM *x4; /* random in Z*q */ + + /* Step 1: C->S */ + u_char *client_id; /* Anti-replay nonce */ + u_int client_id_len; + BIGNUM *g_x1; /* g^x1 */ + BIGNUM *g_x2; /* g^x2 */ + + /* Step 1: S->C */ + u_char *server_id; /* Anti-replay nonce */ + u_int server_id_len; + BIGNUM *g_x3; /* g^x3 */ + BIGNUM *g_x4; /* g^x4 */ + + /* Step 2: C->S */ + BIGNUM *a; /* g^((x1+x3+x4)*x2*s) */ + + /* Step 2: S->C */ + BIGNUM *b; /* g^((x1+x2+x3)*x4*s) */ + + /* Confirmation: C->S */ + u_char *h_k_cid_sessid; /* H(k || client_id || session_id) */ + u_int h_k_cid_sessid_len; + + /* Confirmation: S->C */ + u_char *h_k_sid_sessid; /* H(k || server_id || session_id) */ + u_int h_k_sid_sessid_len; +}; + +/* jpake.c */ +struct jpake_group *jpake_default_group(void); +BIGNUM *bn_rand_range_gt_one(const BIGNUM *high); +int hash_buffer(const u_char *, u_int, const EVP_MD *, u_char **, u_int *); +void jpake_debug3_bn(const BIGNUM *, const char *, ...) + __attribute__((__nonnull__ (2))) + __attribute__((format(printf, 2, 3))); +void jpake_debug3_buf(const u_char *, u_int, const char *, ...) + __attribute__((__nonnull__ (3))) + __attribute__((format(printf, 3, 4))); +void jpake_dump(struct jpake_ctx *, const char *, ...) + __attribute__((__nonnull__ (2))) + __attribute__((format(printf, 2, 3))); +struct jpake_ctx *jpake_new(void); +void jpake_free(struct jpake_ctx *); + +void jpake_step1(struct jpake_group *, u_char **, u_int *, + BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **, + u_char **, u_int *, u_char **, u_int *); + +void jpake_step2(struct jpake_group *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); + +void jpake_confirm_hash(const BIGNUM *, + const u_char *, u_int, + const u_char *, u_int, + u_char **, u_int *); + +void jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); + +int jpake_check_confirm(const BIGNUM *, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int); + +/* schnorr.c */ +int schnorr_sign(const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const BIGNUM *, const u_char *, u_int , + u_char **, u_int *); +int schnorr_verify(const BIGNUM *, const BIGNUM *, const BIGNUM *, + const BIGNUM *, const u_char *, u_int, + const u_char *, u_int); + +#endif /* JPAKE_H */ + diff --git a/kex.c b/kex.c index 332fadf6e20b..48b54f5f7341 100644 --- a/kex.c +++ b/kex.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kex.c,v 1.79 2007/06/05 06:52:37 djm Exp $ */ +/* $OpenBSD: kex.c,v 1.80 2008/09/06 12:24:13 djm Exp $ */ /* * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. * diff --git a/kexgexs.c b/kexgexs.c index a037f57f2814..76a0f8ca7164 100644 --- a/kexgexs.c +++ b/kexgexs.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexgexs.c,v 1.10 2006/11/06 21:25:28 markus Exp $ */ +/* $OpenBSD: kexgexs.c,v 1.11 2009/01/01 21:17:36 djm Exp $ */ /* * Copyright (c) 2000 Niels Provos. All rights reserved. * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -56,7 +56,8 @@ kexgex_server(Kex *kex) DH *dh; u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL; u_int sbloblen, klen, slen, hashlen; - int min = -1, max = -1, nbits = -1, type, kout; + int omin = -1, min = -1, omax = -1, max = -1, onbits = -1, nbits = -1; + int type, kout; if (kex->load_host_key == NULL) fatal("Cannot load hostkey"); @@ -68,27 +69,29 @@ kexgex_server(Kex *kex) switch (type) { case SSH2_MSG_KEX_DH_GEX_REQUEST: debug("SSH2_MSG_KEX_DH_GEX_REQUEST received"); - min = packet_get_int(); - nbits = packet_get_int(); - max = packet_get_int(); + omin = min = packet_get_int(); + onbits = nbits = packet_get_int(); + omax = max = packet_get_int(); min = MAX(DH_GRP_MIN, min); max = MIN(DH_GRP_MAX, max); + nbits = MAX(DH_GRP_MIN, nbits); + nbits = MIN(DH_GRP_MAX, nbits); break; case SSH2_MSG_KEX_DH_GEX_REQUEST_OLD: debug("SSH2_MSG_KEX_DH_GEX_REQUEST_OLD received"); - nbits = packet_get_int(); - min = DH_GRP_MIN; - max = DH_GRP_MAX; + onbits = nbits = packet_get_int(); /* unused for old GEX */ + omin = min = DH_GRP_MIN; + omax = max = DH_GRP_MAX; break; default: fatal("protocol error during kex, no DH_GEX_REQUEST: %d", type); } packet_check_eom(); - if (max < min || nbits < min || max < nbits) + if (omax < omin || onbits < omin || omax < onbits) fatal("DH_GEX_REQUEST, bad parameters: %d !< %d !< %d", - min, nbits, max); + omin, onbits, omax); /* Contact privileged parent */ dh = PRIVSEP(choose_dh(min, nbits, max)); @@ -149,7 +152,7 @@ kexgex_server(Kex *kex) key_to_blob(server_host_key, &server_host_key_blob, &sbloblen); if (type == SSH2_MSG_KEX_DH_GEX_REQUEST_OLD) - min = max = -1; + omin = min = omax = max = -1; /* calc H */ kexgex_hash( @@ -159,7 +162,7 @@ kexgex_server(Kex *kex) buffer_ptr(&kex->peer), buffer_len(&kex->peer), buffer_ptr(&kex->my), buffer_len(&kex->my), server_host_key_blob, sbloblen, - min, nbits, max, + omin, onbits, omax, dh->p, dh->g, dh_client_pub, dh->pub_key, diff --git a/key.c b/key.c index 2ea13d27d1b1..3e17da601621 100644 --- a/key.c +++ b/key.c @@ -1,4 +1,4 @@ -/* $OpenBSD: key.c,v 1.78 2008/07/07 23:32:51 stevesk Exp $ */ +/* $OpenBSD: key.c,v 1.80 2008/10/10 05:00:12 stevesk Exp $ */ /* * read_bignum(): * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -369,7 +369,8 @@ key_fingerprint_randomart(u_char *dgst_raw, u_int dgst_raw_len, const Key *k) y = MIN(y, FLDSIZE_Y - 1); /* augment the field */ - field[x][y]++; + if (field[x][y] < len - 2) + field[x][y]++; input = input >> 2; } } @@ -427,7 +428,7 @@ key_fingerprint(const Key *k, enum fp_type dgst_type, enum fp_rep dgst_rep) retval = key_fingerprint_randomart(dgst_raw, dgst_raw_len, k); break; default: - fatal("key_fingerprint_ex: bad digest representation %d", + fatal("key_fingerprint: bad digest representation %d", dgst_rep); break; } diff --git a/loginrec.c b/loginrec.c index b41114198721..f4af06736018 100644 --- a/loginrec.c +++ b/loginrec.c @@ -1456,25 +1456,14 @@ syslogin_write_entry(struct logininfo *li) **/ #ifdef USE_LASTLOG -#define LL_FILE 1 -#define LL_DIR 2 -#define LL_OTHER 3 - -static void -lastlog_construct(struct logininfo *li, struct lastlog *last) -{ - /* clear the structure */ - memset(last, '\0', sizeof(*last)); - - line_stripname(last->ll_line, li->line, sizeof(last->ll_line)); - strlcpy(last->ll_host, li->hostname, - MIN_SIZEOF(last->ll_host, li->hostname)); - last->ll_time = li->tv_sec; -} +#if !defined(LASTLOG_WRITE_PUTUTXLINE) || !defined(HAVE_GETLASTLOGXBYNAME) +/* open the file (using filemode) and seek to the login entry */ static int -lastlog_filetype(char *filename) +lastlog_openseek(struct logininfo *li, int *fd, int filemode) { + off_t offset; + char lastlog_file[1024]; struct stat st; if (stat(LASTLOG_FILE, &st) != 0) { @@ -1482,34 +1471,12 @@ lastlog_filetype(char *filename) LASTLOG_FILE, strerror(errno)); return (0); } - if (S_ISDIR(st.st_mode)) - return (LL_DIR); - else if (S_ISREG(st.st_mode)) - return (LL_FILE); - else - return (LL_OTHER); -} - - -/* open the file (using filemode) and seek to the login entry */ -static int -lastlog_openseek(struct logininfo *li, int *fd, int filemode) -{ - off_t offset; - int type; - char lastlog_file[1024]; - - type = lastlog_filetype(LASTLOG_FILE); - switch (type) { - case LL_FILE: - strlcpy(lastlog_file, LASTLOG_FILE, - sizeof(lastlog_file)); - break; - case LL_DIR: + if (S_ISDIR(st.st_mode)) { snprintf(lastlog_file, sizeof(lastlog_file), "%s/%s", LASTLOG_FILE, li->username); - break; - default: + } else if (S_ISREG(st.st_mode)) { + strlcpy(lastlog_file, LASTLOG_FILE, sizeof(lastlog_file)); + } else { logit("%s: %.100s is not a file or directory!", __func__, LASTLOG_FILE); return (0); @@ -1522,7 +1489,7 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) return (0); } - if (type == LL_FILE) { + if (S_ISREG(st.st_mode)) { /* find this uid's offset in the lastlog file */ offset = (off_t) ((long)li->uid * sizeof(struct lastlog)); @@ -1535,52 +1502,74 @@ lastlog_openseek(struct logininfo *li, int *fd, int filemode) return (1); } +#endif /* !LASTLOG_WRITE_PUTUTXLINE || !HAVE_GETLASTLOGXBYNAME */ -static int -lastlog_perform_login(struct logininfo *li) -{ - struct lastlog last; - int fd; - - /* create our struct lastlog */ - lastlog_construct(li, &last); - - if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) - return (0); - - /* write the entry */ - if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { - close(fd); - logit("%s: Error writing to %s: %s", __func__, - LASTLOG_FILE, strerror(errno)); - return (0); - } - - close(fd); - return (1); -} - +#ifdef LASTLOG_WRITE_PUTUTXLINE int lastlog_write_entry(struct logininfo *li) { switch(li->type) { case LTYPE_LOGIN: - return (lastlog_perform_login(li)); + return 1; /* lastlog written by pututxline */ + default: + logit("lastlog_write_entry: Invalid type field"); + return 0; + } +} +#else /* LASTLOG_WRITE_PUTUTXLINE */ +int +lastlog_write_entry(struct logininfo *li) +{ + struct lastlog last; + int fd; + + switch(li->type) { + case LTYPE_LOGIN: + /* create our struct lastlog */ + memset(&last, '\0', sizeof(last)); + line_stripname(last.ll_line, li->line, sizeof(last.ll_line)); + strlcpy(last.ll_host, li->hostname, + MIN_SIZEOF(last.ll_host, li->hostname)); + last.ll_time = li->tv_sec; + + if (!lastlog_openseek(li, &fd, O_RDWR|O_CREAT)) + return (0); + + /* write the entry */ + if (atomicio(vwrite, fd, &last, sizeof(last)) != sizeof(last)) { + close(fd); + logit("%s: Error writing to %s: %s", __func__, + LASTLOG_FILE, strerror(errno)); + return (0); + } + + close(fd); + return (1); default: logit("%s: Invalid type field", __func__); return (0); } } +#endif /* LASTLOG_WRITE_PUTUTXLINE */ -static void -lastlog_populate_entry(struct logininfo *li, struct lastlog *last) +#ifdef HAVE_GETLASTLOGXBYNAME +int +lastlog_get_entry(struct logininfo *li) { - line_fullname(li->line, last->ll_line, sizeof(li->line)); - strlcpy(li->hostname, last->ll_host, - MIN_SIZEOF(li->hostname, last->ll_host)); - li->tv_sec = last->ll_time; -} + struct lastlogx l, *ll; + if ((ll = getlastlogxbyname(li->username, &l)) == NULL) { + memset(&l, '\0', sizeof(l)); + ll = &l; + } + line_fullname(li->line, ll->ll_line, sizeof(li->line)); + strlcpy(li->hostname, ll->ll_host, + MIN_SIZEOF(li->hostname, ll->ll_host)); + li->tv_sec = ll->ll_tv.tv_sec; + li->tv_usec = ll->ll_tv.tv_usec; + return (1); +} +#else /* HAVE_GETLASTLOGXBYNAME */ int lastlog_get_entry(struct logininfo *li) { @@ -1598,7 +1587,10 @@ lastlog_get_entry(struct logininfo *li) memset(&last, '\0', sizeof(last)); /* FALLTHRU */ case sizeof(last): - lastlog_populate_entry(li, &last); + line_fullname(li->line, last.ll_line, sizeof(li->line)); + strlcpy(li->hostname, last.ll_host, + MIN_SIZEOF(li->hostname, last.ll_host)); + li->tv_sec = last.ll_time; return (1); case -1: error("%s: Error reading from %s: %s", __func__, @@ -1613,6 +1605,7 @@ lastlog_get_entry(struct logininfo *li) /* NOTREACHED */ return (0); } +#endif /* HAVE_GETLASTLOGXBYNAME */ #endif /* USE_LASTLOG */ #ifdef USE_BTMP diff --git a/misc.c b/misc.c index 8b303f16f772..143dbf0e2d01 100644 --- a/misc.c +++ b/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.69 2008/06/13 01:38:23 dtucker Exp $ */ +/* $OpenBSD: misc.c,v 1.71 2009/02/21 19:32:04 tobias Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005,2006 Damien Miller. All rights reserved. @@ -221,23 +221,19 @@ pwcopy(struct passwd *pw) /* * Convert ASCII string to TCP/IP port number. - * Port must be >0 and <=65535. - * Return 0 if invalid. + * Port must be >=0 and <=65535. + * Return -1 if invalid. */ int a2port(const char *s) { - long port; - char *endp; + long long port; + const char *errstr; - errno = 0; - port = strtol(s, &endp, 0); - if (s == endp || *endp != '\0' || - (errno == ERANGE && (port == LONG_MIN || port == LONG_MAX)) || - port <= 0 || port > 65535) - return 0; - - return port; + port = strtonum(s, 0, 65535, &errstr); + if (errstr != NULL) + return -1; + return (int)port; } int @@ -718,7 +714,8 @@ sanitise_stdfd(void) int nullfd, dupfd; if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { - fprintf(stderr, "Couldn't open /dev/null: %s", strerror(errno)); + fprintf(stderr, "Couldn't open /dev/null: %s\n", + strerror(errno)); exit(1); } while (++dupfd <= 2) { @@ -726,7 +723,7 @@ sanitise_stdfd(void) if (fcntl(dupfd, F_GETFL, 0) >= 0) continue; if (dup2(nullfd, dupfd) == -1) { - fprintf(stderr, "dup2: %s", strerror(errno)); + fprintf(stderr, "dup2: %s\n", strerror(errno)); exit(1); } } diff --git a/moduli.0 b/moduli.0 index 55a315fab3fc..d4c0d4e67dcc 100644 --- a/moduli.0 +++ b/moduli.0 @@ -69,4 +69,4 @@ SEE ALSO Diffie-Hellman Group Exchange for the Secure Shell (SSH) Transport Layer Protocol, RFC 4419, 2006. -OpenBSD 4.4 June 26, 2008 2 +OpenBSD 4.5 June 26, 2008 2 diff --git a/monitor.c b/monitor.c index 73cf6bc9b969..f57e74ba5ced 100644 --- a/monitor.c +++ b/monitor.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.c,v 1.99 2008/07/10 18:08:11 markus Exp $ */ +/* $OpenBSD: monitor.c,v 1.101 2009/02/12 03:26:22 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -87,6 +87,7 @@ #include "misc.h" #include "compat.h" #include "ssh2.h" +#include "jpake.h" #ifdef GSSAPI static Gssctxt *gsscontext = NULL; @@ -149,6 +150,11 @@ int mm_answer_rsa_challenge(int, Buffer *); int mm_answer_rsa_response(int, Buffer *); int mm_answer_sesskey(int, Buffer *); int mm_answer_sessid(int, Buffer *); +int mm_answer_jpake_get_pwdata(int, Buffer *); +int mm_answer_jpake_step1(int, Buffer *); +int mm_answer_jpake_step2(int, Buffer *); +int mm_answer_jpake_key_confirm(int, Buffer *); +int mm_answer_jpake_check_confirm(int, Buffer *); #ifdef USE_PAM int mm_answer_pam_start(int, Buffer *); @@ -233,6 +239,13 @@ struct mon_table mon_dispatch_proto20[] = { {MONITOR_REQ_GSSSTEP, MON_ISAUTH, mm_answer_gss_accept_ctx}, {MONITOR_REQ_GSSUSEROK, MON_AUTH, mm_answer_gss_userok}, {MONITOR_REQ_GSSCHECKMIC, MON_ISAUTH, mm_answer_gss_checkmic}, +#endif +#ifdef JPAKE + {MONITOR_REQ_JPAKE_GET_PWDATA, MON_ONCE, mm_answer_jpake_get_pwdata}, + {MONITOR_REQ_JPAKE_STEP1, MON_ISAUTH, mm_answer_jpake_step1}, + {MONITOR_REQ_JPAKE_STEP2, MON_ONCE, mm_answer_jpake_step2}, + {MONITOR_REQ_JPAKE_KEY_CONFIRM, MON_ONCE, mm_answer_jpake_key_confirm}, + {MONITOR_REQ_JPAKE_CHECK_CONFIRM, MON_AUTH, mm_answer_jpake_check_confirm}, #endif {0, 0, NULL} }; @@ -379,6 +392,15 @@ monitor_child_preauth(Authctxt *_authctxt, struct monitor *pmonitor) if (!authenticated) authctxt->failures++; } +#ifdef JPAKE + /* Cleanup JPAKE context after authentication */ + if (ent->flags & MON_AUTHDECIDE) { + if (authctxt->jpake_ctx != NULL) { + jpake_free(authctxt->jpake_ctx); + authctxt->jpake_ctx = NULL; + } + } +#endif } if (!authctxt->valid) @@ -1478,7 +1500,9 @@ mm_answer_rsa_challenge(int sock, Buffer *m) fatal("%s: key type mismatch", __func__); if ((key = key_from_blob(blob, blen)) == NULL) fatal("%s: received bad key", __func__); - + if (key->type != KEY_RSA) + fatal("%s: received bad key type %d", __func__, key->type); + key->type = KEY_RSA1; if (ssh1_challenge) BN_clear_free(ssh1_challenge); ssh1_challenge = auth_rsa_generate_challenge(key); @@ -1969,3 +1993,206 @@ mm_answer_gss_userok(int sock, Buffer *m) return (authenticated); } #endif /* GSSAPI */ + +#ifdef JPAKE +int +mm_answer_jpake_step1(int sock, Buffer *m) +{ + struct jpake_ctx *pctx; + u_char *x3_proof, *x4_proof; + u_int x3_proof_len, x4_proof_len; + + if (!options.zero_knowledge_password_authentication) + fatal("zero_knowledge_password_authentication disabled"); + + if (authctxt->jpake_ctx != NULL) + fatal("%s: authctxt->jpake_ctx already set (%p)", + __func__, authctxt->jpake_ctx); + authctxt->jpake_ctx = pctx = jpake_new(); + + jpake_step1(pctx->grp, + &pctx->server_id, &pctx->server_id_len, + &pctx->x3, &pctx->x4, &pctx->g_x3, &pctx->g_x4, + &x3_proof, &x3_proof_len, + &x4_proof, &x4_proof_len); + + JPAKE_DEBUG_CTX((pctx, "step1 done in %s", __func__)); + + buffer_clear(m); + + buffer_put_string(m, pctx->server_id, pctx->server_id_len); + buffer_put_bignum2(m, pctx->g_x3); + buffer_put_bignum2(m, pctx->g_x4); + buffer_put_string(m, x3_proof, x3_proof_len); + buffer_put_string(m, x4_proof, x4_proof_len); + + debug3("%s: sending step1", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_STEP1, m); + + bzero(x3_proof, x3_proof_len); + bzero(x4_proof, x4_proof_len); + xfree(x3_proof); + xfree(x4_proof); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_GET_PWDATA, 1); + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 0); + + return 0; +} + +int +mm_answer_jpake_get_pwdata(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + char *hash_scheme, *salt; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + auth2_jpake_get_pwdata(authctxt, &pctx->s, &hash_scheme, &salt); + + buffer_clear(m); + /* pctx->s is sensitive, not returned to slave */ + buffer_put_cstring(m, hash_scheme); + buffer_put_cstring(m, salt); + + debug3("%s: sending pwdata", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_GET_PWDATA, m); + + bzero(hash_scheme, strlen(hash_scheme)); + bzero(salt, strlen(salt)); + xfree(hash_scheme); + xfree(salt); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP2, 1); + + return 0; +} + +int +mm_answer_jpake_step2(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x1_proof, *x2_proof, *x4_s_proof; + u_int x1_proof_len, x2_proof_len, x4_s_proof_len; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + if ((pctx->g_x1 = BN_new()) == NULL || + (pctx->g_x2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + buffer_get_bignum2(m, pctx->g_x1); + buffer_get_bignum2(m, pctx->g_x2); + pctx->client_id = buffer_get_string(m, &pctx->client_id_len); + x1_proof = buffer_get_string(m, &x1_proof_len); + x2_proof = buffer_get_string(m, &x2_proof_len); + + jpake_step2(pctx->grp, pctx->s, pctx->g_x3, + pctx->g_x1, pctx->g_x2, pctx->x4, + pctx->client_id, pctx->client_id_len, + pctx->server_id, pctx->server_id_len, + x1_proof, x1_proof_len, + x2_proof, x2_proof_len, + &pctx->b, + &x4_s_proof, &x4_s_proof_len); + + JPAKE_DEBUG_CTX((pctx, "step2 done in %s", __func__)); + + bzero(x1_proof, x1_proof_len); + bzero(x2_proof, x2_proof_len); + xfree(x1_proof); + xfree(x2_proof); + + buffer_clear(m); + + buffer_put_bignum2(m, pctx->b); + buffer_put_string(m, x4_s_proof, x4_s_proof_len); + + debug3("%s: sending step2", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_STEP2, m); + + bzero(x4_s_proof, x4_s_proof_len); + xfree(x4_s_proof); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_KEY_CONFIRM, 1); + + return 0; +} + +int +mm_answer_jpake_key_confirm(int sock, Buffer *m) +{ + struct jpake_ctx *pctx = authctxt->jpake_ctx; + u_char *x2_s_proof; + u_int x2_s_proof_len; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + if ((pctx->a = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + buffer_get_bignum2(m, pctx->a); + x2_s_proof = buffer_get_string(m, &x2_s_proof_len); + + jpake_key_confirm(pctx->grp, pctx->s, pctx->a, + pctx->x4, pctx->g_x3, pctx->g_x4, pctx->g_x1, pctx->g_x2, + pctx->server_id, pctx->server_id_len, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + x2_s_proof, x2_s_proof_len, + &pctx->k, + &pctx->h_k_sid_sessid, &pctx->h_k_sid_sessid_len); + + JPAKE_DEBUG_CTX((pctx, "key_confirm done in %s", __func__)); + + bzero(x2_s_proof, x2_s_proof_len); + buffer_clear(m); + + /* pctx->k is sensitive, not sent */ + buffer_put_string(m, pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len); + + debug3("%s: sending confirmation hash", __func__); + mm_request_send(sock, MONITOR_ANS_JPAKE_KEY_CONFIRM, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_CHECK_CONFIRM, 1); + + return 0; +} + +int +mm_answer_jpake_check_confirm(int sock, Buffer *m) +{ + int authenticated = 0; + u_char *peer_confirm_hash; + u_int peer_confirm_hash_len; + struct jpake_ctx *pctx = authctxt->jpake_ctx; + + if (pctx == NULL) + fatal("%s: pctx == NULL", __func__); + + peer_confirm_hash = buffer_get_string(m, &peer_confirm_hash_len); + + authenticated = jpake_check_confirm(pctx->k, + pctx->client_id, pctx->client_id_len, + session_id2, session_id2_len, + peer_confirm_hash, peer_confirm_hash_len) && authctxt->valid; + + JPAKE_DEBUG_CTX((pctx, "check_confirm done in %s", __func__)); + + bzero(peer_confirm_hash, peer_confirm_hash_len); + xfree(peer_confirm_hash); + + buffer_clear(m); + buffer_put_int(m, authenticated); + + debug3("%s: sending result %d", __func__, authenticated); + mm_request_send(sock, MONITOR_ANS_JPAKE_CHECK_CONFIRM, m); + + monitor_permit(mon_dispatch, MONITOR_REQ_JPAKE_STEP1, 1); + + auth_method = "jpake-01@openssh.com"; + return authenticated; +} + +#endif /* JPAKE */ diff --git a/monitor.h b/monitor.h index 464009ad8197..a8a2c0c199ff 100644 --- a/monitor.h +++ b/monitor.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor.h,v 1.14 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: monitor.h,v 1.15 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -60,7 +60,12 @@ enum monitor_reqtype { MONITOR_REQ_PAM_RESPOND, MONITOR_ANS_PAM_RESPOND, MONITOR_REQ_PAM_FREE_CTX, MONITOR_ANS_PAM_FREE_CTX, MONITOR_REQ_AUDIT_EVENT, MONITOR_REQ_AUDIT_COMMAND, - MONITOR_REQ_TERM + MONITOR_REQ_TERM, + MONITOR_REQ_JPAKE_STEP1, MONITOR_ANS_JPAKE_STEP1, + MONITOR_REQ_JPAKE_GET_PWDATA, MONITOR_ANS_JPAKE_GET_PWDATA, + MONITOR_REQ_JPAKE_STEP2, MONITOR_ANS_JPAKE_STEP2, + MONITOR_REQ_JPAKE_KEY_CONFIRM, MONITOR_ANS_JPAKE_KEY_CONFIRM, + MONITOR_REQ_JPAKE_CHECK_CONFIRM, MONITOR_ANS_JPAKE_CHECK_CONFIRM, }; struct mm_master; diff --git a/monitor_fdpass.c b/monitor_fdpass.c index cab538bc9003..4b9a066bcf0f 100644 --- a/monitor_fdpass.c +++ b/monitor_fdpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_fdpass.c,v 1.17 2008/03/24 16:11:07 deraadt Exp $ */ +/* $OpenBSD: monitor_fdpass.c,v 1.18 2008/11/30 11:59:26 dtucker Exp $ */ /* * Copyright 2001 Niels Provos * All rights reserved. @@ -45,17 +45,16 @@ mm_send_fd(int sock, int fd) { #if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; - struct iovec vec; - char ch = '\0'; - ssize_t n; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; - char tmp[CMSG_SPACE(sizeof(int))]; char buf[CMSG_SPACE(sizeof(int))]; } cmsgbuf; struct cmsghdr *cmsg; #endif + struct iovec vec; + char ch = '\0'; + ssize_t n; memset(&msg, 0, sizeof(msg)); #ifdef HAVE_ACCRIGHTS_IN_MSGHDR @@ -76,7 +75,10 @@ mm_send_fd(int sock, int fd) msg.msg_iov = &vec; msg.msg_iovlen = 1; - if ((n = sendmsg(sock, &msg, 0)) == -1) { + while ((n = sendmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || + errno == EINTR)) + debug3("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); + if (n == -1) { error("%s: sendmsg(%d): %s", __func__, fd, strerror(errno)); return -1; @@ -99,10 +101,6 @@ mm_receive_fd(int sock) { #if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR)) struct msghdr msg; - struct iovec vec; - ssize_t n; - char ch; - int fd; #ifndef HAVE_ACCRIGHTS_IN_MSGHDR union { struct cmsghdr hdr; @@ -110,6 +108,10 @@ mm_receive_fd(int sock) } cmsgbuf; struct cmsghdr *cmsg; #endif + struct iovec vec; + ssize_t n; + char ch; + int fd; memset(&msg, 0, sizeof(msg)); vec.iov_base = &ch; @@ -124,10 +126,14 @@ mm_receive_fd(int sock) msg.msg_controllen = sizeof(cmsgbuf.buf); #endif - if ((n = recvmsg(sock, &msg, 0)) == -1) { + while ((n = recvmsg(sock, &msg, 0)) == -1 && (errno == EAGAIN || + errno == EINTR)) + debug3("%s: recvmsg: %s", __func__, strerror(errno)); + if (n == -1) { error("%s: recvmsg: %s", __func__, strerror(errno)); return -1; } + if (n != 1) { error("%s: recvmsg: expected received 1 got %ld", __func__, (long)n); @@ -145,6 +151,7 @@ mm_receive_fd(int sock) error("%s: no message header", __func__); return -1; } + #ifndef BROKEN_CMSG_TYPE if (cmsg->cmsg_type != SCM_RIGHTS) { error("%s: expected type %d got %d", __func__, diff --git a/monitor_wrap.c b/monitor_wrap.c index 40463d07800a..0986fc51827c 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.c,v 1.63 2008/07/10 18:08:11 markus Exp $ */ +/* $OpenBSD: monitor_wrap.c,v 1.64 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright 2002 Niels Provos * Copyright 2002 Markus Friedl @@ -40,6 +40,7 @@ #include #include +#include #include "openbsd-compat/sys-queue.h" #include "xmalloc.h" @@ -70,7 +71,7 @@ #include "atomicio.h" #include "monitor_fdpass.h" #include "misc.h" -#include "servconf.h" +#include "jpake.h" #include "channels.h" #include "session.h" @@ -1256,3 +1257,165 @@ mm_ssh_gssapi_userok(char *user) return (authenticated); } #endif /* GSSAPI */ + +#ifdef JPAKE +void +mm_auth2_jpake_get_pwdata(Authctxt *authctxt, BIGNUM **s, + char **hash_scheme, char **salt) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_GET_PWDATA, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_GET_PWDATA", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_GET_PWDATA, &m); + + *hash_scheme = buffer_get_string(&m, NULL); + *salt = buffer_get_string(&m, NULL); + + buffer_free(&m); +} + +void +mm_jpake_step1(struct jpake_group *grp, + u_char **id, u_int *id_len, + BIGNUM **priv1, BIGNUM **priv2, BIGNUM **g_priv1, BIGNUM **g_priv2, + u_char **priv1_proof, u_int *priv1_proof_len, + u_char **priv2_proof, u_int *priv2_proof_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_STEP1, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP1", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_STEP1, &m); + + if ((*priv1 = BN_new()) == NULL || + (*priv2 = BN_new()) == NULL || + (*g_priv1 = BN_new()) == NULL || + (*g_priv2 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + *id = buffer_get_string(&m, id_len); + /* priv1 and priv2 are, well, private */ + buffer_get_bignum2(&m, *g_priv1); + buffer_get_bignum2(&m, *g_priv2); + *priv1_proof = buffer_get_string(&m, priv1_proof_len); + *priv2_proof = buffer_get_string(&m, priv2_proof_len); + + buffer_free(&m); +} + +void +mm_jpake_step2(struct jpake_group *grp, BIGNUM *s, + BIGNUM *mypub1, BIGNUM *theirpub1, BIGNUM *theirpub2, BIGNUM *mypriv2, + const u_char *theirid, u_int theirid_len, + const u_char *myid, u_int myid_len, + const u_char *theirpub1_proof, u_int theirpub1_proof_len, + const u_char *theirpub2_proof, u_int theirpub2_proof_len, + BIGNUM **newpub, + u_char **newpub_exponent_proof, u_int *newpub_exponent_proof_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* monitor already has all bignums except theirpub1, theirpub2 */ + buffer_put_bignum2(&m, theirpub1); + buffer_put_bignum2(&m, theirpub2); + /* monitor already knows our id */ + buffer_put_string(&m, theirid, theirid_len); + buffer_put_string(&m, theirpub1_proof, theirpub1_proof_len); + buffer_put_string(&m, theirpub2_proof, theirpub2_proof_len); + + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_STEP2, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_STEP2", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_STEP2, &m); + + if ((*newpub = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + buffer_get_bignum2(&m, *newpub); + *newpub_exponent_proof = buffer_get_string(&m, + newpub_exponent_proof_len); + + buffer_free(&m); +} + +void +mm_jpake_key_confirm(struct jpake_group *grp, BIGNUM *s, BIGNUM *step2_val, + BIGNUM *mypriv2, BIGNUM *mypub1, BIGNUM *mypub2, + BIGNUM *theirpub1, BIGNUM *theirpub2, + const u_char *my_id, u_int my_id_len, + const u_char *their_id, u_int their_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *theirpriv2_s_proof, u_int theirpriv2_s_proof_len, + BIGNUM **k, + u_char **confirm_hash, u_int *confirm_hash_len) +{ + Buffer m; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* monitor already has all bignums except step2_val */ + buffer_put_bignum2(&m, step2_val); + /* monitor already knows all the ids */ + buffer_put_string(&m, theirpriv2_s_proof, theirpriv2_s_proof_len); + + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_KEY_CONFIRM, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_KEY_CONFIRM", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_KEY_CONFIRM, &m); + + /* 'k' is sensitive and stays in the monitor */ + *confirm_hash = buffer_get_string(&m, confirm_hash_len); + + buffer_free(&m); +} + +int +mm_jpake_check_confirm(const BIGNUM *k, + const u_char *peer_id, u_int peer_id_len, + const u_char *sess_id, u_int sess_id_len, + const u_char *peer_confirm_hash, u_int peer_confirm_hash_len) +{ + Buffer m; + int success = 0; + + debug3("%s entering", __func__); + + buffer_init(&m); + /* k is dummy in slave, ignored */ + /* monitor knows all the ids */ + buffer_put_string(&m, peer_confirm_hash, peer_confirm_hash_len); + mm_request_send(pmonitor->m_recvfd, + MONITOR_REQ_JPAKE_CHECK_CONFIRM, &m); + + debug3("%s: waiting for MONITOR_ANS_JPAKE_CHECK_CONFIRM", __func__); + mm_request_receive_expect(pmonitor->m_recvfd, + MONITOR_ANS_JPAKE_CHECK_CONFIRM, &m); + + success = buffer_get_int(&m); + buffer_free(&m); + + debug3("%s: success = %d", __func__, success); + return success; +} +#endif /* JPAKE */ diff --git a/monitor_wrap.h b/monitor_wrap.h index 329189c2ada0..55c4b99f354b 100644 --- a/monitor_wrap.h +++ b/monitor_wrap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: monitor_wrap.h,v 1.20 2006/08/03 03:34:42 deraadt Exp $ */ +/* $OpenBSD: monitor_wrap.h,v 1.21 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright 2002 Niels Provos @@ -101,6 +101,26 @@ int mm_bsdauth_respond(void *, u_int, char **); int mm_skey_query(void *, char **, char **, u_int *, char ***, u_int **); int mm_skey_respond(void *, u_int, char **); +/* jpake */ +struct jpake_group; +void mm_auth2_jpake_get_pwdata(struct Authctxt *, BIGNUM **, char **, char **); +void mm_jpake_step1(struct jpake_group *, u_char **, u_int *, + BIGNUM **, BIGNUM **, BIGNUM **, BIGNUM **, + u_char **, u_int *, u_char **, u_int *); +void mm_jpake_step2(struct jpake_group *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); +void mm_jpake_key_confirm(struct jpake_group *, BIGNUM *, BIGNUM *, + BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, + const u_char *, u_int, const u_char *, u_int, + const u_char *, u_int, const u_char *, u_int, + BIGNUM **, u_char **, u_int *); +int mm_jpake_check_confirm(const BIGNUM *, + const u_char *, u_int, const u_char *, u_int, const u_char *, u_int); + + /* zlib allocation hooks */ void *mm_zalloc(struct mm_master *, u_int, u_int); diff --git a/myproposal.h b/myproposal.h index 87a9e5820024..7bca3bcae44a 100644 --- a/myproposal.h +++ b/myproposal.h @@ -1,4 +1,4 @@ -/* $OpenBSD: myproposal.h,v 1.22 2007/06/07 19:37:34 pvalchev Exp $ */ +/* $OpenBSD: myproposal.h,v 1.23 2009/01/23 07:58:11 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -41,11 +41,12 @@ #endif #define KEX_DEFAULT_PK_ALG "ssh-rsa,ssh-dss" + #define KEX_DEFAULT_ENCRYPT \ + "aes128-ctr,aes192-ctr,aes256-ctr," \ + "arcfour256,arcfour128," \ "aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \ - "arcfour128,arcfour256,arcfour," \ - "aes192-cbc,aes256-cbc,rijndael-cbc@lysator.liu.se," \ - "aes128-ctr,aes192-ctr,aes256-ctr" + "aes192-cbc,aes256-cbc,arcfour,rijndael-cbc@lysator.liu.se" #define KEX_DEFAULT_MAC \ "hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160," \ "hmac-ripemd160@openssh.com," \ diff --git a/nchan.c b/nchan.c index e0ebf43f151c..160445e5a26a 100644 --- a/nchan.c +++ b/nchan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: nchan.c,v 1.60 2008/06/30 12:16:02 djm Exp $ */ +/* $OpenBSD: nchan.c,v 1.62 2008/11/07 18:50:18 stevesk Exp $ */ /* * Copyright (c) 1999, 2000, 2001, 2002 Markus Friedl. All rights reserved. * @@ -387,6 +387,8 @@ chan_send_eow2(Channel *c) c->self); return; } + if (!(datafellows & SSH_NEW_OPENSSH)) + return; packet_start(SSH2_MSG_CHANNEL_REQUEST); packet_put_int(c->remote_id); packet_put_cstring("eow@openssh.com"); @@ -484,12 +486,12 @@ chan_shutdown_write(Channel *c) if (c->sock != -1) { if (shutdown(c->sock, SHUT_WR) < 0) debug2("channel %d: chan_shutdown_write: " - "shutdown() failed for fd%d: %.100s", + "shutdown() failed for fd %d: %.100s", c->self, c->sock, strerror(errno)); } else { if (channel_close_fd(&c->wfd) < 0) logit("channel %d: chan_shutdown_write: " - "close() failed for fd%d: %.100s", + "close() failed for fd %d: %.100s", c->self, c->wfd, strerror(errno)); } } @@ -508,13 +510,13 @@ chan_shutdown_read(Channel *c) if (shutdown(c->sock, SHUT_RD) < 0 && errno != ENOTCONN) error("channel %d: chan_shutdown_read: " - "shutdown() failed for fd%d [i%d o%d]: %.100s", + "shutdown() failed for fd %d [i%d o%d]: %.100s", c->self, c->sock, c->istate, c->ostate, strerror(errno)); } else { if (channel_close_fd(&c->rfd) < 0) logit("channel %d: chan_shutdown_read: " - "close() failed for fd%d: %.100s", + "close() failed for fd %d: %.100s", c->self, c->rfd, strerror(errno)); } } diff --git a/openbsd-compat/bsd-poll.c b/openbsd-compat/bsd-poll.c index 284db3a1fcd3..f899d7a244c7 100644 --- a/openbsd-compat/bsd-poll.c +++ b/openbsd-compat/bsd-poll.c @@ -1,4 +1,4 @@ -/* $Id: bsd-poll.c,v 1.3 2008/04/04 05:16:36 djm Exp $ */ +/* $Id: bsd-poll.c,v 1.4 2008/08/29 21:32:38 dtucker Exp $ */ /* * Copyright (c) 2004, 2005, 2007 Darren Tucker (dtucker at zip com au). @@ -46,11 +46,12 @@ poll(struct pollfd *fds, nfds_t nfds, int timeout) struct timeval tv, *tvp = NULL; for (i = 0; i < nfds; i++) { + fd = fds[i].fd; if (fd >= FD_SETSIZE) { errno = EINVAL; return -1; } - maxfd = MAX(maxfd, fds[i].fd); + maxfd = MAX(maxfd, fd); } nmemb = howmany(maxfd + 1 , NFDBITS); diff --git a/openbsd-compat/port-uw.c b/openbsd-compat/port-uw.c index ebc229a6a06e..be9905a6af9b 100644 --- a/openbsd-compat/port-uw.c +++ b/openbsd-compat/port-uw.c @@ -25,7 +25,7 @@ #include "includes.h" -#ifdef HAVE_LIBIAF +#if defined(HAVE_LIBIAF) && !defined(HAVE_SECUREWARE) #include #ifdef HAVE_CRYPT_H # include @@ -145,5 +145,5 @@ get_iaf_password(struct passwd *pw) fatal("ia_openinfo: Unable to open the shadow passwd file"); } #endif /* USE_LIBIAF */ -#endif /* HAVE_LIBIAF */ +#endif /* HAVE_LIBIAF and not HAVE_SECUREWARE */ diff --git a/openbsd-compat/xcrypt.c b/openbsd-compat/xcrypt.c index d8636bb398e1..6291e2884c5c 100644 --- a/openbsd-compat/xcrypt.c +++ b/openbsd-compat/xcrypt.c @@ -28,7 +28,7 @@ #include #include -# ifdef HAVE_CRYPT_H +# if defined(HAVE_CRYPT_H) && !defined(HAVE_SECUREWARE) # include # endif diff --git a/openbsd-compat/xmmap.c b/openbsd-compat/xmmap.c index 23efe3888956..04c6babc2864 100644 --- a/openbsd-compat/xmmap.c +++ b/openbsd-compat/xmmap.c @@ -23,7 +23,7 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* $Id: xmmap.c,v 1.14 2007/06/11 02:52:24 djm Exp $ */ +/* $Id: xmmap.c,v 1.15 2009/02/16 04:21:40 djm Exp $ */ #include "includes.h" @@ -71,7 +71,8 @@ xmmap(size_t size) fatal("mkstemp(\"%s\"): %s", MM_SWAP_TEMPLATE, strerror(errno)); unlink(tmpname); - ftruncate(tmpfd, size); + if (ftruncate(tmpfd, size) != 0) + fatal("%s: ftruncate: %s", __func__, strerror(errno)); address = mmap(NULL, size, PROT_WRITE|PROT_READ, MAP_SHARED, tmpfd, (off_t)0); close(tmpfd); diff --git a/packet.c b/packet.c index 8abd43eb4619..5afc84ce0bc2 100644 --- a/packet.c +++ b/packet.c @@ -1,4 +1,4 @@ -/* $OpenBSD: packet.c,v 1.157 2008/07/10 18:08:11 markus Exp $ */ +/* $OpenBSD: packet.c,v 1.160 2009/02/13 11:50:21 markus Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -84,6 +84,8 @@ #define DBG(x) #endif +#define PACKET_MAX_SIZE (256 * 1024) + /* * This variable contains the file descriptors used for communicating with * the other side. connection_in is used for reading; connection_out for @@ -160,6 +162,10 @@ static u_int ssh1_keylen; /* roundup current message to extra_pad bytes */ static u_char extra_pad = 0; +/* XXX discard incoming data after MAC error */ +static u_int packet_discard = 0; +static Mac *packet_discard_mac = NULL; + struct packet { TAILQ_ENTRY(packet) next; u_char type; @@ -209,6 +215,36 @@ packet_set_timeout(int timeout, int count) packet_timeout_ms = timeout * count * 1000; } +static void +packet_stop_discard(void) +{ + if (packet_discard_mac) { + char buf[1024]; + + memset(buf, 'a', sizeof(buf)); + while (buffer_len(&incoming_packet) < PACKET_MAX_SIZE) + buffer_append(&incoming_packet, buf, sizeof(buf)); + (void) mac_compute(packet_discard_mac, + p_read.seqnr, + buffer_ptr(&incoming_packet), + PACKET_MAX_SIZE); + } + logit("Finished discarding for %.200s", get_remote_ipaddr()); + cleanup_exit(255); +} + +static void +packet_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) +{ + if (enc == NULL || !cipher_is_cbc(enc->cipher)) + packet_disconnect("Packet corrupt"); + if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) + packet_discard_mac = mac; + if (buffer_len(&input) >= discard) + packet_stop_discard(); + packet_discard = discard - buffer_len(&input); +} + /* Returns 1 if remote host is connected via socket, 0 if not. */ int @@ -1127,6 +1163,9 @@ packet_read_poll2(u_int32_t *seqnr_p) Mac *mac = NULL; Comp *comp = NULL; + if (packet_discard) + return SSH_MSG_NONE; + if (newkeys[MODE_IN] != NULL) { enc = &newkeys[MODE_IN]->enc; mac = &newkeys[MODE_IN]->mac; @@ -1148,11 +1187,14 @@ packet_read_poll2(u_int32_t *seqnr_p) block_size); cp = buffer_ptr(&incoming_packet); packet_length = get_u32(cp); - if (packet_length < 1 + 4 || packet_length > 256 * 1024) { + if (packet_length < 1 + 4 || packet_length > PACKET_MAX_SIZE) { #ifdef PACKET_DEBUG buffer_dump(&incoming_packet); #endif - packet_disconnect("Bad packet length %u.", packet_length); + logit("Bad packet length %u.", packet_length); + packet_start_discard(enc, mac, packet_length, + PACKET_MAX_SIZE); + return SSH_MSG_NONE; } DBG(debug("input: packet len %u", packet_length+4)); buffer_consume(&input, block_size); @@ -1161,9 +1203,13 @@ packet_read_poll2(u_int32_t *seqnr_p) need = 4 + packet_length - block_size; DBG(debug("partial packet %d, need %d, maclen %d", block_size, need, maclen)); - if (need % block_size != 0) - fatal("padding error: need %d block %d mod %d", + if (need % block_size != 0) { + logit("padding error: need %d block %d mod %d", need, block_size, need % block_size); + packet_start_discard(enc, mac, packet_length, + PACKET_MAX_SIZE - block_size); + return SSH_MSG_NONE; + } /* * check if the entire packet has been received and * decrypt into incoming_packet @@ -1185,11 +1231,19 @@ packet_read_poll2(u_int32_t *seqnr_p) macbuf = mac_compute(mac, p_read.seqnr, buffer_ptr(&incoming_packet), buffer_len(&incoming_packet)); - if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) - packet_disconnect("Corrupted MAC on input."); + if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) { + logit("Corrupted MAC on input."); + if (need > PACKET_MAX_SIZE) + fatal("internal error need %d", need); + packet_start_discard(enc, mac, packet_length, + PACKET_MAX_SIZE - need); + return SSH_MSG_NONE; + } + DBG(debug("MAC #%d ok", p_read.seqnr)); buffer_consume(&input, mac->mac_len); } + /* XXX now it's safe to use fatal/packet_disconnect */ if (seqnr_p != NULL) *seqnr_p = p_read.seqnr; if (++p_read.seqnr == 0) @@ -1322,6 +1376,13 @@ packet_read_poll(void) void packet_process_incoming(const char *buf, u_int len) { + if (packet_discard) { + keep_alive_timeouts = 0; /* ?? */ + if (len >= packet_discard) + packet_stop_discard(); + packet_discard -= len; + return; + } buffer_append(&input, buf, len); } diff --git a/pathnames.h b/pathnames.h index f2571e2749f7..80c5d9cbb709 100644 --- a/pathnames.h +++ b/pathnames.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pathnames.h,v 1.16 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: pathnames.h,v 1.17 2008/12/29 02:23:26 stevesk Exp $ */ /* * Author: Tatu Ylonen @@ -54,7 +54,7 @@ #define _PATH_SSH_DAEMON_PID_FILE _PATH_SSH_PIDDIR "/sshd.pid" /* - * The directory in user\'s home directory in which the files reside. The + * The directory in user's home directory in which the files reside. The * directory should be world-readable (though not all files are). */ #define _PATH_SSH_USER_DIR ".ssh" @@ -77,9 +77,9 @@ #define _PATH_SSH_CLIENT_ID_RSA ".ssh/id_rsa" /* - * Configuration file in user\'s home directory. This file need not be + * Configuration file in user's home directory. This file need not be * readable by anyone but the user him/herself, but does not contain anything - * particularly secret. If the user\'s home directory resides on an NFS + * particularly secret. If the user's home directory resides on an NFS * volume where root is mapped to nobody, this may need to be world-readable. */ #define _PATH_SSH_USER_CONFFILE ".ssh/config" @@ -87,7 +87,7 @@ /* * File containing a list of those rsa keys that permit logging in as this * user. This file need not be readable by anyone but the user him/herself, - * but does not contain anything particularly secret. If the user\'s home + * but does not contain anything particularly secret. If the user's home * directory resides on an NFS volume where root is mapped to nobody, this * may need to be world-readable. (This file is read by the daemon which is * running as root.) diff --git a/readconf.c b/readconf.c index 73f6eb361e7f..53fc6c7ba598 100644 --- a/readconf.c +++ b/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.167 2008/06/26 11:46:31 grunk Exp $ */ +/* $OpenBSD: readconf.c,v 1.176 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -130,7 +130,7 @@ typedef enum { oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, oSendEnv, oControlPath, oControlMaster, oHashKnownHosts, oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, - oVisualHostKey, + oVisualHostKey, oZeroKnowledgePasswordAuthentication, oDeprecated, oUnsupported } OpCodes; @@ -172,7 +172,7 @@ static struct { { "fallbacktorsh", oDeprecated }, { "usersh", oDeprecated }, { "identityfile", oIdentityFile }, - { "identityfile2", oIdentityFile }, /* alias */ + { "identityfile2", oIdentityFile }, /* obsolete */ { "identitiesonly", oIdentitiesOnly }, { "hostname", oHostName }, { "hostkeyalias", oHostKeyAlias }, @@ -188,8 +188,8 @@ static struct { { "host", oHost }, { "escapechar", oEscapeChar }, { "globalknownhostsfile", oGlobalKnownHostsFile }, - { "userknownhostsfile", oUserKnownHostsFile }, /* obsolete */ - { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, + { "globalknownhostsfile2", oGlobalKnownHostsFile2 }, /* obsolete */ + { "userknownhostsfile", oUserKnownHostsFile }, { "userknownhostsfile2", oUserKnownHostsFile2 }, /* obsolete */ { "connectionattempts", oConnectionAttempts }, { "batchmode", oBatchMode }, @@ -228,6 +228,13 @@ static struct { { "localcommand", oLocalCommand }, { "permitlocalcommand", oPermitLocalCommand }, { "visualhostkey", oVisualHostKey }, +#ifdef JPAKE + { "zeroknowledgepasswordauthentication", + oZeroKnowledgePasswordAuthentication }, +#else + { "zeroknowledgepasswordauthentication", oUnsupported }, +#endif + { NULL, oBadOption } }; @@ -249,10 +256,9 @@ add_local_forward(Options *options, const Forward *newfwd) fatal("Too many local forwards (max %d).", SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->local_forwards[options->num_local_forwards++]; - fwd->listen_host = (newfwd->listen_host == NULL) ? - NULL : xstrdup(newfwd->listen_host); + fwd->listen_host = newfwd->listen_host; fwd->listen_port = newfwd->listen_port; - fwd->connect_host = xstrdup(newfwd->connect_host); + fwd->connect_host = newfwd->connect_host; fwd->connect_port = newfwd->connect_port; } @@ -270,10 +276,9 @@ add_remote_forward(Options *options, const Forward *newfwd) SSH_MAX_FORWARDS_PER_DIRECTION); fwd = &options->remote_forwards[options->num_remote_forwards++]; - fwd->listen_host = (newfwd->listen_host == NULL) ? - NULL : xstrdup(newfwd->listen_host); + fwd->listen_host = newfwd->listen_host; fwd->listen_port = newfwd->listen_port; - fwd->connect_host = xstrdup(newfwd->connect_host); + fwd->connect_host = newfwd->connect_host; fwd->connect_port = newfwd->connect_port; } @@ -412,6 +417,10 @@ process_config_line(Options *options, const char *host, intptr = &options->password_authentication; goto parse_flag; + case oZeroKnowledgePasswordAuthentication: + intptr = &options->zero_knowledge_password_authentication; + goto parse_flag; + case oKbdInteractiveAuthentication: intptr = &options->kbd_interactive_authentication; goto parse_flag; @@ -706,56 +715,40 @@ process_config_line(Options *options, const char *host, case oLocalForward: case oRemoteForward: + case oDynamicForward: arg = strdelim(&s); if (arg == NULL || *arg == '\0') fatal("%.200s line %d: Missing port argument.", filename, linenum); - arg2 = strdelim(&s); - if (arg2 == NULL || *arg2 == '\0') - fatal("%.200s line %d: Missing target argument.", - filename, linenum); - /* construct a string for parse_forward */ - snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); + if (opcode == oLocalForward || + opcode == oRemoteForward) { + arg2 = strdelim(&s); + if (arg2 == NULL || *arg2 == '\0') + fatal("%.200s line %d: Missing target argument.", + filename, linenum); - if (parse_forward(&fwd, fwdarg) == 0) + /* construct a string for parse_forward */ + snprintf(fwdarg, sizeof(fwdarg), "%s:%s", arg, arg2); + } else if (opcode == oDynamicForward) { + strlcpy(fwdarg, arg, sizeof(fwdarg)); + } + + if (parse_forward(&fwd, fwdarg, + opcode == oDynamicForward ? 1 : 0, + opcode == oRemoteForward ? 1 : 0) == 0) fatal("%.200s line %d: Bad forwarding specification.", filename, linenum); if (*activep) { - if (opcode == oLocalForward) + if (opcode == oLocalForward || + opcode == oDynamicForward) add_local_forward(options, &fwd); else if (opcode == oRemoteForward) add_remote_forward(options, &fwd); } break; - case oDynamicForward: - arg = strdelim(&s); - if (!arg || *arg == '\0') - fatal("%.200s line %d: Missing port argument.", - filename, linenum); - memset(&fwd, '\0', sizeof(fwd)); - fwd.connect_host = "socks"; - fwd.listen_host = hpdelim(&arg); - if (fwd.listen_host == NULL || - strlen(fwd.listen_host) >= NI_MAXHOST) - fatal("%.200s line %d: Bad forwarding specification.", - filename, linenum); - if (arg) { - fwd.listen_port = a2port(arg); - fwd.listen_host = cleanhostname(fwd.listen_host); - } else { - fwd.listen_port = a2port(fwd.listen_host); - fwd.listen_host = NULL; - } - if (fwd.listen_port == 0) - fatal("%.200s line %d: Badly formatted port number.", - filename, linenum); - if (*activep) - add_local_forward(options, &fwd); - break; - case oClearAllForwardings: intptr = &options->clear_forwardings; goto parse_flag; @@ -959,7 +952,6 @@ read_config_file(const char *filename, const char *host, Options *options, int active, linenum; int bad_options = 0; - /* Open the file. */ if ((f = fopen(filename, "r")) == NULL) return 0; @@ -1072,6 +1064,7 @@ initialize_options(Options * options) options->local_command = NULL; options->permit_local_command = -1; options->visual_host_key = -1; + options->zero_knowledge_password_authentication = -1; } /* @@ -1208,6 +1201,8 @@ fill_default_options(Options * options) options->permit_local_command = 0; if (options->visual_host_key == -1) options->visual_host_key = 0; + if (options->zero_knowledge_password_authentication == -1) + options->zero_knowledge_password_authentication = 0; /* options->local_command should not be set by default */ /* options->proxy_command should not be set by default */ /* options->user will be set in the main program if appropriate */ @@ -1219,11 +1214,14 @@ fill_default_options(Options * options) /* * parse_forward * parses a string containing a port forwarding specification of the form: + * dynamicfwd == 0 * [listenhost:]listenport:connecthost:connectport + * dynamicfwd == 1 + * [listenhost:]listenport * returns number of arguments parsed or zero on error */ int -parse_forward(Forward *fwd, const char *fwdspec) +parse_forward(Forward *fwd, const char *fwdspec, int dynamicfwd, int remotefwd) { int i; char *p, *cp, *fwdarg[4]; @@ -1240,11 +1238,23 @@ parse_forward(Forward *fwd, const char *fwdspec) if ((fwdarg[i] = hpdelim(&cp)) == NULL) break; - /* Check for trailing garbage in 4-arg case*/ + /* Check for trailing garbage */ if (cp != NULL) i = 0; /* failure */ switch (i) { + case 1: + fwd->listen_host = NULL; + fwd->listen_port = a2port(fwdarg[0]); + fwd->connect_host = xstrdup("socks"); + break; + + case 2: + fwd->listen_host = xstrdup(cleanhostname(fwdarg[0])); + fwd->listen_port = a2port(fwdarg[1]); + fwd->connect_host = xstrdup("socks"); + break; + case 3: fwd->listen_host = NULL; fwd->listen_port = a2port(fwdarg[0]); @@ -1264,19 +1274,37 @@ parse_forward(Forward *fwd, const char *fwdspec) xfree(p); - if (fwd->listen_port == 0 || fwd->connect_port == 0) + if (dynamicfwd) { + if (!(i == 1 || i == 2)) + goto fail_free; + } else { + if (!(i == 3 || i == 4)) + goto fail_free; + if (fwd->connect_port <= 0) + goto fail_free; + } + + if (fwd->listen_port < 0 || (!remotefwd && fwd->listen_port == 0)) goto fail_free; if (fwd->connect_host != NULL && strlen(fwd->connect_host) >= NI_MAXHOST) goto fail_free; + if (fwd->listen_host != NULL && + strlen(fwd->listen_host) >= NI_MAXHOST) + goto fail_free; + return (i); fail_free: - if (fwd->connect_host != NULL) + if (fwd->connect_host != NULL) { xfree(fwd->connect_host); - if (fwd->listen_host != NULL) + fwd->connect_host = NULL; + } + if (fwd->listen_host != NULL) { xfree(fwd->listen_host); + fwd->listen_host = NULL; + } return (0); } diff --git a/readconf.h b/readconf.h index 47c7aef4e046..8fb3a8528163 100644 --- a/readconf.h +++ b/readconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.h,v 1.74 2008/06/26 11:46:31 grunk Exp $ */ +/* $OpenBSD: readconf.h,v 1.78 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen @@ -20,9 +20,9 @@ typedef struct { char *listen_host; /* Host (address) to listen on. */ - u_short listen_port; /* Port to forward. */ + int listen_port; /* Port to forward. */ char *connect_host; /* Host to connect. */ - u_short connect_port; /* Port to connect on connect_host. */ + int connect_port; /* Port to connect on connect_host. */ } Forward; /* Data structure for representing option data. */ @@ -49,6 +49,7 @@ typedef struct { * authentication. */ int kbd_interactive_authentication; /* Try keyboard-interactive auth. */ char *kbd_interactive_devices; /* Keyboard-interactive auth devices. */ + int zero_knowledge_password_authentication; /* Try jpake */ int batch_mode; /* Batch mode: do not ask for passwords. */ int check_host_ip; /* Also keep track of keys for IP address */ int strict_host_key_checking; /* Strict host key checking. */ @@ -133,7 +134,7 @@ typedef struct { void initialize_options(Options *); void fill_default_options(Options *); int read_config_file(const char *, const char *, Options *, int); -int parse_forward(Forward *, const char *); +int parse_forward(Forward *, const char *, int, int); int process_config_line(Options *, const char *, char *, const char *, int, int *); diff --git a/regress/conch-ciphers.sh b/regress/conch-ciphers.sh index 84b19061892c..5b65cd993ad4 100755 --- a/regress/conch-ciphers.sh +++ b/regress/conch-ciphers.sh @@ -7,7 +7,8 @@ DATA=/bin/ls COPY=${OBJ}/copy if test "x$REGRESS_INTEROP_CONCH" != "xyes" ; then - fatal "conch interop tests not enabled" + echo "conch interop tests not enabled" + exit 0 fi start_sshd diff --git a/regress/putty-ciphers.sh b/regress/putty-ciphers.sh index 40435ef41a65..928ea60d262f 100755 --- a/regress/putty-ciphers.sh +++ b/regress/putty-ciphers.sh @@ -1,4 +1,4 @@ -# $OpenBSD: putty-ciphers.sh,v 1.2 2008/06/30 10:31:11 djm Exp $ +# $OpenBSD: putty-ciphers.sh,v 1.3 2008/11/10 02:06:35 djm Exp $ # Placed in the Public Domain. tid="putty ciphers" @@ -7,10 +7,11 @@ DATA=/bin/ls COPY=${OBJ}/copy if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then - fatal "putty interop tests not enabled" + echo "putty interop tests not enabled" + exit 0 fi -for c in aes blowfish 3des arcfour ; do +for c in aes blowfish 3des arcfour aes128-ctr aes192-ctr aes256-ctr ; do verbose "$tid: cipher $c" cp ${OBJ}/.putty/sessions/localhost_proxy \ ${OBJ}/.putty/sessions/cipher_$c diff --git a/regress/putty-kex.sh b/regress/putty-kex.sh index 2534b857532d..293885a8a0ba 100755 --- a/regress/putty-kex.sh +++ b/regress/putty-kex.sh @@ -7,7 +7,8 @@ DATA=/bin/ls COPY=${OBJ}/copy if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then - fatal "putty interop tests not enabled" + echo "putty interop tests not enabled" + exit 0 fi for k in dh-gex-sha1 dh-group1-sha1 dh-group14-sha1 ; do diff --git a/regress/putty-transfer.sh b/regress/putty-transfer.sh index 6b21f3be72b4..9e1e1550a9f3 100755 --- a/regress/putty-transfer.sh +++ b/regress/putty-transfer.sh @@ -7,7 +7,8 @@ DATA=/bin/ls COPY=${OBJ}/copy if test "x$REGRESS_INTEROP_PUTTY" != "xyes" ; then - fatal "putty interop tests not enabled" + echo "putty interop tests not enabled" + exit 0 fi # XXX support protocol 1 too diff --git a/schnorr.c b/schnorr.c new file mode 100644 index 000000000000..546975072221 --- /dev/null +++ b/schnorr.c @@ -0,0 +1,409 @@ +/* $OpenBSD: schnorr.c,v 1.2 2009/02/18 04:31:21 djm Exp $ */ +/* + * Copyright (c) 2008 Damien Miller. All rights reserved. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Implementation of Schnorr signatures / zero-knowledge proofs, based on + * description in: + * + * F. Hao, P. Ryan, "Password Authenticated Key Exchange by Juggling", + * 16th Workshop on Security Protocols, Cambridge, April 2008 + * + * http://grouper.ieee.org/groups/1363/Research/contributions/hao-ryan-2008.pdf + */ + +#include "includes.h" + +#include + +#include +#include +#include + +#include +#include + +#include "xmalloc.h" +#include "buffer.h" +#include "log.h" + +#include "jpake.h" + +/* #define SCHNORR_DEBUG */ /* Privacy-violating debugging */ +/* #define SCHNORR_MAIN */ /* Include main() selftest */ + +/* XXX */ +/* Parametise signature hash? (sha256, sha1, etc.) */ +/* Signature format - include type name, hash type, group params? */ + +#ifndef SCHNORR_DEBUG +# define SCHNORR_DEBUG_BN(a) +# define SCHNORR_DEBUG_BUF(a) +#else +# define SCHNORR_DEBUG_BN(a) jpake_debug3_bn a +# define SCHNORR_DEBUG_BUF(a) jpake_debug3_buf a +#endif /* SCHNORR_DEBUG */ + +/* + * Calculate hash component of Schnorr signature H(g || g^v || g^x || id) + * using SHA1. Returns signature as bignum or NULL on error. + */ +static BIGNUM * +schnorr_hash(const BIGNUM *p, const BIGNUM *q, const BIGNUM *g, + const BIGNUM *g_v, const BIGNUM *g_x, + const u_char *id, u_int idlen) +{ + u_char *digest; + u_int digest_len; + BIGNUM *h; + EVP_MD_CTX evp_md_ctx; + Buffer b; + int success = -1; + + if ((h = BN_new()) == NULL) { + error("%s: BN_new", __func__); + return NULL; + } + + buffer_init(&b); + EVP_MD_CTX_init(&evp_md_ctx); + + /* h = H(g || p || q || g^v || g^x || id) */ + buffer_put_bignum2(&b, g); + buffer_put_bignum2(&b, p); + buffer_put_bignum2(&b, q); + buffer_put_bignum2(&b, g_v); + buffer_put_bignum2(&b, g_x); + buffer_put_string(&b, id, idlen); + + SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), + "%s: hashblob", __func__)); + if (hash_buffer(buffer_ptr(&b), buffer_len(&b), EVP_sha256(), + &digest, &digest_len) != 0) { + error("%s: hash_buffer", __func__); + goto out; + } + if (BN_bin2bn(digest, (int)digest_len, h) == NULL) { + error("%s: BN_bin2bn", __func__); + goto out; + } + success = 0; + SCHNORR_DEBUG_BN((h, "%s: h = ", __func__)); + out: + buffer_free(&b); + EVP_MD_CTX_cleanup(&evp_md_ctx); + bzero(digest, digest_len); + xfree(digest); + digest_len = 0; + if (success == 0) + return h; + BN_clear_free(h); + return NULL; +} + +/* + * Generate Schnorr signature to prove knowledge of private value 'x' used + * in public exponent g^x, under group defined by 'grp_p', 'grp_q' and 'grp_g' + * 'idlen' bytes from 'id' will be included in the signature hash as an anti- + * replay salt. + * On success, 0 is returned and *siglen bytes of signature are returned in + * *sig (caller to free). Returns -1 on failure. + */ +int +schnorr_sign(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, + const BIGNUM *x, const BIGNUM *g_x, const u_char *id, u_int idlen, + u_char **sig, u_int *siglen) +{ + int success = -1; + Buffer b; + BIGNUM *h, *tmp, *v, *g_v, *r; + BN_CTX *bn_ctx; + + SCHNORR_DEBUG_BN((x, "%s: x = ", __func__)); + SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); + + /* Avoid degenerate cases: g^0 yields a spoofable signature */ + if (BN_cmp(g_x, BN_value_one()) <= 0) { + error("%s: g_x < 1", __func__); + return -1; + } + + h = g_v = r = tmp = v = NULL; + if ((bn_ctx = BN_CTX_new()) == NULL) { + error("%s: BN_CTX_new", __func__); + goto out; + } + if ((g_v = BN_new()) == NULL || + (r = BN_new()) == NULL || + (tmp = BN_new()) == NULL) { + error("%s: BN_new", __func__); + goto out; + } + + /* + * v must be a random element of Zq, so 1 <= v < q + * we also exclude v = 1, since g^1 looks dangerous + */ + if ((v = bn_rand_range_gt_one(grp_p)) == NULL) { + error("%s: bn_rand_range2", __func__); + goto out; + } + SCHNORR_DEBUG_BN((v, "%s: v = ", __func__)); + + /* g_v = g^v mod p */ + if (BN_mod_exp(g_v, grp_g, v, grp_p, bn_ctx) == -1) { + error("%s: BN_mod_exp (g^v mod p)", __func__); + goto out; + } + SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); + + /* h = H(g || g^v || g^x || id) */ + if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x, + id, idlen)) == NULL) { + error("%s: schnorr_hash failed", __func__); + goto out; + } + + /* r = v - xh mod q */ + if (BN_mod_mul(tmp, x, h, grp_q, bn_ctx) == -1) { + error("%s: BN_mod_mul (tmp = xv mod q)", __func__); + goto out; + } + if (BN_mod_sub(r, v, tmp, grp_q, bn_ctx) == -1) { + error("%s: BN_mod_mul (r = v - tmp)", __func__); + goto out; + } + SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); + + /* Signature is (g_v, r) */ + buffer_init(&b); + /* XXX sigtype-hash as string? */ + buffer_put_bignum2(&b, g_v); + buffer_put_bignum2(&b, r); + *siglen = buffer_len(&b); + *sig = xmalloc(*siglen); + memcpy(*sig, buffer_ptr(&b), *siglen); + SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), + "%s: sigblob", __func__)); + buffer_free(&b); + success = 0; + out: + BN_CTX_free(bn_ctx); + if (h != NULL) + BN_clear_free(h); + if (v != NULL) + BN_clear_free(v); + BN_clear_free(r); + BN_clear_free(g_v); + BN_clear_free(tmp); + + return success; +} + +/* + * Verify Schnorr signature 'sig' of length 'siglen' against public exponent + * g_x (g^x) under group defined by 'grp_p', 'grp_q' and 'grp_g'. + * Signature hash will be salted with 'idlen' bytes from 'id'. + * Returns -1 on failure, 0 on incorrect signature or 1 on matching signature. + */ +int +schnorr_verify(const BIGNUM *grp_p, const BIGNUM *grp_q, const BIGNUM *grp_g, + const BIGNUM *g_x, const u_char *id, u_int idlen, + const u_char *sig, u_int siglen) +{ + int success = -1; + Buffer b; + BIGNUM *g_v, *h, *r, *g_xh, *g_r, *expected; + BN_CTX *bn_ctx; + u_int rlen; + + SCHNORR_DEBUG_BN((g_x, "%s: g_x = ", __func__)); + + /* Avoid degenerate cases: g^0 yields a spoofable signature */ + if (BN_cmp(g_x, BN_value_one()) <= 0) { + error("%s: g_x < 1", __func__); + return -1; + } + + g_v = h = r = g_xh = g_r = expected = NULL; + if ((bn_ctx = BN_CTX_new()) == NULL) { + error("%s: BN_CTX_new", __func__); + goto out; + } + if ((g_v = BN_new()) == NULL || + (r = BN_new()) == NULL || + (g_xh = BN_new()) == NULL || + (g_r = BN_new()) == NULL || + (expected = BN_new()) == NULL) { + error("%s: BN_new", __func__); + goto out; + } + + /* Extract g^v and r from signature blob */ + buffer_init(&b); + buffer_append(&b, sig, siglen); + SCHNORR_DEBUG_BUF((buffer_ptr(&b), buffer_len(&b), + "%s: sigblob", __func__)); + buffer_get_bignum2(&b, g_v); + buffer_get_bignum2(&b, r); + rlen = buffer_len(&b); + buffer_free(&b); + if (rlen != 0) { + error("%s: remaining bytes in signature %d", __func__, rlen); + goto out; + } + buffer_free(&b); + SCHNORR_DEBUG_BN((g_v, "%s: g_v = ", __func__)); + SCHNORR_DEBUG_BN((r, "%s: r = ", __func__)); + + /* h = H(g || g^v || g^x || id) */ + if ((h = schnorr_hash(grp_p, grp_q, grp_g, g_v, g_x, + id, idlen)) == NULL) { + error("%s: schnorr_hash failed", __func__); + goto out; + } + + /* g_xh = (g^x)^h */ + if (BN_mod_exp(g_xh, g_x, h, grp_p, bn_ctx) == -1) { + error("%s: BN_mod_exp (g_x^h mod p)", __func__); + goto out; + } + SCHNORR_DEBUG_BN((g_xh, "%s: g_xh = ", __func__)); + + /* g_r = g^r */ + if (BN_mod_exp(g_r, grp_g, r, grp_p, bn_ctx) == -1) { + error("%s: BN_mod_exp (g_x^h mod p)", __func__); + goto out; + } + SCHNORR_DEBUG_BN((g_r, "%s: g_r = ", __func__)); + + /* expected = g^r * g_xh */ + if (BN_mod_mul(expected, g_r, g_xh, grp_p, bn_ctx) == -1) { + error("%s: BN_mod_mul (expected = g_r mod p)", __func__); + goto out; + } + SCHNORR_DEBUG_BN((expected, "%s: expected = ", __func__)); + + /* Check g_v == expected */ + success = BN_cmp(expected, g_v) == 0; + out: + BN_CTX_free(bn_ctx); + if (h != NULL) + BN_clear_free(h); + BN_clear_free(g_v); + BN_clear_free(r); + BN_clear_free(g_xh); + BN_clear_free(g_r); + BN_clear_free(expected); + return success; +} + +#ifdef SCHNORR_MAIN +static void +schnorr_selftest_one(const BIGNUM *grp_p, const BIGNUM *grp_q, + const BIGNUM *grp_g, const BIGNUM *x) +{ + BIGNUM *g_x; + u_char *sig; + u_int siglen; + BN_CTX *bn_ctx; + + if ((bn_ctx = BN_CTX_new()) == NULL) + fatal("%s: BN_CTX_new", __func__); + if ((g_x = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + if (BN_mod_exp(g_x, grp_g, x, grp_p, bn_ctx) == -1) + fatal("%s: g_x", __func__); + if (schnorr_sign(grp_p, grp_q, grp_g, x, g_x, "junk", 4, &sig, &siglen)) + fatal("%s: schnorr_sign", __func__); + if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4, + sig, siglen) != 1) + fatal("%s: verify fail", __func__); + if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "JUNK", 4, + sig, siglen) != 0) + fatal("%s: verify should have failed (bad ID)", __func__); + sig[4] ^= 1; + if (schnorr_verify(grp_p, grp_q, grp_g, g_x, "junk", 4, + sig, siglen) != 0) + fatal("%s: verify should have failed (bit error)", __func__); + xfree(sig); + BN_free(g_x); + BN_CTX_free(bn_ctx); +} + +static void +schnorr_selftest(void) +{ + BIGNUM *x; + struct jpake_group *grp; + u_int i; + char *hh; + + grp = jpake_default_group(); + if ((x = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + SCHNORR_DEBUG_BN((grp->p, "%s: grp->p = ", __func__)); + SCHNORR_DEBUG_BN((grp->q, "%s: grp->q = ", __func__)); + SCHNORR_DEBUG_BN((grp->g, "%s: grp->g = ", __func__)); + + /* [1, 20) */ + for (i = 1; i < 20; i++) { + printf("x = %u\n", i); + fflush(stdout); + if (BN_set_word(x, i) != 1) + fatal("%s: set x word", __func__); + schnorr_selftest_one(grp->p, grp->q, grp->g, x); + } + + /* 100 x random [0, p) */ + for (i = 0; i < 100; i++) { + if (BN_rand_range(x, grp->p) != 1) + fatal("%s: BN_rand_range", __func__); + hh = BN_bn2hex(x); + printf("x = (random) 0x%s\n", hh); + free(hh); + fflush(stdout); + schnorr_selftest_one(grp->p, grp->q, grp->g, x); + } + + /* [q-20, q) */ + if (BN_set_word(x, 20) != 1) + fatal("%s: BN_set_word (x = 20)", __func__); + if (BN_sub(x, grp->q, x) != 1) + fatal("%s: BN_sub (q - x)", __func__); + for (i = 0; i < 19; i++) { + hh = BN_bn2hex(x); + printf("x = (q - %d) 0x%s\n", 20 - i, hh); + free(hh); + fflush(stdout); + schnorr_selftest_one(grp->p, grp->q, grp->g, x); + if (BN_add(x, x, BN_value_one()) != 1) + fatal("%s: BN_add (x + 1)", __func__); + } + BN_free(x); +} + +int +main(int argc, char **argv) +{ + log_init(argv[0], SYSLOG_LEVEL_DEBUG3, SYSLOG_FACILITY_USER, 1); + + schnorr_selftest(); + return 0; +} +#endif + diff --git a/scp.0 b/scp.0 index b6b9d919c241..26b3fc728ab5 100644 --- a/scp.0 +++ b/scp.0 @@ -145,4 +145,4 @@ AUTHORS Timo Rinne Tatu Ylonen -OpenBSD 4.4 July 12, 2008 3 +OpenBSD 4.5 July 12, 2008 3 diff --git a/scp.c b/scp.c index 9f8b7a192ac6..323747806874 100644 --- a/scp.c +++ b/scp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: scp.c,v 1.163 2008/06/13 18:55:22 dtucker Exp $ */ +/* $OpenBSD: scp.c,v 1.164 2008/10/10 04:55:16 stevesk Exp $ */ /* * scp - secure remote copy. This is basically patched BSD rcp which * uses ssh to do the data transfer (instead of using rcmd). @@ -434,7 +434,7 @@ main(int argc, char **argv) } /* * Finally check the exit status of the ssh process, if one was forked - * and no error has occured yet + * and no error has occurred yet */ if (do_cmd_pid != -1 && errs == 0) { if (remin != -1) diff --git a/servconf.c b/servconf.c index 66e22979f926..e7fc2a7812a7 100644 --- a/servconf.c +++ b/servconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.c,v 1.186 2008/07/04 03:44:59 djm Exp $ */ +/* $OpenBSD: servconf.c,v 1.194 2009/01/22 10:02:34 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -42,8 +42,8 @@ #include "channels.h" #include "groupaccess.h" -static void add_listen_addr(ServerOptions *, char *, u_short); -static void add_one_listen_addr(ServerOptions *, char *, u_short); +static void add_listen_addr(ServerOptions *, char *, int); +static void add_one_listen_addr(ServerOptions *, char *, int); /* Use of privilege separation or not */ extern int use_privsep; @@ -127,6 +127,7 @@ initialize_server_options(ServerOptions *options) options->num_permitted_opens = -1; options->adm_forced_command = NULL; options->chroot_directory = NULL; + options->zero_knowledge_password_authentication = -1; } void @@ -258,6 +259,8 @@ fill_default_server_options(ServerOptions *options) options->authorized_keys_file = _PATH_SSH_USER_PERMITTED_KEYS; if (options->permit_tun == -1) options->permit_tun = SSH_TUNMODE_NO; + if (options->zero_knowledge_password_authentication == -1) + options->zero_knowledge_password_authentication = 0; /* Turn privilege separation on by default */ if (use_privsep == -1) @@ -302,6 +305,7 @@ typedef enum { sGssAuthentication, sGssCleanupCreds, sAcceptEnv, sPermitTunnel, sMatch, sPermitOpen, sForceCommand, sChrootDirectory, sUsePrivilegeSeparation, sAllowAgentForwarding, + sZeroKnowledgePasswordAuthentication, sDeprecated, sUnsupported } ServerOpCodes; @@ -368,6 +372,11 @@ static struct { { "kbdinteractiveauthentication", sKbdInteractiveAuthentication, SSHCFG_ALL }, { "challengeresponseauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, { "skeyauthentication", sChallengeResponseAuthentication, SSHCFG_GLOBAL }, /* alias */ +#ifdef JPAKE + { "zeroknowledgepasswordauthentication", sZeroKnowledgePasswordAuthentication, SSHCFG_ALL }, +#else + { "zeroknowledgepasswordauthentication", sUnsupported, SSHCFG_ALL }, +#endif { "checkmail", sDeprecated, SSHCFG_GLOBAL }, { "listenaddress", sListenAddress, SSHCFG_GLOBAL }, { "addressfamily", sAddressFamily, SSHCFG_GLOBAL }, @@ -380,7 +389,7 @@ static struct { { "x11uselocalhost", sX11UseLocalhost, SSHCFG_ALL }, { "xauthlocation", sXAuthLocation, SSHCFG_GLOBAL }, { "strictmodes", sStrictModes, SSHCFG_GLOBAL }, - { "permitemptypasswords", sEmptyPasswd, SSHCFG_GLOBAL }, + { "permitemptypasswords", sEmptyPasswd, SSHCFG_ALL }, { "permituserenvironment", sPermitUserEnvironment, SSHCFG_GLOBAL }, { "uselogin", sUseLogin, SSHCFG_GLOBAL }, { "compression", sCompression, SSHCFG_GLOBAL }, @@ -451,7 +460,7 @@ parse_token(const char *cp, const char *filename, } static void -add_listen_addr(ServerOptions *options, char *addr, u_short port) +add_listen_addr(ServerOptions *options, char *addr, int port) { u_int i; @@ -467,7 +476,7 @@ add_listen_addr(ServerOptions *options, char *addr, u_short port) } static void -add_one_listen_addr(ServerOptions *options, char *addr, u_short port) +add_one_listen_addr(ServerOptions *options, char *addr, int port) { struct addrinfo hints, *ai, *aitop; char strport[NI_MAXSERV]; @@ -477,7 +486,7 @@ add_one_listen_addr(ServerOptions *options, char *addr, u_short port) hints.ai_family = options->address_family; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = (addr == NULL) ? AI_PASSIVE : 0; - snprintf(strport, sizeof strport, "%u", port); + snprintf(strport, sizeof strport, "%d", port); if ((gaierr = getaddrinfo(addr, strport, &hints, &aitop)) != 0) fatal("bad addr or host: %s (%s)", addr ? addr : "", @@ -633,7 +642,7 @@ process_server_config_line(ServerOptions *options, char *line, SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; ServerOpCodes opcode; - u_short port; + int port; u_int i, flags = 0; size_t len; @@ -690,7 +699,7 @@ process_server_config_line(ServerOptions *options, char *line, fatal("%s line %d: missing port number.", filename, linenum); options->ports[options->num_ports++] = a2port(arg); - if (options->ports[options->num_ports-1] == 0) + if (options->ports[options->num_ports-1] <= 0) fatal("%s line %d: Badly formatted port number.", filename, linenum); break; @@ -743,7 +752,7 @@ process_server_config_line(ServerOptions *options, char *line, p = cleanhostname(p); if (arg == NULL) port = 0; - else if ((port = a2port(arg)) == 0) + else if ((port = a2port(arg)) <= 0) fatal("%s line %d: bad port number", filename, linenum); add_listen_addr(options, p, port); @@ -890,6 +899,10 @@ process_server_config_line(ServerOptions *options, char *line, intptr = &options->password_authentication; goto parse_flag; + case sZeroKnowledgePasswordAuthentication: + intptr = &options->zero_knowledge_password_authentication; + goto parse_flag; + case sKbdInteractiveAuthentication: intptr = &options->kbd_interactive_authentication; goto parse_flag; @@ -1252,7 +1265,7 @@ process_server_config_line(ServerOptions *options, char *line, fatal("%s line %d: missing host in PermitOpen", filename, linenum); p = cleanhostname(p); - if (arg == NULL || (port = a2port(arg)) == 0) + if (arg == NULL || (port = a2port(arg)) <= 0) fatal("%s line %d: bad port number in " "PermitOpen", filename, linenum); if (*activep && n == -1) @@ -1377,7 +1390,9 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) M_CP_INTOPT(kerberos_authentication); M_CP_INTOPT(hostbased_authentication); M_CP_INTOPT(kbd_interactive_authentication); + M_CP_INTOPT(zero_knowledge_password_authentication); M_CP_INTOPT(permit_root_login); + M_CP_INTOPT(permit_empty_passwd); M_CP_INTOPT(allow_tcp_forwarding); M_CP_INTOPT(allow_agent_forwarding); @@ -1439,7 +1454,7 @@ fmt_intarg(ServerOpCodes code, int val) if (code == sPermitRootLogin) { switch (val) { case PERMIT_NO_PASSWD: - return "without-passord"; + return "without-password"; case PERMIT_FORCED_ONLY: return "forced-commands-only"; case PERMIT_YES: @@ -1544,11 +1559,15 @@ dump_config(ServerOptions *o) } /* integer arguments */ +#ifdef USE_PAM + dump_cfg_int(sUsePAM, o->use_pam); +#endif dump_cfg_int(sServerKeyBits, o->server_key_bits); dump_cfg_int(sLoginGraceTime, o->login_grace_time); dump_cfg_int(sKeyRegenerationTime, o->key_regeneration_time); dump_cfg_int(sX11DisplayOffset, o->x11_display_offset); dump_cfg_int(sMaxAuthTries, o->max_authtries); + dump_cfg_int(sMaxSessions, o->max_sessions); dump_cfg_int(sClientAliveInterval, o->client_alive_interval); dump_cfg_int(sClientAliveCountMax, o->client_alive_count_max); @@ -1562,12 +1581,22 @@ dump_config(ServerOptions *o) o->hostbased_uses_name_from_packet_only); dump_cfg_fmtint(sRSAAuthentication, o->rsa_authentication); dump_cfg_fmtint(sPubkeyAuthentication, o->pubkey_authentication); +#ifdef KRB5 dump_cfg_fmtint(sKerberosAuthentication, o->kerberos_authentication); dump_cfg_fmtint(sKerberosOrLocalPasswd, o->kerberos_or_local_passwd); dump_cfg_fmtint(sKerberosTicketCleanup, o->kerberos_ticket_cleanup); +# ifdef USE_AFS dump_cfg_fmtint(sKerberosGetAFSToken, o->kerberos_get_afs_token); +# endif +#endif +#ifdef GSSAPI dump_cfg_fmtint(sGssAuthentication, o->gss_authentication); dump_cfg_fmtint(sGssCleanupCreds, o->gss_cleanup_creds); +#endif +#ifdef JPAKE + dump_cfg_fmtint(sZeroKnowledgePasswordAuthentication, + o->zero_knowledge_password_authentication); +#endif dump_cfg_fmtint(sPasswordAuthentication, o->password_authentication); dump_cfg_fmtint(sKbdInteractiveAuthentication, o->kbd_interactive_authentication); @@ -1626,7 +1655,5 @@ dump_config(ServerOptions *o) } dump_cfg_string(sPermitTunnel, s); - printf("permitopen"); channel_print_adm_permitted_opens(); - printf("\n"); } diff --git a/servconf.h b/servconf.h index 40ac64f13509..b3ac7da4b651 100644 --- a/servconf.h +++ b/servconf.h @@ -1,4 +1,4 @@ -/* $OpenBSD: servconf.h,v 1.85 2008/06/10 04:50:25 dtucker Exp $ */ +/* $OpenBSD: servconf.h,v 1.87 2009/01/22 10:02:34 djm Exp $ */ /* * Author: Tatu Ylonen @@ -41,9 +41,9 @@ #define INTERNAL_SFTP_NAME "internal-sftp" typedef struct { - u_int num_ports; - u_int ports_from_cmdline; - u_short ports[MAX_PORTS]; /* Port number to listen on. */ + u_int num_ports; + u_int ports_from_cmdline; + int ports[MAX_PORTS]; /* Port number to listen on. */ char *listen_addr; /* Address on which the server listens. */ struct addrinfo *listen_addrs; /* Addresses on which the server listens. */ int address_family; /* Address family used by the server. */ @@ -96,6 +96,8 @@ typedef struct { * authentication. */ int kbd_interactive_authentication; /* If true, permit */ int challenge_response_authentication; + int zero_knowledge_password_authentication; + /* If true, permit jpake auth */ int permit_empty_passwd; /* If false, do not permit empty * passwords. */ int permit_user_env; /* If true, read ~/.ssh/environment */ diff --git a/serverloop.c b/serverloop.c index 77d9dee75ceb..81cafe6ad553 100644 --- a/serverloop.c +++ b/serverloop.c @@ -1,4 +1,4 @@ -/* $OpenBSD: serverloop.c,v 1.153 2008/06/30 12:15:39 djm Exp $ */ +/* $OpenBSD: serverloop.c,v 1.157 2009/02/12 03:16:01 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -942,7 +942,7 @@ server_request_direct_tcpip(void) { Channel *c; char *target, *originator; - int target_port, originator_port; + u_short target_port, originator_port; target = packet_get_string(NULL); target_port = packet_get_int(); @@ -1095,7 +1095,7 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) { char *rtype; int want_reply; - int success = 0; + int success = 0, allocated_listen_port = 0; rtype = packet_get_string(NULL); want_reply = packet_get_char(); @@ -1117,7 +1117,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) /* check permissions */ if (!options.allow_tcp_forwarding || - no_port_forwarding_flag + no_port_forwarding_flag || + (!want_reply && listen_port == 0) #ifndef NO_IPPORT_RESERVED_CONCEPT || (listen_port < IPPORT_RESERVED && pw->pw_uid != 0) #endif @@ -1127,7 +1128,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) } else { /* Start listening on the port */ success = channel_setup_remote_fwd_listener( - listen_address, listen_port, options.gateway_ports); + listen_address, listen_port, + &allocated_listen_port, options.gateway_ports); } xfree(listen_address); } else if (strcmp(rtype, "cancel-tcpip-forward") == 0) { @@ -1149,6 +1151,8 @@ server_input_global_request(int type, u_int32_t seq, void *ctxt) if (want_reply) { packet_start(success ? SSH2_MSG_REQUEST_SUCCESS : SSH2_MSG_REQUEST_FAILURE); + if (success && allocated_listen_port > 0) + packet_put_int(allocated_listen_port); packet_send(); packet_write_wait(); } @@ -1202,9 +1206,9 @@ server_init_dispatch_20(void) dispatch_set(SSH2_MSG_CHANNEL_REQUEST, &server_input_channel_req); dispatch_set(SSH2_MSG_CHANNEL_WINDOW_ADJUST, &channel_input_window_adjust); dispatch_set(SSH2_MSG_GLOBAL_REQUEST, &server_input_global_request); - dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &channel_input_status_confirm); - dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &channel_input_status_confirm); /* client_alive */ + dispatch_set(SSH2_MSG_CHANNEL_SUCCESS, &server_input_keep_alive); + dispatch_set(SSH2_MSG_CHANNEL_FAILURE, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_SUCCESS, &server_input_keep_alive); dispatch_set(SSH2_MSG_REQUEST_FAILURE, &server_input_keep_alive); /* rekeying */ diff --git a/session.c b/session.c index 93babf95701a..f2549e0cd7f1 100644 --- a/session.c +++ b/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.241 2008/06/16 13:22:53 dtucker Exp $ */ +/* $OpenBSD: session.c,v 1.245 2009/01/22 09:46:01 djm Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -95,6 +95,12 @@ #include #endif +#define IS_INTERNAL_SFTP(c) \ + (!strncmp(c, INTERNAL_SFTP_NAME, sizeof(INTERNAL_SFTP_NAME) - 1) && \ + (c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\0' || \ + c[sizeof(INTERNAL_SFTP_NAME) - 1] == ' ' || \ + c[sizeof(INTERNAL_SFTP_NAME) - 1] == '\t')) + /* func */ Session *session_new(void); @@ -228,7 +234,7 @@ auth_input_request_forwarding(struct passwd * pw) SSH_CHANNEL_AUTH_SOCKET, sock, sock, -1, CHAN_X11_WINDOW_DEFAULT, CHAN_X11_PACKET_DEFAULT, 0, "auth socket", 1); - strlcpy(nc->path, auth_sock_name, sizeof(nc->path)); + nc->path = xstrdup(auth_sock_name); return 1; authsock_err: @@ -781,7 +787,7 @@ do_exec(Session *s, const char *command) if (options.adm_forced_command) { original_command = command; command = options.adm_forced_command; - if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + if (IS_INTERNAL_SFTP(command)) s->is_subsystem = SUBSYSTEM_INT_SFTP; else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; @@ -789,7 +795,7 @@ do_exec(Session *s, const char *command) } else if (forced_command) { original_command = command; command = forced_command; - if (strcmp(INTERNAL_SFTP_NAME, command) == 0) + if (IS_INTERNAL_SFTP(command)) s->is_subsystem = SUBSYSTEM_INT_SFTP; else if (s->is_subsystem) s->is_subsystem = SUBSYSTEM_EXT; @@ -926,7 +932,7 @@ check_quietlogin(Session *s, const char *command) /* * Sets the value of the given variable in the environment. If the variable - * already exists, its value is overriden. + * already exists, its value is overridden. */ void child_set_env(char ***envp, u_int *envsizep, const char *name, @@ -1789,7 +1795,7 @@ do_child(Session *s, const char *command) char *p, *args; setproctitle("%s@internal-sftp-server", s->pw->pw_name); - args = strdup(command ? command : "sftp-server"); + args = xstrdup(command ? command : "sftp-server"); for (i = 0, (p = strtok(args, " ")); p; (p = strtok(NULL, " "))) if (i < ARGV_MAX - 1) argv[i++] = p; diff --git a/sftp-server-main.c b/sftp-server-main.c index 2b14569e4756..7e644ab8982b 100644 --- a/sftp-server-main.c +++ b/sftp-server-main.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp-server-main.c,v 1.3 2008/03/26 23:44:41 djm Exp $ */ +/* $OpenBSD: sftp-server-main.c,v 1.4 2009/02/21 19:32:04 tobias Exp $ */ /* * Copyright (c) 2008 Markus Friedl. All rights reserved. * @@ -42,7 +42,8 @@ main(int argc, char **argv) sanitise_stdfd(); if ((user_pw = getpwuid(getuid())) == NULL) { - fprintf(stderr, "No user found for uid %lu", (u_long)getuid()); + fprintf(stderr, "No user found for uid %lu\n", + (u_long)getuid()); return 1; } diff --git a/sftp-server.0 b/sftp-server.0 index 941e99e14f78..510ceb64b4b4 100644 --- a/sftp-server.0 +++ b/sftp-server.0 @@ -47,4 +47,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 4.4 July 18, 2008 1 +OpenBSD 4.5 July 18, 2008 1 diff --git a/sftp.0 b/sftp.0 index 965e1fa18be3..4835c4f289eb 100644 --- a/sftp.0 +++ b/sftp.0 @@ -7,8 +7,8 @@ SYNOPSIS sftp [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config] [-o ssh_option] [-P sftp_server_path] [-R num_requests] [-S program] [-s subsystem | sftp_server] host - sftp [[user@]host[:file [file]]] - sftp [[user@]host[:dir[/]]] + sftp [user@]host[:file ...] + sftp [user@]host[:dir[/]] sftp -b batchfile [user@]host DESCRIPTION @@ -257,7 +257,7 @@ INTERACTIVE COMMANDS version Display the sftp protocol version. - ! command + !command Execute command in local shell. ! Escape to local shell. @@ -271,4 +271,4 @@ SEE ALSO T. Ylonen and S. Lehtinen, SSH File Transfer Protocol, draft-ietf-secsh- filexfer-00.txt, January 2001, work in progress material. -OpenBSD 4.4 July 15, 2008 5 +OpenBSD 4.5 December 9, 2008 5 diff --git a/sftp.1 b/sftp.1 index b4f9a6884554..37ccb3a38ba7 100644 --- a/sftp.1 +++ b/sftp.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: sftp.1,v 1.67 2008/07/15 02:23:14 djm Exp $ +.\" $OpenBSD: sftp.1,v 1.69 2008/12/09 15:35:00 sobrado Exp $ .\" .\" Copyright (c) 2001 Damien Miller. All rights reserved. .\" @@ -22,7 +22,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: July 15 2008 $ +.Dd $Mdocdate: December 9 2008 $ .Dt SFTP 1 .Os .Sh NAME @@ -43,13 +43,12 @@ .Ar host .Ek .Nm sftp -.Oo Oo Ar user Ns @ Oc Ns -.Ar host Ns Oo : Ns Ar file Oo -.Ar file Oc Oc Oc +.Oo Ar user Ns @ Oc Ns +.Ar host Ns Op : Ns Ar .Nm sftp -.Oo Oo Ar user Ns @ Oc Ns +.Oo Ar user Ns @ Oc Ns .Ar host Ns Oo : Ns Ar dir Ns -.Oo Ar / Oc Oc Oc +.Op Ar / Oc .Nm sftp .Fl b Ar batchfile .Oo Ar user Ns @ Oc Ns Ar host @@ -442,7 +441,7 @@ to Display the .Nm protocol version. -.It Ic \&! Ar command +.It Ic \&! Ns Ar command Execute .Ar command in local shell. diff --git a/sftp.c b/sftp.c index e1aa49d0f086..66bd111b122c 100644 --- a/sftp.c +++ b/sftp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sftp.c,v 1.103 2008/07/13 22:16:03 djm Exp $ */ +/* $OpenBSD: sftp.c,v 1.107 2009/02/02 11:15:14 dtucker Exp $ */ /* * Copyright (c) 2001-2004 Damien Miller * @@ -207,36 +207,37 @@ cmd_interrupt(int signo) static void help(void) { - printf("Available commands:\n"); - printf("cd path Change remote directory to 'path'\n"); - printf("lcd path Change local directory to 'path'\n"); - printf("chgrp grp path Change group of file 'path' to 'grp'\n"); - printf("chmod mode path Change permissions of file 'path' to 'mode'\n"); - printf("chown own path Change owner of file 'path' to 'own'\n"); - printf("df [path] Display statistics for current directory or\n"); - printf(" filesystem containing 'path'\n"); - printf("help Display this help text\n"); - printf("get remote-path [local-path] Download file\n"); - printf("lls [ls-options [path]] Display local directory listing\n"); - printf("ln oldpath newpath Symlink remote file\n"); - printf("lmkdir path Create local directory\n"); - printf("lpwd Print local working directory\n"); - printf("ls [path] Display remote directory listing\n"); - printf("lumask umask Set local umask to 'umask'\n"); - printf("mkdir path Create remote directory\n"); - printf("progress Toggle display of progress meter\n"); - printf("put local-path [remote-path] Upload file\n"); - printf("pwd Display remote working directory\n"); - printf("exit Quit sftp\n"); - printf("quit Quit sftp\n"); - printf("rename oldpath newpath Rename remote file\n"); - printf("rmdir path Remove remote directory\n"); - printf("rm path Delete remote file\n"); - printf("symlink oldpath newpath Symlink remote file\n"); - printf("version Show SFTP version\n"); - printf("!command Execute 'command' in local shell\n"); - printf("! Escape to local shell\n"); - printf("? Synonym for help\n"); + printf("Available commands:\n" + "bye Quit sftp\n" + "cd path Change remote directory to 'path'\n" + "chgrp grp path Change group of file 'path' to 'grp'\n" + "chmod mode path Change permissions of file 'path' to 'mode'\n" + "chown own path Change owner of file 'path' to 'own'\n" + "df [-hi] [path] Display statistics for current directory or\n" + " filesystem containing 'path'\n" + "exit Quit sftp\n" + "get [-P] remote-path [local-path] Download file\n" + "help Display this help text\n" + "lcd path Change local directory to 'path'\n" + "lls [ls-options [path]] Display local directory listing\n" + "lmkdir path Create local directory\n" + "ln oldpath newpath Symlink remote file\n" + "lpwd Print local working directory\n" + "ls [-1aflnrSt] [path] Display remote directory listing\n" + "lumask umask Set local umask to 'umask'\n" + "mkdir path Create remote directory\n" + "progress Toggle display of progress meter\n" + "put [-P] local-path [remote-path] Upload file\n" + "pwd Display remote working directory\n" + "quit Quit sftp\n" + "rename oldpath newpath Rename remote file\n" + "rm path Delete remote file\n" + "rmdir path Remove remote directory\n" + "symlink oldpath newpath Symlink remote file\n" + "version Show SFTP version\n" + "!command Execute 'command' in local shell\n" + "! Escape to local shell\n" + "? Synonym for help\n"); } static void @@ -1234,8 +1235,8 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, int err_abort) { char *path1, *path2, *tmp; - int pflag, lflag, iflag, hflag, cmdnum, i; - unsigned long n_arg; + int pflag = 0, lflag = 0, iflag = 0, hflag = 0, cmdnum, i; + unsigned long n_arg = 0; Attrib a, *aa; char path_buf[MAXPATHLEN]; int err = 0; @@ -1386,17 +1387,19 @@ parse_dispatch_command(struct sftp_conn *conn, const char *cmd, char **pwd, remote_glob(conn, path1, GLOB_NOCHECK, NULL, &g); for (i = 0; g.gl_pathv[i] && !interrupted; i++) { if (!(aa = do_stat(conn, g.gl_pathv[i], 0))) { - if (err != 0 && err_abort) + if (err_abort) { + err = -1; break; - else + } else continue; } if (!(aa->flags & SSH2_FILEXFER_ATTR_UIDGID)) { error("Can't get current ownership of " "remote file \"%s\"", g.gl_pathv[i]); - if (err != 0 && err_abort) + if (err_abort) { + err = -1; break; - else + } else continue; } aa->flags &= SSH2_FILEXFER_ATTR_UIDGID; @@ -1668,8 +1671,8 @@ usage(void) "usage: %s [-1Cv] [-B buffer_size] [-b batchfile] [-F ssh_config]\n" " [-o ssh_option] [-P sftp_server_path] [-R num_requests]\n" " [-S program] [-s subsystem | sftp_server] host\n" - " %s [[user@]host[:file [file]]]\n" - " %s [[user@]host[:dir[/]]]\n" + " %s [user@]host[:file ...]\n" + " %s [user@]host[:dir[/]]\n" " %s -b batchfile [user@]host\n", __progname, __progname, __progname, __progname); exit(1); } diff --git a/ssh-add.0 b/ssh-add.0 index 3652bb5e5f1b..2ef77d339e93 100644 --- a/ssh-add.0 +++ b/ssh-add.0 @@ -103,4 +103,4 @@ AUTHORS ated OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.4 June 12, 2007 2 +OpenBSD 4.5 June 12, 2007 2 diff --git a/ssh-agent.0 b/ssh-agent.0 index 90348a6b2bb7..c219432125bc 100644 --- a/ssh-agent.0 +++ b/ssh-agent.0 @@ -114,4 +114,4 @@ AUTHORS ated OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.4 June 5, 2007 2 +OpenBSD 4.5 June 5, 2007 2 diff --git a/ssh-keygen.0 b/ssh-keygen.0 index ca8b5cf8c721..b08d43b6d50d 100644 --- a/ssh-keygen.0 +++ b/ssh-keygen.0 @@ -14,7 +14,7 @@ SYNOPSIS ssh-keygen -l [-f input_keyfile] ssh-keygen -B [-f input_keyfile] ssh-keygen -D reader - ssh-keygen -F hostname [-f known_hosts_file] + ssh-keygen -F hostname [-f known_hosts_file] [-l] ssh-keygen -H [-f known_hosts_file] ssh-keygen -R hostname [-f known_hosts_file] ssh-keygen -U reader [-f input_keyfile] @@ -286,4 +286,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.4 June 12, 2008 5 +OpenBSD 4.5 July 24, 2008 5 diff --git a/ssh-keygen.1 b/ssh-keygen.1 index 3fff59e77082..3596cc1747c2 100644 --- a/ssh-keygen.1 +++ b/ssh-keygen.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keygen.1,v 1.78 2008/06/12 19:10:09 jmc Exp $ +.\" $OpenBSD: ssh-keygen.1,v 1.79 2008/07/24 23:55:30 sthen Exp $ .\" .\" -*- nroff -*- .\" @@ -37,7 +37,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: June 12 2008 $ +.Dd $Mdocdate: July 24 2008 $ .Dt SSH-KEYGEN 1 .Os .Sh NAME @@ -83,6 +83,7 @@ .Nm ssh-keygen .Fl F Ar hostname .Op Fl f Ar known_hosts_file +.Op Fl l .Nm ssh-keygen .Fl H .Op Fl f Ar known_hosts_file diff --git a/ssh-keygen.c b/ssh-keygen.c index f7e284062152..5765cff08849 100644 --- a/ssh-keygen.c +++ b/ssh-keygen.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keygen.c,v 1.171 2008/07/13 21:22:52 sthen Exp $ */ +/* $OpenBSD: ssh-keygen.c,v 1.173 2009/02/21 19:32:04 tobias Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1994 Tatu Ylonen , Espoo, Finland @@ -135,7 +135,7 @@ ask_filename(struct passwd *pw, const char *prompt) name = _PATH_SSH_CLIENT_ID_RSA; break; default: - fprintf(stderr, "bad key type"); + fprintf(stderr, "bad key type\n"); exit(1); break; } @@ -421,7 +421,7 @@ do_convert_from_ssh2(struct passwd *pw) PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) : key_write(k, stdout); if (!ok) { - fprintf(stderr, "key write failed"); + fprintf(stderr, "key write failed\n"); exit(1); } key_free(k); @@ -1015,11 +1015,11 @@ do_change_comment(struct passwd *pw) } f = fdopen(fd, "w"); if (f == NULL) { - printf("fdopen %s failed", identity_file); + printf("fdopen %s failed\n", identity_file); exit(1); } if (!key_write(public, f)) - fprintf(stderr, "write key failed"); + fprintf(stderr, "write key failed\n"); key_free(public); fprintf(f, " %s\n", new_comment); fclose(f); @@ -1366,7 +1366,7 @@ main(int argc, char **argv) printf("Generating public/private %s key pair.\n", key_type_name); private = key_generate(type, bits); if (private == NULL) { - fprintf(stderr, "key_generate failed"); + fprintf(stderr, "key_generate failed\n"); exit(1); } public = key_from_private(private); @@ -1426,7 +1426,7 @@ main(int argc, char **argv) if (identity_comment) { strlcpy(comment, identity_comment, sizeof(comment)); } else { - /* Create default commend field for the passphrase. */ + /* Create default comment field for the passphrase. */ snprintf(comment, sizeof comment, "%s@%s", pw->pw_name, hostname); } @@ -1456,11 +1456,11 @@ main(int argc, char **argv) } f = fdopen(fd, "w"); if (f == NULL) { - printf("fdopen %s failed", identity_file); + printf("fdopen %s failed\n", identity_file); exit(1); } if (!key_write(public, f)) - fprintf(stderr, "write key failed"); + fprintf(stderr, "write key failed\n"); fprintf(f, " %s\n", comment); fclose(f); diff --git a/ssh-keyscan.0 b/ssh-keyscan.0 index 5cd68816c57d..dadfd4b63ae2 100644 --- a/ssh-keyscan.0 +++ b/ssh-keyscan.0 @@ -5,7 +5,7 @@ NAME SYNOPSIS ssh-keyscan [-46Hv] [-f file] [-p port] [-T timeout] [-t type] - [host | addrlist namelist] [...] + [host | addrlist namelist] ... DESCRIPTION ssh-keyscan is a utility for gathering the public ssh host keys of a num- @@ -80,7 +80,7 @@ FILES /etc/ssh/ssh_known_hosts EXAMPLES - Print the rsa1 host key for machine hostname: + Print the rsa host key for machine hostname: $ ssh-keyscan hostname @@ -104,4 +104,4 @@ BUGS This is because it opens a connection to the ssh port, reads the public key, and drops the connection as soon as it gets the key. -OpenBSD 4.4 April 30, 2008 2 +OpenBSD 4.5 December 29, 2008 2 diff --git a/ssh-keyscan.1 b/ssh-keyscan.1 index 8a4f3bcba3cf..4a58645665e7 100644 --- a/ssh-keyscan.1 +++ b/ssh-keyscan.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ssh-keyscan.1,v 1.24 2008/04/30 10:14:03 djm Exp $ +.\" $OpenBSD: ssh-keyscan.1,v 1.26 2008/12/29 01:12:36 stevesk Exp $ .\" .\" Copyright 1995, 1996 by David Mazieres . .\" @@ -6,7 +6,7 @@ .\" permitted provided that due credit is given to the author and the .\" OpenBSD project by leaving this copyright notice intact. .\" -.Dd $Mdocdate: April 30 2008 $ +.Dd $Mdocdate: December 29 2008 $ .Dt SSH-KEYSCAN 1 .Os .Sh NAME @@ -21,7 +21,7 @@ .Op Fl T Ar timeout .Op Fl t Ar type .Op Ar host | addrlist namelist -.Op Ar ... +.Ar ... .Ek .Sh DESCRIPTION .Nm @@ -137,7 +137,7 @@ or .Pa /etc/ssh/ssh_known_hosts .Sh EXAMPLES Print the -.Pa rsa1 +.Pa rsa host key for machine .Pa hostname : .Bd -literal diff --git a/ssh-keyscan.c b/ssh-keyscan.c index d810777646e4..9a91be499ec7 100644 --- a/ssh-keyscan.c +++ b/ssh-keyscan.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-keyscan.c,v 1.76 2008/04/30 10:14:03 djm Exp $ */ +/* $OpenBSD: ssh-keyscan.c,v 1.78 2009/01/22 10:02:34 djm Exp $ */ /* * Copyright 1995, 1996 by David Mazieres . * @@ -713,8 +713,9 @@ fatal(const char *fmt,...) static void usage(void) { - fprintf(stderr, "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" - "\t\t [host | addrlist namelist] [...]\n", + fprintf(stderr, + "usage: %s [-46Hv] [-f file] [-p port] [-T timeout] [-t type]\n" + "\t\t [host | addrlist namelist] ...\n", __progname); exit(1); } @@ -747,7 +748,7 @@ main(int argc, char **argv) break; case 'p': ssh_port = a2port(optarg); - if (ssh_port == 0) { + if (ssh_port <= 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(1); } diff --git a/ssh-keysign.0 b/ssh-keysign.0 index 07ffeca5c2ff..5da5e5388ebe 100644 --- a/ssh-keysign.0 +++ b/ssh-keysign.0 @@ -39,4 +39,4 @@ HISTORY AUTHORS Markus Friedl -OpenBSD 4.4 May 31, 2007 1 +OpenBSD 4.5 May 31, 2007 1 diff --git a/ssh-rand-helper.0 b/ssh-rand-helper.0 index e1d31c1cd25b..690e14159128 100644 --- a/ssh-rand-helper.0 +++ b/ssh-rand-helper.0 @@ -48,4 +48,4 @@ AUTHORS SEE ALSO ssh(1), ssh-add(1), ssh-keygen(1), sshd(8) -OpenBSD 4.4 April 14, 2002 1 +OpenBSD 4.5 April 14, 2002 1 diff --git a/ssh.0 b/ssh.0 index 21e5ac9a38da..1788bf9ccceb 100644 --- a/ssh.0 +++ b/ssh.0 @@ -4,7 +4,7 @@ NAME ssh - OpenSSH SSH client (remote login program) SYNOPSIS - ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec] + ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec] [-D [bind_address:]port] [-e escape_char] [-F configfile] [-i identity_file] [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port] @@ -304,12 +304,15 @@ DESCRIPTION [bind_address/]host/port/hostport. By default, the listening socket on the server will be bound to - the loopback interface only. This may be overriden by specifying - a bind_address. An empty bind_address, or the address `*', indi- - cates that the remote socket should listen on all interfaces. + the loopback interface only. This may be overridden by specify- + ing a bind_address. An empty bind_address, or the address `*', + indicates that the remote socket should listen on all interfaces. Specifying a remote bind_address will only succeed if the serv- er's GatewayPorts option is enabled (see sshd_config(5)). + If the port argument is `0', the listen port will be dynamically + allocated on the server and reported to the client at run time. + -S ctl_path Specifies the location of a control socket for connection shar- ing. Refer to the description of ControlPath and ControlMaster @@ -365,6 +368,9 @@ DESCRIPTION -Y Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. + -y Send log information using the syslog(3) system module. By de- + fault this information is sent to stderr. + ssh may additionally obtain configuration data from a per-user configura- tion file and a system-wide configuration file. The file format and con- figuration options are described in ssh_config(5). @@ -500,8 +506,8 @@ ESCAPE CHARACTERS version 2 and if the peer supports it). ~C Open command line. Currently this allows the addition of port - forwardings using the -L and -R options (see above). It also al- - lows the cancellation of existing remote port-forwardings using + forwardings using the -L, -R and -D options (see above). It also + allows the cancellation of existing remote port-forwardings using -KR[bind_address:]port. !command allows the user to execute a local command if the PermitLocalCommand option is enabled in ssh_config(5). Basic help is available, using the -h option. @@ -864,4 +870,4 @@ AUTHORS created OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.4 July 2, 2008 14 +OpenBSD 4.5 February 12, 2009 14 diff --git a/ssh.1 b/ssh.1 index 1883578f2269..421783be3698 100644 --- a/ssh.1 +++ b/ssh.1 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh.1,v 1.277 2008/07/02 13:47:39 djm Exp $ -.Dd $Mdocdate: July 2 2008 $ +.\" $OpenBSD: ssh.1,v 1.282 2009/02/12 03:44:25 djm Exp $ +.Dd $Mdocdate: February 12 2009 $ .Dt SSH 1 .Os .Sh NAME @@ -43,7 +43,7 @@ .Nd OpenSSH SSH client (remote login program) .Sh SYNOPSIS .Nm ssh -.Op Fl 1246AaCfgKkMNnqsTtVvXxY +.Op Fl 1246AaCfgKkMNnqsTtVvXxYy .Op Fl b Ar bind_address .Op Fl c Ar cipher_spec .Oo Fl D\ \& @@ -550,7 +550,7 @@ using an alternative syntax: .Pp By default, the listening socket on the server will be bound to the loopback interface only. -This may be overriden by specifying a +This may be overridden by specifying a .Ar bind_address . An empty .Ar bind_address , @@ -563,6 +563,13 @@ will only succeed if the server's .Cm GatewayPorts option is enabled (see .Xr sshd_config 5 ) . +.Pp +If the +.Ar port +argument is +.Ql 0 , +the listen port will be dynamically allocated on the server and reported +to the client at run time. .It Fl S Ar ctl_path Specifies the location of a control socket for connection sharing. Refer to the description of @@ -658,6 +665,11 @@ Disables X11 forwarding. Enables trusted X11 forwarding. Trusted X11 forwardings are not subjected to the X11 SECURITY extension controls. +.It Fl y +Send log information using the +.Xr syslog 3 +system module. +By default this information is sent to stderr. .El .Pp .Nm @@ -893,9 +905,10 @@ Send a BREAK to the remote system .It Cm ~C Open command line. Currently this allows the addition of port forwardings using the -.Fl L -and +.Fl L , .Fl R +and +.Fl D options (see above). It also allows the cancellation of existing remote port-forwardings using diff --git a/ssh.c b/ssh.c index e2dd67d688bd..9d43bb74fc32 100644 --- a/ssh.c +++ b/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.318 2008/07/02 13:47:39 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.324 2009/02/12 03:00:56 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -179,7 +179,7 @@ static void usage(void) { fprintf(stderr, -"usage: ssh [-1246AaCfgKkMNnqsTtVvXxY] [-b bind_address] [-c cipher_spec]\n" +"usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" " [-D [bind_address:]port] [-e escape_char] [-F configfile]\n" " [-i identity_file] [-L [bind_address:]port:host:hostport]\n" " [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]\n" @@ -203,7 +203,7 @@ void muxserver_listen(void); int main(int ac, char **av) { - int i, opt, exit_status; + int i, opt, exit_status, use_syslog; char *p, *cp, *line, buf[256]; struct stat st; struct passwd *pw; @@ -269,10 +269,11 @@ main(int ac, char **av) /* Parse command-line arguments. */ host = NULL; + use_syslog = 0; again: while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" - "ACD:F:I:KL:MNO:PR:S:TVw:XY")) != -1) { + "ACD:F:I:KL:MNO:PR:S:TVw:XYy")) != -1) { switch (opt) { case '1': options.protocol = SSH_PROTO_1; @@ -299,6 +300,9 @@ main(int ac, char **av) case 'X': options.forward_x11 = 1; break; + case 'y': + use_syslog = 1; + break; case 'Y': options.forward_x11 = 1; options.forward_x11_trusted = 1; @@ -439,7 +443,7 @@ main(int ac, char **av) break; case 'p': options.port = a2port(optarg); - if (options.port == 0) { + if (options.port <= 0) { fprintf(stderr, "Bad port '%s'\n", optarg); exit(255); } @@ -449,7 +453,7 @@ main(int ac, char **av) break; case 'L': - if (parse_forward(&fwd, optarg)) + if (parse_forward(&fwd, optarg, 0, 0)) add_local_forward(&options, &fwd); else { fprintf(stderr, @@ -460,7 +464,7 @@ main(int ac, char **av) break; case 'R': - if (parse_forward(&fwd, optarg)) { + if (parse_forward(&fwd, optarg, 0, 1)) { add_remote_forward(&options, &fwd); } else { fprintf(stderr, @@ -471,30 +475,14 @@ main(int ac, char **av) break; case 'D': - cp = p = xstrdup(optarg); - memset(&fwd, '\0', sizeof(fwd)); - fwd.connect_host = "socks"; - if ((fwd.listen_host = hpdelim(&cp)) == NULL) { - fprintf(stderr, "Bad dynamic forwarding " - "specification '%.100s'\n", optarg); - exit(255); - } - if (cp != NULL) { - fwd.listen_port = a2port(cp); - fwd.listen_host = - cleanhostname(fwd.listen_host); + if (parse_forward(&fwd, optarg, 1, 0)) { + add_local_forward(&options, &fwd); } else { - fwd.listen_port = a2port(fwd.listen_host); - fwd.listen_host = NULL; - } - - if (fwd.listen_port == 0) { - fprintf(stderr, "Bad dynamic port '%s'\n", - optarg); + fprintf(stderr, + "Bad dynamic forwarding specification " + "'%s'\n", optarg); exit(255); } - add_local_forward(&options, &fwd); - xfree(p); break; case 'C': @@ -614,7 +602,7 @@ main(int ac, char **av) */ log_init(av[0], options.log_level == -1 ? SYSLOG_LEVEL_INFO : options.log_level, - SYSLOG_FACILITY_USER, 1); + SYSLOG_FACILITY_USER, !use_syslog); /* * Read per-user configuration file. Ignore the system wide config @@ -640,7 +628,7 @@ main(int ac, char **av) channel_set_af(options.address_family); /* reinit */ - log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, 1); + log_init(av[0], options.log_level, SYSLOG_FACILITY_USER, !use_syslog); seed_rng(); @@ -849,9 +837,16 @@ ssh_confirm_remote_forward(int type, u_int32_t seq, void *ctxt) { Forward *rfwd = (Forward *)ctxt; + /* XXX verbose() on failure? */ debug("remote forward %s for: listen %d, connect %s:%d", type == SSH2_MSG_REQUEST_SUCCESS ? "success" : "failure", rfwd->listen_port, rfwd->connect_host, rfwd->connect_port); + if (type == SSH2_MSG_REQUEST_SUCCESS && rfwd->listen_port == 0) { + logit("Allocated port %u for remote forward to %s:%d", + packet_get_int(), + rfwd->connect_host, rfwd->connect_port); + } + if (type == SSH2_MSG_REQUEST_FAILURE) { if (options.exit_on_forward_failure) fatal("Error: remote port forwarding failed for " @@ -1200,7 +1195,8 @@ ssh_session2(void) id = ssh_session2_open(); /* If we don't expect to open a new session, then disallow it */ - if (options.control_master == SSHCTL_MASTER_NO) { + if (options.control_master == SSHCTL_MASTER_NO && + (datafellows & SSH_NEW_OPENSSH)) { debug("Requesting no-more-sessions@openssh.com"); packet_start(SSH2_MSG_GLOBAL_REQUEST); packet_put_cstring("no-more-sessions@openssh.com"); diff --git a/ssh2.h b/ssh2.h index cf56bc4ee135..1c33dc268b38 100644 --- a/ssh2.h +++ b/ssh2.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh2.h,v 1.10 2006/03/25 22:22:43 djm Exp $ */ +/* $OpenBSD: ssh2.h,v 1.11 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. @@ -111,6 +111,12 @@ #define SSH2_MSG_USERAUTH_PASSWD_CHANGEREQ 60 #define SSH2_MSG_USERAUTH_INFO_REQUEST 60 #define SSH2_MSG_USERAUTH_INFO_RESPONSE 61 +#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1 60 +#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1 61 +#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2 62 +#define SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2 63 +#define SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM 64 +#define SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM 65 /* connection protocol: generic */ @@ -159,3 +165,4 @@ #define SSH2_OPEN_RESOURCE_SHORTAGE 4 #define SSH2_EXTENDED_DATA_STDERR 1 + diff --git a/ssh_config b/ssh_config index 8cb0698a8d89..f28d59583477 100644 --- a/ssh_config +++ b/ssh_config @@ -1,4 +1,4 @@ -# $OpenBSD: ssh_config,v 1.23 2007/06/08 04:40:40 pvalchev Exp $ +# $OpenBSD: ssh_config,v 1.25 2009/02/17 01:28:32 djm Exp $ # This is the ssh client system-wide configuration file. See # ssh_config(5) for more information. This file provides defaults for @@ -37,9 +37,10 @@ # Port 22 # Protocol 2,1 # Cipher 3des -# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc +# Ciphers aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128,aes128-cbc,3des-cbc # MACs hmac-md5,hmac-sha1,umac-64@openssh.com,hmac-ripemd160 # EscapeChar ~ # Tunnel no # TunnelDevice any:any # PermitLocalCommand no +# VisualHostKey no diff --git a/ssh_config.0 b/ssh_config.0 index e2e645854041..e5ded8e31975 100644 --- a/ssh_config.0 +++ b/ssh_config.0 @@ -41,7 +41,7 @@ DESCRIPTION Host Restricts the following declarations (up to the next Host key- word) to be only for those hosts that match one of the patterns given after the keyword. If more than one pattern is provided, - they should be separated by whitepsace. A single `*' as a pat- + they should be separated by whitespace. A single `*' as a pat- tern can be used to provide global defaults for all hosts. The host is the hostname argument given on the command line (i.e. the name is not converted to a canonicalized host name before match- @@ -93,9 +93,9 @@ DESCRIPTION ``arcfour128'', ``arcfour256'', ``arcfour'', ``blowfish-cbc'', and ``cast128-cbc''. The default is: - aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, - arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, - aes192-ctr,aes256-ctr + aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, + aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, + aes256-cbc,arcfour ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings @@ -463,8 +463,11 @@ DESCRIPTION specified by enclosing addresses in square brackets or by using an alternative syntax: [bind_address/]port and host/hostport. Multiple forwardings may be specified, and additional forwardings - can be given on the command line. Only the superuser can forward - privileged ports. + can be given on the command line. Privileged ports can be for- + warded only when logging in as root on the remote machine. + + If the port argument is `0', the listen port will be dynamically + allocated on the server and reported to the client at run time. If the bind_address is not specified, the default is to only bind to loopback addresses. If the bind_address is `*' or an empty @@ -609,9 +612,11 @@ DESCRIPTION VisualHostKey If this flag is set to ``yes'', an ASCII art representation of - the remote host key fingerprint is printed additionally to the - hex fingerprint string. If this flag is set to ``no'', only the - hex fingerprint string will be printed. The default is ``no''. + the remote host key fingerprint is printed in addition to the hex + fingerprint string at login and for unknown host keys. If this + flag is set to ``no'', no fingerprint strings are printed at lo- + gin and only the hex fingerprint string will be printed for un- + known host keys. The default is ``no''. XAuthLocation Specifies the full pathname of the xauth(1) program. The default @@ -662,4 +667,4 @@ AUTHORS ated OpenSSH. Markus Friedl contributed the support for SSH protocol versions 1.5 and 2.0. -OpenBSD 4.4 June 26, 2008 11 +OpenBSD 4.5 February 22, 2009 11 diff --git a/ssh_config.5 b/ssh_config.5 index 85e7ba06d7d8..ea9a20b23e33 100644 --- a/ssh_config.5 +++ b/ssh_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: ssh_config.5,v 1.111 2008/06/26 11:46:31 grunk Exp $ -.Dd $Mdocdate: June 26 2008 $ +.\" $OpenBSD: ssh_config.5,v 1.119 2009/02/22 23:50:57 djm Exp $ +.Dd $Mdocdate: February 22 2009 $ .Dt SSH_CONFIG 5 .Os .Sh NAME @@ -103,7 +103,7 @@ Restricts the following declarations (up to the next .Cm Host keyword) to be only for those hosts that match one of the patterns given after the keyword. -If more than one pattern is provided, they should be separated by whitepsace. +If more than one pattern is provided, they should be separated by whitespace. A single .Ql * as a pattern can be used to provide global @@ -204,9 +204,9 @@ and .Dq cast128-cbc . The default is: .Bd -literal -offset 3n -aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, -arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, -aes192-ctr,aes256-ctr +aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, +aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, +aes256-cbc,arcfour .Ed .It Cm ClearAllForwardings Specifies that all local, remote, and dynamic port forwardings @@ -811,7 +811,15 @@ and .Ar host Ns / Ns Ar hostport . Multiple forwardings may be specified, and additional forwardings can be given on the command line. -Only the superuser can forward privileged ports. +Privileged ports can be forwarded only when +logging in as root on the remote machine. +.Pp +If the +.Ar port +argument is +.Ql 0 , +the listen port will be dynamically allocated on the server and reported +to the client at run time. .Pp If the .Ar bind_address @@ -1064,10 +1072,12 @@ in If this flag is set to .Dq yes , an ASCII art representation of the remote host key fingerprint is -printed additionally to the hex fingerprint string. +printed in addition to the hex fingerprint string at login and +for unknown host keys. If this flag is set to .Dq no , -only the hex fingerprint string will be printed. +no fingerprint strings are printed at login and +only the hex fingerprint string will be printed for unknown host keys. The default is .Dq no . .It Cm XAuthLocation diff --git a/sshconnect.c b/sshconnect.c index ec8ba33e0167..c04aa1057181 100644 --- a/sshconnect.c +++ b/sshconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshconnect.c,v 1.211 2008/07/01 07:24:22 dtucker Exp $ */ +/* $OpenBSD: sshconnect.c,v 1.212 2008/10/14 18:11:33 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -70,10 +70,6 @@ extern uid_t original_real_uid; extern uid_t original_effective_uid; extern pid_t proxy_command_pid; -#ifndef INET6_ADDRSTRLEN /* for non IPv6 machines */ -#define INET6_ADDRSTRLEN 46 -#endif - static int show_other_keys(const char *, Key *); static void warn_changed_key(Key *); @@ -741,8 +737,8 @@ check_host_key(char *hostname, struct sockaddr *hostaddr, u_short port, if (options.host_key_alias == NULL && port != 0 && port != SSH_DEFAULT_PORT) { debug("checking without port identifier"); - if (check_host_key(hostname, hostaddr, 0, host_key, 2, - user_hostfile, system_hostfile) == 0) { + if (check_host_key(hostname, hostaddr, 0, host_key, + ROQUIET, user_hostfile, system_hostfile) == 0) { debug("found matching key w/out port"); break; } diff --git a/sshconnect2.c b/sshconnect2.c index 067c875df1b9..a762eec3bdb4 100644 --- a/sshconnect2.c +++ b/sshconnect2.c @@ -1,6 +1,7 @@ -/* $OpenBSD: sshconnect2.c,v 1.166 2008/07/17 08:48:00 djm Exp $ */ +/* $OpenBSD: sshconnect2.c,v 1.170 2008/11/04 08:22:13 djm Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. + * Copyright (c) 2008 Damien Miller. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -67,6 +68,7 @@ #include "msg.h" #include "pathnames.h" #include "uidswap.h" +#include "jpake.h" #ifdef GSSAPI #include "ssh-gss.h" @@ -201,6 +203,7 @@ struct Authctxt { struct Authmethod { char *name; /* string to compare against server's list */ int (*userauth)(Authctxt *authctxt); + void (*cleanup)(Authctxt *authctxt); int *enabled; /* flag in option struct that enables method */ int *batch_flag; /* flag in option struct that disables method */ }; @@ -212,13 +215,18 @@ void input_userauth_error(int, u_int32_t, void *); void input_userauth_info_req(int, u_int32_t, void *); void input_userauth_pk_ok(int, u_int32_t, void *); void input_userauth_passwd_changereq(int, u_int32_t, void *); +void input_userauth_jpake_server_step1(int, u_int32_t, void *); +void input_userauth_jpake_server_step2(int, u_int32_t, void *); +void input_userauth_jpake_server_confirm(int, u_int32_t, void *); int userauth_none(Authctxt *); int userauth_pubkey(Authctxt *); int userauth_passwd(Authctxt *); int userauth_kbdint(Authctxt *); int userauth_hostbased(Authctxt *); -int userauth_kerberos(Authctxt *); +int userauth_jpake(Authctxt *); + +void userauth_jpake_cleanup(Authctxt *); #ifdef GSSAPI int userauth_gssapi(Authctxt *authctxt); @@ -244,30 +252,43 @@ Authmethod authmethods[] = { #ifdef GSSAPI {"gssapi-with-mic", userauth_gssapi, + NULL, &options.gss_authentication, NULL}, #endif {"hostbased", userauth_hostbased, + NULL, &options.hostbased_authentication, NULL}, {"publickey", userauth_pubkey, + NULL, &options.pubkey_authentication, NULL}, +#ifdef JPAKE + {"jpake-01@openssh.com", + userauth_jpake, + userauth_jpake_cleanup, + &options.zero_knowledge_password_authentication, + &options.batch_mode}, +#endif {"keyboard-interactive", userauth_kbdint, + NULL, &options.kbd_interactive_authentication, &options.batch_mode}, {"password", userauth_passwd, + NULL, &options.password_authentication, &options.batch_mode}, {"none", userauth_none, NULL, + NULL, NULL}, - {NULL, NULL, NULL, NULL} + {NULL, NULL, NULL, NULL, NULL} }; void @@ -335,6 +356,9 @@ ssh_userauth2(const char *local_user, const char *server_user, char *host, void userauth(Authctxt *authctxt, char *authlist) { + if (authctxt->method != NULL && authctxt->method->cleanup != NULL) + authctxt->method->cleanup(authctxt); + if (authctxt->methoddata) { xfree(authctxt->methoddata); authctxt->methoddata = NULL; @@ -367,6 +391,7 @@ userauth(Authctxt *authctxt, char *authlist) } } +/* ARGSUSED */ void input_userauth_error(int type, u_int32_t seq, void *ctxt) { @@ -374,6 +399,7 @@ input_userauth_error(int type, u_int32_t seq, void *ctxt) "type %d", type); } +/* ARGSUSED */ void input_userauth_banner(int type, u_int32_t seq, void *ctxt) { @@ -383,12 +409,11 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) debug3("input_userauth_banner"); raw = packet_get_string(&len); lang = packet_get_string(NULL); - if (options.log_level >= SYSLOG_LEVEL_INFO) { + if (len > 0 && options.log_level >= SYSLOG_LEVEL_INFO) { if (len > 65536) len = 65536; msg = xmalloc(len * 4 + 1); /* max expansion from strnvis() */ - strnvis(msg, raw, len * 4, VIS_SAFE|VIS_OCTAL); - msg[len*4] = '\0'; + strnvis(msg, raw, len * 4 + 1, VIS_SAFE|VIS_OCTAL); fprintf(stderr, "%s", msg); xfree(msg); } @@ -396,6 +421,7 @@ input_userauth_banner(int type, u_int32_t seq, void *ctxt) xfree(lang); } +/* ARGSUSED */ void input_userauth_success(int type, u_int32_t seq, void *ctxt) { @@ -413,6 +439,7 @@ input_userauth_success(int type, u_int32_t seq, void *ctxt) authctxt->success = 1; /* break out */ } +/* ARGSUSED */ void input_userauth_failure(int type, u_int32_t seq, void *ctxt) { @@ -433,6 +460,8 @@ input_userauth_failure(int type, u_int32_t seq, void *ctxt) userauth(authctxt, authlist); } + +/* ARGSUSED */ void input_userauth_pk_ok(int type, u_int32_t seq, void *ctxt) { @@ -615,6 +644,7 @@ process_gssapi_token(void *ctxt, gss_buffer_t recv_tok) return status; } +/* ARGSUSED */ void input_gssapi_response(int type, u_int32_t plen, void *ctxt) { @@ -654,6 +684,7 @@ input_gssapi_response(int type, u_int32_t plen, void *ctxt) } } +/* ARGSUSED */ void input_gssapi_token(int type, u_int32_t plen, void *ctxt) { @@ -681,6 +712,7 @@ input_gssapi_token(int type, u_int32_t plen, void *ctxt) } } +/* ARGSUSED */ void input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) { @@ -710,6 +742,7 @@ input_gssapi_errtok(int type, u_int32_t plen, void *ctxt) /* Server will be returning a failed packet after this one */ } +/* ARGSUSED */ void input_gssapi_error(int type, u_int32_t plen, void *ctxt) { @@ -774,9 +807,11 @@ userauth_passwd(Authctxt *authctxt) return 1; } + /* * parse PASSWD_CHANGEREQ, prompt user and send SSH2_MSG_USERAUTH_REQUEST */ +/* ARGSUSED */ void input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) { @@ -841,6 +876,209 @@ input_userauth_passwd_changereq(int type, u_int32_t seqnr, void *ctxt) &input_userauth_passwd_changereq); } +#ifdef JPAKE +static char * +pw_encrypt(const char *password, const char *crypt_scheme, const char *salt) +{ + /* OpenBSD crypt(3) handles all of these */ + if (strcmp(crypt_scheme, "crypt") == 0 || + strcmp(crypt_scheme, "bcrypt") == 0 || + strcmp(crypt_scheme, "md5crypt") == 0 || + strcmp(crypt_scheme, "crypt-extended") == 0) + return xstrdup(crypt(password, salt)); + error("%s: unsupported password encryption scheme \"%.100s\"", + __func__, crypt_scheme); + return NULL; +} + +static BIGNUM * +jpake_password_to_secret(Authctxt *authctxt, const char *crypt_scheme, + const char *salt) +{ + char prompt[256], *password, *crypted; + u_char *secret; + u_int secret_len; + BIGNUM *ret; + + snprintf(prompt, sizeof(prompt), "%.30s@%.128s's password (JPAKE): ", + authctxt->server_user, authctxt->host); + password = read_passphrase(prompt, 0); + + if ((crypted = pw_encrypt(password, crypt_scheme, salt)) == NULL) { + logit("Disabling %s authentication", authctxt->method->name); + authctxt->method->enabled = NULL; + /* Continue with an empty password to fail gracefully */ + crypted = xstrdup(""); + } + +#ifdef JPAKE_DEBUG + debug3("%s: salt = %s", __func__, salt); + debug3("%s: scheme = %s", __func__, crypt_scheme); + debug3("%s: crypted = %s", __func__, crypted); +#endif + + if (hash_buffer(crypted, strlen(crypted), EVP_sha256(), + &secret, &secret_len) != 0) + fatal("%s: hash_buffer", __func__); + + bzero(password, strlen(password)); + bzero(crypted, strlen(crypted)); + xfree(password); + xfree(crypted); + + if ((ret = BN_bin2bn(secret, secret_len, NULL)) == NULL) + fatal("%s: BN_bin2bn (secret)", __func__); + bzero(secret, secret_len); + xfree(secret); + + return ret; +} + +/* ARGSUSED */ +void +input_userauth_jpake_server_step1(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->methoddata; + u_char *x3_proof, *x4_proof, *x2_s_proof; + u_int x3_proof_len, x4_proof_len, x2_s_proof_len; + char *crypt_scheme, *salt; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, NULL); + + if ((pctx->g_x3 = BN_new()) == NULL || + (pctx->g_x4 = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Fetch step 1 values */ + crypt_scheme = packet_get_string(NULL); + salt = packet_get_string(NULL); + pctx->server_id = packet_get_string(&pctx->server_id_len); + packet_get_bignum2(pctx->g_x3); + packet_get_bignum2(pctx->g_x4); + x3_proof = packet_get_string(&x3_proof_len); + x4_proof = packet_get_string(&x4_proof_len); + packet_check_eom(); + + JPAKE_DEBUG_CTX((pctx, "step 1 received in %s", __func__)); + + /* Obtain password and derive secret */ + pctx->s = jpake_password_to_secret(authctxt, crypt_scheme, salt); + bzero(crypt_scheme, strlen(crypt_scheme)); + bzero(salt, strlen(salt)); + xfree(crypt_scheme); + xfree(salt); + JPAKE_DEBUG_BN((pctx->s, "%s: s = ", __func__)); + + /* Calculate step 2 values */ + jpake_step2(pctx->grp, pctx->s, pctx->g_x1, + pctx->g_x3, pctx->g_x4, pctx->x2, + pctx->server_id, pctx->server_id_len, + pctx->client_id, pctx->client_id_len, + x3_proof, x3_proof_len, + x4_proof, x4_proof_len, + &pctx->a, + &x2_s_proof, &x2_s_proof_len); + + bzero(x3_proof, x3_proof_len); + bzero(x4_proof, x4_proof_len); + xfree(x3_proof); + xfree(x4_proof); + + JPAKE_DEBUG_CTX((pctx, "step 2 sending in %s", __func__)); + + /* Send values for step 2 */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP2); + packet_put_bignum2(pctx->a); + packet_put_string(x2_s_proof, x2_s_proof_len); + packet_send(); + + bzero(x2_s_proof, x2_s_proof_len); + xfree(x2_s_proof); + + /* Expect step 2 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, + input_userauth_jpake_server_step2); +} + +/* ARGSUSED */ +void +input_userauth_jpake_server_step2(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->methoddata; + u_char *x4_s_proof; + u_int x4_s_proof_len; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP2, NULL); + + if ((pctx->b = BN_new()) == NULL) + fatal("%s: BN_new", __func__); + + /* Fetch step 2 values */ + packet_get_bignum2(pctx->b); + x4_s_proof = packet_get_string(&x4_s_proof_len); + packet_check_eom(); + + JPAKE_DEBUG_CTX((pctx, "step 2 received in %s", __func__)); + + /* Derive shared key and calculate confirmation hash */ + jpake_key_confirm(pctx->grp, pctx->s, pctx->b, + pctx->x2, pctx->g_x1, pctx->g_x2, pctx->g_x3, pctx->g_x4, + pctx->client_id, pctx->client_id_len, + pctx->server_id, pctx->server_id_len, + session_id2, session_id2_len, + x4_s_proof, x4_s_proof_len, + &pctx->k, + &pctx->h_k_cid_sessid, &pctx->h_k_cid_sessid_len); + + bzero(x4_s_proof, x4_s_proof_len); + xfree(x4_s_proof); + + JPAKE_DEBUG_CTX((pctx, "confirm sending in %s", __func__)); + + /* Send key confirmation proof */ + packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_CONFIRM); + packet_put_string(pctx->h_k_cid_sessid, pctx->h_k_cid_sessid_len); + packet_send(); + + /* Expect confirmation from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, + input_userauth_jpake_server_confirm); +} + +/* ARGSUSED */ +void +input_userauth_jpake_server_confirm(int type, u_int32_t seq, void *ctxt) +{ + Authctxt *authctxt = ctxt; + struct jpake_ctx *pctx = authctxt->methoddata; + + /* Disable this message */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_CONFIRM, NULL); + + pctx->h_k_sid_sessid = packet_get_string(&pctx->h_k_sid_sessid_len); + packet_check_eom(); + + JPAKE_DEBUG_CTX((pctx, "confirm received in %s", __func__)); + + /* Verify expected confirmation hash */ + if (jpake_check_confirm(pctx->k, + pctx->server_id, pctx->server_id_len, + session_id2, session_id2_len, + pctx->h_k_sid_sessid, pctx->h_k_sid_sessid_len) == 1) + debug("%s: %s success", __func__, authctxt->method->name); + else { + debug("%s: confirmation mismatch", __func__); + /* XXX stash this so if auth succeeds then we can warn/kill */ + } + + userauth_jpake_cleanup(authctxt); +} +#endif /* JPAKE */ + static int identity_sign(Identity *id, u_char **sigp, u_int *lenp, u_char *data, u_int datalen) @@ -1415,6 +1653,76 @@ userauth_hostbased(Authctxt *authctxt) return 1; } +#ifdef JPAKE +int +userauth_jpake(Authctxt *authctxt) +{ + struct jpake_ctx *pctx; + u_char *x1_proof, *x2_proof; + u_int x1_proof_len, x2_proof_len; + static int attempt = 0; /* XXX share with userauth_password's? */ + + if (attempt++ >= options.number_of_password_prompts) + return 0; + if (attempt != 1) + error("Permission denied, please try again."); + + if (authctxt->methoddata != NULL) + fatal("%s: authctxt->methoddata already set (%p)", + __func__, authctxt->methoddata); + + authctxt->methoddata = pctx = jpake_new(); + + /* + * Send request immediately, to get the protocol going while + * we do the initial computations. + */ + packet_start(SSH2_MSG_USERAUTH_REQUEST); + packet_put_cstring(authctxt->server_user); + packet_put_cstring(authctxt->service); + packet_put_cstring(authctxt->method->name); + packet_send(); + packet_write_wait(); + + jpake_step1(pctx->grp, + &pctx->client_id, &pctx->client_id_len, + &pctx->x1, &pctx->x2, &pctx->g_x1, &pctx->g_x2, + &x1_proof, &x1_proof_len, + &x2_proof, &x2_proof_len); + + JPAKE_DEBUG_CTX((pctx, "step 1 sending in %s", __func__)); + + packet_start(SSH2_MSG_USERAUTH_JPAKE_CLIENT_STEP1); + packet_put_string(pctx->client_id, pctx->client_id_len); + packet_put_bignum2(pctx->g_x1); + packet_put_bignum2(pctx->g_x2); + packet_put_string(x1_proof, x1_proof_len); + packet_put_string(x2_proof, x2_proof_len); + packet_send(); + + bzero(x1_proof, x1_proof_len); + bzero(x2_proof, x2_proof_len); + xfree(x1_proof); + xfree(x2_proof); + + /* Expect step 1 packet from peer */ + dispatch_set(SSH2_MSG_USERAUTH_JPAKE_SERVER_STEP1, + input_userauth_jpake_server_step1); + + return 1; +} + +void +userauth_jpake_cleanup(Authctxt *authctxt) +{ + debug3("%s: clean up", __func__); + if (authctxt->methoddata != NULL) { + jpake_free(authctxt->methoddata); + authctxt->methoddata = NULL; + } +} +#endif /* JPAKE */ + /* find auth method */ /* @@ -1516,3 +1824,4 @@ authmethods_get(void) buffer_free(&b); return list; } + diff --git a/sshd.0 b/sshd.0 index 04d64776ee3e..d6f02324e5a8 100644 --- a/sshd.0 +++ b/sshd.0 @@ -458,8 +458,7 @@ FILES are writable by other users, then the file could be modified or replaced by unauthorized users. In this case, sshd will not al- low it to be used unless the StrictModes option has been set to - ``no''. The recommended permissions can be set by executing - ``chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys''. + ``no''. ~/.ssh/environment This file is read into the environment at login (if it exists). @@ -572,4 +571,4 @@ CAVEATS System security is not improved unless rshd, rlogind, and rexecd are dis- abled (thus completely disabling rlogin and rsh into the machine). -OpenBSD 4.4 July 2, 2008 9 +OpenBSD 4.5 October 3, 2008 9 diff --git a/sshd.8 b/sshd.8 index c4c4181fcda3..a4b9e90c718a 100644 --- a/sshd.8 +++ b/sshd.8 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd.8,v 1.246 2008/07/02 02:24:18 djm Exp $ -.Dd $Mdocdate: July 2 2008 $ +.\" $OpenBSD: sshd.8,v 1.247 2008/10/03 13:08:12 jmc Exp $ +.Dd $Mdocdate: October 3 2008 $ .Dt SSHD 8 .Os .Sh NAME @@ -741,8 +741,6 @@ will not allow it to be used unless the .Cm StrictModes option has been set to .Dq no . -The recommended permissions can be set by executing -.Dq chmod go-w ~/ ~/.ssh ~/.ssh/authorized_keys . .Pp .It ~/.ssh/environment This file is read into the environment at login (if it exists). diff --git a/sshd.c b/sshd.c index 6e5bb5476a57..3b5cd3cfd60e 100644 --- a/sshd.c +++ b/sshd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sshd.c,v 1.364 2008/07/10 18:08:11 markus Exp $ */ +/* $OpenBSD: sshd.c,v 1.366 2009/01/22 10:02:34 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -117,7 +117,6 @@ #include "ssh-gss.h" #endif #include "monitor_wrap.h" -#include "monitor_fdpass.h" #include "version.h" #ifdef LIBWRAP @@ -1334,7 +1333,7 @@ main(int ac, char **av) exit(1); } options.ports[options.num_ports++] = a2port(optarg); - if (options.ports[options.num_ports-1] == 0) { + if (options.ports[options.num_ports-1] <= 0) { fprintf(stderr, "Bad port number.\n"); exit(1); } diff --git a/sshd_config.0 b/sshd_config.0 index 15a6c9004a47..067f757dea80 100644 --- a/sshd_config.0 +++ b/sshd_config.0 @@ -122,9 +122,9 @@ DESCRIPTION ``arcfour256'', ``arcfour'', ``blowfish-cbc'', and ``cast128-cbc''. The default is: - aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, - arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, - aes192-ctr,aes256-ctr + aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, + aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, + aes256-cbc,arcfour ClientAliveCountMax Sets the number of client alive messages (see below) which may be @@ -337,13 +337,14 @@ DESCRIPTION example, ``192.0.2.0/33'' and ``192.0.2.0/8'' respectively. Only a subset of keywords may be used on the lines following a - Match keyword. Available keywords are AllowTcpForwarding, - Banner, ChrootDirectory, ForceCommand, GatewayPorts, - GSSAPIAuthentication, HostbasedAuthentication, + Match keyword. Available keywords are AllowAgentForwarding, + AllowTcpForwarding, Banner, ChrootDirectory, ForceCommand, + GatewayPorts, GSSAPIAuthentication, HostbasedAuthentication, KbdInteractiveAuthentication, KerberosAuthentication, - MaxAuthTries, MaxSessions, PasswordAuthentication, PermitOpen, - PermitRootLogin, RhostsRSAAuthentication, RSAAuthentication, - X11DisplayOffset, X11Forwarding, and X11UseLocalHost. + MaxAuthTries, MaxSessions, PasswordAuthentication, + PermitEmptyPasswords, PermitOpen, PermitRootLogin, + RhostsRSAAuthentication, RSAAuthentication, X11DisplayOffset, + X11Forwarding and X11UseLocalHost. MaxAuthTries Specifies the maximum number of authentication attempts permitted @@ -627,4 +628,4 @@ AUTHORS versions 1.5 and 2.0. Niels Provos and Markus Friedl contributed support for privilege separation. -OpenBSD 4.4 July 2, 2008 10 +OpenBSD 4.5 February 22, 2009 10 diff --git a/sshd_config.5 b/sshd_config.5 index 7255b1c22600..dfd07b713ee2 100644 --- a/sshd_config.5 +++ b/sshd_config.5 @@ -34,8 +34,8 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.\" $OpenBSD: sshd_config.5,v 1.96 2008/07/02 02:24:18 djm Exp $ -.Dd $Mdocdate: July 2 2008 $ +.\" $OpenBSD: sshd_config.5,v 1.102 2009/02/22 23:59:25 djm Exp $ +.Dd $Mdocdate: February 22 2009 $ .Dt SSHD_CONFIG 5 .Os .Sh NAME @@ -240,9 +240,9 @@ and .Dq cast128-cbc . The default is: .Bd -literal -offset 3n -aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour128, -arcfour256,arcfour,aes192-cbc,aes256-cbc,aes128-ctr, -aes192-ctr,aes256-ctr +aes128-ctr,aes192-ctr,aes256-ctr,arcfour256,arcfour128, +aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,aes192-cbc, +aes256-cbc,arcfour .Ed .It Cm ClientAliveCountMax Sets the number of client alive messages (see below) which may be @@ -593,6 +593,7 @@ Only a subset of keywords may be used on the lines following a .Cm Match keyword. Available keywords are +.Cm AllowAgentForwarding , .Cm AllowTcpForwarding , .Cm Banner , .Cm ChrootDirectory , @@ -605,12 +606,13 @@ Available keywords are .Cm MaxAuthTries , .Cm MaxSessions , .Cm PasswordAuthentication , +.Cm PermitEmptyPasswords , .Cm PermitOpen , .Cm PermitRootLogin , .Cm RhostsRSAAuthentication , .Cm RSAAuthentication , .Cm X11DisplayOffset , -.Cm X11Forwarding , +.Cm X11Forwarding and .Cm X11UseLocalHost . .It Cm MaxAuthTries diff --git a/sshpty.c b/sshpty.c index 5a0d1a7adb12..bbbc0fefee54 100644 --- a/sshpty.c +++ b/sshpty.c @@ -46,6 +46,13 @@ #define O_NOCTTY 0 #endif +#ifdef __APPLE__ +# include +# if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) +# define __APPLE_PRIVPTY__ +# endif +#endif + /* * Allocates and opens a pty. Returns 0 if no pty could be allocated, or * nonzero if a pty was successfully allocated. On success, open file @@ -78,10 +85,12 @@ pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, size_t namebuflen) void pty_release(const char *tty) { +#ifndef __APPLE_PRIVPTY__ if (chown(tty, (uid_t) 0, (gid_t) 0) < 0) error("chown %.100s 0 0 failed: %.100s", tty, strerror(errno)); if (chmod(tty, (mode_t) 0666) < 0) error("chmod %.100s 0666 failed: %.100s", tty, strerror(errno)); +#endif /* __APPLE_PRIVPTY__ */ } /* Makes the tty the process's controlling tty and sets it to sane modes. */ diff --git a/ttymodes.c b/ttymodes.c index e116b1999069..6f51b8a70836 100644 --- a/ttymodes.c +++ b/ttymodes.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ttymodes.c,v 1.28 2008/07/07 00:31:41 stevesk Exp $ */ +/* $OpenBSD: ttymodes.c,v 1.29 2008/11/02 00:16:16 stevesk Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -311,11 +311,9 @@ tty_make_modes(int fd, struct termios *tiop) /* Store input and output baud rates. */ baud = speed_to_baud(cfgetospeed(&tio)); - debug3("tty_make_modes: ospeed %d", baud); buffer_put_char(&buf, tty_op_ospeed); buffer_put_int(&buf, baud); baud = speed_to_baud(cfgetispeed(&tio)); - debug3("tty_make_modes: ispeed %d", baud); buffer_put_char(&buf, tty_op_ispeed); buffer_put_int(&buf, baud); @@ -359,7 +357,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr) if (compat20) { *n_bytes_ptr = packet_get_int(); - debug3("tty_parse_modes: SSH2 n_bytes %d", *n_bytes_ptr); if (*n_bytes_ptr == 0) return; get_arg = packet_get_int; @@ -391,7 +388,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr) case TTY_OP_ISPEED_PROTO2: n_bytes += 4; baud = packet_get_int(); - debug3("tty_parse_modes: ispeed %d", baud); if (failure != -1 && cfsetispeed(&tio, baud_to_speed(baud)) == -1) error("cfsetispeed failed for %d", baud); @@ -402,7 +398,6 @@ tty_parse_modes(int fd, int *n_bytes_ptr) case TTY_OP_OSPEED_PROTO2: n_bytes += 4; baud = packet_get_int(); - debug3("tty_parse_modes: ospeed %d", baud); if (failure != -1 && cfsetospeed(&tio, baud_to_speed(baud)) == -1) error("cfsetospeed failed for %d", baud); diff --git a/uidswap.c b/uidswap.c index 91d878c30e1b..8376483967a9 100644 --- a/uidswap.c +++ b/uidswap.c @@ -233,6 +233,16 @@ permanently_set_uid(struct passwd *pw) fatal("setgid %u: %.100s", (u_int)pw->pw_gid, strerror(errno)); #endif +#ifdef __APPLE__ + /* + * OS X requires initgroups after setgid to opt back into + * memberd support for >16 supplemental groups. + */ + if (initgroups(pw->pw_name, pw->pw_gid) < 0) + fatal("initgroups %.100s %u: %.100s", + pw->pw_name, (u_int)pw->pw_gid, strerror(errno)); +#endif + #if defined(HAVE_SETRESUID) && !defined(BROKEN_SETRESUID) if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) < 0) fatal("setresuid %u: %.100s", (u_int)pw->pw_uid, strerror(errno)); diff --git a/version.h b/version.h index 41a081f12d61..f2f3196ab705 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ -/* $OpenBSD: version.h,v 1.54 2008/07/21 08:19:07 djm Exp $ */ +/* $OpenBSD: version.h,v 1.55 2009/02/23 00:06:15 djm Exp $ */ -#define SSH_VERSION "OpenSSH_5.1" +#define SSH_VERSION "OpenSSH_5.2" #define SSH_PORTABLE "p1" #define SSH_RELEASE SSH_VERSION SSH_PORTABLE From 5c0c0b37134b0adf152fe50a421560992e8cd5f8 Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Mon, 4 May 2009 00:41:07 +0000 Subject: [PATCH 003/544] Update for 5.00. --- FREEBSD-upgrade | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/FREEBSD-upgrade b/FREEBSD-upgrade index ee8f7a8fdbe0..b34bce4d64b1 100644 --- a/FREEBSD-upgrade +++ b/FREEBSD-upgrade @@ -8,23 +8,24 @@ Imported by: mv magic/* . rmdir magic - mv -i src/* . + mv -n src/* . + mv src/Makefile.am Makefile.am-src rm -rf src - mv -i doc/* . + mv -n doc/* . rm -rf doc rm -rf python rm -f lt* rm -f missing depcomp rm -f config.{guess,sub} - cvs import -m "Virgin import of Christos Zoulas's FILE 4.21." \ - src/contrib/file ZOULAS file_4_21 + cvs import -m "Virgin import of Christos Zoulas's FILE 5.00." \ + src/contrib/file ZOULAS file_5_00 Never make local changes to ZOULAS `file'. Christos is very willing to work with us to meet our FreeBSD needs. Thus submit any desired changes to him and wait for the next release and vendor import to get them. - + obrien@NUXI.com -15-Sept-2002 +15-April-2009 From a00b852cabee66db8ae02e29ecd3d713aa4169f9 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 6 May 2009 23:09:26 +0000 Subject: [PATCH 004/544] add support for the Beacon Not Ready (BNR) interrupt (available on 5211 and later) --- sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c | 6 +++++- sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c | 6 +++++- sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c | 4 ++++ 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c b/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c index 26035b8b1146..be467def34ad 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar5211_interrupts.c,v 1.6 2008/11/27 22:29:52 sam Exp $ + * $FreeBSD$ */ #include "opt_ah.h" @@ -64,6 +64,8 @@ ar5211GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) *masked |= HAL_INT_RX; if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL)) *masked |= HAL_INT_TX; + if (isr & AR_ISR_BNR) + *masked |= HAL_INT_BNR; /* * Receive overrun is usually non-fatal on Oahu/Spirit. * BUT on some parts rx could fail and the chip must be reset. @@ -137,6 +139,8 @@ ar5211SetInterrupts(struct ath_hal *ah, HAL_INT ints) } if (ints & HAL_INT_RX) mask |= AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXDESC; + if (ints & AR_ISR_BNR) + mask |= HAL_INT_BNR; if (ints & HAL_INT_FATAL) { /* * NB: ar5212Reset sets MCABT+SSERR+DPERR in AR_IMR_S2 diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c index 5d0b39cf9ae0..d8f25d72b713 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar5212_interrupts.c,v 1.6 2008/11/27 22:30:00 sam Exp $ + * $FreeBSD$ */ #include "opt_ah.h" @@ -92,6 +92,8 @@ ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXERR); ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL); } + if (isr & AR_ISR_BNR) + *masked |= HAL_INT_BNR; /* * Receive overrun is usually non-fatal on Oahu/Spirit. @@ -173,6 +175,8 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) if (ints & HAL_INT_CABEND) mask2 |= (AR_IMR_S2_CABEND ); } + if (ints & HAL_INT_BNR) + mask |= AR_IMR_BNR; if (ints & HAL_INT_FATAL) { /* * NB: ar5212Reset sets MCABT+SSERR+DPERR in AR_IMR_S2 diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c index 7b6f951175f0..7aa538d6c540 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c @@ -119,6 +119,8 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXERR); ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL); } + if (isr & AR_ISR_BNR) + *masked |= HAL_INT_BNR; /* Interrupt Mitigation on AR5416 */ #ifdef AR5416_INT_MITIGATION @@ -227,6 +229,8 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints) if (ints & HAL_INT_TSFOOR) mask2 |= AR_IMR_S2_TSFOOR; } + if (ints & HAL_INT_BNR) + mask |= AR_IMR_BNR; /* Write the new IMR and store off our SW copy. */ HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask); From a8962181ad927aeb773e821d39e39c1c74e04bee Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 6 May 2009 23:49:55 +0000 Subject: [PATCH 005/544] o cleanup checks for which vap combinations are permitted and what to use for ic_opmode o fixes the case where creating ahdemo+wds vaps caused ic_opmode to be set to hostap --- sys/dev/ath/if_ath.c | 52 +++++++++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index d0fb6eeaf4bc..8e3f1d426314 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -863,23 +863,26 @@ ath_vap_create(struct ieee80211com *ic, IEEE80211_ADDR_COPY(mac, mac0); ATH_LOCK(sc); + ic_opmode = opmode; /* default to opmode of new vap */ switch (opmode) { case IEEE80211_M_STA: - if (sc->sc_nstavaps != 0) { /* XXX only 1 sta for now */ + if (sc->sc_nstavaps != 0) { /* XXX only 1 for now */ device_printf(sc->sc_dev, "only 1 sta vap supported\n"); goto bad; } if (sc->sc_nvaps) { /* - * When there are multiple vaps we must fall - * back to s/w beacon miss handling. + * With multiple vaps we must fall back + * to s/w beacon miss handling. */ flags |= IEEE80211_CLONE_NOBEACONS; } - if (flags & IEEE80211_CLONE_NOBEACONS) + if (flags & IEEE80211_CLONE_NOBEACONS) { + /* + * Station mode w/o beacons are implemented w/ AP mode. + */ ic_opmode = IEEE80211_M_HOSTAP; - else - ic_opmode = opmode; + } break; case IEEE80211_M_IBSS: if (sc->sc_nvaps != 0) { /* XXX only 1 for now */ @@ -887,12 +890,16 @@ ath_vap_create(struct ieee80211com *ic, "only 1 ibss vap supported\n"); goto bad; } - ic_opmode = opmode; needbeacon = 1; break; case IEEE80211_M_AHDEMO: #ifdef IEEE80211_SUPPORT_TDMA if (flags & IEEE80211_CLONE_TDMA) { + if (sc->sc_nvaps != 0) { + device_printf(sc->sc_dev, + "only 1 tdma vap supported\n"); + goto bad; + } needbeacon = 1; flags |= IEEE80211_CLONE_NOBEACONS; } @@ -900,29 +907,34 @@ ath_vap_create(struct ieee80211com *ic, #endif case IEEE80211_M_MONITOR: if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) { + /* + * Adopt existing mode. Adding a monitor or ahdemo + * vap to an existing configuration is of dubious + * value but should be ok. + */ /* XXX not right for monitor mode */ ic_opmode = ic->ic_opmode; - } else - ic_opmode = opmode; + } break; case IEEE80211_M_HOSTAP: needbeacon = 1; - /* fall thru... */ + break; case IEEE80211_M_WDS: - if (sc->sc_nvaps && ic->ic_opmode == IEEE80211_M_STA) { + if (sc->sc_nvaps != 0 && ic->ic_opmode == IEEE80211_M_STA) { device_printf(sc->sc_dev, "wds not supported in sta mode\n"); goto bad; } - if (opmode == IEEE80211_M_WDS) { - /* - * Silently remove any request for a unique - * bssid; WDS vap's always share the local - * mac address. - */ - flags &= ~IEEE80211_CLONE_BSSID; - } - ic_opmode = IEEE80211_M_HOSTAP; + /* + * Silently remove any request for a unique + * bssid; WDS vap's always share the local + * mac address. + */ + flags &= ~IEEE80211_CLONE_BSSID; + if (sc->sc_nvaps == 0) + ic_opmode = IEEE80211_M_HOSTAP; + else + ic_opmode = ic->ic_opmode; break; default: device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); From ab06fdf2a55f8c5bbcaea3de9796cc7dc4f50a30 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 7 May 2009 00:35:32 +0000 Subject: [PATCH 006/544] optimize ath_tx_findrix: there's no need to walk the rates table as sc_rixmap is an inverse map NB: could eliminate the check for an invalid rate by filling in 0 for invalid entries but the rate control modules use it to identify bogus rates so leave it for now --- sys/dev/ath/if_ath.c | 38 ++++++++++++++++++-------------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index 8e3f1d426314..aa52a3ed989b 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -4222,17 +4222,15 @@ ath_tx_cleanup(struct ath_softc *sc) } /* - * Return h/w rate index for an IEEE rate (w/o basic rate bit). + * Return h/w rate index for an IEEE rate (w/o basic rate bit) + * using the current rates in sc_rixmap. */ -static int -ath_tx_findrix(const HAL_RATE_TABLE *rt, int rate) +static __inline int +ath_tx_findrix(const struct ath_softc *sc, uint8_t rate) { - int i; - - for (i = 0; i < rt->rateCount; i++) - if ((rt->info[i].dot11Rate & IEEE80211_RATE_VAL) == rate) - return i; - return 0; /* NB: lowest rate */ + int rix = sc->sc_rixmap[rate]; + /* NB: return lowest rix for invalid rate */ + return (rix == 0xff ? 0 : rix); } /* @@ -5760,8 +5758,8 @@ ath_newassoc(struct ieee80211_node *ni, int isnew) struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; const struct ieee80211_txparam *tp = ni->ni_txparms; - an->an_mcastrix = ath_tx_findrix(sc->sc_currates, tp->mcastrate); - an->an_mgmtrix = ath_tx_findrix(sc->sc_currates, tp->mgmtrate); + an->an_mcastrix = ath_tx_findrix(sc, tp->mcastrate); + an->an_mgmtrix = ath_tx_findrix(sc, tp->mgmtrate); ath_rate_newassoc(sc, an, isnew); if (isnew && @@ -6009,9 +6007,9 @@ ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode) * 11g, otherwise at 1Mb/s. */ if (mode == IEEE80211_MODE_11G) - sc->sc_protrix = ath_tx_findrix(rt, 2*2); + sc->sc_protrix = ath_tx_findrix(sc, 2*2); else - sc->sc_protrix = ath_tx_findrix(rt, 2*1); + sc->sc_protrix = ath_tx_findrix(sc, 2*1); /* NB: caller is responsible for reseting rate control state */ #undef N } @@ -6749,7 +6747,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, rt = sc->sc_currates; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - rix = ath_tx_findrix(rt, params->ibp_rate0); + rix = ath_tx_findrix(sc, params->ibp_rate0); txrate = rt->info[rix].rateCode; if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) txrate |= rt->info[rix].shortPreamble; @@ -6761,7 +6759,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, txantenna = sc->sc_txantenna; ctsduration = 0; if (flags & (HAL_TXDESC_CTSENA | HAL_TXDESC_RTSENA)) { - cix = ath_tx_findrix(rt, params->ibp_ctsrate); + cix = ath_tx_findrix(sc, params->ibp_ctsrate); ctsrate = rt->info[cix].rateCode; if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) { ctsrate |= rt->info[cix].shortPreamble; @@ -6827,19 +6825,19 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, bf->bf_txflags = flags; if (ismrr) { - rix = ath_tx_findrix(rt, params->ibp_rate1); + rix = ath_tx_findrix(sc, params->ibp_rate1); rate1 = rt->info[rix].rateCode; if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) rate1 |= rt->info[rix].shortPreamble; if (params->ibp_try2) { - rix = ath_tx_findrix(rt, params->ibp_rate2); + rix = ath_tx_findrix(sc, params->ibp_rate2); rate2 = rt->info[rix].rateCode; if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) rate2 |= rt->info[rix].shortPreamble; } else rate2 = 0; if (params->ibp_try3) { - rix = ath_tx_findrix(rt, params->ibp_rate3); + rix = ath_tx_findrix(sc, params->ibp_rate3); rate3 = rt->info[rix].rateCode; if (params->ibp_flags & IEEE80211_BPF_SHORTPRE) rate3 |= rt->info[rix].shortPreamble; @@ -7063,9 +7061,9 @@ ath_tdma_config(struct ath_softc *sc, struct ieee80211vap *vap) */ tdma = vap->iv_tdma; if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) - rix = ath_tx_findrix(sc->sc_currates, tp->ucastrate); + rix = ath_tx_findrix(sc, tp->ucastrate); else - rix = ath_tx_findrix(sc->sc_currates, tp->mcastrate); + rix = ath_tx_findrix(sc, tp->mcastrate); /* XXX short preamble assumed */ sc->sc_tdmaguard = ath_hal_computetxtime(ah, sc->sc_currates, ifp->if_mtu + IEEE80211_MAXOVERHEAD, rix, AH_TRUE); From a173706bbddcc3a5c0d8af9e079017570a04665b Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 7 May 2009 02:13:56 +0000 Subject: [PATCH 007/544] Use vendor and product macro expansion to make the device table smaller and more readable. --- sys/dev/usb/serial/u3g.c | 113 +++++++++++++++++++-------------------- 1 file changed, 56 insertions(+), 57 deletions(-) diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 19009c6eea9b..ef88694999e4 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -71,7 +71,6 @@ SYSCTL_INT(_hw_usb2_u3g, OID_AUTO, debug, CTLFLAG_RW, #define U3GSP_HSPA 6 #define U3GSP_MAX 7 -#define U3GFL_NONE 0x0000 /* No flags */ #define U3GFL_HUAWEI_INIT 0x0001 /* Init command required */ #define U3GFL_SCSI_EJECT 0x0002 /* SCSI eject command required */ #define U3GFL_SIERRA_INIT 0x0004 /* Init command required */ @@ -158,70 +157,70 @@ MODULE_DEPEND(u3g, ucom, 1, 1, 1); MODULE_DEPEND(u3g, usb, 1, 1, 1); static const struct usb2_device_id u3g_devs[] = { +#define U3G_DEV(v,p,i) { USB_VPI(USB_VENDOR_##v, USB_PRODUCT_##v##_##p, i) } /* OEM: Option */ - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3G, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GQUAD, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GT3GPLUS, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAX36, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_GTMAXHSUPA, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_OPTION, USB_PRODUCT_OPTION_VODAFONEMC3G, U3GFL_NONE)}, + U3G_DEV(OPTION, GT3G, 0), + U3G_DEV(OPTION, GT3GQUAD, 0), + U3G_DEV(OPTION, GT3GPLUS, 0), + U3G_DEV(OPTION, GTMAX36, 0), + U3G_DEV(OPTION, GTMAXHSUPA, 0), + U3G_DEV(OPTION, VODAFONEMC3G, 0), /* OEM: Qualcomm, Inc. */ - {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_ZTE_STOR, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_QUALCOMMINC, USB_PRODUCT_QUALCOMMINC_CDMA_MSM, U3GFL_SCSI_EJECT)}, + U3G_DEV(QUALCOMMINC, ZTE_STOR, U3GFL_SCSI_EJECT), + U3G_DEV(QUALCOMMINC, CDMA_MSM, U3GFL_SCSI_EJECT), /* OEM: Huawei */ - {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_MOBILE, U3GFL_HUAWEI_INIT)}, - {USB_VPI(USB_VENDOR_HUAWEI, USB_PRODUCT_HUAWEI_E220, U3GFL_HUAWEI_INIT)}, + U3G_DEV(HUAWEI, MOBILE, U3GFL_HUAWEI_INIT), + U3G_DEV(HUAWEI, E220, U3GFL_HUAWEI_INIT), /* OEM: Novatel */ - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_CDMA_MODEM, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ES620, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_MC950D, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U720, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U727, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U740_2, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_U870, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V620, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V640, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V720, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_V740, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_X950D, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_XU870, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_NOVATEL, USB_PRODUCT_NOVATEL_ZEROCD, U3GFL_SCSI_EJECT)}, - {USB_VPI(USB_VENDOR_DELL, USB_PRODUCT_DELL_U740, U3GFL_SCSI_EJECT)}, + U3G_DEV(NOVATEL, CDMA_MODEM, 0), + U3G_DEV(NOVATEL, ES620, 0), + U3G_DEV(NOVATEL, MC950D, 0), + U3G_DEV(NOVATEL, U720, 0), + U3G_DEV(NOVATEL, U727, 0), + U3G_DEV(NOVATEL, U740, 0), + U3G_DEV(NOVATEL, U740_2, 0), + U3G_DEV(NOVATEL, U870, 0), + U3G_DEV(NOVATEL, V620, 0), + U3G_DEV(NOVATEL, V640, 0), + U3G_DEV(NOVATEL, V720, 0), + U3G_DEV(NOVATEL, V740, 0), + U3G_DEV(NOVATEL, X950D, 0), + U3G_DEV(NOVATEL, XU870, 0), + U3G_DEV(NOVATEL, ZEROCD, U3GFL_SCSI_EJECT), + U3G_DEV(DELL, U740, 0), /* OEM: Merlin */ - {USB_VPI(USB_VENDOR_MERLIN, USB_PRODUCT_MERLIN_V620, U3GFL_NONE)}, + U3G_DEV(MERLIN, V620, 0), /* OEM: Sierra Wireless: */ - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD580, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD595, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC595U, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC597E, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_C597, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880E, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC880U, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881E, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC881U, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_EM5625, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5720_2, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC5725, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MINI5725, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AIRCARD875, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_2, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8755_3, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8765, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_AC875U, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8775_2, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8780, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_MC8781, U3GFL_NONE)}, - {USB_VPI(USB_VENDOR_HP, USB_PRODUCT_HP_HS2300, U3GFL_NONE)}, + U3G_DEV(SIERRA, AIRCARD580, 0), + U3G_DEV(SIERRA, AIRCARD595, 0), + U3G_DEV(SIERRA, AC595U, 0), + U3G_DEV(SIERRA, AC597E, 0), + U3G_DEV(SIERRA, C597, 0), + U3G_DEV(SIERRA, AC880, 0), + U3G_DEV(SIERRA, AC880E, 0), + U3G_DEV(SIERRA, AC880U, 0), + U3G_DEV(SIERRA, AC881, 0), + U3G_DEV(SIERRA, AC881E, 0), + U3G_DEV(SIERRA, AC881U, 0), + U3G_DEV(SIERRA, EM5625, 0), + U3G_DEV(SIERRA, MC5720, 0), + U3G_DEV(SIERRA, MC5720_2, 0), + U3G_DEV(SIERRA, MC5725, 0), + U3G_DEV(SIERRA, MINI5725, 0), + U3G_DEV(SIERRA, AIRCARD875, 0), + U3G_DEV(SIERRA, MC8755, 0), + U3G_DEV(SIERRA, MC8755_2, 0), + U3G_DEV(SIERRA, MC8755_3, 0), + U3G_DEV(SIERRA, MC8765, 0), + U3G_DEV(SIERRA, AC875U, 0), + U3G_DEV(SIERRA, MC8775_2, 0), + U3G_DEV(SIERRA, MC8780, 0), + U3G_DEV(SIERRA, MC8781, 0), + U3G_DEV(HP, HS2300, 0), /* Sierra TruInstaller device ID */ - {USB_VPI(USB_VENDOR_SIERRA, USB_PRODUCT_SIERRA_TRUINSTALL, U3GFL_SIERRA_INIT)}, + U3G_DEV(SIERRA, TRUINSTALL, U3GFL_SIERRA_INIT), /* PRUEBA SILABS */ - {USB_VPI(USB_VENDOR_SILABS, USB_PRODUCT_SILABS_SAEL, U3GFL_SAEL_M460_INIT)}, + U3G_DEV(SILABS, SAEL, U3GFL_SAEL_M460_INIT), }; static void From e92a451510bdd10cd84ac11e8df88e379bb6d7e1 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 7 May 2009 02:15:58 +0000 Subject: [PATCH 008/544] - Fix the u3g port detection where it would not calculate the correct number of ports when multiple interfaces are present. - Claim all interfaces regardless of how many are attached --- sys/dev/usb/serial/u3g.c | 93 +++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 50 deletions(-) diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index ef88694999e4..ae066123ce3d 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -439,12 +439,9 @@ u3g_attach(device_t dev) struct u3g_softc *sc = device_get_softc(dev); struct usb2_interface *iface; struct usb2_interface_descriptor *id; - uint32_t flags; - uint8_t m; - uint8_t n; + int error, iface_valid, flags, nports; + int ep, n; uint8_t i; - uint8_t x; - int error; DPRINTF("sc=%p\n", sc); @@ -462,72 +459,68 @@ u3g_attach(device_t dev) sc->sc_udev = uaa->device; - x = 0; /* interface index */ - i = 0; /* endpoint index */ - m = 0; /* number of ports */ + /* Claim all interfaces on the device */ + iface_valid = 0; + for (i = uaa->info.bIfaceIndex; i < USB_IFACE_MAX; i++) { + iface = usb2_get_iface(uaa->device, i); + if (iface == NULL) + break; + id = usb2_get_interface_descriptor(iface); + if (id == NULL || id->bInterfaceClass != UICLASS_VENDOR) + continue; + usb2_set_parent_iface(uaa->device, i, uaa->info.bIfaceIndex); + iface_valid |= (1<device, x); - if (iface == NULL) { - if (m != 0) - break; /* end of interfaces */ - DPRINTF("did not find any modem endpoints\n"); - goto detach; - } - - id = usb2_get_interface_descriptor(iface); - if ((id == NULL) || - (id->bInterfaceClass != UICLASS_VENDOR)) { - /* next interface */ - x++; - i = 0; - continue; - } + for (n = 0; n < U3G_N_TRANSFER; n++) + u3g_config_tmp[n].ep_index = ep; /* try to allocate a set of BULK endpoints */ - error = usb2_transfer_setup(uaa->device, &x, - sc->sc_xfer[m], u3g_config_tmp, U3G_N_TRANSFER, - &sc->sc_ucom[m], &sc->sc_mtx); + error = usb2_transfer_setup(uaa->device, &i, + sc->sc_xfer[nports], u3g_config_tmp, U3G_N_TRANSFER, + &sc->sc_ucom[nports], &sc->sc_mtx); if (error) { /* next interface */ - x++; - i = 0; + i++; + ep = 0; continue; } - /* grab other interface, if any */ - if (x != uaa->info.bIfaceIndex) - usb2_set_parent_iface(uaa->device, x, - uaa->info.bIfaceIndex); - /* set stall by default */ mtx_lock(&sc->sc_mtx); - usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_WR]); - usb2_transfer_set_stall(sc->sc_xfer[m][U3G_BULK_RD]); + usb2_transfer_set_stall(sc->sc_xfer[nports][U3G_BULK_WR]); + usb2_transfer_set_stall(sc->sc_xfer[nports][U3G_BULK_RD]); mtx_unlock(&sc->sc_mtx); - m++; /* found one port */ - i++; /* next endpoint index */ + nports++; /* found one port */ + ep++; + if (nports == U3G_MAXPORTS) + break; } + if (nports == 0) { + device_printf(dev, "no ports found\n"); + goto detach; + } + sc->sc_numports = nports; - sc->sc_numports = m; - - error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom, + error = usb2_com_attach(&sc->sc_super_ucom, sc->sc_ucom, sc->sc_numports, sc, &u3g_callback, &sc->sc_mtx); if (error) { DPRINTF("usb2_com_attach failed\n"); goto detach; } - if (sc->sc_numports != 1) { - /* be verbose */ - device_printf(dev, "Found %u ports.\n", - (unsigned int)sc->sc_numports); - } + if (sc->sc_numports > 1) + device_printf(dev, "Found %u ports.\n", sc->sc_numports); return (0); detach: From 426909d9694cda33a247ea244a95d947773657df Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 7 May 2009 02:17:09 +0000 Subject: [PATCH 009/544] Add the Sierra AC885U and increase the max ports to 8. --- sys/dev/usb/serial/u3g.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index ae066123ce3d..407d98e8625a 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -58,7 +58,7 @@ SYSCTL_INT(_hw_usb2_u3g, OID_AUTO, debug, CTLFLAG_RW, &u3g_debug, 0, "Debug level"); #endif -#define U3G_MAXPORTS 4 +#define U3G_MAXPORTS 8 #define U3G_CONFIG_INDEX 0 #define U3G_BSIZE 2048 @@ -202,6 +202,7 @@ static const struct usb2_device_id u3g_devs[] = { U3G_DEV(SIERRA, AC881, 0), U3G_DEV(SIERRA, AC881E, 0), U3G_DEV(SIERRA, AC881U, 0), + U3G_DEV(SIERRA, AC885U, 0), U3G_DEV(SIERRA, EM5625, 0), U3G_DEV(SIERRA, MC5720, 0), U3G_DEV(SIERRA, MC5720_2, 0), From 1a52a4abf7af9e7cc74b04b4ca5ce6d71a3d671c Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 03:23:22 +0000 Subject: [PATCH 010/544] Rework r191742. Use the protocol family constants for the domain argument validation. Return EAFNOSUPPORT in case when the incorrect domain argument is specified. Return EPROTONOSUPPORT instead of passing values that are not 0 to the BSD layer. Suggested by: rwatson Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_socket.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index c92fd127e822..91a1a46f6761 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -855,14 +855,21 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) } */ bsd_args; bsd_args.domain = linux_to_bsd_domain(args->domain); - if (bsd_args.domain == -1) - return (EINVAL); + if (bsd_args.domain != PF_LOCAL) + return (EAFNOSUPPORT); bsd_args.type = args->type; - if (bsd_args.domain == AF_LOCAL && args->protocol == PF_UNIX) - bsd_args.protocol = 0; + if (args->protocol != 0 && args->protocol != PF_UNIX) + + /* + * Use of PF_UNIX as protocol argument is not right, + * but Linux does it. + * Do not map PF_UNIX as its Linux value is identical + * to FreeBSD one. + */ + return (EPROTONOSUPPORT); else - bsd_args.protocol = args->protocol; + bsd_args.protocol = 0; bsd_args.rsv = (int *)PTRIN(args->rsv); return (socketpair(td, &bsd_args)); } From f83954e24a39497043386ad9cf35c2986cac6b3e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 7 May 2009 05:42:13 +0000 Subject: [PATCH 011/544] Define the kernel pmap in the same way on arm as on every other architecture. Eliminate an unused definition. Tested by: cognet --- sys/arm/arm/pmap.c | 2 -- sys/arm/include/pmap.h | 5 ++--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/sys/arm/arm/pmap.c b/sys/arm/arm/pmap.c index b209bd7f940b..cbd6c21638bc 100644 --- a/sys/arm/arm/pmap.c +++ b/sys/arm/arm/pmap.c @@ -224,7 +224,6 @@ extern void *end; vm_offset_t kernel_vm_end = 0; struct pmap kernel_pmap_store; -pmap_t kernel_pmap; static pt_entry_t *csrc_pte, *cdst_pte; static vm_offset_t csrcp, cdstp; @@ -2337,7 +2336,6 @@ pmap_bootstrap(vm_offset_t firstaddr, vm_offset_t lastaddr, struct pv_addr *l1pt firstaddr, loadaddr)); virtual_avail = firstaddr; - kernel_pmap = &kernel_pmap_store; kernel_pmap->pm_l1 = l1; kernel_l1pa = l1pt->pv_pa; diff --git a/sys/arm/include/pmap.h b/sys/arm/include/pmap.h index 4a8d828f9dea..63ec3f479c81 100644 --- a/sys/arm/include/pmap.h +++ b/sys/arm/include/pmap.h @@ -138,7 +138,8 @@ struct pmap { typedef struct pmap *pmap_t; #ifdef _KERNEL -extern pmap_t kernel_pmap; +extern struct pmap kernel_pmap_store; +#define kernel_pmap (&kernel_pmap_store) #define pmap_kernel() kernel_pmap #define PMAP_ASSERT_LOCKED(pmap) \ @@ -166,8 +167,6 @@ typedef struct pv_entry { int pv_flags; /* flags (wired, etc...) */ } *pv_entry_t; -#define PV_ENTRY_NULL ((pv_entry_t) 0) - #ifdef _KERNEL boolean_t pmap_get_pde_pte(pmap_t, vm_offset_t, pd_entry_t **, pt_entry_t **); From d7d9cfed36932ef331a19d835795fb81c23bbafa Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 7 May 2009 05:44:13 +0000 Subject: [PATCH 012/544] Eliminate an incorrect comment. --- sys/vm/vm_fault.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/vm/vm_fault.c b/sys/vm/vm_fault.c index 48ed9912f906..3a21616a7803 100644 --- a/sys/vm/vm_fault.c +++ b/sys/vm/vm_fault.c @@ -1248,8 +1248,6 @@ vm_fault_copy_entry(dst_map, src_map, dst_entry, src_entry) * * Return value: * number of pages in marray - * - * This routine can't block. */ static int vm_fault_additional_pages(m, rbehind, rahead, marray, reqpage) From d9b063cc9d455f3952902a07db64d8d20e0a8302 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 09:34:02 +0000 Subject: [PATCH 013/544] Return EAFNOSUPPORT instead of EINVAL in case when the incorrect or unsupported domain argument is specified. Approved by: kib (mentor) --- sys/compat/linux/linux_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 91a1a46f6761..5d77f22b2e3d 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -599,7 +599,7 @@ linux_socket(struct thread *td, struct linux_socket_args *args) bsd_args.type = args->type; bsd_args.domain = linux_to_bsd_domain(args->domain); if (bsd_args.domain == -1) - return (EINVAL); + return (EAFNOSUPPORT); retval_socket = socket(td, &bsd_args); if (bsd_args.type == SOCK_RAW From 13f20d7e8607cbd09df8ec9f82eaea86874e4af2 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 09:39:20 +0000 Subject: [PATCH 014/544] To avoid excessive code duplication move MI definitions to the MI header file. As it is defined in Linux. Approved by: kib (mentor) MFC after: 1 month --- sys/amd64/linux32/linux.h | 8 -------- sys/compat/linux/linux_ioctl.c | 1 + sys/compat/linux/linux_socket.h | 10 ++++++++++ sys/i386/linux/linux.h | 8 -------- 4 files changed, 11 insertions(+), 16 deletions(-) diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 0e30382f94b4..78abf63f38a7 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -669,14 +669,6 @@ union l_semun { #define LINUX_SENDMSG 16 #define LINUX_RECVMSG 17 -#define LINUX_AF_UNSPEC 0 -#define LINUX_AF_UNIX 1 -#define LINUX_AF_INET 2 -#define LINUX_AF_AX25 3 -#define LINUX_AF_IPX 4 -#define LINUX_AF_APPLETALK 5 -#define LINUX_AF_INET6 10 - #define LINUX_SOL_SOCKET 1 #define LINUX_SOL_IP 0 #define LINUX_SOL_IPX 256 diff --git a/sys/compat/linux/linux_ioctl.c b/sys/compat/linux/linux_ioctl.c index 55cf1b9f32e6..2b4ca75834f2 100644 --- a/sys/compat/linux/linux_ioctl.c +++ b/sys/compat/linux/linux_ioctl.c @@ -77,6 +77,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include CTASSERT(LINUX_IFNAMSIZ == IFNAMSIZ); diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index 5a5d3f5c78de..9257a7db593c 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -80,4 +80,14 @@ #define CMSG_HDRSZ CMSG_LEN(0) #define L_CMSG_HDRSZ LINUX_CMSG_LEN(0) +/* Supported address families */ + +#define LINUX_AF_UNSPEC 0 +#define LINUX_AF_UNIX 1 +#define LINUX_AF_INET 2 +#define LINUX_AF_AX25 3 +#define LINUX_AF_IPX 4 +#define LINUX_AF_APPLETALK 5 +#define LINUX_AF_INET6 10 + #endif /* _LINUX_SOCKET_H_ */ diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index ca01c894a375..132e431a6009 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -645,14 +645,6 @@ union l_semun { #define LINUX_SENDMSG 16 #define LINUX_RECVMSG 17 -#define LINUX_AF_UNSPEC 0 -#define LINUX_AF_UNIX 1 -#define LINUX_AF_INET 2 -#define LINUX_AF_AX25 3 -#define LINUX_AF_IPX 4 -#define LINUX_AF_APPLETALK 5 -#define LINUX_AF_INET6 10 - #define LINUX_SOL_SOCKET 1 #define LINUX_SOL_IP 0 #define LINUX_SOL_IPX 256 From 4ec3ea90ebe846c9edd4c13ff5527420a52f3d1e Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 10:01:05 +0000 Subject: [PATCH 015/544] Add preliminary KTR(9) support to the linux emulation layer. Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_mib.c | 4 ++-- sys/compat/linux/linux_util.h | 29 +++++++++++++++++++++++++++++ sys/modules/linux/Makefile | 3 +++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index b47ec044e765..331b91e4abd4 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -318,7 +318,7 @@ linux_set_oss_version(struct thread *td, int oss_version) return (0); } -#ifdef DEBUG +#if defined(DEBUG) || defined(KTR) u_char linux_debug_map[howmany(LINUX_SYS_MAXSYSCALL, sizeof(u_char))]; @@ -377,4 +377,4 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, debug, 0, 0, linux_sysctl_debug, "A", "Linux debugging control"); -#endif /* DEBUG */ +#endif /* DEBUG || KTR */ diff --git a/sys/compat/linux/linux_util.h b/sys/compat/linux/linux_util.h index 4caad9d857b1..4363a327c9d3 100644 --- a/sys/compat/linux/linux_util.h +++ b/sys/compat/linux/linux_util.h @@ -106,4 +106,33 @@ int linux_driver_get_major_minor(char *node, int *major, int *minor); char *linux_get_char_devices(void); void linux_free_get_char_devices(char *string); +#if defined(KTR) + +#define KTR_LINUX KTR_SUBSYS +#define LINUX_CTRFMT(nm, fmt) #nm"("fmt")" + +#define LINUX_CTR6(f, m, p1, p2, p3, p4, p5, p6) do { \ + if (ldebug(f)) \ + CTR6(KTR_LINUX, LINUX_CTRFMT(f, m), \ + p1, p2, p3, p4, p5, p6); \ +} while (0) + +#define LINUX_CTR(f) LINUX_CTR6(f, "", 0, 0, 0, 0, 0, 0) +#define LINUX_CTR0(f, m) LINUX_CTR6(f, m, 0, 0, 0, 0, 0, 0) +#define LINUX_CTR1(f, m, p1) LINUX_CTR6(f, m, p1, 0, 0, 0, 0, 0) +#define LINUX_CTR2(f, m, p1, p2) LINUX_CTR6(f, m, p1, p2, 0, 0, 0, 0) +#define LINUX_CTR3(f, m, p1, p2, p3) LINUX_CTR6(f, m, p1, p2, p3, 0, 0, 0) +#define LINUX_CTR4(f, m, p1, p2, p3, p4) LINUX_CTR6(f, m, p1, p2, p3, p4, 0, 0) +#define LINUX_CTR5(f, m, p1, p2, p3, p4, p5) LINUX_CTR6(f, m, p1, p2, p3, p4, p5, 0) +#else +#define LINUX_CTR(f) +#define LINUX_CTR0(f, m) +#define LINUX_CTR1(f, m, p1) +#define LINUX_CTR2(f, m, p1, p2) +#define LINUX_CTR3(f, m, p1, p2, p3) +#define LINUX_CTR4(f, m, p1, p2, p3, p4) +#define LINUX_CTR5(f, m, p1, p2, p3, p4, p5) +#define LINUX_CTR6(f, m, p1, p2, p3, p4, p5, p6) +#endif + #endif /* !_LINUX_UTIL_H_ */ diff --git a/sys/modules/linux/Makefile b/sys/modules/linux/Makefile index 0995c3aedb43..b2bdd97f9f53 100644 --- a/sys/modules/linux/Makefile +++ b/sys/modules/linux/Makefile @@ -55,6 +55,9 @@ linux${SFX}_genassym.o: linux${SFX}_genassym.c linux.h @ machine .if !defined(KERNBUILDDIR) opt_inet6.h: echo "#define INET6 1" > ${.TARGET} +.if defined(KTR) +CFLAGS+= -DKTR +.endif .endif .include From 4d706dcc088a9c200bf5a9925d7bf504bd0f29eb Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 12:55:58 +0000 Subject: [PATCH 016/544] Change linux struct tms definition to match actual linux one. Approved by: kib (mentor) MFC after: 2 weeks --- sys/compat/linux/linux_misc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 82bd7b91838e..01eaa24813ef 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -653,10 +653,10 @@ linux_time(struct thread *td, struct linux_time_args *args) } struct l_times_argv { - l_long tms_utime; - l_long tms_stime; - l_long tms_cutime; - l_long tms_cstime; + l_clock_t tms_utime; + l_clock_t tms_stime; + l_clock_t tms_cutime; + l_clock_t tms_cstime; }; #define CLK_TCK 100 /* Linux uses 100 */ From 46b303e83d53aaff3e408c9695d45d3fa6a42b7a Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 7 May 2009 13:49:48 +0000 Subject: [PATCH 017/544] Add tcsetsid(3). The entire world seems to use the non-standard TIOCSCTTY ioctl to make a TTY a controlling terminal of a session. Even though tcsetsid(3) is also non-standard, I think it's a lot better to use in our own source code, mainly because it's similar to tcsetpgrp(), tcgetpgrp() and tcgetsid(). I stole the idea from QNX. They do it the other way around; their TIOCSCTTY is just a wrapper around tcsetsid(). tcsetsid() then calls into an IPC framework. --- lib/libc/gen/Makefile.inc | 4 +- lib/libc/gen/Symbol.map | 1 + lib/libc/gen/tcgetsid.3 | 3 +- lib/libc/gen/tcsetsid.3 | 92 +++++++++++++++++++++++++++++++++++++++ lib/libc/gen/termios.c | 12 +++++ lib/libutil/login_tty.c | 10 +++-- sys/sys/termios.h | 3 +- 7 files changed, 118 insertions(+), 7 deletions(-) create mode 100644 lib/libc/gen/tcsetsid.3 diff --git a/lib/libc/gen/Makefile.inc b/lib/libc/gen/Makefile.inc index 0ee2ffb259a7..a4badb911448 100644 --- a/lib/libc/gen/Makefile.inc +++ b/lib/libc/gen/Makefile.inc @@ -70,8 +70,8 @@ MAN+= alarm.3 arc4random.3 \ siginterrupt.3 signal.3 sigsetops.3 sleep.3 \ statvfs.3 stringlist.3 \ strtofflags.3 sysconf.3 sysctl.3 syslog.3 tcgetpgrp.3 tcgetsid.3 \ - tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 time.3 times.3 timezone.3 \ - ttyname.3 tzset.3 ualarm.3 ucontext.3 ulimit.3 uname.3 \ + tcsendbreak.3 tcsetattr.3 tcsetpgrp.3 tcsetsid.3 time.3 times.3 \ + timezone.3 ttyname.3 tzset.3 ualarm.3 ucontext.3 ulimit.3 uname.3 \ unvis.3 usleep.3 utime.3 valloc.3 vis.3 wordexp.3 MLINKS+=arc4random.3 arc4random_addrandom.3 arc4random.3 arc4random_stir.3 \ diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 69cf703e1112..2d23153804a9 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -363,6 +363,7 @@ FBSD_1.1 { posix_spawnattr_setsigmask; posix_spawnp; tcgetsid; + tcsetsid; }; FBSDprivate_1.0 { diff --git a/lib/libc/gen/tcgetsid.3 b/lib/libc/gen/tcgetsid.3 index 11c8d0c41566..a270a0bdb9c3 100644 --- a/lib/libc/gen/tcgetsid.3 +++ b/lib/libc/gen/tcgetsid.3 @@ -63,7 +63,8 @@ is not the controlling terminal. .Sh SEE ALSO .Xr getsid 2 , .Xr setsid 2 , -.Xr tcgetpgrp 3 +.Xr tcgetpgrp 3 , +.Xr tcsetsid 3 .Sh STANDARDS The .Fn tcgetsid diff --git a/lib/libc/gen/tcsetsid.3 b/lib/libc/gen/tcsetsid.3 new file mode 100644 index 000000000000..d0f1d985753e --- /dev/null +++ b/lib/libc/gen/tcsetsid.3 @@ -0,0 +1,92 @@ +.\" Copyright (c) 2009 Ed Schouten +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 4, 2009 +.Dt TCSETSID 3 +.Os +.Sh NAME +.Nm tcsetsid +.Nd set session ID associated with a controlling terminal +.Sh LIBRARY +.Lb libc +.Sh SYNOPSIS +.In sys/types.h +.In termios.h +.Ft int +.Fn tcsetsid "int fd" "pid_t pid" +.Sh DESCRIPTION +The +.Fn tcsetsid +function sets associates a session identified by +.Fa pid +with a controlling terminal specified by +.Fa fd . +.Pp +This implementation only allows the controlling terminal to be changed +by the session leader itself. +This implies that +.Fa pid +always has to be equal to the process ID. +.Pp +It is unsupported to associate with a terminal that already has an +associated session. +Conversely, it is also unsupported to associate to a terminal when +the session is already associated with a different terminal. +.Sh ERRORS +If an error occurs, +.Fn tcsetsid +returns -1 and the global variable +.Va errno +is set to indicate the error, as follows: +.Bl -tag -width Er +.It Bq Er EBADF +The +.Fa fd +argument is not a valid file descriptor. +.It Bq Er ENOTTY +The file descriptor represented by +.Fa fd +is not a terminal. +.It Bq Er EINVAL +The +.Fa pid +argument is not equal to the session ID of the calling process. +.It Bq Er EPERM +The calling process is not a session leader. +.It Bq Er EPERM +The session already has an associated terminal or the terminal already +has an associated session. +.El +.Sh SEE ALSO +.Xr getsid 2 , +.Xr setsid 2 , +.Xr tcgetpgrp 3 , +.Xr tcgetsid 3 +.Sh HISTORY +A +.Fn tcsetsid +function first appeared in QNX. +It does not comply to any standard. diff --git a/lib/libc/gen/termios.c b/lib/libc/gen/termios.c index 4c6dcff012fe..85ca4e335d38 100644 --- a/lib/libc/gen/termios.c +++ b/lib/libc/gen/termios.c @@ -110,6 +110,18 @@ tcgetsid(int fd) return ((pid_t)s); } +int +tcsetsid(int fd, pid_t pid) +{ + + if (pid != getsid(0)) { + errno = EINVAL; + return (-1); + } + + return (_ioctl(fd, TIOCSCTTY, NULL)); +} + speed_t cfgetospeed(t) const struct termios *t; diff --git a/lib/libutil/login_tty.c b/lib/libutil/login_tty.c index 51299bdd82a6..a14e244e45aa 100644 --- a/lib/libutil/login_tty.c +++ b/lib/libutil/login_tty.c @@ -37,17 +37,21 @@ static char sccsid[] = "@(#)login_tty.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include -#include #include #include +#include #include int login_tty(int fd) { - (void) setsid(); - if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1) + pid_t s; + + s = setsid(); + if (s == -1) + return (-1); + if (tcsetsid(fd, s) == -1) return (-1); (void) dup2(fd, 0); (void) dup2(fd, 1); diff --git a/sys/sys/termios.h b/sys/sys/termios.h index 192c3f28be47..0543d6ee64b6 100644 --- a/sys/sys/termios.h +++ b/sys/sys/termios.h @@ -272,8 +272,9 @@ int tcsendbreak(int, int); #if __POSIX_VISIBLE >= 200112 || __BSD_VISIBLE pid_t tcgetsid(int); #endif - #if __BSD_VISIBLE +int tcsetsid(int, pid_t); + void cfmakeraw(struct termios *); int cfsetspeed(struct termios *, speed_t); #endif From c65b9bfa3cd8171dc75d91da62a57a2b1a07f856 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 14:24:50 +0000 Subject: [PATCH 018/544] Linux exports HZ value to user space via AT_CLKTCK auxiliary vector entry, which is available for Glibc as sysconf(_SC_CLK_TCK). If AT_CLKTCK entry is not exported, Glibc uses 100. linux_times() shall use the value that is exported to user space. Pointyhat to: dchagin PR: kern/134251 Approved by: kib (mentor) MFC after: 2 weeks --- sys/compat/linux/linux_misc.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 01eaa24813ef..198818e3580d 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -659,9 +659,7 @@ struct l_times_argv { l_clock_t tms_cstime; }; -#define CLK_TCK 100 /* Linux uses 100 */ - -#define CONVTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +#define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) int linux_times(struct thread *td, struct linux_times_args *args) From 7909a690308ce3f852657d6d6b389ecc8e539268 Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 7 May 2009 14:34:49 +0000 Subject: [PATCH 019/544] s/ath0/wlan0/ since we no longer use the real device directly. --- share/man/man4/if_bridge.4 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/share/man/man4/if_bridge.4 b/share/man/man4/if_bridge.4 index 9eebe98354e0..b1304e30193e 100644 --- a/share/man/man4/if_bridge.4 +++ b/share/man/man4/if_bridge.4 @@ -342,7 +342,7 @@ The following when placed in the file will cause a bridge called .Dq Li bridge0 to be created, and will add the interfaces -.Dq Li ath0 +.Dq Li wlan0 and .Dq Li fxp0 to the bridge, and then enable packet forwarding. @@ -351,14 +351,14 @@ Such a configuration could be used to implement a simple in ad-hoc mode). .Bd -literal -offset indent cloned_interfaces="bridge0" -ifconfig_bridge0="addm ath0 addm fxp0 up" +ifconfig_bridge0="addm wlan0 addm fxp0 up" .Ed .Pp For the bridge to forward packets all member interfaces and the bridge need to be up. The above example would also require: .Bd -literal -offset indent -ifconfig_ath0="up ssid my_ap mode 11g mediaopt hostap" +ifconfig_wlan0="up ssid my_ap mode 11g mediaopt hostap" ifconfig_fxp0="up" .Ed .Pp From 1a1859949798afc100ef815d4154eb860ab675bc Mon Sep 17 00:00:00 2001 From: Steven Kreuzer Date: Thu, 7 May 2009 14:39:01 +0000 Subject: [PATCH 020/544] Adding myself as a ports committer Approved by: wxs (mentor) --- share/misc/committers-ports.dot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index ac082c2db819..229f06316be1 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -137,6 +137,7 @@ sem [label="Sergey Matveychuk\nsem@FreeBSD.org\n2004/07/07"] sergei [label="Sergei Kolobov\nsergei@FreeBSD.org\n2003/10/21"] shaun [label="Shaun Amott\nshaun@FreeBSD.org\n2006/06/19"] simon [label="Simon L. Nielsen\nsimon@FreeBSD.org\n2005/01/08"] +skreuzer [label="Steven Kreuzer\nskreuzer@FreeBSD.org\n2009/03/25"] sobomax[label="Maxim Sobolev\nsobomax@FreeBSD.org\n2000/05/17"] stas [label="Stanislav Sedov\nstas@FreeBSD.org\n2006/09/18"] stefan [label="Stefan Walter\nstefan@FreeBSD.org\n2006/05/07"] @@ -328,4 +329,6 @@ tmclaugh -> xride will -> lioux +wxs -> skreuzer + } From 9330df7e5d198c221963a0db0a8e82d4bfc01c08 Mon Sep 17 00:00:00 2001 From: Steven Kreuzer Date: Thu, 7 May 2009 15:32:13 +0000 Subject: [PATCH 021/544] Add my birthday Approved by: wxs (mentor) --- usr.bin/calendar/calendars/calendar.freebsd | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.bin/calendar/calendars/calendar.freebsd b/usr.bin/calendar/calendars/calendar.freebsd index 6f89ee02fce0..8680d0797aad 100644 --- a/usr.bin/calendar/calendars/calendar.freebsd +++ b/usr.bin/calendar/calendars/calendar.freebsd @@ -39,6 +39,7 @@ 02/01 Paul Saab born in Champaign-Urbana, Illinois, United States, 1978 02/01 Martin Wilke born in Ludwigsfelde, Brandenburg, Germany, 1980 02/01 Christian Brueffer born in Gronau, Nordrhein-Westfalen, Germany, 1982 +02/01 Steven Kreuzer born in Oceanside, New York, 1982 02/01 Juli Mallett born in Washington, Pennsylvania, United States, 1985 02/02 Michael W Lucas born in Detroit, Michigan, United States, 1967 02/02 Diomidis D. Spinellis born in Athens, Greece, 1967 From ca8c3e7bbaac263db5c38b3b5c0568a8cd12c7a7 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Thu, 7 May 2009 16:14:31 +0000 Subject: [PATCH 022/544] Add KTR(9) tracing for futex emulation. Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_futex.c | 60 +++++++++++++++++++++++++++------- 1 file changed, 49 insertions(+), 11 deletions(-) diff --git a/sys/compat/linux/linux_futex.c b/sys/compat/linux/linux_futex.c index 3024dc497902..d72a699cadea 100644 --- a/sys/compat/linux/linux_futex.c +++ b/sys/compat/linux/linux_futex.c @@ -43,6 +43,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $") #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ __KERNEL_RCSID(1, "$NetBSD: linux_futex.c,v 1.7 2006/07/24 19:01:49 manu Exp $") #endif #include #include +#include MALLOC_DEFINE(M_FUTEX, "futex", "Linux futexes"); MALLOC_DEFINE(M_FUTEX_WP, "futex wp", "Linux futexes wp"); @@ -131,11 +133,15 @@ futex_put(struct futex *f, struct waiting_proc *wp) FUTEXES_UNLOCK; FUTEX_UNLOCK(f); + LINUX_CTR2(sys_futex, "futex_put destroy uaddr %p ref %d", + f->f_uaddr, f->f_refcount); FUTEX_DESTROY(f); free(f, M_FUTEX); return; } + LINUX_CTR2(sys_futex, "futex_put uaddr %p ref %d", + f->f_uaddr, f->f_refcount); FUTEXES_UNLOCK; FUTEX_UNLOCK(f); } @@ -170,12 +176,15 @@ futex_get0(uint32_t *uaddr, struct futex **newf, uint32_t flags) FUTEX_LOCK(f); *newf = f; + LINUX_CTR2(sys_futex, "futex_get uaddr %p ref %d", + uaddr, f->f_refcount); return (0); } } if (flags & FUTEX_DONTCREATE) { FUTEXES_UNLOCK; + LINUX_CTR1(sys_futex, "futex_get uaddr %p null", uaddr); return (0); } @@ -198,6 +207,8 @@ futex_get0(uint32_t *uaddr, struct futex **newf, uint32_t flags) LIST_INSERT_HEAD(&futex_list, tmpf, f_list); FUTEXES_UNLOCK; + LINUX_CTR2(sys_futex, "futex_get uaddr %p ref %d new", + uaddr, tmpf->f_refcount); *newf = tmpf; return (0); } @@ -232,13 +243,21 @@ futex_sleep(struct futex *f, struct waiting_proc *wp, unsigned long timeout) int error; FUTEX_ASSERT_LOCKED(f); + LINUX_CTR4(sys_futex, "futex_sleep enter uaddr %p wp %p timo %ld ref %d", + f->f_uaddr, wp, timeout, f->f_refcount); error = sx_sleep(wp, &f->f_lck, PCATCH, "futex", timeout); if (wp->wp_flags & FUTEX_WP_REQUEUED) { KASSERT(f != wp->wp_futex, ("futex != wp_futex")); + LINUX_CTR5(sys_futex, "futex_sleep out error %d uaddr %p w" + " %p requeued uaddr %p ref %d", + error, f->f_uaddr, wp, wp->wp_futex->f_uaddr, + wp->wp_futex->f_refcount); futex_put(f, NULL); f = wp->wp_futex; FUTEX_LOCK(f); - } + } else + LINUX_CTR3(sys_futex, "futex_sleep out error %d uaddr %p wp %p", + error, f->f_uaddr, wp); futex_put(f, wp); return (error); @@ -252,6 +271,8 @@ futex_wake(struct futex *f, int n) FUTEX_ASSERT_LOCKED(f); TAILQ_FOREACH_SAFE(wp, &f->f_waiting_proc, wp_list, wpt) { + LINUX_CTR3(sys_futex, "futex_wake uaddr %p wp %p ref %d", + f->f_uaddr, wp, f->f_refcount); wp->wp_flags |= FUTEX_WP_REMOVED; TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list); wakeup_one(wp); @@ -273,10 +294,14 @@ futex_requeue(struct futex *f, int n, struct futex *f2, int n2) TAILQ_FOREACH_SAFE(wp, &f->f_waiting_proc, wp_list, wpt) { if (++count <= n) { + LINUX_CTR2(sys_futex, "futex_req_wake uaddr %p wp %p", + f->f_uaddr, wp); wp->wp_flags |= FUTEX_WP_REMOVED; TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list); wakeup_one(wp); } else { + LINUX_CTR3(sys_futex, "futex_requeue uaddr %p wp %p to %p", + f->f_uaddr, wp, f2->f_uaddr); wp->wp_flags |= FUTEX_WP_REQUEUED; /* Move wp to wp_list of f2 futex */ TAILQ_REMOVE(&f->f_waiting_proc, wp, wp_list); @@ -421,6 +446,8 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) switch (args->op) { case LINUX_FUTEX_WAIT: + LINUX_CTR2(sys_futex, "WAIT val %d uaddr %p", + args->val, args->uaddr); #ifdef DEBUG if (ldebug(sys_futex)) printf(ARGS(sys_futex, "futex_wait val %d uaddr %p"), @@ -431,15 +458,14 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) return (error); error = copyin(args->uaddr, &val, sizeof(val)); if (error) { + LINUX_CTR1(sys_futex, "WAIT copyin failed %d", + error); futex_put(f, wp); return (error); } if (val != args->val) { -#ifdef DEBUG - if (ldebug(sys_futex)) - printf(ARGS(sys_futex, "futex_wait uaddr %p WHOOPS %d != %d"), - args->uaddr, args->val, val); -#endif + LINUX_CTR3(sys_futex, "WAIT uaddr %p val %d != uval %d", + args->uaddr, args->val, val); futex_put(f, wp); return (EWOULDBLOCK); } @@ -449,6 +475,9 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_WAKE: + LINUX_CTR2(sys_futex, "WAKE val %d uaddr %p", + args->val, args->uaddr); + /* * XXX: Linux is able to cope with different addresses * corresponding to the same mapped memory in the sleeping @@ -472,6 +501,11 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_CMP_REQUEUE: + LINUX_CTR5(sys_futex, "CMP_REQUEUE uaddr %p " + "val %d val3 %d uaddr2 %p val2 %d", + args->uaddr, args->val, args->val3, args->uaddr2, + (int)(unsigned long)args->timeout); + #ifdef DEBUG if (ldebug(sys_futex)) printf(ARGS(sys_futex, "futex_cmp_requeue uaddr %p " @@ -505,16 +539,15 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) } error = copyin(args->uaddr, &val, sizeof(val)); if (error) { + LINUX_CTR1(sys_futex, "CMP_REQUEUE copyin failed %d", + error); futex_put(f2, NULL); futex_put(f, NULL); return (error); } if (val != args->val3) { -#ifdef DEBUG - if (ldebug(sys_futex)) - printf(ARGS(sys_futex, "futex_cmp_requeue WHOOPS" - " VAL %d != UVAL %d"), args->val, val); -#endif + LINUX_CTR2(sys_futex, "CMP_REQUEUE val %d != uval %d", + args->val, val); futex_put(f2, NULL); futex_put(f, NULL); return (EAGAIN); @@ -528,6 +561,11 @@ linux_sys_futex(struct thread *td, struct linux_sys_futex_args *args) case LINUX_FUTEX_WAKE_OP: + LINUX_CTR5(sys_futex, "WAKE_OP " + "uaddr %p op %d val %x uaddr2 %p val3 %x", + args->uaddr, args->op, args->val, + args->uaddr2, args->val3); + #ifdef DEBUG if (ldebug(sys_futex)) printf(ARGS(sys_futex, "futex_wake_op " From 506d3686a28e0a272d8bfb13d9847e3feaae9b4b Mon Sep 17 00:00:00 2001 From: Ed Maste Date: Thu, 7 May 2009 16:31:50 +0000 Subject: [PATCH 023/544] Update example with feedback from thompsa@. --- share/man/man4/if_bridge.4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/man/man4/if_bridge.4 b/share/man/man4/if_bridge.4 index b1304e30193e..7b31fa18f107 100644 --- a/share/man/man4/if_bridge.4 +++ b/share/man/man4/if_bridge.4 @@ -358,7 +358,8 @@ For the bridge to forward packets all member interfaces and the bridge need to be up. The above example would also require: .Bd -literal -offset indent -ifconfig_wlan0="up ssid my_ap mode 11g mediaopt hostap" +create_args_wlan0="wlanmode hostap" +ifconfig_wlan0="up ssid my_ap mode 11g" ifconfig_fxp0="up" .Ed .Pp From 892f1c7141cc003a4a6676f6dfcbaa9c07a5d119 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 7 May 2009 16:42:45 +0000 Subject: [PATCH 024/544] ABI expansions to hopefully future-proof our MIB/netstat code for 8.0 --- sys/netinet/sctp_uio.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/netinet/sctp_uio.h b/sys/netinet/sctp_uio.h index efcd2c4e4fa8..e58325d75933 100644 --- a/sys/netinet/sctp_uio.h +++ b/sys/netinet/sctp_uio.h @@ -764,6 +764,8 @@ struct sctp_timeval { }; struct sctpstat { + struct sctp_timeval sctps_discontinuitytime; /* sctpStats 18 + * (TimeStamp) */ /* MIB according to RFC 3873 */ uint32_t sctps_currestab; /* sctpStats 1 (Gauge32) */ uint32_t sctps_activeestab; /* sctpStats 2 (Counter32) */ @@ -948,8 +950,8 @@ struct sctpstat { uint32_t sctps_fwdtsn_map_over; /* number of map array over-runs via * fwd-tsn's */ - struct sctp_timeval sctps_discontinuitytime; /* sctpStats 18 - * (TimeStamp) */ + uint32_t sctps_reserved[32]; /* Future ABI compat - remove int's + * from here when adding new */ }; #define SCTP_STAT_INCR(_x) SCTP_STAT_INCR_BY(_x,1) From 096ed42dad6b3566289727a09e659601aeb5e338 Mon Sep 17 00:00:00 2001 From: Randall Stewart Date: Thu, 7 May 2009 16:43:49 +0000 Subject: [PATCH 025/544] repository sync to multi-OS repo ... spaceing change --- sys/netinet/sctp_crc32.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netinet/sctp_crc32.c b/sys/netinet/sctp_crc32.c index 9594369a8b12..aeb97153855c 100644 --- a/sys/netinet/sctp_crc32.c +++ b/sys/netinet/sctp_crc32.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include + #if !defined(SCTP_WITH_NO_CSUM) static uint32_t From 822e5d76f84cf7b2ef650ad8907b93efcda1b211 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 7 May 2009 17:05:03 +0000 Subject: [PATCH 026/544] Use a 32 bit type for the interface mask as this equals the max interface count. --- sys/dev/usb/serial/u3g.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 407d98e8625a..9c15ef782b58 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -440,7 +440,8 @@ u3g_attach(device_t dev) struct u3g_softc *sc = device_get_softc(dev); struct usb2_interface *iface; struct usb2_interface_descriptor *id; - int error, iface_valid, flags, nports; + uint32_t iface_valid; + int error, flags, nports; int ep, n; uint8_t i; From 14358b0fec83e34f754d1b153d925d3bd6757f51 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 7 May 2009 17:39:23 +0000 Subject: [PATCH 027/544] If we have a regular rint handler, never go into rint_bypass mode. It turns out if we called cfmakeraw() on a TTY with only a rint handler in place, it could inject data into the TTY, even though it should be redirected. Always take a look at the hooks before looking at the termios flags. --- sys/kern/tty_ttydisc.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/kern/tty_ttydisc.c b/sys/kern/tty_ttydisc.c index 2bb83dd24e90..634b58e14dff 100644 --- a/sys/kern/tty_ttydisc.c +++ b/sys/kern/tty_ttydisc.c @@ -560,12 +560,15 @@ ttydisc_optimize(struct tty *tp) { tty_lock_assert(tp, MA_OWNED); - if ((!CMP_FLAG(i, ICRNL|IGNCR|IMAXBEL|INLCR|ISTRIP|IXON) && + if (ttyhook_hashook(tp, rint_bypass)) { + tp->t_flags |= TF_BYPASS; + } else if (ttyhook_hashook(tp, rint)) { + tp->t_flags &= ~TF_BYPASS; + } else if (!CMP_FLAG(i, ICRNL|IGNCR|IMAXBEL|INLCR|ISTRIP|IXON) && (!CMP_FLAG(i, BRKINT) || CMP_FLAG(i, IGNBRK)) && (!CMP_FLAG(i, PARMRK) || CMP_FLAG(i, IGNPAR|IGNBRK) == (IGNPAR|IGNBRK)) && - !CMP_FLAG(l, ECHO|ICANON|IEXTEN|ISIG|PENDIN)) || - ttyhook_hashook(tp, rint_bypass)) { + !CMP_FLAG(l, ECHO|ICANON|IEXTEN|ISIG|PENDIN)) { tp->t_flags |= TF_BYPASS; } else { tp->t_flags &= ~TF_BYPASS; From 541bfd618025040690a601f15c4f84ad21f25614 Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Thu, 7 May 2009 18:03:47 +0000 Subject: [PATCH 028/544] Add PCI IDs for the Broadcom 5825 incarnation. Submitted by: Brian A. Seklecki MFC after: 1 day --- sys/dev/ubsec/ubsec.c | 7 +++++-- sys/dev/ubsec/ubsecreg.h | 1 + 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/dev/ubsec/ubsec.c b/sys/dev/ubsec/ubsec.c index f0e5399db241..3fb9df2e6dcc 100644 --- a/sys/dev/ubsec/ubsec.c +++ b/sys/dev/ubsec/ubsec.c @@ -220,7 +220,8 @@ ubsec_probe(device_t dev) pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5820 || pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5821 || pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5822 || - pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5823 + pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5823 || + pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5825 )) return (BUS_PROBE_DEFAULT); return (ENXIO); @@ -240,6 +241,7 @@ ubsec_partname(struct ubsec_softc *sc) case PCI_PRODUCT_BROADCOM_5821: return "Broadcom 5821"; case PCI_PRODUCT_BROADCOM_5822: return "Broadcom 5822"; case PCI_PRODUCT_BROADCOM_5823: return "Broadcom 5823"; + case PCI_PRODUCT_BROADCOM_5825: return "Broadcom 5825"; } return "Broadcom unknown-part"; case PCI_VENDOR_BLUESTEEL: @@ -301,7 +303,8 @@ ubsec_attach(device_t dev) if ((pci_get_vendor(dev) == PCI_VENDOR_BROADCOM && (pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5821 || pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5822 || - pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5823)) || + pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5823 || + pci_get_device(dev) == PCI_PRODUCT_BROADCOM_5825)) || (pci_get_vendor(dev) == PCI_VENDOR_SUN && (pci_get_device(dev) == PCI_PRODUCT_SUN_SCA1K || pci_get_device(dev) == PCI_PRODUCT_SUN_5821))) { diff --git a/sys/dev/ubsec/ubsecreg.h b/sys/dev/ubsec/ubsecreg.h index 2ba1f937d06e..f78dc450f4cd 100644 --- a/sys/dev/ubsec/ubsecreg.h +++ b/sys/dev/ubsec/ubsecreg.h @@ -62,6 +62,7 @@ #define PCI_PRODUCT_BROADCOM_5821 0x5821 /* 5821 */ #define PCI_PRODUCT_BROADCOM_5822 0x5822 /* 5822 */ #define PCI_PRODUCT_BROADCOM_5823 0x5823 /* 5823 */ +#define PCI_PRODUCT_BROADCOM_5825 0x5825 /* 5825 */ /* Sun Microsystems */ #define PCI_PRODUCT_SUN_5821 0x5454 /* Crypto 5821 */ From 41b72e6e504cae5b1f61f1a8ccd8979fae28af3c Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 7 May 2009 18:14:21 +0000 Subject: [PATCH 029/544] Eliminate the loop and the call to pause(9) in vfs_vget_ino(). If vfs_busy(MBF_NOWAIT) failed, unlock the vnode and sleep in vfs_busy(). Suggested and reviewed by: jeff Tested by: pho MFC after: 3 weeks --- sys/kern/vfs_vnops.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 2f085d96ab8e..00082093431d 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1292,15 +1292,17 @@ vn_vget_ino(struct vnode *vp, ino_t ino, int lkflags, struct vnode **rvp) ltype = VOP_ISLOCKED(vp); KASSERT(ltype == LK_EXCLUSIVE || ltype == LK_SHARED, ("vn_vget_ino: vp not locked")); - for (;;) { - error = vfs_busy(mp, MBF_NOWAIT); - if (error == 0) - break; + error = vfs_busy(mp, MBF_NOWAIT); + if (error != 0) { VOP_UNLOCK(vp, 0); - pause("vn_vget", 1); + error = vfs_busy(mp, 0); vn_lock(vp, ltype | LK_RETRY); - if (vp->v_iflag & VI_DOOMED) + if (error != 0) return (ENOENT); + if (vp->v_iflag & VI_DOOMED) { + vfs_unbusy(mp); + return (ENOENT); + } } VOP_UNLOCK(vp, 0); error = VFS_VGET(mp, ino, lkflags, rvp); From 7ae27ff49f75ab84aa08078514699692fb9c4f16 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Thu, 7 May 2009 18:36:47 +0000 Subject: [PATCH 030/544] Move the per-prison Linux MIB from a private one-off pointer to the new OSD-based jail extensions. This allows the Linux MIB to accessed via jail_set and jail_get, and serves as a demonstration of adding jail support to a module. Reviewed by: dchagin, kib Approved by: bz (mentor) --- sys/amd64/linux32/linux32_sysvec.c | 2 + sys/compat/linux/linux_mib.c | 422 ++++++++++++++++++++++------- sys/compat/linux/linux_mib.h | 3 + sys/compat/linux/linux_stats.c | 1 - sys/i386/linux/linux_sysvec.c | 2 + sys/kern/kern_jail.c | 1 - sys/sys/jail.h | 2 +- 7 files changed, 333 insertions(+), 100 deletions(-) diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index a0415f3a4cca..2d7103414b94 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -1124,6 +1124,7 @@ linux_elf_modevent(module_t mod, int type, void *data) linux_proc_exec, NULL, 1000); linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); + linux_osd_jail_register(); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else @@ -1151,6 +1152,7 @@ linux_elf_modevent(module_t mod, int type, void *data) EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + linux_osd_jail_deregister(); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index 331b91e4abd4..fd1777328729 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -35,9 +35,11 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include +#include #include "opt_compat.h" @@ -55,6 +57,8 @@ struct linux_prison { int pr_use_linux26; /* flag to determine whether to use 2.6 emulation */ }; +static unsigned linux_osd_jail_slot; + SYSCTL_NODE(_compat, OID_AUTO, linux, CTLFLAG_RW, 0, "Linux mode"); @@ -128,58 +132,308 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version, /* * Returns holding the prison mutex if return non-NULL. */ -static struct prison * -linux_get_prison(struct thread *td) +static struct linux_prison * +linux_get_prison(struct thread *td, struct prison **prp) { - register struct prison *pr; - register struct linux_prison *lpr; + struct prison *pr; + struct linux_prison *lpr; KASSERT(td == curthread, ("linux_get_prison() called on !curthread")); - if (!jailed(td->td_ucred)) + *prp = pr = td->td_ucred->cr_prison; + if (pr == NULL || !linux_osd_jail_slot) return (NULL); - pr = td->td_ucred->cr_prison; mtx_lock(&pr->pr_mtx); - if (pr->pr_linux == NULL) { - /* - * If we don't have a linux prison structure yet, allocate - * one. We have to handle the race where another thread - * could be adding a linux prison to this process already. - */ + lpr = osd_jail_get(pr, linux_osd_jail_slot); + if (lpr == NULL) mtx_unlock(&pr->pr_mtx); - lpr = malloc(sizeof(struct linux_prison), M_PRISON, - M_WAITOK | M_ZERO); - mtx_lock(&pr->pr_mtx); - if (pr->pr_linux == NULL) - pr->pr_linux = lpr; - else - free(lpr, M_PRISON); + return (lpr); +} + +/* + * Ensure a prison has its own Linux info. The prison should be locked on + * entrance and will be locked on exit (though it may get unlocked in the + * interrim). + */ +static int +linux_alloc_prison(struct prison *pr, struct linux_prison **lprp) +{ + struct linux_prison *lpr, *nlpr; + int error; + + /* If this prison already has Linux info, return that. */ + error = 0; + mtx_assert(&pr->pr_mtx, MA_OWNED); + lpr = osd_jail_get(pr, linux_osd_jail_slot); + if (lpr != NULL) + goto done; + /* + * Allocate a new info record. Then check again, in case something + * changed during the allocation. + */ + mtx_unlock(&pr->pr_mtx); + nlpr = malloc(sizeof(struct linux_prison), M_PRISON, M_WAITOK); + mtx_lock(&pr->pr_mtx); + lpr = osd_jail_get(pr, linux_osd_jail_slot); + if (lpr != NULL) { + free(nlpr, M_PRISON); + goto done; } - return (pr); + error = osd_jail_set(pr, linux_osd_jail_slot, nlpr); + if (error) + free(nlpr, M_PRISON); + else { + lpr = nlpr; + mtx_lock(&osname_lock); + strncpy(lpr->pr_osname, linux_osname, LINUX_MAX_UTSNAME); + strncpy(lpr->pr_osrelease, linux_osrelease, LINUX_MAX_UTSNAME); + lpr->pr_oss_version = linux_oss_version; + lpr->pr_use_linux26 = linux_use_linux26; + mtx_unlock(&osname_lock); + } +done: + if (lprp != NULL) + *lprp = lpr; + return (error); +} + +/* + * Jail OSD methods for Linux prison data. + */ +static int +linux_prison_create(void *obj, void *data) +{ + int error; + struct prison *pr = obj; + struct vfsoptlist *opts = data; + + if (vfs_flagopt(opts, "nolinux", NULL, 0)) + return (0); + /* + * Inherit a prison's initial values from its parent + * (different from NULL which also inherits changes). + */ + mtx_lock(&pr->pr_mtx); + error = linux_alloc_prison(pr, NULL); + mtx_unlock(&pr->pr_mtx); + return (error); +} + +static int +linux_prison_check(void *obj __unused, void *data) +{ + struct vfsoptlist *opts = data; + char *osname, *osrelease; + size_t len; + int error, oss_version; + + /* Check that the parameters are correct. */ + (void)vfs_flagopt(opts, "linux", NULL, 0); + (void)vfs_flagopt(opts, "nolinux", NULL, 0); + error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len); + if (error != ENOENT) { + if (error != 0) + return (error); + if (len == 0 || osname[len - 1] != '\0') + return (EINVAL); + if (len > LINUX_MAX_UTSNAME) { + vfs_opterror(opts, "linux.osname too long"); + return (ENAMETOOLONG); + } + } + error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len); + if (error != ENOENT) { + if (error != 0) + return (error); + if (len == 0 || osrelease[len - 1] != '\0') + return (EINVAL); + if (len > LINUX_MAX_UTSNAME) { + vfs_opterror(opts, "linux.osrelease too long"); + return (ENAMETOOLONG); + } + } + error = vfs_copyopt(opts, "linux.oss_version", &oss_version, + sizeof(oss_version)); + return (error == ENOENT ? 0 : error); +} + +static int +linux_prison_set(void *obj, void *data) +{ + struct linux_prison *lpr; + struct prison *pr = obj; + struct vfsoptlist *opts = data; + char *osname, *osrelease; + size_t len; + int error, gotversion, nolinux, oss_version, yeslinux; + + /* Set the parameters, which should be correct. */ + yeslinux = vfs_flagopt(opts, "linux", NULL, 0); + nolinux = vfs_flagopt(opts, "nolinux", NULL, 0); + error = vfs_getopt(opts, "linux.osname", (void **)&osname, &len); + if (error == ENOENT) + osname = NULL; + else + yeslinux = 1; + error = vfs_getopt(opts, "linux.osrelease", (void **)&osrelease, &len); + if (error == ENOENT) + osrelease = NULL; + else + yeslinux = 1; + error = vfs_copyopt(opts, "linux.oss_version", &oss_version, + sizeof(oss_version)); + gotversion = error == 0; + yeslinux |= gotversion; + if (nolinux) { + /* "nolinux": inherit the parent's Linux info. */ + mtx_lock(&pr->pr_mtx); + osd_jail_del(pr, linux_osd_jail_slot); + mtx_unlock(&pr->pr_mtx); + } else if (yeslinux) { + /* + * "linux" or "linux.*": + * the prison gets its own Linux info. + */ + mtx_lock(&pr->pr_mtx); + error = linux_alloc_prison(pr, &lpr); + if (error) { + mtx_unlock(&pr->pr_mtx); + return (error); + } + if (osname) + strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME); + if (osrelease) { + strlcpy(lpr->pr_osrelease, osrelease, + LINUX_MAX_UTSNAME); + lpr->pr_use_linux26 = strlen(osrelease) >= 3 && + osrelease[2] == '6'; + } + if (gotversion) + lpr->pr_oss_version = oss_version; + mtx_unlock(&pr->pr_mtx); + } + return (0); +} + +SYSCTL_JAIL_PARAM_NODE(linux, "Jail Linux parameters"); +SYSCTL_JAIL_PARAM(, nolinux, CTLTYPE_INT | CTLFLAG_RW, + "BN", "Jail w/ no Linux parameters"); +SYSCTL_JAIL_PARAM_STRING(_linux, osname, CTLFLAG_RW, LINUX_MAX_UTSNAME, + "Jail Linux kernel OS name"); +SYSCTL_JAIL_PARAM_STRING(_linux, osrelease, CTLFLAG_RW, LINUX_MAX_UTSNAME, + "Jail Linux kernel OS release"); +SYSCTL_JAIL_PARAM(_linux, oss_version, CTLTYPE_INT | CTLFLAG_RW, + "I", "Jail Linux OSS version"); + +static int +linux_prison_get(void *obj, void *data) +{ + struct linux_prison *lpr; + struct prison *pr = obj; + struct vfsoptlist *opts = data; + int error, i; + + mtx_lock(&pr->pr_mtx); + /* Tell whether this prison has its own Linux info. */ + lpr = osd_jail_get(pr, linux_osd_jail_slot); + i = lpr != NULL; + error = vfs_setopt(opts, "linux", &i, sizeof(i)); + if (error != 0 && error != ENOENT) + goto done; + i = !i; + error = vfs_setopt(opts, "nolinux", &i, sizeof(i)); + if (error != 0 && error != ENOENT) + goto done; + /* + * It's kind of bogus to give the root info, but leave it to the caller + * to check the above flag. + */ + if (lpr != NULL) { + error = vfs_setopts(opts, "linux.osname", lpr->pr_osname); + if (error != 0 && error != ENOENT) + goto done; + error = vfs_setopts(opts, "linux.osrelease", lpr->pr_osrelease); + if (error != 0 && error != ENOENT) + goto done; + error = vfs_setopt(opts, "linux.oss_version", + &lpr->pr_oss_version, sizeof(lpr->pr_oss_version)); + if (error != 0 && error != ENOENT) + goto done; + } else { + mtx_lock(&osname_lock); + error = vfs_setopts(opts, "linux.osname", linux_osname); + if (error != 0 && error != ENOENT) + goto done; + error = vfs_setopts(opts, "linux.osrelease", linux_osrelease); + if (error != 0 && error != ENOENT) + goto done; + error = vfs_setopt(opts, "linux.oss_version", + &linux_oss_version, sizeof(linux_oss_version)); + if (error != 0 && error != ENOENT) + goto done; + mtx_unlock(&osname_lock); + } + error = 0; + + done: + mtx_unlock(&pr->pr_mtx); + return (error); +} + +static void +linux_prison_destructor(void *data) +{ + + free(data, M_PRISON); +} + +void +linux_osd_jail_register(void) +{ + struct prison *pr; + osd_method_t methods[PR_MAXMETHOD] = { + [PR_METHOD_CREATE] = linux_prison_create, + [PR_METHOD_GET] = linux_prison_get, + [PR_METHOD_SET] = linux_prison_set, + [PR_METHOD_CHECK] = linux_prison_check + }; + + linux_osd_jail_slot = + osd_jail_register(linux_prison_destructor, methods); + if (linux_osd_jail_slot > 0) { + /* Copy the system linux info to any current prisons. */ + sx_xlock(&allprison_lock); + TAILQ_FOREACH(pr, &allprison, pr_list) { + mtx_lock(&pr->pr_mtx); + (void)linux_alloc_prison(pr, NULL); + mtx_unlock(&pr->pr_mtx); + } + sx_xunlock(&allprison_lock); + } +} + +void +linux_osd_jail_deregister(void) +{ + + if (linux_osd_jail_slot) + osd_jail_deregister(linux_osd_jail_slot); } void linux_get_osname(struct thread *td, char *dst) { - register struct prison *pr; - register struct linux_prison *lpr; + struct prison *pr; + struct linux_prison *lpr; - pr = td->td_ucred->cr_prison; - if (pr != NULL) { - mtx_lock(&pr->pr_mtx); - if (pr->pr_linux != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - if (lpr->pr_osname[0]) { - bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME); - mtx_unlock(&pr->pr_mtx); - return; - } - } + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + bcopy(lpr->pr_osname, dst, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); + } else { + mtx_lock(&osname_lock); + bcopy(linux_osname, dst, LINUX_MAX_UTSNAME); + mtx_unlock(&osname_lock); } - - mtx_lock(&osname_lock); - bcopy(linux_osname, dst, LINUX_MAX_UTSNAME); - mtx_unlock(&osname_lock); } int @@ -188,10 +442,9 @@ linux_set_osname(struct thread *td, char *osname) struct prison *pr; struct linux_prison *lpr; - pr = linux_get_prison(td); - if (pr != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - strcpy(lpr->pr_osname, osname); + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); } else { mtx_lock(&osname_lock); @@ -205,27 +458,18 @@ linux_set_osname(struct thread *td, char *osname) void linux_get_osrelease(struct thread *td, char *dst) { - register struct prison *pr; + struct prison *pr; struct linux_prison *lpr; - pr = td->td_ucred->cr_prison; - if (pr != NULL) { - mtx_lock(&pr->pr_mtx); - if (pr->pr_linux != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - if (lpr->pr_osrelease[0]) { - bcopy(lpr->pr_osrelease, dst, - LINUX_MAX_UTSNAME); - mtx_unlock(&pr->pr_mtx); - return; - } - } + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + bcopy(lpr->pr_osrelease, dst, LINUX_MAX_UTSNAME); mtx_unlock(&pr->pr_mtx); + } else { + mtx_lock(&osname_lock); + bcopy(linux_osrelease, dst, LINUX_MAX_UTSNAME); + mtx_unlock(&osname_lock); } - - mtx_lock(&osname_lock); - bcopy(linux_osrelease, dst, LINUX_MAX_UTSNAME); - mtx_unlock(&osname_lock); } int @@ -233,16 +477,14 @@ linux_use26(struct thread *td) { struct prison *pr; struct linux_prison *lpr; - int use26 = linux_use_linux26; + int use26; - pr = td->td_ucred->cr_prison; - if (pr != NULL) { - if (pr->pr_linux != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - use26 = lpr->pr_use_linux26; - } - } - + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + use26 = lpr->pr_use_linux26; + mtx_unlock(&pr->pr_mtx); + } else + use26 = linux_use_linux26; return (use26); } @@ -251,20 +493,18 @@ linux_set_osrelease(struct thread *td, char *osrelease) { struct prison *pr; struct linux_prison *lpr; - int use26; - use26 = (strlen(osrelease) >= 3 && osrelease[2] == '6'); - - pr = linux_get_prison(td); - if (pr != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - strcpy(lpr->pr_osrelease, osrelease); - lpr->pr_use_linux26 = use26; + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME); + lpr->pr_use_linux26 = + strlen(osrelease) >= 3 && osrelease[2] == '6'; mtx_unlock(&pr->pr_mtx); } else { mtx_lock(&osname_lock); strcpy(linux_osrelease, osrelease); - linux_use_linux26 = use26; + linux_use_linux26 = + strlen(osrelease) >= 3 && osrelease[2] == '6'; mtx_unlock(&osname_lock); } @@ -274,27 +514,16 @@ linux_set_osrelease(struct thread *td, char *osrelease) int linux_get_oss_version(struct thread *td) { - register struct prison *pr; - register struct linux_prison *lpr; + struct prison *pr; + struct linux_prison *lpr; int version; - pr = td->td_ucred->cr_prison; - if (pr != NULL) { - mtx_lock(&pr->pr_mtx); - if (pr->pr_linux != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; - if (lpr->pr_oss_version) { - version = lpr->pr_oss_version; - mtx_unlock(&pr->pr_mtx); - return (version); - } - } + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { + version = lpr->pr_oss_version; mtx_unlock(&pr->pr_mtx); - } - - mtx_lock(&osname_lock); - version = linux_oss_version; - mtx_unlock(&osname_lock); + } else + version = linux_oss_version; return (version); } @@ -304,9 +533,8 @@ linux_set_oss_version(struct thread *td, int oss_version) struct prison *pr; struct linux_prison *lpr; - pr = linux_get_prison(td); - if (pr != NULL) { - lpr = (struct linux_prison *)pr->pr_linux; + lpr = linux_get_prison(td, &pr); + if (lpr != NULL) { lpr->pr_oss_version = oss_version; mtx_unlock(&pr->pr_mtx); } else { diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h index 85f616352ad0..8e5d650f981b 100644 --- a/sys/compat/linux/linux_mib.h +++ b/sys/compat/linux/linux_mib.h @@ -31,6 +31,9 @@ #ifndef _LINUX_MIB_H_ #define _LINUX_MIB_H_ +void linux_osd_jail_register(void); +void linux_osd_jail_deregister(void); + void linux_get_osname(struct thread *td, char *dst); int linux_set_osname(struct thread *td, char *osname); diff --git a/sys/compat/linux/linux_stats.c b/sys/compat/linux/linux_stats.c index c7b303780db6..479ccf3c955c 100644 --- a/sys/compat/linux/linux_stats.c +++ b/sys/compat/linux/linux_stats.c @@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 7e64fa8d0653..7af87a76986d 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -1091,6 +1091,7 @@ linux_elf_modevent(module_t mod, int type, void *data) linux_get_machine(&linux_platform); linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); + linux_osd_jail_register(); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else @@ -1118,6 +1119,7 @@ linux_elf_modevent(module_t mod, int type, void *data) EVENTHANDLER_DEREGISTER(process_exit, linux_exit_tag); EVENTHANDLER_DEREGISTER(schedtail, linux_schedtail_tag); EVENTHANDLER_DEREGISTER(process_exec, linux_exec_tag); + linux_osd_jail_deregister(); if (bootverbose) printf("Linux ELF exec handler removed\n"); } else diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 7c0e7c993ea0..069f1f0f1b9c 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1713,7 +1713,6 @@ prison_deref(struct prison *pr, int flags) VFS_UNLOCK_GIANT(vfslocked); } mtx_destroy(&pr->pr_mtx); - free(pr->pr_linux, M_PRISON); #ifdef INET free(pr->pr_ip4, M_PRISON); #endif diff --git a/sys/sys/jail.h b/sys/sys/jail.h index f97d87a197e1..60e2d324b66e 100644 --- a/sys/sys/jail.h +++ b/sys/sys/jail.h @@ -162,7 +162,7 @@ struct prison { struct vnode *pr_root; /* (c) vnode to rdir */ char pr_host[MAXHOSTNAMELEN]; /* (p) jail hostname */ char pr_name[MAXHOSTNAMELEN]; /* (p) admin jail name */ - void *pr_linux; /* (p) linux abi */ + void *pr_spare; /* was pr_linux */ int pr_securelevel; /* (p) securelevel */ struct task pr_task; /* (d) destroy task */ struct mtx pr_mtx; From 88413c6b888d01537175945f14b75e3757527543 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Thu, 7 May 2009 19:17:06 +0000 Subject: [PATCH 031/544] Add ID of one more SII3132 revision found on adaptec aar-1225sa rev a2. PR: kern/127289 --- sys/dev/ata/ata-pci.h | 1 + sys/dev/ata/chipsets/ata-siliconimage.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index 42f478eeb4df..b1f3eb70504e 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -345,6 +345,7 @@ struct ata_pci_controller { #define ATA_SII3124 0x31241095 #define ATA_SII3132 0x31321095 #define ATA_SII3132_1 0x02421095 +#define ATA_SII3132_2 0x02441095 #define ATA_SII0680 0x06801095 #define ATA_CMD646 0x06461095 #define ATA_CMD648 0x06481095 diff --git a/sys/dev/ata/chipsets/ata-siliconimage.c b/sys/dev/ata/chipsets/ata-siliconimage.c index b163276c72c4..f4f086bfbcb2 100644 --- a/sys/dev/ata/chipsets/ata-siliconimage.c +++ b/sys/dev/ata/chipsets/ata-siliconimage.c @@ -99,6 +99,7 @@ ata_sii_probe(device_t dev) { ATA_SII3124, 0x00, SII_PRBIO, SII_4CH, ATA_SA300, "3124" }, { ATA_SII3132, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, { ATA_SII3132_1, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, + { ATA_SII3132_2, 0x00, SII_PRBIO, 0, ATA_SA300, "3132" }, { ATA_SII0680, 0x00, SII_MEMIO, SII_SETCLK, ATA_UDMA6, "680" }, { ATA_CMD649, 0x00, 0, SII_INTR, ATA_UDMA5, "(CMD) 649" }, { ATA_CMD648, 0x00, 0, SII_INTR, ATA_UDMA4, "(CMD) 648" }, From e03d223bd445dd8a7f0e0ea5861db9e3be00601d Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Thu, 7 May 2009 19:46:29 +0000 Subject: [PATCH 032/544] Give vfs_getopt the type it's expecting. Write 100 times: "32 bits is so twentieth century." Noticed by: dchagin --- sys/compat/linux/linux_mib.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index fd1777328729..676ddcd0d9aa 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -223,8 +223,7 @@ linux_prison_check(void *obj __unused, void *data) { struct vfsoptlist *opts = data; char *osname, *osrelease; - size_t len; - int error, oss_version; + int error, len, oss_version; /* Check that the parameters are correct. */ (void)vfs_flagopt(opts, "linux", NULL, 0); @@ -263,8 +262,7 @@ linux_prison_set(void *obj, void *data) struct prison *pr = obj; struct vfsoptlist *opts = data; char *osname, *osrelease; - size_t len; - int error, gotversion, nolinux, oss_version, yeslinux; + int error, gotversion, len, nolinux, oss_version, yeslinux; /* Set the parameters, which should be correct. */ yeslinux = vfs_flagopt(opts, "linux", NULL, 0); From 3982c6995387e412ba78cc0145d5e73563a5c639 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 19:57:14 +0000 Subject: [PATCH 033/544] No man page currently exists so comment the two uncommented non-trivial functions --- sys/sys/buf_ring.h | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/sys/sys/buf_ring.h b/sys/sys/buf_ring.h index efea85aa6f0b..0ffe5a265b7d 100644 --- a/sys/sys/buf_ring.h +++ b/sys/sys/buf_ring.h @@ -1,6 +1,6 @@ /************************************************************************** * - * Copyright (c) 2007,2008 Kip Macy kmacy@freebsd.org + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -69,7 +69,10 @@ struct buf_ring { void *br_ring[0]; }; - +/* + * multi-producer safe lock-free ring buffer enqueue + * + */ static __inline int buf_ring_enqueue(struct buf_ring *br, void *buf) { @@ -169,8 +172,9 @@ buf_ring_dequeue_mc(struct buf_ring *br) } /* - * Single-Consumer dequeue for uses where dequeue - * is protected by a lock + * single-consumer dequeue + * use where dequeue is protected by a lock + * e.g. a network driver's tx queue lock */ static __inline void * buf_ring_dequeue_sc(struct buf_ring *br) @@ -208,6 +212,11 @@ buf_ring_dequeue_sc(struct buf_ring *br) return (buf); } +/* + * return a pointer to the first entry in the ring + * without modifying it, or NULL if the ring is empty + * race-prone if not protected by a lock + */ static __inline void * buf_ring_peek(struct buf_ring *br) { From 62fa227ccdb343645e5b6adcb0e1db00fa233bc5 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 20:28:06 +0000 Subject: [PATCH 034/544] Asynchronously release vnodes to avoid blocking on range locks when calling back in to zfs. This is based on a fix that went in to opensolaris on March 9th. However, it uses a dedicated thread instead of a Solaris' taskq to avoid doing a blocking memory allocation with the vnode interlock held. This fixes a long-time deadlock in ZFS. This is not, strictly speaking, an LOR. The spa_zio thread releases a vnode, this calls in to vn_reclaim which in turn needs to acquire range locks to sync dirty data out to disk. The range locks are already held by a user-level process waiting on a condition variable that it the process is waiting on a spa_zio thread to signal it on. The process could not be signalled because the spa_zio thread could not proceed. The nature of this problem was not apparent due to ZFS locks opting out of witness which meant that DDB did not know about the locks that were held by ZFS. Reviewed by: pjd MFC after: 7 days --- .../contrib/opensolaris/uts/common/fs/vnode.c | 137 ++++++++++++++++++ .../opensolaris/uts/common/fs/zfs/dmu.c | 1 + .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 20 ++- .../opensolaris/uts/common/fs/zfs/zil.c | 2 +- .../opensolaris/uts/common/sys/vnode.h | 9 ++ 5 files changed, 165 insertions(+), 4 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c b/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c index 00a10aae8ec9..bf613e5adb55 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/vnode.c @@ -41,6 +41,7 @@ #include #include +#include #include /* Extensible attribute (xva) routines. */ @@ -72,3 +73,139 @@ xva_getxoptattr(xvattr_t *xvap) xoap = &xvap->xva_xoptattrs; return (xoap); } + +static STAILQ_HEAD(, vnode) vn_rele_async_list; +static struct mtx vn_rele_async_lock; +static struct cv vn_rele_async_cv; +static int vn_rele_list_length; +static int vn_rele_async_thread_exit; + +typedef struct { + struct vnode *stqe_next; +} vnode_link_t; + +/* + * Like vn_rele() except if we are going to call VOP_INACTIVE() then do it + * asynchronously using a taskq. This can avoid deadlocks caused by re-entering + * the file system as a result of releasing the vnode. Note, file systems + * already have to handle the race where the vnode is incremented before the + * inactive routine is called and does its locking. + * + * Warning: Excessive use of this routine can lead to performance problems. + * This is because taskqs throttle back allocation if too many are created. + */ +void +vn_rele_async(vnode_t *vp, taskq_t *taskq /* unused */) +{ + + KASSERT(vp != NULL, ("vrele: null vp")); + VFS_ASSERT_GIANT(vp->v_mount); + VI_LOCK(vp); + + if (vp->v_usecount > 1 || ((vp->v_iflag & VI_DOINGINACT) && + vp->v_usecount == 1)) { + vp->v_usecount--; + vdropl(vp); + return; + } + if (vp->v_usecount != 1) { +#ifdef DIAGNOSTIC + vprint("vrele: negative ref count", vp); +#endif + VI_UNLOCK(vp); + panic("vrele: negative ref cnt"); + } + /* + * We are exiting + */ + if (vn_rele_async_thread_exit != 0) { + vrele(vp); + return; + } + + mtx_lock(&vn_rele_async_lock); + + /* STAILQ_INSERT_TAIL */ + (*(vnode_link_t *)&vp->v_cstart).stqe_next = NULL; + *vn_rele_async_list.stqh_last = vp; + vn_rele_async_list.stqh_last = + &((vnode_link_t *)&vp->v_cstart)->stqe_next; + + /****************************************/ + vn_rele_list_length++; + if ((vn_rele_list_length % 100) == 0) + cv_signal(&vn_rele_async_cv); + mtx_unlock(&vn_rele_async_lock); + VI_UNLOCK(vp); +} + +static void +vn_rele_async_init(void *arg) +{ + + mtx_init(&vn_rele_async_lock, "valock", NULL, MTX_DEF); + STAILQ_INIT(&vn_rele_async_list); + + /* cv_init(&vn_rele_async_cv, "vacv"); */ + vn_rele_async_cv.cv_description = "vacv"; + vn_rele_async_cv.cv_waiters = 0; +} + +void +vn_rele_async_fini(void) +{ + + mtx_lock(&vn_rele_async_lock); + vn_rele_async_thread_exit = 1; + cv_signal(&vn_rele_async_cv); + while (vn_rele_async_thread_exit != 0) + cv_wait(&vn_rele_async_cv, &vn_rele_async_lock); + mtx_unlock(&vn_rele_async_lock); + mtx_destroy(&vn_rele_async_lock); +} + + +static void +vn_rele_async_cleaner(void) +{ + STAILQ_HEAD(, vnode) vn_tmp_list; + struct vnode *curvnode; + + STAILQ_INIT(&vn_tmp_list); + mtx_lock(&vn_rele_async_lock); + while (vn_rele_async_thread_exit == 0) { + STAILQ_CONCAT(&vn_tmp_list, &vn_rele_async_list); + vn_rele_list_length = 0; + mtx_unlock(&vn_rele_async_lock); + + while (!STAILQ_EMPTY(&vn_tmp_list)) { + curvnode = STAILQ_FIRST(&vn_tmp_list); + + /* STAILQ_REMOVE_HEAD */ + STAILQ_FIRST(&vn_tmp_list) = + ((vnode_link_t *)&curvnode->v_cstart)->stqe_next; + if (STAILQ_FIRST(&vn_tmp_list) == NULL) + vn_tmp_list.stqh_last = &STAILQ_FIRST(&vn_tmp_list); + /***********************/ + vrele(curvnode); + } + mtx_lock(&vn_rele_async_lock); + if (vn_rele_list_length == 0) + cv_timedwait(&vn_rele_async_cv, &vn_rele_async_lock, + hz/10); + } + + vn_rele_async_thread_exit = 0; + cv_broadcast(&vn_rele_async_cv); + mtx_unlock(&vn_rele_async_lock); + thread_exit(); +} + +static struct proc *vn_rele_async_proc; +static struct kproc_desc up_kp = { + "vaclean", + vn_rele_async_cleaner, + &vn_rele_async_proc +}; +SYSINIT(vaclean, SI_SUB_KTHREAD_UPDATE, SI_ORDER_FIRST, kproc_start, &up_kp); +SYSINIT(vn_rele_async_setup, SI_SUB_VFS, SI_ORDER_FIRST, vn_rele_async_init, NULL); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 377efb9d105e..1fb1c6fc5600 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -1199,6 +1199,7 @@ dmu_init(void) void dmu_fini(void) { + vn_rele_async_fini(); arc_fini(); dnode_fini(); dbuf_fini(); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 7792f6e57900..458d5bcb88af 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -93,6 +93,7 @@ * pushing cached pages (which acquires range locks) and syncing out * cached atime changes. Third, zfs_zinactive() may require a new tx, * which could deadlock the system if you were already holding one. + * If you must call VN_RELE() within a tx then use VN_RELE_ASYNC(). * * (3) All range locks must be grabbed before calling dmu_tx_assign(), * as they can span dmu_tx_assign() calls. @@ -928,7 +929,11 @@ zfs_get_done(dmu_buf_t *db, void *vzgd) vfslocked = VFS_LOCK_GIANT(vp->v_vfsp); dmu_buf_rele(db, vzgd); zfs_range_unlock(rl); - VN_RELE(vp); + /* + * Release the vnode asynchronously as we currently have the + * txg stopped from syncing. + */ + VN_RELE_ASYNC(vp, NULL); zil_add_block(zgd->zgd_zilog, zgd->zgd_bp); kmem_free(zgd, sizeof (zgd_t)); VFS_UNLOCK_GIANT(vfslocked); @@ -959,7 +964,12 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) if (zfs_zget(zfsvfs, lr->lr_foid, &zp) != 0) return (ENOENT); if (zp->z_unlinked) { - VN_RELE(ZTOV(zp)); + /* + * Release the vnode asynchronously as we currently have the + * txg stopped from syncing. + */ + VN_RELE_ASYNC(ZTOV(zp), NULL); + return (ENOENT); } @@ -1031,7 +1041,11 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, zio_t *zio) } out: zfs_range_unlock(rl); - VN_RELE(ZTOV(zp)); + /* + * Release the vnode asynchronously as we currently have the + * txg stopped from syncing. + */ + VN_RELE_ASYNC(ZTOV(zp), NULL); return (error); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c index 1f6fa0db9460..a7c2b377ebcc 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zil.c @@ -1041,7 +1041,7 @@ zil_clean(zilog_t *zilog) if ((itx != NULL) && (itx->itx_lr.lrc_txg <= spa_last_synced_txg(zilog->zl_spa))) { (void) taskq_dispatch(zilog->zl_clean_taskq, - (void (*)(void *))zil_itx_clean, zilog, TQ_NOSLEEP); + (task_func_t *)zil_itx_clean, zilog, TQ_SLEEP); } mutex_exit(&zilog->zl_lock); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h index c0e5b1bc4acf..dca37159b7da 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h @@ -377,6 +377,15 @@ typedef struct caller_context { void xva_init(xvattr_t *); xoptattr_t *xva_getxoptattr(xvattr_t *); /* Get ptr to xoptattr_t */ +struct taskq; +void vn_rele_async(struct vnode *vp, struct taskq *taskq); +void vn_rele_async_fini(void); + + +#define VN_RELE_ASYNC(vp, taskq) { \ + vn_rele_async(vp, taskq); \ +} + /* * Flags to VOP_SETATTR/VOP_GETATTR. */ From 77d0162c7002928e00e5695760b170f95254fb23 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 20:57:06 +0000 Subject: [PATCH 035/544] Allow the VM to provide backpressure on the ARC cache as it does on Solaris. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 7ca528033c4f..de9a97381744 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -131,6 +131,8 @@ #include #include +#include + static kmutex_t arc_reclaim_thr_lock; static kcondvar_t arc_reclaim_thr_cv; /* used to signal reclaim thr */ static uint8_t arc_thread_exit; @@ -1809,6 +1811,13 @@ arc_reclaim_needed(void) #ifdef _KERNEL + /* + * If pages are needed or we're within 2048 pages + * of needing to page need to reclaim + */ + if (vm_pages_needed || (vm_paging_target() > -2048)) + return (1); + if (needfree) return (1); From 6ef1a81d6e086ba8fc03080c34ca92c52c1b2a79 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 21:51:13 +0000 Subject: [PATCH 036/544] avoid LOR and gratuitous extra lock acquisitions by moving user_evict list buffers to a temporary list --- .../opensolaris/uts/common/fs/zfs/arc.c | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index de9a97381744..a3e25803933f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -1712,14 +1712,23 @@ arc_adjust(void) static void arc_do_user_evicts(void) { + static arc_buf_t *tmp_arc_eviction_list; + + /* + * Move list over to avoid LOR + */ +restart: mutex_enter(&arc_eviction_mtx); - while (arc_eviction_list != NULL) { - arc_buf_t *buf = arc_eviction_list; - arc_eviction_list = buf->b_next; + tmp_arc_eviction_list = arc_eviction_list; + arc_eviction_list = NULL; + mutex_exit(&arc_eviction_mtx); + + while (tmp_arc_eviction_list != NULL) { + arc_buf_t *buf = tmp_arc_eviction_list; + tmp_arc_eviction_list = buf->b_next; rw_enter(&buf->b_lock, RW_WRITER); buf->b_hdr = NULL; rw_exit(&buf->b_lock); - mutex_exit(&arc_eviction_mtx); if (buf->b_efunc != NULL) VERIFY(buf->b_efunc(buf) == 0); @@ -1727,9 +1736,10 @@ arc_do_user_evicts(void) buf->b_efunc = NULL; buf->b_private = NULL; kmem_cache_free(buf_cache, buf); - mutex_enter(&arc_eviction_mtx); } - mutex_exit(&arc_eviction_mtx); + + if (arc_eviction_list != NULL) + goto restart; } /* From fb1db28b6d98a0f41f59ca57fbbaab7a9e9a26fb Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Thu, 7 May 2009 23:01:03 +0000 Subject: [PATCH 037/544] Partially revert r191171, which went too far in trying to eliminate some duplicated code. In particular, archive_read_open_filename() has different close handling than archive_read_open_fd(), so delegating the former to the latter in the degenerate case (a NULL filename is treated as stdin) broke reading from pipelines. In particular, this fixes occasional port failures that were seen when using "gunzip | tar" pipelines under /bin/csh. Thanks to Alexey Shuvaev for reporting this failure and patiently helping me to track down the cause. --- lib/libarchive/archive_read_open_filename.c | 69 +++++++++++++++------ 1 file changed, 49 insertions(+), 20 deletions(-) diff --git a/lib/libarchive/archive_read_open_filename.c b/lib/libarchive/archive_read_open_filename.c index 356fae9d61fb..64a89b52b3c9 100644 --- a/lib/libarchive/archive_read_open_filename.c +++ b/lib/libarchive/archive_read_open_filename.c @@ -85,20 +85,32 @@ archive_read_open_filename(struct archive *a, const char *filename, int fd; archive_clear_error(a); - if (filename == NULL || filename[0] == '\0') - return (archive_read_open_fd(a, 0, block_size)); - - fd = open(filename, O_RDONLY | O_BINARY); - if (fd < 0) { - archive_set_error(a, errno, "Failed to open '%s'", filename); - return (ARCHIVE_FATAL); + if (filename == NULL || filename[0] == '\0') { + /* We used to invoke archive_read_open_fd(a,0,block_size) + * here, but that doesn't (and shouldn't) handle the + * end-of-file flush when reading stdout from a pipe. + * Basically, read_open_fd() is intended for folks who + * are willing to handle such details themselves. This + * API is intended to be a little smarter for folks who + * want easy handling of the common case. + */ + filename = ""; /* Normalize NULL to "" */ + fd = 0; + } else { + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) { + archive_set_error(a, errno, + "Failed to open '%s'", filename); + return (ARCHIVE_FATAL); + } } if (fstat(fd, &st) != 0) { archive_set_error(a, errno, "Can't stat '%s'", filename); return (ARCHIVE_FATAL); } - mine = (struct read_file_data *)malloc(sizeof(*mine) + strlen(filename)); + mine = (struct read_file_data *)calloc(1, + sizeof(*mine) + strlen(filename)); b = malloc(block_size); if (mine == NULL || b == NULL) { archive_set_error(a, ENOMEM, "No memory"); @@ -117,15 +129,20 @@ archive_read_open_filename(struct archive *a, const char *filename, if (S_ISREG(st.st_mode)) { archive_read_extract_set_skip_file(a, st.st_dev, st.st_ino); /* - * Skip is a performance optimization for anything - * that supports lseek(). Generally, that only - * includes regular files and possibly raw disk - * devices, but there's no good portable way to detect - * raw disks. + * Enabling skip here is a performance optimization + * for anything that supports lseek(). On FreeBSD + * (and probably many other systems), only regular + * files and raw disk devices support lseek() (on + * other input types, lseek() returns success but + * doesn't actually change the file pointer, which + * just completely screws up the position-tracking + * logic). In addition, I've yet to find a portable + * way to determine if a device is a raw disk device. + * So I don't see a way to do much better than to only + * enable this optimization for regular files. */ mine->can_skip = 1; - } else - mine->can_skip = 0; + } return (archive_read_open2(a, mine, NULL, file_read, file_skip, file_close)); } @@ -139,8 +156,11 @@ file_read(struct archive *a, void *client_data, const void **buff) *buff = mine->buffer; bytes_read = read(mine->fd, mine->buffer, mine->block_size); if (bytes_read < 0) { - archive_set_error(a, errno, "Error reading '%s'", - mine->filename); + if (mine->filename[0] == '\0') + archive_set_error(a, errno, "Error reading stdin"); + else + archive_set_error(a, errno, "Error reading '%s'", + mine->filename); } return (bytes_read); } @@ -190,8 +210,15 @@ file_skip(struct archive *a, void *client_data, off_t request) * likely caused by a programmer error (too large request) * or a corrupted archive file. */ - archive_set_error(a, errno, "Error seeking in '%s'", - mine->filename); + if (mine->filename[0] == '\0') + /* + * Should never get here, since lseek() on stdin ought + * to return an ESPIPE error. + */ + archive_set_error(a, errno, "Error seeking in stdin"); + else + archive_set_error(a, errno, "Error seeking in '%s'", + mine->filename); return (-1); } return (new_offset - old_offset); @@ -225,7 +252,9 @@ file_close(struct archive *a, void *client_data) mine->block_size); } while (bytesRead > 0); } - close(mine->fd); + /* If a named file was opened, then it needs to be closed. */ + if (mine->filename[0] != '\0') + close(mine->fd); } free(mine->buffer); free(mine); From c20fd07777190ab838185f04e8b5e6c1364a13c4 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 23:02:15 +0000 Subject: [PATCH 038/544] move VN_RELE_ASYNC to the compatibility layer with the rest of the VN_* defines --- sys/cddl/compat/opensolaris/sys/vnode.h | 1 + sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h | 5 ----- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/sys/cddl/compat/opensolaris/sys/vnode.h b/sys/cddl/compat/opensolaris/sys/vnode.h index 68288a76fa21..44741d2250bb 100644 --- a/sys/cddl/compat/opensolaris/sys/vnode.h +++ b/sys/cddl/compat/opensolaris/sys/vnode.h @@ -75,6 +75,7 @@ vn_is_readonly(vnode_t *vp) #define VN_HOLD(v) vref(v) #define VN_RELE(v) vrele(v) #define VN_URELE(v) vput(v) +#define VN_RELE_ASYNC(v, tq) vn_rele_async(v, tq); #define VOP_REALVP(vp, vpp, ct) (*(vpp) = (vp), 0) diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h index dca37159b7da..a166315160ab 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/vnode.h @@ -381,11 +381,6 @@ struct taskq; void vn_rele_async(struct vnode *vp, struct taskq *taskq); void vn_rele_async_fini(void); - -#define VN_RELE_ASYNC(vp, taskq) { \ - vn_rele_async(vp, taskq); \ -} - /* * Flags to VOP_SETATTR/VOP_GETATTR. */ From 74fecee286949427b8e31303bab947cbc2ef2def Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 23:02:51 +0000 Subject: [PATCH 039/544] define VN_RELE_ASYNC for use by libzpool --- cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h | 1 + 1 file changed, 1 insertion(+) diff --git a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h index 971584dfa156..7ae7f9d1b484 100644 --- a/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h +++ b/cddl/contrib/opensolaris/lib/libzpool/common/sys/zfs_context.h @@ -418,6 +418,7 @@ typedef struct vsecattr { #define VOP_FSYNC(vp, f, cr, ct) fsync((vp)->v_fd) #define VN_RELE(vp) vn_close(vp, 0, NULL, NULL) +#define VN_RELE_ASYNC(vp, taskq) vn_close(vp, 0, NULL, NULL) #define vn_lock(vp, type) #define VOP_UNLOCK(vp, type) From a6827463ad4efb525135bf0ce5e594580afc819f Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 7 May 2009 23:34:41 +0000 Subject: [PATCH 040/544] don't call vn_rele_async_fini in the !_KERNEL case --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c index 1fb1c6fc5600..842677bc4e5e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/dmu.c @@ -1199,7 +1199,9 @@ dmu_init(void) void dmu_fini(void) { +#ifdef _KERNEL vn_rele_async_fini(); +#endif arc_fini(); dnode_fini(); dbuf_fini(); From 8ab663f3054e66b4eb6bacaabb9b41493eeb8ae0 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Fri, 8 May 2009 00:15:27 +0000 Subject: [PATCH 041/544] kill unused OS_GETUPTIME --- sys/dev/ath/ah_osdep.c | 9 --------- sys/dev/ath/ah_osdep.h | 2 -- 2 files changed, 11 deletions(-) diff --git a/sys/dev/ath/ah_osdep.c b/sys/dev/ath/ah_osdep.c index b5880eedc368..ee9cd347484b 100644 --- a/sys/dev/ath/ah_osdep.c +++ b/sys/dev/ath/ah_osdep.c @@ -363,15 +363,6 @@ ath_hal_delay(int n) DELAY(n); } -u_int32_t -ath_hal_getuptime(struct ath_hal *ah) -{ - struct bintime bt; - getbinuptime(&bt); - return (bt.sec * 1000) + - (((uint64_t)1000 * (uint32_t)(bt.frac >> 32)) >> 32); -} - void ath_hal_memzero(void *dst, size_t n) { diff --git a/sys/dev/ath/ah_osdep.h b/sys/dev/ath/ah_osdep.h index 32f2796289c2..05cccff96c11 100644 --- a/sys/dev/ath/ah_osdep.h +++ b/sys/dev/ath/ah_osdep.h @@ -70,8 +70,6 @@ extern void *ath_hal_memcpy(void *, const void *, size_t); #define abs(_a) __builtin_abs(_a) struct ath_hal; -extern u_int32_t ath_hal_getuptime(struct ath_hal *); -#define OS_GETUPTIME(_ah) ath_hal_getuptime(_ah) /* * Register read/write operations are either handled through From b4307a77d2662b3a213b6a2af27c5e10e2cde2b8 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Fri, 8 May 2009 00:23:00 +0000 Subject: [PATCH 042/544] kill more portability functions that are no longer useful --- sys/dev/ath/ah_osdep.c | 21 --------------------- sys/dev/ath/ah_osdep.h | 9 +++------ sys/dev/ath/ath_hal/ar5416/ar5416_reset.c | 4 ++-- 3 files changed, 5 insertions(+), 29 deletions(-) diff --git a/sys/dev/ath/ah_osdep.c b/sys/dev/ath/ah_osdep.c index ee9cd347484b..7d4239b6396c 100644 --- a/sys/dev/ath/ah_osdep.c +++ b/sys/dev/ath/ah_osdep.c @@ -353,24 +353,3 @@ ath_hal_assert_failed(const char* filename, int lineno, const char *msg) panic("ath_hal_assert"); } #endif /* AH_ASSERT */ - -/* - * Delay n microseconds. - */ -void -ath_hal_delay(int n) -{ - DELAY(n); -} - -void -ath_hal_memzero(void *dst, size_t n) -{ - bzero(dst, n); -} - -void * -ath_hal_memcpy(void *dst, const void *src, size_t n) -{ - return memcpy(dst, src, n); -} diff --git a/sys/dev/ath/ah_osdep.h b/sys/dev/ath/ah_osdep.h index 05cccff96c11..69d13e0419ed 100644 --- a/sys/dev/ath/ah_osdep.h +++ b/sys/dev/ath/ah_osdep.h @@ -58,14 +58,11 @@ typedef bus_space_handle_t HAL_BUS_HANDLE; /* * Delay n microseconds. */ -extern void ath_hal_delay(int); -#define OS_DELAY(_n) ath_hal_delay(_n) +#define OS_DELAY(_n) DELAY(_n) #define OS_INLINE __inline -#define OS_MEMZERO(_a, _n) ath_hal_memzero((_a), (_n)) -extern void ath_hal_memzero(void *, size_t); -#define OS_MEMCPY(_d, _s, _n) ath_hal_memcpy(_d,_s,_n) -extern void *ath_hal_memcpy(void *, const void *, size_t); +#define OS_MEMZERO(_a, _n) bzero((_a), (_n)) +#define OS_MEMCPY(_d, _s, _n) memcpy(_d,_s,_n) #define abs(_a) __builtin_abs(_a) diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c index ac3d84ae473c..459358869687 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_reset.c @@ -818,7 +818,7 @@ ar5416SetTransmitPower(struct ath_hal *ah, HALASSERT(AH_PRIVATE(ah)->ah_eeversion >= AR_EEPROM_VER14_1); /* Setup info for the actual eeprom */ - ath_hal_memzero(ratesArray, sizeof(ratesArray)); + OS_MEMZERO(ratesArray, sizeof(ratesArray)); cfgCtl = ath_hal_getctl(ah, chan); powerLimit = chan->ic_maxregpower * 2; twiceAntennaReduction = chan->ic_maxantgain; @@ -1759,7 +1759,7 @@ ar5416SetPowerCalTable(struct ath_hal *ah, struct ar5416eeprom *pEepData, uint16_t xpdGainValues[AR5416_NUM_PD_GAINS]; uint32_t reg32, regOffset, regChainOffset; - ath_hal_memzero(xpdGainValues, sizeof(xpdGainValues)); + OS_MEMZERO(xpdGainValues, sizeof(xpdGainValues)); xpdMask = pEepData->modalHeader[IEEE80211_IS_CHAN_2GHZ(chan)].xpdGain; From 9ab20e104c725eb316253051ac826d1b5a8d8423 Mon Sep 17 00:00:00 2001 From: "Stephane E. Potvin" Date: Fri, 8 May 2009 02:18:46 +0000 Subject: [PATCH 043/544] Change the internal buffer used to store input lines from a static buffer to a dynamically allocated one in order to support input lines of arbitrary length. Approved by: kan (mentor) MFC after: 1 month --- gnu/usr.bin/patch/common.h | 5 +- gnu/usr.bin/patch/inp.c | 4 +- gnu/usr.bin/patch/patch.c | 5 ++ gnu/usr.bin/patch/pch.c | 97 ++++++++++++++++++++++---------------- gnu/usr.bin/patch/pch.h | 2 +- gnu/usr.bin/patch/util.c | 14 +++--- sys/sys/param.h | 2 +- 7 files changed, 75 insertions(+), 54 deletions(-) diff --git a/gnu/usr.bin/patch/common.h b/gnu/usr.bin/patch/common.h index ed97132183f6..7063be682429 100644 --- a/gnu/usr.bin/patch/common.h +++ b/gnu/usr.bin/patch/common.h @@ -63,7 +63,7 @@ #define MAXHUNKSIZE 200000 /* is this enough lines? */ #define INITHUNKMAX 125 /* initial dynamic allocation size */ -#define MAXLINELEN 4096 +#define INITLINELEN 4096 #define BUFFERSIZE 4096 #define SCCSPREFIX "s." @@ -105,7 +105,8 @@ EXT int optind_last; /* for restarting plan_b */ EXT struct stat filestat; /* file statistics area */ EXT int filemode INIT(0644); -EXT char buf[MAXLINELEN]; /* general purpose buffer */ +EXT char *buf; /* general purpose buffer */ +EXT size_t buf_size; /* size of the general purpose buffer */ EXT FILE *ofp INIT(Nullfp); /* output file pointer */ EXT FILE *rejfp INIT(Nullfp); /* reject file pointer */ diff --git a/gnu/usr.bin/patch/inp.c b/gnu/usr.bin/patch/inp.c index d77ef65ff841..17f8adb6a9e0 100644 --- a/gnu/usr.bin/patch/inp.c +++ b/gnu/usr.bin/patch/inp.c @@ -79,7 +79,7 @@ plan_a(char *filename) int ifd, statfailed; Reg1 char *s; Reg2 LINENUM iline; - char lbuf[MAXLINELEN]; + char lbuf[INITLINELEN]; int output_elsewhere = strcmp(filename, outname); extern int check_patch; @@ -284,7 +284,7 @@ plan_b(char *filename) pfatal2("can't open file %s", filename); if ((tifd = creat(TMPINNAME, 0666)) < 0) pfatal2("can't open file %s", TMPINNAME); - while (fgets(buf, sizeof buf, ifp) != Nullch) { + while (fgets(buf, buf_size, ifp) != Nullch) { if (revision != Nullch && !found_revision && rev_in_string(buf)) found_revision = TRUE; if ((i = strlen(buf)) > maxlen) diff --git a/gnu/usr.bin/patch/patch.c b/gnu/usr.bin/patch/patch.c index 8e06c33beaf5..fbf7e709f266 100644 --- a/gnu/usr.bin/patch/patch.c +++ b/gnu/usr.bin/patch/patch.c @@ -155,6 +155,11 @@ char **argv; for (i = 0; i= 0L) { /* nothing but deletes!? */ p_start = first_command_line; @@ -427,15 +427,15 @@ next_intuit_at(long file_pos, long file_line) void skip_to(long file_pos, long file_line) { - char *ret; + size_t len; assert(p_base <= file_pos); if (verbose && p_base < file_pos) { Fseek(pfp, p_base, 0); say1("The text leading up to this was:\n--------------------------\n"); while (ftell(pfp) < file_pos) { - ret = fgets(buf, sizeof buf, pfp); - assert(ret != Nullch); + len = pgets(FALSE); + assert(len != 0); say2("|%s", buf); } say1("--------------------------\n"); @@ -486,7 +486,7 @@ bool another_hunk(void) { Reg1 char *s; - Reg8 char *ret; + size_t len; Reg2 int context = 0; while (p_end >= 0) { @@ -517,9 +517,9 @@ another_hunk(void) Reg7 LINENUM ptrn_copiable = 0; /* # of copiable lines in ptrn */ - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || strnNE(buf, "********", 8)) { + if (len == 0 || strnNE(buf, "********", 8)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -527,9 +527,9 @@ another_hunk(void) p_hunk_beg = p_input_line + 1; while (p_end < p_max) { line_beginning = ftell(pfp); - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) { + if (len == 0) { if (p_max - p_end < 4) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { @@ -839,9 +839,9 @@ another_hunk(void) Reg5 LINENUM filldst; /* index of new lines */ char ch; - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || strnNE(buf, "@@ -", 4)) { + if (len == 0 || strnNE(buf, "@@ -", 4)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -895,9 +895,9 @@ another_hunk(void) p_hunk_beg = p_input_line + 1; while (fillsrc <= p_ptrn_lines || filldst <= p_end) { line_beginning = ftell(pfp); - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) { + if (len == 0) { if (p_max - filldst < 3) Strcpy(buf, " \n"); /* assume blank lines got chopped */ else { @@ -994,9 +994,9 @@ another_hunk(void) long line_beginning = ftell(pfp); p_context = 0; - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch || !isdigit((unsigned char)*buf)) { + if (len == 0 || !isdigit((unsigned char)*buf)) { next_intuit_at(line_beginning,p_input_line); return FALSE; } @@ -1035,9 +1035,9 @@ another_hunk(void) } p_Char[0] = '*'; for (i=1; i<=p_ptrn_lines; i++) { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '<') @@ -1057,9 +1057,9 @@ another_hunk(void) } if (hunk_type == 'c') { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '-') @@ -1073,9 +1073,9 @@ another_hunk(void) } p_Char[i] = '='; for (i++; i<=p_end; i++) { - ret = pgets(buf, sizeof buf, pfp); + len = pgets(TRUE); p_input_line++; - if (ret == Nullch) + if (len == 0) fatal2("unexpected end of file in patch at line %ld\n", p_input_line); if (*buf != '>') @@ -1118,28 +1118,43 @@ another_hunk(void) } /* - * Input a line from the patch file, worrying about indentation. + * Input a line from the patch file. + * Worry about indentation if do_indent is true. + * The line is read directly into the buf global variable which + * is resized if necessary in order to hold the complete line. + * Returns the number of characters read including the terminating + * '\n', if any. */ -char * -pgets(char *bf, int sz, FILE *fp) +size_t +pgets(bool do_indent) { - char *ret = fgets(bf, sz, fp); - Reg1 char *s; - Reg2 int indent = 0; + char *line; + size_t len; + int indent = 0, skipped = 0; - if (p_indent && ret != Nullch) { - for (s=buf; - indent < p_indent && (*s == ' ' || *s == '\t' || *s == 'X'); - s++) { - if (*s == '\t') - indent += 8 - (indent % 7); - else - indent++; + line = fgetln(pfp, &len); + if (line != Nullch) { + if (len + 1 > buf_size) { + while (len + 1 > buf_size) + buf_size *= 2; + free(buf); + buf = malloc(buf_size); + if (buf == Nullch) + fatal1("out of memory\n"); } - if (buf != s) - Strcpy(buf, s); + if (do_indent == TRUE && p_indent) { + for (; + indent < p_indent && (*line == ' ' || *line == '\t' || *line == 'X'); + line++, skipped++) { + if (*line == '\t') + indent += 8 - (indent %7); + else + indent++; + } + } + Strlcpy(buf, line, len + 1 - skipped); } - return ret; + return len; } /* @@ -1360,7 +1375,7 @@ do_ed_script(void) } for (;;) { beginning_of_this_line = ftell(pfp); - if (pgets(buf, sizeof buf, pfp) == Nullch) { + if (pgets(TRUE) == 0) { next_intuit_at(beginning_of_this_line, p_input_line); break; } @@ -1373,7 +1388,7 @@ do_ed_script(void) if (!skip_rest_of_patch) fputs(buf, pipefp); if (*t != 'd') { - while (pgets(buf, sizeof buf, pfp) != Nullch) { + while (pgets(TRUE) != 0) { p_input_line++; if (!skip_rest_of_patch) fputs(buf, pipefp); diff --git a/gnu/usr.bin/patch/pch.h b/gnu/usr.bin/patch/pch.h index d815fe8d14e8..0393dea1494a 100644 --- a/gnu/usr.bin/patch/pch.h +++ b/gnu/usr.bin/patch/pch.h @@ -32,5 +32,5 @@ LINENUM pch_context(void); LINENUM pch_hunk_beg(void); char pch_char(LINENUM _line); char *pfetch(LINENUM _line); -char *pgets(char *_bf, int _sz, FILE *_fp); +size_t pgets(bool _do_indent); void do_ed_script(void); diff --git a/gnu/usr.bin/patch/util.c b/gnu/usr.bin/patch/util.c index b6e6652646b4..5a76a0359f55 100644 --- a/gnu/usr.bin/patch/util.c +++ b/gnu/usr.bin/patch/util.c @@ -46,7 +46,7 @@ move_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(1, buf, i) != 1) pfatal1("write failed"); Close(fromfd); @@ -126,7 +126,7 @@ move_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(tofd, buf, i) != i) pfatal1("write failed"); Close(fromfd); @@ -152,7 +152,7 @@ copy_file(char *from, char *to) fromfd = open(from, 0); if (fromfd < 0) pfatal2("internal error, can't reopen %s", from); - while ((i = read(fromfd, buf, sizeof buf)) > 0) + while ((i = read(fromfd, buf, buf_size)) > 0) if (write(tofd, buf, i) != i) pfatal2("write to %s failed", to); Close(fromfd); @@ -256,20 +256,20 @@ long arg1,arg2,arg3; Fflush(stderr); write(2, buf, strlen(buf)); if (tty2) { /* might be redirected to a file */ - r = read(2, buf, sizeof buf); + r = read(2, buf, buf_size); } else if (isatty(1)) { /* this may be new file output */ Fflush(stdout); write(1, buf, strlen(buf)); - r = read(1, buf, sizeof buf); + r = read(1, buf, buf_size); } else if ((ttyfd = open(_PATH_TTY, 2)) >= 0 && isatty(ttyfd)) { /* might be deleted or unwriteable */ write(ttyfd, buf, strlen(buf)); - r = read(ttyfd, buf, sizeof buf); + r = read(ttyfd, buf, buf_size); Close(ttyfd); } else if (isatty(0)) { /* this is probably patch input */ Fflush(stdin); write(0, buf, strlen(buf)); - r = read(0, buf, sizeof buf); + r = read(0, buf, buf_size); } else { /* no terminal at all--default it */ buf[0] = '\n'; buf[1] = 0; diff --git a/sys/sys/param.h b/sys/sys/param.h index fcf1a53cad67..7c77b9370ae4 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800085 /* Master, propagated to newvers */ +#define __FreeBSD_version 800086 /* Master, propagated to newvers */ #ifndef LOCORE #include From 6e8e2779b31d3473a2737f69ffe8192576e7eb21 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Fri, 8 May 2009 03:19:57 +0000 Subject: [PATCH 044/544] Add one more board ID with inverted external amplifier control. PR: kern/121156 --- sys/dev/sound/pci/ich.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/sound/pci/ich.c b/sys/dev/sound/pci/ich.c index 7351355ea963..dc234a76b9a1 100644 --- a/sys/dev/sound/pci/ich.c +++ b/sys/dev/sound/pci/ich.c @@ -1009,6 +1009,7 @@ ich_pci_attach(device_t dev) switch (subdev) { case 0x202f161f: /* Gateway 7326GZ */ case 0x203a161f: /* Gateway 4028GZ */ + case 0x203e161f: /* Gateway 3520GZ/M210 */ case 0x204c161f: /* Kvazar-Micro Senator 3592XT */ case 0x8144104d: /* Sony VAIO PCG-TR* */ case 0x8197104d: /* Sony S1XP */ From b569d2132edd3ddc62bbb4f16debb64c87965179 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Fri, 8 May 2009 13:44:33 +0000 Subject: [PATCH 045/544] Drain the tasks before the interface stop call in case a restart was queued. --- sys/dev/ipw/if_ipw.c | 2 +- sys/dev/iwi/if_iwi.c | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 9d67724f2c61..eac9091a748e 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -404,13 +404,13 @@ ipw_detach(device_t dev) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + ieee80211_draintask(ic, &sc->sc_init_task); ipw_stop(sc); bpfdetach(ifp); ieee80211_ifdetach(ic); callout_drain(&sc->sc_wdtimer); - ieee80211_draintask(ic, &sc->sc_init_task); ipw_release(sc); diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 6957f9b9a87d..b04403b0a645 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -459,17 +459,17 @@ iwi_detach(device_t dev) struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; - iwi_stop(sc); - - bpfdetach(ifp); - ieee80211_ifdetach(ic); - /* NB: do early to drain any pending tasks */ ieee80211_draintask(ic, &sc->sc_radiontask); ieee80211_draintask(ic, &sc->sc_radiofftask); ieee80211_draintask(ic, &sc->sc_restarttask); ieee80211_draintask(ic, &sc->sc_disassoctask); + iwi_stop(sc); + + bpfdetach(ifp); + ieee80211_ifdetach(ic); + iwi_put_firmware(sc); iwi_release_fw_dma(sc); From fcec7b25b83cce28458a932d1302235b13cf459e Mon Sep 17 00:00:00 2001 From: Philip Paeps Date: Fri, 8 May 2009 14:09:31 +0000 Subject: [PATCH 046/544] Sync ubsec(4) with reality, note BCM5825 support. Pointed out by: brueffer MFC after: 1 minute --- share/man/man4/ubsec.4 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/share/man/man4/ubsec.4 b/share/man/man4/ubsec.4 index 11bc362cf080..fdd02c0ee61a 100644 --- a/share/man/man4/ubsec.4 +++ b/share/man/man4/ubsec.4 @@ -102,6 +102,8 @@ Faster version of the BCM5820. Faster version of the BCM5820. .It Broadcom BCM5823 A BCM5822 with AES capability. +.It Broadcom BCM5825 +Faster version of the BCM5823. .El .Sh SEE ALSO .Xr crypt 3 , From 29b02909eb4d38a8803d0e125285c19c92e34da5 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 8 May 2009 14:11:06 +0000 Subject: [PATCH 047/544] Introduce a new virtualization container, provisionally named vprocg, to hold virtualized instances of hostname and domainname, as well as a new top-level virtualization struct vimage, which holds pointers to struct vnet and struct vprocg. Struct vprocg is likely to become replaced in the near future with a new jail management API import. As a consequence of this change, change struct ucred to point to a struct vimage, instead of directly pointing to a vnet. Merge vnet / vimage / ucred refcounting infrastructure from p4 / vimage branch. Permit kldload / kldunload operations to be executed only from the default vimage context. This change should have no functional impact on nooptions VIMAGE kernel builds. Reviewed by: bz Approved by: julian (mentor) --- .../compat/opensolaris/kern/opensolaris.c | 3 + .../opensolaris/kern/opensolaris_misc.c | 2 +- sys/compat/svr4/svr4_stat.c | 1 + sys/i386/ibcs2/ibcs2_socksys.c | 1 + sys/kern/init_main.c | 5 +- sys/kern/kern_exit.c | 5 + sys/kern/kern_fork.c | 3 + sys/kern/kern_jail.c | 4 + sys/kern/kern_linker.c | 12 ++ sys/kern/kern_mib.c | 7 +- sys/kern/kern_prot.c | 10 ++ sys/kern/kern_vimage.c | 23 ++++ sys/nlm/nlm_advlock.c | 5 +- sys/sys/kernel.h | 2 + sys/sys/sysctl.h | 4 + sys/sys/ucred.h | 2 +- sys/sys/vimage.h | 110 +++++++++++++----- 17 files changed, 166 insertions(+), 33 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris.c b/sys/cddl/compat/opensolaris/kern/opensolaris.c index f1f84fb570a4..003120fe8ad6 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris.c @@ -32,8 +32,10 @@ #include #include #include +#include #include #include +#include cpu_core_t cpu_core[MAXCPU]; kmutex_t cpu_lock; @@ -81,6 +83,7 @@ opensolaris_modevent(module_t mod __unused, int type, void *data __unused) switch (type) { case MOD_LOAD: + utsname.nodename = G_hostname; break; case MOD_UNLOAD: diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c index 279ae4c042bb..af98827f0f1e 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_misc.c @@ -37,7 +37,7 @@ __FBSDID("$FreeBSD$"); char hw_serial[11] = "0"; struct opensolaris_utsname utsname = { - .nodename = hostname + .nodename = "unset" }; int diff --git a/sys/compat/svr4/svr4_stat.c b/sys/compat/svr4/svr4_stat.c index 3492aa8ebb40..6ddac4452396 100644 --- a/sys/compat/svr4/svr4_stat.c +++ b/sys/compat/svr4/svr4_stat.c @@ -412,6 +412,7 @@ svr4_sys_systeminfo(td, uap) struct thread *td; struct svr4_sys_systeminfo_args *uap; { + INIT_VPROCG(TD_TO_VPROCG(td)); char *str = NULL; int error = 0; register_t *retval = td->td_retval; diff --git a/sys/i386/ibcs2/ibcs2_socksys.c b/sys/i386/ibcs2/ibcs2_socksys.c index f4eb97cee94e..2dba77d17c51 100644 --- a/sys/i386/ibcs2/ibcs2_socksys.c +++ b/sys/i386/ibcs2/ibcs2_socksys.c @@ -174,6 +174,7 @@ ibcs2_setipdomainname(td, uap) struct thread *td; struct setipdomainname_args *uap; { + INIT_VPROCG(TD_TO_VPROCG(td)); char hname[MAXHOSTNAMELEN], *ptr; int error, sctl[2], hlen; diff --git a/sys/kern/init_main.c b/sys/kern/init_main.c index 96ebf36cc0d7..97b7f0fcf578 100644 --- a/sys/kern/init_main.c +++ b/sys/kern/init_main.c @@ -454,7 +454,10 @@ proc0_init(void *dummy __unused) p->p_ucred->cr_ruidinfo = uifind(0); p->p_ucred->cr_prison = NULL; /* Don't jail it. */ #ifdef VIMAGE - p->p_ucred->cr_vnet = LIST_FIRST(&vnet_head); + KASSERT(LIST_FIRST(&vimage_head) != NULL, ("vimage_head empty")); + P_TO_VIMAGE(p) = LIST_FIRST(&vimage_head); /* set ucred->cr_vimage */ + refcount_acquire(&P_TO_VIMAGE(p)->vi_ucredrefc); + LIST_FIRST(&vprocg_head)->nprocs++; #endif #ifdef AUDIT audit_cred_kproc0(p->p_ucred); diff --git a/sys/kern/kern_exit.c b/sys/kern/kern_exit.c index a10e915e0a11..89b92c61a1a1 100644 --- a/sys/kern/kern_exit.c +++ b/sys/kern/kern_exit.c @@ -70,6 +70,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #ifdef KTRACE #include #endif @@ -737,6 +738,7 @@ kern_wait(struct thread *td, pid_t pid, int *status, int options, nfound++; PROC_SLOCK(p); if (p->p_state == PRS_ZOMBIE) { + INIT_VPROCG(P_TO_VPROCG(p)); if (rusage) { *rusage = p->p_ru; calcru(p, &rusage->ru_utime, &rusage->ru_stime); @@ -837,6 +839,9 @@ kern_wait(struct thread *td, pid_t pid, int *status, int options, uma_zfree(proc_zone, p); sx_xlock(&allproc_lock); nprocs--; +#ifdef VIMAGE + vprocg->nprocs--; +#endif sx_xunlock(&allproc_lock); return (0); } diff --git a/sys/kern/kern_fork.c b/sys/kern/kern_fork.c index 76695e711713..4e8dbb19ee2f 100644 --- a/sys/kern/kern_fork.c +++ b/sys/kern/kern_fork.c @@ -350,6 +350,9 @@ fork1(td, flags, pages, procp) * are hard-limits as to the number of processes that can run. */ nprocs++; +#ifdef VIMAGE + P_TO_VPROCG(p1)->nprocs++; +#endif /* * Find an unused process ID. We remember a range of unused IDs diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 069f1f0f1b9c..3bc5c10c6765 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -2218,6 +2218,10 @@ prison_check(struct ucred *cred1, struct ucred *cred2) if (cred2->cr_prison != cred1->cr_prison) return (ESRCH); } +#ifdef VIMAGE + if (cred2->cr_vimage->v_procg != cred1->cr_vimage->v_procg) + return (ESRCH); +#endif return (0); } diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 2237107e3704..4e0c5a30d3bc 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -992,6 +992,12 @@ kern_kldload(struct thread *td, const char *file, int *fileid) if ((error = priv_check(td, PRIV_KLD_LOAD)) != 0) return (error); +#ifdef VIMAGE + /* Only the default vimage is permitted to kldload modules. */ + if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) + return (EPERM); +#endif + /* * It's possible that kldloaded module will attach a new ifnet, * so vnet context must be set when this ocurs. @@ -1063,6 +1069,12 @@ kern_kldunload(struct thread *td, int fileid, int flags) if ((error = priv_check(td, PRIV_KLD_UNLOAD)) != 0) return (error); +#ifdef VIMAGE + /* Only the default vimage is permitted to kldunload modules. */ + if (!IS_DEFAULT_VIMAGE(TD_TO_VIMAGE(td))) + return (EPERM); +#endif + CURVNET_SET(TD_TO_VNET(td)); KLD_LOCK(); lf = linker_find_file_by_id(fileid); diff --git a/sys/kern/kern_mib.c b/sys/kern/kern_mib.c index 05f90310ea09..43fcfa4ae0e3 100644 --- a/sys/kern/kern_mib.c +++ b/sys/kern/kern_mib.c @@ -208,8 +208,9 @@ static char machine_arch[] = MACHINE_ARCH; SYSCTL_STRING(_hw, HW_MACHINE_ARCH, machine_arch, CTLFLAG_RD, machine_arch, 0, "System architecture"); -/* should become #ifndef VIMAGE */ +#ifdef VIMAGE_GLOBALS char hostname[MAXHOSTNAMELEN]; +#endif /* * This mutex is used to protect the hostname and domainname variables, and @@ -348,12 +349,14 @@ SYSCTL_PROC(_kern, OID_AUTO, conftxt, CTLTYPE_STRING|CTLFLAG_RW, 0, 0, sysctl_kern_config, "", "Kernel configuration file"); #endif -/* should become #ifndef VIMAGE */ +#ifdef VIMAGE_GLOBALS char domainname[MAXHOSTNAMELEN]; /* Protected by hostname_mtx. */ +#endif static int sysctl_domainname(SYSCTL_HANDLER_ARGS) { + INIT_VPROCG(TD_TO_VPROCG(req->td)); char tmpdomainname[MAXHOSTNAMELEN]; int error; diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c index 9f13644f1528..b35f81f5316e 100644 --- a/sys/kern/kern_prot.c +++ b/sys/kern/kern_prot.c @@ -69,6 +69,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #if defined(INET) || defined(INET6) #include @@ -1824,6 +1825,11 @@ crfree(struct ucred *cr) */ if (jailed(cr)) prison_free(cr->cr_prison); +#ifdef VIMAGE + /* XXX TODO: find out why and when cr_vimage can be NULL here! */ + if (cr->cr_vimage != NULL) + refcount_release(&cr->cr_vimage->vi_ucredrefc); +#endif #ifdef AUDIT audit_cred_destroy(cr); #endif @@ -1859,6 +1865,10 @@ crcopy(struct ucred *dest, struct ucred *src) uihold(dest->cr_ruidinfo); if (jailed(dest)) prison_hold(dest->cr_prison); +#ifdef VIMAGE + KASSERT(src->cr_vimage != NULL, ("cr_vimage == NULL")); + refcount_acquire(&dest->cr_vimage->vi_ucredrefc); +#endif #ifdef AUDIT audit_cred_copy(src, dest); #endif diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index 21d502e4c3fe..e20b382029f5 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); MALLOC_DEFINE(M_VIMAGE, "vimage", "vimage resource container"); MALLOC_DEFINE(M_VNET, "vnet", "network stack control block"); +MALLOC_DEFINE(M_VPROCG, "vprocg", "process group control block"); static TAILQ_HEAD(vnet_modlink_head, vnet_modlink) vnet_modlink_head; static TAILQ_HEAD(vnet_modpending_head, vnet_modlink) vnet_modpending_head; @@ -56,7 +57,13 @@ static int vnet_mod_constructor(struct vnet_modlink *); static int vnet_mod_destructor(struct vnet_modlink *); #ifdef VIMAGE +struct vimage_list_head vimage_head; struct vnet_list_head vnet_head; +struct vprocg_list_head vprocg_head; +#else +#ifndef VIMAGE_GLOBALS +struct vprocg vprocg_0; +#endif #endif void @@ -294,6 +301,8 @@ static void vi_init(void *unused) { #ifdef VIMAGE + struct vimage *vip; + struct vprocg *vprocg; struct vnet *vnet; #endif @@ -301,13 +310,27 @@ vi_init(void *unused) TAILQ_INIT(&vnet_modpending_head); #ifdef VIMAGE + LIST_INIT(&vimage_head); + LIST_INIT(&vprocg_head); LIST_INIT(&vnet_head); + vip = malloc(sizeof(struct vimage), M_VIMAGE, M_NOWAIT | M_ZERO); + if (vip == NULL) + panic("malloc failed for struct vimage"); + LIST_INSERT_HEAD(&vimage_head, vip, vi_le); + + vprocg = malloc(sizeof(struct vprocg), M_VPROCG, M_NOWAIT | M_ZERO); + if (vprocg == NULL) + panic("malloc failed for struct vprocg"); + vip->v_procg = vprocg; + LIST_INSERT_HEAD(&vprocg_head, vprocg, vprocg_le); + vnet = malloc(sizeof(struct vnet), M_VNET, M_NOWAIT | M_ZERO); if (vnet == NULL) panic("vi_alloc: malloc failed"); LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); vnet->vnet_magic_n = VNET_MAGIC_N; + vip->v_net = vnet; /* We MUST clear curvnet in vi_init_done before going SMP. */ curvnet = LIST_FIRST(&vnet_head); diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c index 2c1f1a6f385b..a2c62f04c113 100644 --- a/sys/nlm/nlm_advlock.c +++ b/sys/nlm/nlm_advlock.c @@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -1222,12 +1223,12 @@ nlm_init_lock(struct flock *fl, int flags, int svid, } mtx_lock(&hostname_mtx); - snprintf(oh_space, 32, "%d@%s", svid, hostname); + snprintf(oh_space, 32, "%d@%s", svid, G_hostname); mtx_unlock(&hostname_mtx); oh_len = strlen(oh_space); memset(lock, 0, sizeof(*lock)); - lock->caller_name = hostname; + lock->caller_name = G_hostname; lock->fh.n_len = fhlen; lock->fh.n_bytes = fh; lock->oh.n_len = oh_len; diff --git a/sys/sys/kernel.h b/sys/sys/kernel.h index fa397c4ffcbd..997e20d70092 100644 --- a/sys/sys/kernel.h +++ b/sys/sys/kernel.h @@ -58,8 +58,10 @@ extern struct mtx hostname_mtx; extern unsigned long hostid; extern char hostuuid[64]; +#ifdef VIMAGE_GLOBALS extern char hostname[MAXHOSTNAMELEN]; extern char domainname[MAXHOSTNAMELEN]; +#endif extern char kernelname[MAXPATHLEN]; extern int tick; /* usec per tick (1000000 / hz) */ diff --git a/sys/sys/sysctl.h b/sys/sys/sysctl.h index c6da7b9f06a3..10fc0f0f8bc4 100644 --- a/sys/sys/sysctl.h +++ b/sys/sys/sysctl.h @@ -459,6 +459,10 @@ TAILQ_HEAD(sysctl_ctx_list, sysctl_ctx_entry); TD_TO_VNET(curthread)->mod_data[oidp->oid_v_mod]; \ arg1 = cp + (size_t) arg1; \ break; \ + case V_PROCG: \ + cp = (char *) TD_TO_VPROCG(curthread); \ + arg1 = cp + (size_t) arg1; \ + break; \ default: \ panic("unsupported module id %d", oidp->oid_v_subs); \ } \ diff --git a/sys/sys/ucred.h b/sys/sys/ucred.h index 338b0567437f..bac48996cc2a 100644 --- a/sys/sys/ucred.h +++ b/sys/sys/ucred.h @@ -55,7 +55,7 @@ struct ucred { struct uidinfo *cr_uidinfo; /* per euid resource consumption */ struct uidinfo *cr_ruidinfo; /* per ruid resource consumption */ struct prison *cr_prison; /* jail(2) */ - struct vnet *cr_vnet; /* vimage / vnet */ + struct vimage *cr_vimage; /* vimage */ void *cr_pspare[2]; /* general use 2 */ #define cr_endcopy cr_label struct label *cr_label; /* MAC label */ diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index ccd0c7384457..8c107ea0d507 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -44,13 +44,15 @@ #define VNET_DEBUG #endif +struct vprocg; +struct vnet; +struct kld_sym_lookup; + typedef int vnet_attach_fn(const void *); typedef int vnet_detach_fn(const void *); #ifndef VIMAGE_GLOBALS -struct kld_sym_lookup; - struct vnet_symmap { char *name; size_t offset; @@ -111,6 +113,7 @@ struct vnet_modlink { /* Major module IDs for vimage sysctl virtualization. */ #define V_GLOBAL 0 /* global variable - no indirection */ #define V_NET 1 +#define V_PROCG 2 /* Name mappings for minor module IDs in vimage sysctl virtualization. */ #define V_MOD_vnet_net VNET_MOD_NET @@ -121,6 +124,8 @@ struct vnet_modlink { #define V_MOD_vnet_pf VNET_MOD_PF #define V_MOD_vnet_gif VNET_MOD_GIF #define V_MOD_vnet_ipsec VNET_MOD_IPSEC + +#define V_MOD_vprocg 0 /* no minor module ids like in vnet */ int vi_symlookup(struct kld_sym_lookup *, char *); void vnet_mod_register(const struct vnet_modinfo *); @@ -157,21 +162,45 @@ void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); #define VNET_SYMMAP_END { NULL, 0 } #endif /* !VIMAGE_GLOBALS */ -#ifdef VIMAGE -struct vnet { - void *mod_data[VNET_MOD_MAX]; - LIST_ENTRY(vnet) vnet_le; /* all vnets list */ - u_int vnet_magic_n; - u_int ifccnt; - u_int sockcnt; +struct vimage { + LIST_ENTRY(vimage) vi_le; /* all vimage list */ + LIST_ENTRY(vimage) vi_sibling; /* vimages with same parent */ + LIST_HEAD(, vimage) vi_child_head; /* direct offspring list */ + struct vimage *vi_parent; /* ptr to parent vimage */ + u_int vi_id; /* ID num */ + u_int vi_ucredrefc; /* # of ucreds pointing to us */ + char vi_name[MAXHOSTNAMELEN]; + struct vnet *v_net; + struct vprocg *v_procg; }; -#endif +struct vnet { + void *mod_data[VNET_MOD_MAX]; + LIST_ENTRY(vnet) vnet_le; /* all vnets list */ + u_int vnet_magic_n; + u_int vnet_id; /* ID num */ + u_int ifccnt; + u_int sockcnt; +}; + +struct vprocg { + LIST_ENTRY(vprocg) vprocg_le; + u_int vprocg_id; /* ID num */ + u_int nprocs; + char _hostname[MAXHOSTNAMELEN]; + char _domainname[MAXHOSTNAMELEN]; +}; + +#ifndef VIMAGE_GLOBALS #ifdef VIMAGE -#define curvnet curthread->td_vnet +LIST_HEAD(vimage_list_head, vimage); +extern struct vimage_list_head vimage_head; #else -#define curvnet NULL +extern struct vprocg vprocg_0; #endif +#endif + +#define curvnet curthread->td_vnet #define VNET_MAGIC_N 0x3e0d8f29 @@ -251,28 +280,57 @@ extern struct vnet_list_head vnet_head; #define VNET_FOREACH(arg) #endif -#define TD_TO_VNET(td) (td)->td_ucred->cr_vnet +#ifdef VIMAGE +LIST_HEAD(vprocg_list_head, vprocg); +extern struct vprocg_list_head vprocg_head; +#define INIT_VPROCG(arg) struct vprocg *vprocg = (arg); +#else +#define INIT_VPROCG(arg) +#endif + +#ifdef VIMAGE +#define IS_DEFAULT_VIMAGE(arg) ((arg)->vi_id == 0) +#define IS_DEFAULT_VNET(arg) ((arg)->vnet_id == 0) +#else +#define IS_DEFAULT_VIMAGE(arg) 1 +#define IS_DEFAULT_VNET(arg) 1 +#endif + +#ifdef VIMAGE +#define TD_TO_VIMAGE(td) (td)->td_ucred->cr_vimage +#define TD_TO_VNET(td) (td)->td_ucred->cr_vimage->v_net +#define TD_TO_VPROCG(td) (td)->td_ucred->cr_vimage->v_procg +#define P_TO_VIMAGE(p) (p)->p_ucred->cr_vimage +#define P_TO_VNET(p) (p)->p_ucred->cr_vimage->v_net +#define P_TO_VPROCG(p) (p)->p_ucred->cr_vimage->v_procg +#else +#define TD_TO_VIMAGE(td) NULL +#define TD_TO_VNET(td) NULL +#define P_TO_VIMAGE(p) NULL +#define P_TO_VNET(p) NULL +#ifdef VIMAGE_GLOBALS +#define TD_TO_VPROCG(td) NULL +#define P_TO_VPROCG(p) NULL +#else +#define TD_TO_VPROCG(td) &vprocg_0 +#define P_TO_VPROCG(p) &vprocg_0 +#endif +#endif /* Non-VIMAGE null-macros */ -#define IS_DEFAULT_VNET(arg) 1 #define VNET_LIST_RLOCK() #define VNET_LIST_RUNLOCK() -#define INIT_VPROCG(arg) -#define INIT_VCPU(arg) -#define TD_TO_VIMAGE(td) -#define TD_TO_VPROCG(td) -#define TD_TO_VCPU(td) -#define P_TO_VIMAGE(p) -#define P_TO_VNET(p) -#define P_TO_VPROCG(p) -#define P_TO_VCPU(p) /* XXX those defines bellow should probably go into vprocg.h and vcpu.h */ -#define VPROCG(sym) (sym) -#define VCPU(sym) (sym) +#define VPROCG(sym) VSYM(vprocg, sym) + +#ifdef VIMAGE +#define G_hostname TD_TO_VPROCG(&thread0)->_hostname +#else +#define G_hostname VPROCG(hostname) +#endif #define V_hostname VPROCG(hostname) -#define G_hostname VPROCG(hostname) /* global hostname */ #define V_domainname VPROCG(domainname) /* From ddd50c3439ea6489c38da18f4f87baf9b70025e0 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 8 May 2009 14:28:06 +0000 Subject: [PATCH 048/544] Remove a bogus check that unintentionally slipped in r191816. This change has no functional impact on nooptions VIMAGE builds. Submitted by: bz --- sys/netinet/igmp.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/netinet/igmp.c b/sys/netinet/igmp.c index 34390a0532d4..1a311f2ee408 100644 --- a/sys/netinet/igmp.c +++ b/sys/netinet/igmp.c @@ -1100,9 +1100,6 @@ igmp_input_v3_group_query(struct in_multi *inm, struct igmp_ifinfo *igi, nsrc = ntohs(igmpv3->igmp_numsrc); - if (!IS_DEFAULT_VNET(curvnet)) - return (retval); - /* * Deal with group-specific queries upfront. * If any group query is already pending, purge any recorded From 2114e063f053c354cf803871a3fd782c9afeccf8 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 8 May 2009 14:34:25 +0000 Subject: [PATCH 049/544] A NOP change: style / whitespace cleanup of the noise that slipped into r191816. Spotted by: bz Approved by: julian (mentor) (an earlier version of the diff) --- sys/kern/kern_linker.c | 2 +- sys/kern/uipc_socket.c | 4 ++-- sys/kern/uipc_syscalls.c | 2 +- sys/netinet/tcp_hostcache.c | 2 +- sys/sys/proc.h | 4 ++-- sys/sys/vimage.h | 28 ++++++++++++++-------------- 6 files changed, 21 insertions(+), 21 deletions(-) diff --git a/sys/kern/kern_linker.c b/sys/kern/kern_linker.c index 4e0c5a30d3bc..9f2a17ce4e26 100644 --- a/sys/kern/kern_linker.c +++ b/sys/kern/kern_linker.c @@ -999,7 +999,7 @@ kern_kldload(struct thread *td, const char *file, int *fileid) #endif /* - * It's possible that kldloaded module will attach a new ifnet, + * It is possible that kldloaded module will attach a new ifnet, * so vnet context must be set when this ocurs. */ CURVNET_SET(TD_TO_VNET(td)); diff --git a/sys/kern/uipc_socket.c b/sys/kern/uipc_socket.c index 0fd3beedfdc4..0992b3f411e2 100644 --- a/sys/kern/uipc_socket.c +++ b/sys/kern/uipc_socket.c @@ -286,7 +286,7 @@ soalloc(struct vnet *vnet) so->so_gencnt = ++so_gencnt; ++numopensockets; #ifdef VIMAGE - ++vnet->sockcnt; /* locked with so_global_mtx */ + ++vnet->sockcnt; /* Locked with so_global_mtx. */ so->so_vnet = vnet; #endif mtx_unlock(&so_global_mtx); @@ -1306,7 +1306,7 @@ sosend(struct socket *so, struct sockaddr *addr, struct uio *uio, CURVNET_SET(so->so_vnet); error = so->so_proto->pr_usrreqs->pru_sosend(so, addr, uio, top, - control, flags, td); + control, flags, td); CURVNET_RESTORE(); return (error); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index 5689aebbbfab..f86e65747a9f 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -63,8 +63,8 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include +#include #ifdef KTRACE #include #endif diff --git a/sys/netinet/tcp_hostcache.c b/sys/netinet/tcp_hostcache.c index 84586dbf6ea8..93367c5e16a1 100644 --- a/sys/netinet/tcp_hostcache.c +++ b/sys/netinet/tcp_hostcache.c @@ -637,7 +637,7 @@ tcp_hc_purge(void *arg) CURVNET_SET((struct vnet *) arg); INIT_VNET_INET(curvnet); struct hc_metrics *hc_entry, *hc_next; - int all = 0; /* XXX was: (intptr_t)arg - makes no sense? */ + int all = 0; int i; if (V_tcp_hostcache.purgeall) { diff --git a/sys/sys/proc.h b/sys/sys/proc.h index 955072b0c596..dd3e0b2e8257 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -275,8 +275,8 @@ struct thread { struct lpohead td_lprof[2]; /* (a) lock profiling objects. */ struct kdtrace_thread *td_dtrace; /* (*) DTrace-specific data. */ int td_errno; /* Error returned by last syscall. */ - struct vnet *td_vnet; /* (*) Effective vnet */ - const char *td_vnet_lpush; /* (*) Debugging vnet push / pop */ + struct vnet *td_vnet; /* (*) Effective vnet. */ + const char *td_vnet_lpush; /* (*) Debugging vnet push / pop. */ }; struct mtx *thread_lock_block(struct thread *); diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index 8c107ea0d507..ca7209415e5f 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -200,51 +200,51 @@ extern struct vprocg vprocg_0; #endif #endif -#define curvnet curthread->td_vnet +#define curvnet curthread->td_vnet -#define VNET_MAGIC_N 0x3e0d8f29 +#define VNET_MAGIC_N 0x3e0d8f29 #ifdef VIMAGE #ifdef VNET_DEBUG -#define VNET_ASSERT(condition) \ +#define VNET_ASSERT(condition) \ if (!(condition)) { \ printf("VNET_ASSERT @ %s:%d %s():\n", \ __FILE__, __LINE__, __FUNCTION__); \ panic(#condition); \ } -#define CURVNET_SET_QUIET(arg) \ +#define CURVNET_SET_QUIET(arg) \ VNET_ASSERT((arg)->vnet_magic_n == VNET_MAGIC_N); \ struct vnet *saved_vnet = curvnet; \ const char *saved_vnet_lpush = curthread->td_vnet_lpush; \ curvnet = arg; \ curthread->td_vnet_lpush = __FUNCTION__; -#define CURVNET_SET_VERBOSE(arg) \ +#define CURVNET_SET_VERBOSE(arg) \ CURVNET_SET_QUIET(arg) \ if (saved_vnet) \ - printf("curvnet_set(%p) in %s() on cpu %d, prev %p in %s()\n", curvnet, \ - curthread->td_vnet_lpush, curcpu, \ + printf("CURVNET_SET(%p) in %s() on cpu %d, prev %p in %s()\n", \ + curvnet, curthread->td_vnet_lpush, curcpu, \ saved_vnet, saved_vnet_lpush); -#define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) +#define CURVNET_SET(arg) CURVNET_SET_VERBOSE(arg) -#define CURVNET_RESTORE() \ +#define CURVNET_RESTORE() \ VNET_ASSERT(saved_vnet == NULL || \ saved_vnet->vnet_magic_n == VNET_MAGIC_N); \ curvnet = saved_vnet; \ curthread->td_vnet_lpush = saved_vnet_lpush; #else /* !VNET_DEBUG */ -#define VNET_ASSERT(condition) +#define VNET_ASSERT(condition) -#define CURVNET_SET(arg) \ +#define CURVNET_SET(arg) \ struct vnet *saved_vnet = curvnet; \ curvnet = arg; -#define CURVNET_SET_VERBOSE(arg) CURVNET_SET(arg) -#define CURVNET_SET_QUIET(arg) CURVNET_SET(arg) +#define CURVNET_SET_VERBOSE(arg) CURVNET_SET(arg) +#define CURVNET_SET_QUIET(arg) CURVNET_SET(arg) -#define CURVNET_RESTORE() \ +#define CURVNET_RESTORE() \ curvnet = saved_vnet; #endif /* !VNET_DEBUG */ #else /* !VIMAGE */ From 1780110b7e118739ea982acc877afea68d37fce8 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Fri, 8 May 2009 15:14:52 +0000 Subject: [PATCH 050/544] Use log(9) for debug and status messages and hide some of the details with macros to allow for future flexibility in logging. Submitted by: zachary dot loafman at isilon dot com --- sys/nlm/nlm_prot_impl.c | 128 +++++++++++++++++++--------------------- 1 file changed, 60 insertions(+), 68 deletions(-) diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 1add718a2c34..d9472a4fe7b7 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -104,6 +105,16 @@ static bool_t nlm_syscall_registered = FALSE; static int nlm_debug_level; SYSCTL_INT(_debug, OID_AUTO, nlm_debug, CTLFLAG_RW, &nlm_debug_level, 0, ""); +#define NLM_DEBUG(_level, args...) \ + do { \ + if (nlm_debug_level >= (_level)) \ + log(LOG_DEBUG, args); \ + } while(0) +#define NLM_ERR(args...) \ + do { \ + log(LOG_ERR, args); \ + } while(0) + /* * Grace period handling. The value of nlm_grace_threshold is the * value of time_uptime after which we are serving requests normally. @@ -254,7 +265,7 @@ nlm_init(void *dummy) error = syscall_register(&nlm_syscall_offset, &nlm_syscall_sysent, &nlm_syscall_prev_sysent); if (error) - printf("Can't register NLM syscall\n"); + NLM_ERR("Can't register NLM syscall\n"); else nlm_syscall_registered = TRUE; } @@ -450,9 +461,8 @@ nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) } /* Otherwise, bad news. */ - printf("NLM: failed to contact remote rpcbind, " - "stat = %d, port = %d\n", - (int) stat, port); + NLM_ERR("NLM: failed to contact remote rpcbind, " + "stat = %d, port = %d\n", (int) stat, port); CLNT_DESTROY(rpcb); return (NULL); } @@ -506,10 +516,8 @@ nlm_lock_callback(void *arg, int pending) struct nlm_async_lock *af = (struct nlm_async_lock *) arg; struct rpc_callextra ext; - if (nlm_debug_level >= 2) - printf("NLM: async lock %p for %s (sysid %d) granted\n", - af, af->af_host->nh_caller_name, - af->af_host->nh_sysid); + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) granted\n", + af, af->af_host->nh_caller_name, af->af_host->nh_sysid); /* * Send the results back to the host. @@ -608,10 +616,8 @@ nlm_cancel_async_lock(struct nlm_async_lock *af) mtx_lock(&host->nh_lock); if (!error) { - if (nlm_debug_level >= 2) - printf("NLM: async lock %p for %s (sysid %d) " - "cancelled\n", - af, host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(2, "NLM: async lock %p for %s (sysid %d) " + "cancelled\n", af, host->nh_caller_name, host->nh_sysid); /* * Remove from the nh_pending list and free now that @@ -672,15 +678,13 @@ nlm_client_recovery_start(void *arg) { struct nlm_host *host = (struct nlm_host *) arg; - if (nlm_debug_level >= 1) - printf("NLM: client lock recovery for %s started\n", - host->nh_caller_name); + NLM_DEBUG(1, "NLM: client lock recovery for %s started\n", + host->nh_caller_name); nlm_client_recovery(host); - if (nlm_debug_level >= 1) - printf("NLM: client lock recovery for %s completed\n", - host->nh_caller_name); + NLM_DEBUG(1, "NLM: client lock recovery for %s completed\n", + host->nh_caller_name); host->nh_monstate = NLM_MONITORED; nlm_host_release(host); @@ -703,10 +707,9 @@ nlm_host_notify(struct nlm_host *host, int newstate) struct nlm_async_lock *af; if (newstate) { - if (nlm_debug_level >= 1) - printf("NLM: host %s (sysid %d) rebooted, new " - "state is %d\n", - host->nh_caller_name, host->nh_sysid, newstate); + NLM_DEBUG(1, "NLM: host %s (sysid %d) rebooted, new " + "state is %d\n", host->nh_caller_name, + host->nh_sysid, newstate); } /* @@ -786,9 +789,8 @@ nlm_create_host(const char* caller_name) mtx_assert(&nlm_global_lock, MA_OWNED); - if (nlm_debug_level >= 1) - printf("NLM: new host %s (sysid %d)\n", - caller_name, nlm_next_sysid); + NLM_DEBUG(1, "NLM: new host %s (sysid %d)\n", + caller_name, nlm_next_sysid); host = malloc(sizeof(struct nlm_host), M_NLM, M_NOWAIT|M_ZERO); if (!host) return (NULL); @@ -1078,9 +1080,8 @@ nlm_host_unmonitor(struct nlm_host *host) struct timeval timo; enum clnt_stat stat; - if (nlm_debug_level >= 1) - printf("NLM: unmonitoring %s (sysid %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(1, "NLM: unmonitoring %s (sysid %d)\n", + host->nh_caller_name, host->nh_sysid); /* * We put our assigned system ID value in the priv field to @@ -1100,11 +1101,11 @@ nlm_host_unmonitor(struct nlm_host *host) (xdrproc_t) xdr_sm_stat, &smstat, timo); if (stat != RPC_SUCCESS) { - printf("Failed to contact local NSM - rpc error %d\n", stat); + NLM_ERR("Failed to contact local NSM - rpc error %d\n", stat); return; } if (smstat.res_stat == stat_fail) { - printf("Local NSM refuses to unmonitor %s\n", + NLM_ERR("Local NSM refuses to unmonitor %s\n", host->nh_caller_name); return; } @@ -1131,9 +1132,8 @@ nlm_host_monitor(struct nlm_host *host, int state) * detect host reboots. */ host->nh_state = state; - if (nlm_debug_level >= 1) - printf("NLM: host %s (sysid %d) has NSM state %d\n", - host->nh_caller_name, host->nh_sysid, state); + NLM_DEBUG(1, "NLM: host %s (sysid %d) has NSM state %d\n", + host->nh_caller_name, host->nh_sysid, state); } mtx_lock(&host->nh_lock); @@ -1144,9 +1144,8 @@ nlm_host_monitor(struct nlm_host *host, int state) host->nh_monstate = NLM_MONITORED; mtx_unlock(&host->nh_lock); - if (nlm_debug_level >= 1) - printf("NLM: monitoring %s (sysid %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(1, "NLM: monitoring %s (sysid %d)\n", + host->nh_caller_name, host->nh_sysid); /* * We put our assigned system ID value in the priv field to @@ -1167,11 +1166,11 @@ nlm_host_monitor(struct nlm_host *host, int state) (xdrproc_t) xdr_sm_stat, &smstat, timo); if (stat != RPC_SUCCESS) { - printf("Failed to contact local NSM - rpc error %d\n", stat); + NLM_ERR("Failed to contact local NSM - rpc error %d\n", stat); return; } if (smstat.res_stat == stat_fail) { - printf("Local NSM refuses to monitor %s\n", + NLM_ERR("Local NSM refuses to monitor %s\n", host->nh_caller_name); mtx_lock(&host->nh_lock); host->nh_monstate = NLM_MONITOR_FAILED; @@ -1369,7 +1368,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) int i, j, error; if (!addr_count) { - printf("NLM: no service addresses given - can't start server"); + NLM_ERR("NLM: no service addresses given - can't start server"); return (EINVAL); } @@ -1402,7 +1401,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) goto out; nconf = getnetconfigent(netid); if (!nconf) { - printf("Can't lookup netid %s\n", + NLM_ERR("Can't lookup netid %s\n", netid); error = EINVAL; goto out; @@ -1410,7 +1409,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) xprts[j] = svc_tp_create(pool, dispatchers[i], NLM_PROG, versions[i], uaddr, nconf); if (!xprts[j]) { - printf("NLM: unable to create " + NLM_ERR("NLM: unable to create " "(NLM_PROG, %d).\n", versions[i]); error = EINVAL; goto out; @@ -1421,7 +1420,7 @@ nlm_register_services(SVCPOOL *pool, int addr_count, char **addrs) rpcb_unset(NLM_PROG, versions[i], nconf); if (!svc_reg(xprts[j], NLM_PROG, versions[i], dispatchers[i], nconf)) { - printf("NLM: can't register " + NLM_ERR("NLM: can't register " "(NLM_PROG, %d)\n", versions[i]); error = EINVAL; goto out; @@ -1469,7 +1468,8 @@ nlm_server_main(int addr_count, char **addrs) #endif if (nlm_socket) { - printf("NLM: can't start server - it appears to be running already\n"); + NLM_ERR("NLM: can't start server - " + "it appears to be running already\n"); return (EPERM); } @@ -1479,7 +1479,7 @@ nlm_server_main(int addr_count, char **addrs) error = socreate(AF_INET, &nlm_socket, SOCK_DGRAM, 0, td->td_ucred, td); if (error) { - printf("NLM: can't create IPv4 socket - error %d\n", error); + NLM_ERR("NLM: can't create IPv4 socket - error %d\n", error); return (error); } opt.sopt_dir = SOPT_SET; @@ -1495,7 +1495,7 @@ nlm_server_main(int addr_count, char **addrs) error = socreate(AF_INET6, &nlm_socket6, SOCK_DGRAM, 0, td->td_ucred, td); if (error) { - printf("NLM: can't create IPv6 socket - error %d\n", error); + NLM_ERR("NLM: can't create IPv6 socket - error %d\n", error); goto out; return (error); } @@ -1529,7 +1529,7 @@ nlm_server_main(int addr_count, char **addrs) #endif if (!nlm_nsm) { - printf("Can't start NLM - unable to contact NSM\n"); + NLM_ERR("Can't start NLM - unable to contact NSM\n"); error = EINVAL; goto out; } @@ -1553,14 +1553,13 @@ nlm_server_main(int addr_count, char **addrs) struct rpc_err err; CLNT_GETERR(nlm_nsm, &err); - printf("NLM: unexpected error contacting NSM, stat=%d, errno=%d\n", - stat, err.re_errno); + NLM_ERR("NLM: unexpected error contacting NSM, " + "stat=%d, errno=%d\n", stat, err.re_errno); error = EINVAL; goto out; } - if (nlm_debug_level >= 1) - printf("NLM: local NSM state is %d\n", smstat.state); + NLM_DEBUG(1, "NLM: local NSM state is %d\n", smstat.state); nlm_nsm_state = smstat.state; #ifdef NFSCLIENT @@ -1692,8 +1691,7 @@ nlm_sm_notify(struct nlm_sm_status *argp) uint32_t sysid; struct nlm_host *host; - if (nlm_debug_level >= 3) - printf("nlm_sm_notify(): mon_name = %s\n", argp->mon_name); + NLM_DEBUG(3, "nlm_sm_notify(): mon_name = %s\n", argp->mon_name); memcpy(&sysid, &argp->priv, sizeof(sysid)); host = nlm_find_host_by_sysid(sysid); if (host) { @@ -1822,9 +1820,8 @@ nlm_do_test(nlm4_testargs *argp, nlm4_testres *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_test(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_test(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; @@ -1919,9 +1916,8 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_lock(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_lock(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); if (monitor && host->nh_state && argp->state && host->nh_state != argp->state) { @@ -2043,10 +2039,8 @@ nlm_do_lock(nlm4_lockargs *argp, nlm4_res *result, struct svc_req *rqstp, &af->af_granted); free(af, M_NLM); } else { - if (nlm_debug_level >= 2) - printf("NLM: pending async lock %p for %s " - "(sysid %d)\n", - af, host->nh_caller_name, sysid); + NLM_DEBUG(2, "NLM: pending async lock %p for %s " + "(sysid %d)\n", af, host->nh_caller_name, sysid); /* * Don't vrele the vnode just yet - this must * wait until either the async callback @@ -2103,9 +2097,8 @@ nlm_do_cancel(nlm4_cancargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_cancel(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_cancel(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; @@ -2193,9 +2186,8 @@ nlm_do_unlock(nlm4_unlockargs *argp, nlm4_res *result, struct svc_req *rqstp, return (ENOMEM); } - if (nlm_debug_level >= 3) - printf("nlm_do_unlock(): caller_name = %s (sysid = %d)\n", - host->nh_caller_name, host->nh_sysid); + NLM_DEBUG(3, "nlm_do_unlock(): caller_name = %s (sysid = %d)\n", + host->nh_caller_name, host->nh_sysid); nlm_free_finished_locks(host); sysid = host->nh_sysid; From 51e6ba0f00d8544dc694571f07bde46d5a6d2a99 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 8 May 2009 20:06:37 +0000 Subject: [PATCH 051/544] Burn TTY ioctl bridges in compat layers. I really don't want any pieces of code to include ioctl_compat.h, so let the ibcs2 and svr4 compat leave sgtty alone. If they want to support sgtty, they should emulate it on top of termios, not sgtty. The code has been marked with BURN_BRIDGES for a long time. ibcs2 and svr4 are not really popular pieces of code anyway. --- sys/compat/svr4/svr4_ioctl.c | 8 - sys/compat/svr4/svr4_ioctl.h | 2 - sys/compat/svr4/svr4_ttold.c | 382 --------------------------------- sys/compat/svr4/svr4_ttold.h | 122 ----------- sys/conf/files.i386 | 1 - sys/conf/files.pc98 | 1 - sys/i386/ibcs2/ibcs2_ioctl.c | 29 --- sys/i386/ibcs2/syscalls.master | 6 +- sys/modules/svr4/Makefile | 2 +- sys/sys/ioctl_compat.h | 4 + 10 files changed, 7 insertions(+), 550 deletions(-) delete mode 100644 sys/compat/svr4/svr4_ttold.c delete mode 100644 sys/compat/svr4/svr4_ttold.h diff --git a/sys/compat/svr4/svr4_ioctl.c b/sys/compat/svr4/svr4_ioctl.c index b192a2c77ec8..4e91c4bfb23f 100644 --- a/sys/compat/svr4/svr4_ioctl.c +++ b/sys/compat/svr4/svr4_ioctl.c @@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -119,13 +118,6 @@ svr4_sys_ioctl(td, uap) #endif switch (cmd & 0xff00) { -#ifndef BURN_BRIDGES - case SVR4_tIOC: - DPRINTF(("ttold\n")); - fun = svr4_ttold_ioctl; - break; -#endif - case SVR4_TIOC: DPRINTF(("term\n")); fun = svr4_term_ioctl; diff --git a/sys/compat/svr4/svr4_ioctl.h b/sys/compat/svr4/svr4_ioctl.h index e0633a7e4e1f..98b67a1be0e2 100644 --- a/sys/compat/svr4/svr4_ioctl.h +++ b/sys/compat/svr4/svr4_ioctl.h @@ -52,8 +52,6 @@ int svr4_stream_ioctl(struct file *, struct thread *, register_t *, int, u_long, caddr_t); int svr4_term_ioctl(struct file *, struct thread *, register_t *, int, u_long, caddr_t); -int svr4_ttold_ioctl(struct file *, struct thread *, register_t *, - int, u_long, caddr_t); int svr4_fil_ioctl (struct file *, struct thread *, register_t *, int, u_long, caddr_t); int svr4_sock_ioctl (struct file *, struct thread *, register_t *, diff --git a/sys/compat/svr4/svr4_ttold.c b/sys/compat/svr4/svr4_ttold.c deleted file mode 100644 index 3575607faa95..000000000000 --- a/sys/compat/svr4/svr4_ttold.c +++ /dev/null @@ -1,382 +0,0 @@ -/*- - * Copyright (c) 1998 Mark Newton - * Copyright (c) 1994 Christos Zoulas - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -#ifndef BURN_BRIDGES - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -static void svr4_tchars_to_bsd_tchars(const struct svr4_tchars *st, - struct tchars *bt); -static void bsd_tchars_to_svr4_tchars(const struct tchars *bt, - struct svr4_tchars *st); -static void svr4_sgttyb_to_bsd_sgttyb(const struct svr4_sgttyb *ss, - struct sgttyb *bs); -static void bsd_sgttyb_to_svr4_sgttyb(const struct sgttyb *bs, - struct svr4_sgttyb *ss); -static void svr4_ltchars_to_bsd_ltchars(const struct svr4_ltchars *sl, - struct ltchars *bl); -static void bsd_ltchars_to_svr4_ltchars(const struct ltchars *bl, - struct svr4_ltchars *sl); - -#ifdef DEBUG_SVR4 -static void print_svr4_sgttyb(const char *, struct svr4_sgttyb *); -static void print_svr4_tchars(const char *, struct svr4_tchars *); -static void print_svr4_ltchars(const char *, struct svr4_ltchars *); - -static void -print_svr4_sgttyb(str, ss) - const char *str; - struct svr4_sgttyb *ss; -{ - - uprintf("%s\nispeed=%o ospeed=%o ", str, ss->sg_ispeed, ss->sg_ospeed); - uprintf("erase=%o kill=%o flags=%o\n", ss->sg_erase, ss->sg_kill, - ss->sg_flags); -} - -static void -print_svr4_tchars(str, st) - const char *str; - struct svr4_tchars *st; -{ - uprintf("%s\nintrc=%o quitc=%o ", str, st->t_intrc, st->t_quitc); - uprintf("startc=%o stopc=%o eofc=%o brkc=%o\n", st->t_startc, - st->t_stopc, st->t_eofc, st->t_brkc); -} - -static void -print_svr4_ltchars(str, sl) - const char *str; - struct svr4_ltchars *sl; -{ - uprintf("%s\nsuspc=%o dsuspc=%o ", str, sl->t_suspc, sl->t_dsuspc); - uprintf("rprntc=%o flushc=%o werasc=%o lnextc=%o\n", sl->t_rprntc, - sl->t_flushc, sl->t_werasc, sl->t_lnextc); -} -#endif /* DEBUG_SVR4 */ - -static void -svr4_tchars_to_bsd_tchars(st, bt) - const struct svr4_tchars *st; - struct tchars *bt; -{ - bt->t_intrc = st->t_intrc; - bt->t_quitc = st->t_quitc; - bt->t_startc = st->t_startc; - bt->t_stopc = st->t_stopc; - bt->t_eofc = st->t_eofc; - bt->t_brkc = st->t_brkc; -} - - -static void -bsd_tchars_to_svr4_tchars(bt, st) - const struct tchars *bt; - struct svr4_tchars *st; -{ - st->t_intrc = bt->t_intrc; - st->t_quitc = bt->t_quitc; - st->t_startc = bt->t_startc; - st->t_stopc = bt->t_stopc; - st->t_eofc = bt->t_eofc; - st->t_brkc = bt->t_brkc; -} - - -static void -svr4_sgttyb_to_bsd_sgttyb(ss, bs) - const struct svr4_sgttyb *ss; - struct sgttyb *bs; -{ - bs->sg_ispeed = ss->sg_ispeed; - bs->sg_ospeed = ss->sg_ospeed; - bs->sg_erase = ss->sg_erase; - bs->sg_kill = ss->sg_kill; - bs->sg_flags = ss->sg_flags; -}; - - -static void -bsd_sgttyb_to_svr4_sgttyb(bs, ss) - const struct sgttyb *bs; - struct svr4_sgttyb *ss; -{ - ss->sg_ispeed = bs->sg_ispeed; - ss->sg_ospeed = bs->sg_ospeed; - ss->sg_erase = bs->sg_erase; - ss->sg_kill = bs->sg_kill; - ss->sg_flags = bs->sg_flags; -} - - -static void -svr4_ltchars_to_bsd_ltchars(sl, bl) - const struct svr4_ltchars *sl; - struct ltchars *bl; -{ - bl->t_suspc = sl->t_suspc; - bl->t_dsuspc = sl->t_dsuspc; - bl->t_rprntc = sl->t_rprntc; - bl->t_flushc = sl->t_flushc; - bl->t_werasc = sl->t_werasc; - bl->t_lnextc = sl->t_lnextc; -} - - -static void -bsd_ltchars_to_svr4_ltchars(bl, sl) - const struct ltchars *bl; - struct svr4_ltchars *sl; -{ - sl->t_suspc = bl->t_suspc; - sl->t_dsuspc = bl->t_dsuspc; - sl->t_rprntc = bl->t_rprntc; - sl->t_flushc = bl->t_flushc; - sl->t_werasc = bl->t_werasc; - sl->t_lnextc = bl->t_lnextc; -} - - -int -svr4_ttold_ioctl(fp, td, retval, fd, cmd, data) - struct file *fp; - struct thread *td; - register_t *retval; - int fd; - u_long cmd; - caddr_t data; -{ - int error; - - *retval = 0; - - switch (cmd) { - case SVR4_TIOCGPGRP: - { - pid_t pid; - - if ((error = fo_ioctl(fp, TIOCGPGRP, (caddr_t) &pid, - td->td_ucred, td)) != 0) - return error; - - DPRINTF(("TIOCGPGRP %d\n", pid)); - - if ((error = copyout(&pid, data, sizeof(pid))) != 0) - return error; - - } - - case SVR4_TIOCSPGRP: - { - pid_t pid; - - if ((error = copyin(data, &pid, sizeof(pid))) != 0) - return error; - - DPRINTF(("TIOCSPGRP %d\n", pid)); - - return fo_ioctl(fp, TIOCSPGRP, (caddr_t) &pid, - td->td_ucred, td); - } - - case SVR4_TIOCGSID: - { -#if defined(TIOCGSID) - pid_t pid; - if ((error = fo_ioctl(fp, TIOCGSID, (caddr_t) &pid, - td->td_ucred, td)) != 0) - return error; - - DPRINTF(("TIOCGSID %d\n", pid)); - - return copyout(&pid, data, sizeof(pid)); -#else - uprintf("ioctl(TIOCGSID) for pid %d unsupported\n", td->td_proc->p_pid); - return EINVAL; -#endif - } - - case SVR4_TIOCGETP: - { - struct sgttyb bs; - struct svr4_sgttyb ss; - - error = fo_ioctl(fp, TIOCGETP, (caddr_t) &bs, - td->td_ucred, td); - if (error) - return error; - - bsd_sgttyb_to_svr4_sgttyb(&bs, &ss); -#ifdef DEBUG_SVR4 - print_svr4_sgttyb("SVR4_TIOCGETP", &ss); -#endif /* DEBUG_SVR4 */ - return copyout(&ss, data, sizeof(ss)); - } - - case SVR4_TIOCSETP: - case SVR4_TIOCSETN: - { - struct sgttyb bs; - struct svr4_sgttyb ss; - - if ((error = copyin(data, &ss, sizeof(ss))) != 0) - return error; - - svr4_sgttyb_to_bsd_sgttyb(&ss, &bs); -#ifdef DEBUG_SVR4 - print_svr4_sgttyb("SVR4_TIOCSET{P,N}", &ss); -#endif /* DEBUG_SVR4 */ - cmd = (cmd == SVR4_TIOCSETP) ? TIOCSETP : TIOCSETN; - return fo_ioctl(fp, cmd, (caddr_t) &bs, - td->td_ucred, td); - } - - case SVR4_TIOCGETC: - { - struct tchars bt; - struct svr4_tchars st; - - error = fo_ioctl(fp, TIOCGETC, (caddr_t) &bt, - td->td_ucred, td); - if (error) - return error; - - bsd_tchars_to_svr4_tchars(&bt, &st); -#ifdef DEBUG_SVR4 - print_svr4_tchars("SVR4_TIOCGETC", &st); -#endif /* DEBUG_SVR4 */ - return copyout(&st, data, sizeof(st)); - } - - case SVR4_TIOCSETC: - { - struct tchars bt; - struct svr4_tchars st; - - if ((error = copyin(data, &st, sizeof(st))) != 0) - return error; - - svr4_tchars_to_bsd_tchars(&st, &bt); -#ifdef DEBUG_SVR4 - print_svr4_tchars("SVR4_TIOCSETC", &st); -#endif /* DEBUG_SVR4 */ - return fo_ioctl(fp, TIOCSETC, (caddr_t) &bt, - td->td_ucred, td); - } - - case SVR4_TIOCGLTC: - { - struct ltchars bl; - struct svr4_ltchars sl; - - error = fo_ioctl(fp, TIOCGLTC, (caddr_t) &bl, - td->td_ucred, td); - if (error) - return error; - - bsd_ltchars_to_svr4_ltchars(&bl, &sl); -#ifdef DEBUG_SVR4 - print_svr4_ltchars("SVR4_TIOCGLTC", &sl); -#endif /* DEBUG_SVR4 */ - return copyout(&sl, data, sizeof(sl)); - } - - case SVR4_TIOCSLTC: - { - struct ltchars bl; - struct svr4_ltchars sl; - - if ((error = copyin(data, &sl, sizeof(sl))) != 0) - return error; - - svr4_ltchars_to_bsd_ltchars(&sl, &bl); -#ifdef DEBUG_SVR4 - print_svr4_ltchars("SVR4_TIOCSLTC", &sl); -#endif /* DEBUG_SVR4 */ - return fo_ioctl(fp, TIOCSLTC, (caddr_t) &bl, - td->td_ucred, td); - } - - case SVR4_TIOCLGET: - { - int flags; - if ((error = fo_ioctl(fp, TIOCLGET, (caddr_t) &flags, - td->td_ucred, td)) != 0) - return error; - DPRINTF(("SVR4_TIOCLGET %o\n", flags)); - return copyout(&flags, data, sizeof(flags)); - } - - case SVR4_TIOCLSET: - case SVR4_TIOCLBIS: - case SVR4_TIOCLBIC: - { - int flags; - - if ((error = copyin(data, &flags, sizeof(flags))) != 0) - return error; - - switch (cmd) { - case SVR4_TIOCLSET: - cmd = TIOCLSET; - break; - case SVR4_TIOCLBIS: - cmd = TIOCLBIS; - break; - case SVR4_TIOCLBIC: - cmd = TIOCLBIC; - break; - } - - DPRINTF(("SVR4_TIOCL{SET,BIS,BIC} %o\n", flags)); - return fo_ioctl(fp, cmd, (caddr_t) &flags, - td->td_ucred, td); - } - - default: - DPRINTF(("Unknown svr4 ttold %lx\n", cmd)); - return 0; /* ENOSYS really */ - } -} - -#endif /* BURN_BRIDGES */ diff --git a/sys/compat/svr4/svr4_ttold.h b/sys/compat/svr4/svr4_ttold.h deleted file mode 100644 index aecde201c923..000000000000 --- a/sys/compat/svr4/svr4_ttold.h +++ /dev/null @@ -1,122 +0,0 @@ -/*- - * Copyright (c) 1998 Mark Newton - * Copyright (c) 1994 Christos Zoulas - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _SVR4_TTOLD_H_ -#define _SVR4_TTOLD_H_ - -struct svr4_tchars { - char t_intrc; - char t_quitc; - char t_startc; - char t_stopc; - char t_eofc; - char t_brkc; -}; - -struct svr4_sgttyb { - u_char sg_ispeed; - u_char sg_ospeed; - u_char sg_erase; - u_char sg_kill; - int sg_flags; -}; - -struct svr4_ltchars { - char t_suspc; - char t_dsuspc; - char t_rprntc; - char t_flushc; - char t_werasc; - char t_lnextc; -}; - -#ifndef SVR4_tIOC -#define SVR4_tIOC ('t' << 8) -#endif - -#define SVR4_TIOCGETD (SVR4_tIOC | 0) -#define SVR4_TIOCSETD (SVR4_tIOC | 1) -#define SVR4_TIOCHPCL (SVR4_tIOC | 2) -#define SVR4_TIOCGETP (SVR4_tIOC | 8) -#define SVR4_TIOCSETP (SVR4_tIOC | 9) -#define SVR4_TIOCSETN (SVR4_tIOC | 10) -#define SVR4_TIOCEXCL (SVR4_tIOC | 13) -#define SVR4_TIOCNXCL (SVR4_tIOC | 14) -#define SVR4_TIOCFLUSH (SVR4_tIOC | 16) -#define SVR4_TIOCSETC (SVR4_tIOC | 17) -#define SVR4_TIOCGETC (SVR4_tIOC | 18) -#define SVR4_TIOCGPGRP (SVR4_tIOC | 20) -#define SVR4_TIOCSPGRP (SVR4_tIOC | 21) -#define SVR4_TIOCGSID (SVR4_tIOC | 22) -#define SVR4_TIOCSTI (SVR4_tIOC | 23) -#define SVR4_TIOCSSID (SVR4_tIOC | 24) -#define SVR4_TIOCMSET (SVR4_tIOC | 26) -#define SVR4_TIOCMBIS (SVR4_tIOC | 27) -#define SVR4_TIOCMBIC (SVR4_tIOC | 28) -#define SVR4_TIOCMGET (SVR4_tIOC | 29) -#define SVR4_TIOCREMOTE (SVR4_tIOC | 30) -#define SVR4_TIOCSIGNAL (SVR4_tIOC | 31) - -#define SVR4_TIOCSTART (SVR4_tIOC | 110) -#define SVR4_TIOCSTOP (SVR4_tIOC | 111) -#define SVR4_TIOCNOTTY (SVR4_tIOC | 113) -#define SVR4_TIOCOUTQ (SVR4_tIOC | 115) -#define SVR4_TIOCGLTC (SVR4_tIOC | 116) -#define SVR4_TIOCSLTC (SVR4_tIOC | 117) -#define SVR4_TIOCCDTR (SVR4_tIOC | 120) -#define SVR4_TIOCSDTR (SVR4_tIOC | 121) -#define SVR4_TIOCCBRK (SVR4_tIOC | 122) -#define SVR4_TIOCSBRK (SVR4_tIOC | 123) -#define SVR4_TIOCLGET (SVR4_tIOC | 124) -#define SVR4_TIOCLSET (SVR4_tIOC | 125) -#define SVR4_TIOCLBIC (SVR4_tIOC | 126) -#define SVR4_TIOCLBIS (SVR4_tIOC | 127) - -#define SVR4_TIOCM_LE 0001 -#define SVR4_TIOCM_DTR 0002 -#define SVR4_TIOCM_RTS 0004 -#define SVR4_TIOCM_ST 0010 -#define SVR4_TIOCM_SR 0020 -#define SVR4_TIOCM_CTS 0040 -#define SVR4_TIOCM_CAR 0100 -#define SVR4_TIOCM_CD SVR4_TIOCM_CAR -#define SVR4_TIOCM_RNG 0200 -#define SVR4_TIOCM_RI SVR4_TIOCM_RNG -#define SVR4_TIOCM_DSR 0400 - -#define SVR4_OTTYDISC 0 -#define SVR4_NETLDISC 1 -#define SVR4_NTTYDISC 2 -#define SVR4_TABLDISC 3 -#define SVR4_NTABLDISC 4 -#define SVR4_MOUSELDISC 5 -#define SVR4_KBDLDISC 6 - -#endif /* !_SVR4_TTOLD_H_ */ diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index 13f04172cd05..d88be047be8a 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -108,7 +108,6 @@ compat/svr4/svr4_syscallnames.c optional compat_svr4 compat/svr4/svr4_sysent.c optional compat_svr4 compat/svr4/svr4_sysvec.c optional compat_svr4 compat/svr4/svr4_termios.c optional compat_svr4 -compat/svr4/svr4_ttold.c optional compat_svr4 bf_enc.o optional crypto | ipsec \ dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index a6b62b1e844e..4e7e43fa5701 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -71,7 +71,6 @@ compat/svr4/svr4_syscallnames.c optional compat_svr4 compat/svr4/svr4_sysent.c optional compat_svr4 compat/svr4/svr4_sysvec.c optional compat_svr4 compat/svr4/svr4_termios.c optional compat_svr4 -compat/svr4/svr4_ttold.c optional compat_svr4 bf_enc.o optional crypto | ipsec \ dependency "$S/crypto/blowfish/arch/i386/bf_enc.S $S/crypto/blowfish/arch/i386/bf_enc_586.S $S/crypto/blowfish/arch/i386/bf_enc_686.S" \ compile-with "${CC} -c -I$S/crypto/blowfish/arch/i386 ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}" \ diff --git a/sys/i386/ibcs2/ibcs2_ioctl.c b/sys/i386/ibcs2/ibcs2_ioctl.c index 0275c9866286..17749dbc303f 100644 --- a/sys/i386/ibcs2/ibcs2_ioctl.c +++ b/sys/i386/ibcs2/ibcs2_ioctl.c @@ -36,7 +36,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -56,34 +55,6 @@ static void btios2stios(struct termios *, struct ibcs2_termios *); static void stios2stio(struct ibcs2_termios *, struct ibcs2_termio *); static void stio2stios(struct ibcs2_termio *, struct ibcs2_termios *); - -#ifndef BURN_BRIDGES -int -ibcs2_gtty(struct thread *td, struct ibcs2_gtty_args *args) -{ - struct ioctl_args ioctl_arg; - - ioctl_arg.fd = args->fd; - ioctl_arg.com = TIOCGETC; - ioctl_arg.data = (caddr_t)args->buf; - - return ioctl(td, &ioctl_arg); -} - -int -ibcs2_stty(struct thread *td, struct ibcs2_stty_args *args) -{ - struct ioctl_args ioctl_arg; - - ioctl_arg.fd = args->fd; - ioctl_arg.com = TIOCSETC; - ioctl_arg.data = (caddr_t)args->buf; - - return ioctl(td, &ioctl_arg); -} -#endif /* BURN BRIDGES */ - - /* * iBCS2 ioctl calls. */ diff --git a/sys/i386/ibcs2/syscalls.master b/sys/i386/ibcs2/syscalls.master index 274a829c0623..23d585388680 100644 --- a/sys/i386/ibcs2/syscalls.master +++ b/sys/i386/ibcs2/syscalls.master @@ -79,10 +79,8 @@ 29 AUE_NULL STD { int ibcs2_pause(void); } 30 AUE_NULL STD { int ibcs2_utime(char *path, \ struct ibcs2_utimbuf *buf); } -31 AUE_NULL STD { int ibcs2_stty(int fd, \ - struct sgttyb *buf); } -32 AUE_NULL STD { int ibcs2_gtty(int fd, \ - struct sgttyb *buf); } +31 AUE_NULL UNIMPL ibcs2_stty +32 AUE_NULL UNIMPL ibcs2_gtty 33 AUE_ACCESS STD { int ibcs2_access(char *path, int flags); } 34 AUE_NICE STD { int ibcs2_nice(int incr); } 35 AUE_STATFS STD { int ibcs2_statfs(char *path, \ diff --git a/sys/modules/svr4/Makefile b/sys/modules/svr4/Makefile index 86f84465d192..9b969499d490 100644 --- a/sys/modules/svr4/Makefile +++ b/sys/modules/svr4/Makefile @@ -4,7 +4,7 @@ KMOD= svr4 SRCS= svr4_sysent.c svr4_sysvec.c opt_compat.h opt_mac.h opt_svr4.h \ vnode_if.h imgact_svr4.c svr4_signal.c svr4_fcntl.c \ - svr4_misc.c svr4_ioctl.c svr4_stat.c svr4_filio.c svr4_ttold.c \ + svr4_misc.c svr4_ioctl.c svr4_stat.c svr4_filio.c \ svr4_termios.c svr4_stream.c svr4_socket.c svr4_sockio.c \ svr4_machdep.c svr4_resource.c svr4_ipc.c OBJS= svr4_locore.o diff --git a/sys/sys/ioctl_compat.h b/sys/sys/ioctl_compat.h index 6399badf2102..4164c89f4cc0 100644 --- a/sys/sys/ioctl_compat.h +++ b/sys/sys/ioctl_compat.h @@ -40,6 +40,10 @@ #ifdef _KERNEL +#ifndef COMPAT_43TTY +#error "Definitions not available without TTY ioctl compat." +#endif + struct tchars { char t_intrc; /* interrupt */ char t_quitc; /* quit */ From a1c45f054a9659d0f296f97c4413880d3263e02d Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 8 May 2009 20:08:43 +0000 Subject: [PATCH 052/544] Regenerate ibcs2 system call table. --- sys/i386/ibcs2/ibcs2_proto.h | 21 ++++++++------------- sys/i386/ibcs2/ibcs2_syscall.h | 4 +--- sys/i386/ibcs2/ibcs2_sysent.c | 7 +++---- 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/sys/i386/ibcs2/ibcs2_proto.h b/sys/i386/ibcs2/ibcs2_proto.h index f0140306293f..facca1e5f3f6 100644 --- a/sys/i386/ibcs2/ibcs2_proto.h +++ b/sys/i386/ibcs2/ibcs2_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.master 191919 2009-05-08 20:06:37Z ed */ #ifndef _IBCS2_SYSPROTO_H_ @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -117,14 +118,6 @@ struct ibcs2_utime_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char buf_l_[PADL_(struct ibcs2_utimbuf *)]; struct ibcs2_utimbuf * buf; char buf_r_[PADR_(struct ibcs2_utimbuf *)]; }; -struct ibcs2_stty_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char buf_l_[PADL_(struct sgttyb *)]; struct sgttyb * buf; char buf_r_[PADR_(struct sgttyb *)]; -}; -struct ibcs2_gtty_args { - char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; - char buf_l_[PADL_(struct sgttyb *)]; struct sgttyb * buf; char buf_r_[PADR_(struct sgttyb *)]; -}; struct ibcs2_access_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; @@ -302,8 +295,6 @@ int ibcs2_alarm(struct thread *, struct ibcs2_alarm_args *); int ibcs2_fstat(struct thread *, struct ibcs2_fstat_args *); int ibcs2_pause(struct thread *, struct ibcs2_pause_args *); int ibcs2_utime(struct thread *, struct ibcs2_utime_args *); -int ibcs2_stty(struct thread *, struct ibcs2_stty_args *); -int ibcs2_gtty(struct thread *, struct ibcs2_gtty_args *); int ibcs2_access(struct thread *, struct ibcs2_access_args *); int ibcs2_nice(struct thread *, struct ibcs2_nice_args *); int ibcs2_statfs(struct thread *, struct ibcs2_statfs_args *); @@ -348,6 +339,12 @@ int ibcs2_isc(struct thread *, struct ibcs2_isc_args *); #endif /* COMPAT_FREEBSD4 */ + +#ifdef COMPAT_FREEBSD6 + + +#endif /* COMPAT_FREEBSD6 */ + #define IBCS2_SYS_AUE_ibcs2_read AUE_NULL #define IBCS2_SYS_AUE_ibcs2_open AUE_OPEN_RWTC #define IBCS2_SYS_AUE_ibcs2_wait AUE_WAIT4 @@ -369,8 +366,6 @@ int ibcs2_isc(struct thread *, struct ibcs2_isc_args *); #define IBCS2_SYS_AUE_ibcs2_fstat AUE_FSTAT #define IBCS2_SYS_AUE_ibcs2_pause AUE_NULL #define IBCS2_SYS_AUE_ibcs2_utime AUE_NULL -#define IBCS2_SYS_AUE_ibcs2_stty AUE_NULL -#define IBCS2_SYS_AUE_ibcs2_gtty AUE_NULL #define IBCS2_SYS_AUE_ibcs2_access AUE_ACCESS #define IBCS2_SYS_AUE_ibcs2_nice AUE_NICE #define IBCS2_SYS_AUE_ibcs2_statfs AUE_STATFS diff --git a/sys/i386/ibcs2/ibcs2_syscall.h b/sys/i386/ibcs2/ibcs2_syscall.h index c988532d804c..90fe20f179b5 100644 --- a/sys/i386/ibcs2/ibcs2_syscall.h +++ b/sys/i386/ibcs2/ibcs2_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.master 191919 2009-05-08 20:06:37Z ed */ #define IBCS2_SYS_syscall 0 @@ -37,8 +37,6 @@ #define IBCS2_SYS_ibcs2_fstat 28 #define IBCS2_SYS_ibcs2_pause 29 #define IBCS2_SYS_ibcs2_utime 30 -#define IBCS2_SYS_ibcs2_stty 31 -#define IBCS2_SYS_ibcs2_gtty 32 #define IBCS2_SYS_ibcs2_access 33 #define IBCS2_SYS_ibcs2_nice 34 #define IBCS2_SYS_ibcs2_statfs 35 diff --git a/sys/i386/ibcs2/ibcs2_sysent.c b/sys/i386/ibcs2/ibcs2_sysent.c index fceaf3f39e67..8b874951595a 100644 --- a/sys/i386/ibcs2/ibcs2_sysent.c +++ b/sys/i386/ibcs2/ibcs2_sysent.c @@ -3,10 +3,9 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.master 191919 2009-05-08 20:06:37Z ed */ -#include #include #include #include @@ -49,8 +48,8 @@ struct sysent ibcs2_sysent[] = { { AS(ibcs2_fstat_args), (sy_call_t *)ibcs2_fstat, AUE_FSTAT, NULL, 0, 0 }, /* 28 = ibcs2_fstat */ { 0, (sy_call_t *)ibcs2_pause, AUE_NULL, NULL, 0, 0 }, /* 29 = ibcs2_pause */ { AS(ibcs2_utime_args), (sy_call_t *)ibcs2_utime, AUE_NULL, NULL, 0, 0 }, /* 30 = ibcs2_utime */ - { AS(ibcs2_stty_args), (sy_call_t *)ibcs2_stty, AUE_NULL, NULL, 0, 0 }, /* 31 = ibcs2_stty */ - { AS(ibcs2_gtty_args), (sy_call_t *)ibcs2_gtty, AUE_NULL, NULL, 0, 0 }, /* 32 = ibcs2_gtty */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 31 = ibcs2_stty */ + { 0, (sy_call_t *)nosys, AUE_NULL, NULL, 0, 0 }, /* 32 = ibcs2_gtty */ { AS(ibcs2_access_args), (sy_call_t *)ibcs2_access, AUE_ACCESS, NULL, 0, 0 }, /* 33 = ibcs2_access */ { AS(ibcs2_nice_args), (sy_call_t *)ibcs2_nice, AUE_NICE, NULL, 0, 0 }, /* 34 = ibcs2_nice */ { AS(ibcs2_statfs_args), (sy_call_t *)ibcs2_statfs, AUE_STATFS, NULL, 0, 0 }, /* 35 = ibcs2_statfs */ From e5a34e5582087bd6245574db381b3f67deb2885c Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 8 May 2009 20:16:04 +0000 Subject: [PATCH 053/544] Regenerate system call tables to use SVN ids. --- sys/compat/svr4/svr4_proto.h | 9 ++++++++- sys/compat/svr4/svr4_syscall.h | 2 +- sys/compat/svr4/svr4_syscallnames.c | 2 +- sys/compat/svr4/svr4_sysent.c | 3 +-- sys/i386/ibcs2/ibcs2_isc_syscall.h | 2 +- sys/i386/ibcs2/ibcs2_isc_sysent.c | 3 +-- sys/i386/ibcs2/ibcs2_xenix.h | 9 ++++++++- sys/i386/ibcs2/ibcs2_xenix_syscall.h | 2 +- sys/i386/ibcs2/ibcs2_xenix_sysent.c | 3 +-- 9 files changed, 23 insertions(+), 12 deletions(-) diff --git a/sys/compat/svr4/svr4_proto.h b/sys/compat/svr4/svr4_proto.h index b089b9fa84d3..430b5cb76b11 100644 --- a/sys/compat/svr4/svr4_proto.h +++ b/sys/compat/svr4/svr4_proto.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/svr4/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/compat/svr4/syscalls.master 160798 2006-07-28 19:05:28Z jhb */ #ifndef _SVR4_SYSPROTO_H_ @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -496,6 +497,12 @@ int svr4_sys_sendto(struct thread *, struct svr4_sys_sendto_args *); #endif /* COMPAT_FREEBSD4 */ + +#ifdef COMPAT_FREEBSD6 + + +#endif /* COMPAT_FREEBSD6 */ + #define SVR4_SYS_AUE_svr4_sys_open AUE_NULL #define SVR4_SYS_AUE_svr4_sys_wait AUE_NULL #define SVR4_SYS_AUE_svr4_sys_creat AUE_NULL diff --git a/sys/compat/svr4/svr4_syscall.h b/sys/compat/svr4/svr4_syscall.h index 58b7cae05434..fa64a6f8cdfd 100644 --- a/sys/compat/svr4/svr4_syscall.h +++ b/sys/compat/svr4/svr4_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/svr4/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/compat/svr4/syscalls.master 160798 2006-07-28 19:05:28Z jhb */ #define SVR4_SYS_exit 1 diff --git a/sys/compat/svr4/svr4_syscallnames.c b/sys/compat/svr4/svr4_syscallnames.c index 5f91f2429866..7e312589684d 100644 --- a/sys/compat/svr4/svr4_syscallnames.c +++ b/sys/compat/svr4/svr4_syscallnames.c @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/svr4/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/compat/svr4/syscalls.master 160798 2006-07-28 19:05:28Z jhb */ const char *svr4_syscallnames[] = { diff --git a/sys/compat/svr4/svr4_sysent.c b/sys/compat/svr4/svr4_sysent.c index ca5daf73e0fc..098f73a38af9 100644 --- a/sys/compat/svr4/svr4_sysent.c +++ b/sys/compat/svr4/svr4_sysent.c @@ -3,10 +3,9 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/compat/svr4/syscalls.master,v 1.28 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/compat/svr4/syscalls.master 160798 2006-07-28 19:05:28Z jhb */ -#include #include #include #include diff --git a/sys/i386/ibcs2/ibcs2_isc_syscall.h b/sys/i386/ibcs2/ibcs2_isc_syscall.h index ac3085aea5b5..7b4e68475d2f 100644 --- a/sys/i386/ibcs2/ibcs2_isc_syscall.h +++ b/sys/i386/ibcs2/ibcs2_isc_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.isc,v 1.12 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.isc 160798 2006-07-28 19:05:28Z jhb */ #define IBCS2_ISC_ibcs2_rename 2 diff --git a/sys/i386/ibcs2/ibcs2_isc_sysent.c b/sys/i386/ibcs2/ibcs2_isc_sysent.c index ca76a8ca464a..39b8b5c0ef7b 100644 --- a/sys/i386/ibcs2/ibcs2_isc_sysent.c +++ b/sys/i386/ibcs2/ibcs2_isc_sysent.c @@ -3,10 +3,9 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.isc,v 1.12 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.isc 160798 2006-07-28 19:05:28Z jhb */ -#include #include #include #include diff --git a/sys/i386/ibcs2/ibcs2_xenix.h b/sys/i386/ibcs2/ibcs2_xenix.h index 3d35f66a9138..f2a3d6608c74 100644 --- a/sys/i386/ibcs2/ibcs2_xenix.h +++ b/sys/i386/ibcs2/ibcs2_xenix.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.xenix,v 1.14 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.xenix 160798 2006-07-28 19:05:28Z jhb */ #ifndef _IBCS2_XENIX_H_ @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -122,6 +123,12 @@ int xenix_utsname(struct thread *, struct xenix_utsname_args *); #endif /* COMPAT_FREEBSD4 */ + +#ifdef COMPAT_FREEBSD6 + + +#endif /* COMPAT_FREEBSD6 */ + #define IBCS2_XENIX_AUE_xenix_rdchk AUE_NULL #define IBCS2_XENIX_AUE_xenix_chsize AUE_FTRUNCATE #define IBCS2_XENIX_AUE_xenix_ftime AUE_NULL diff --git a/sys/i386/ibcs2/ibcs2_xenix_syscall.h b/sys/i386/ibcs2/ibcs2_xenix_syscall.h index fbf7ecaa4dd9..e88ce2143641 100644 --- a/sys/i386/ibcs2/ibcs2_xenix_syscall.h +++ b/sys/i386/ibcs2/ibcs2_xenix_syscall.h @@ -3,7 +3,7 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.xenix,v 1.14 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.xenix 160798 2006-07-28 19:05:28Z jhb */ #define IBCS2_XENIX_xenix_rdchk 7 diff --git a/sys/i386/ibcs2/ibcs2_xenix_sysent.c b/sys/i386/ibcs2/ibcs2_xenix_sysent.c index 86b4ea71c64e..b227d9a9120e 100644 --- a/sys/i386/ibcs2/ibcs2_xenix_sysent.c +++ b/sys/i386/ibcs2/ibcs2_xenix_sysent.c @@ -3,10 +3,9 @@ * * DO NOT EDIT-- this file is automatically generated. * $FreeBSD$ - * created from FreeBSD: src/sys/i386/ibcs2/syscalls.xenix,v 1.14 2006/07/28 19:05:27 jhb Exp + * created from FreeBSD: head/sys/i386/ibcs2/syscalls.xenix 160798 2006-07-28 19:05:28Z jhb */ -#include #include #include #include From 8ef3f835d2fd822eb6ad6226420ad5c2fb7e5687 Mon Sep 17 00:00:00 2001 From: David Christensen Date: Fri, 8 May 2009 22:20:45 +0000 Subject: [PATCH 054/544] - Fixed incorrect packet length problem caused be earlier change to support ZERO_COPY_SOCKETS. - Created #define for context initialization retry count. MFC after: 1 week --- sys/dev/bce/if_bce.c | 6 ++++-- sys/dev/bce/if_bcereg.h | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index d39af9bee7cd..bd267f73af4e 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -4204,8 +4204,7 @@ bce_init_ctx(struct bce_softc *sc) if ((BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5709) || (BCE_CHIP_NUM(sc) == BCE_CHIP_NUM_5716)) { - /* DRC: Replace this constant value with a #define. */ - int i, retry_cnt = 10; + int i, retry_cnt = CTX_INIT_RETRY_COUNT; u32 val; DBPRINT(sc, BCE_INFO_CTX, "Initializing 5709 context.\n"); @@ -5895,6 +5894,9 @@ bce_rx_intr(struct bce_softc *sc) /* Set the total packet length. */ m0->m_pkthdr.len = m0->m_len = pkt_len; } +#else + /* Set the total packet length. */ + m0->m_pkthdr.len = m0->m_len = pkt_len; #endif /* Remove the trailing Ethernet FCS. */ diff --git a/sys/dev/bce/if_bcereg.h b/sys/dev/bce/if_bcereg.h index 518b4b9cd0ff..32456fde3bfd 100644 --- a/sys/dev/bce/if_bcereg.h +++ b/sys/dev/bce/if_bcereg.h @@ -6232,6 +6232,8 @@ struct l2_fhdr { #endif /* ZERO_COPY_SOCKETS */ +#define CTX_INIT_RETRY_COUNT 10 + /* Context size. */ #define CTX_SHIFT 7 #define CTX_SIZE (1 << CTX_SHIFT) From ad5f463cf975eb6a9c4cb335fc2ce7a84c7d49a7 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 8 May 2009 23:34:35 +0000 Subject: [PATCH 055/544] Flatten all tags of the dist tree of less. --- contrib/less/COPYING => COPYING | 0 contrib/less/INSTALL => INSTALL | 0 contrib/less/LICENSE => LICENSE | 0 contrib/less/Makefile.aut => Makefile.aut | 0 contrib/less/Makefile.dsb => Makefile.dsb | 0 contrib/less/Makefile.dsg => Makefile.dsg | 0 contrib/less/Makefile.dsu => Makefile.dsu | 0 contrib/less/Makefile.in => Makefile.in | 0 contrib/less/Makefile.o2e => Makefile.o2e | 0 contrib/less/Makefile.o9c => Makefile.o9c | 0 contrib/less/Makefile.o9u => Makefile.o9u | 0 contrib/less/Makefile.wnb => Makefile.wnb | 0 contrib/less/Makefile.wnm => Makefile.wnm | 0 contrib/less/NEWS => NEWS | 0 contrib/less/README => README | 0 contrib/less/brac.c => brac.c | 0 contrib/less/ch.c => ch.c | 0 contrib/less/charset.c => charset.c | 0 contrib/less/charset.h => charset.h | 0 contrib/less/cmd.h => cmd.h | 0 contrib/less/cmdbuf.c => cmdbuf.c | 0 contrib/less/command.c => command.c | 0 contrib/less/configure => configure | 0 contrib/less/configure.ac => configure.ac | 0 contrib/less/decode.c => decode.c | 0 contrib/less/defines.ds => defines.ds | 0 contrib/less/defines.h.in => defines.h.in | 0 contrib/less/defines.o2 => defines.o2 | 0 contrib/less/defines.o9 => defines.o9 | 0 contrib/less/defines.wn => defines.wn | 0 contrib/less/edit.c => edit.c | 0 contrib/less/filename.c => filename.c | 0 contrib/less/forwback.c => forwback.c | 0 contrib/less/funcs.h => funcs.h | 0 contrib/less/help.c => help.c | 0 contrib/less/ifile.c => ifile.c | 0 contrib/less/input.c => input.c | 0 contrib/less/install.sh => install.sh | 0 contrib/less/jump.c => jump.c | 0 contrib/less/less.h => less.h | 0 contrib/less/less.hlp => less.hlp | 0 contrib/less/less.man => less.man | 0 contrib/less/less.nro => less.nro | 0 contrib/less/lessecho.c => lessecho.c | 0 contrib/less/lessecho.man => lessecho.man | 0 contrib/less/lessecho.nro => lessecho.nro | 0 contrib/less/lesskey.c => lesskey.c | 0 contrib/less/lesskey.h => lesskey.h | 0 contrib/less/lesskey.man => lesskey.man | 0 contrib/less/lesskey.nro => lesskey.nro | 0 contrib/less/lglob.h => lglob.h | 0 contrib/less/line.c => line.c | 0 contrib/less/linenum.c => linenum.c | 0 contrib/less/lsystem.c => lsystem.c | 0 contrib/less/main.c => main.c | 0 contrib/less/mark.c => mark.c | 0 contrib/less/mkfuncs.awk => mkfuncs.awk | 0 contrib/less/mkhelp.c => mkhelp.c | 0 contrib/less/mkinstalldirs => mkinstalldirs | 0 contrib/less/optfunc.c => optfunc.c | 0 contrib/less/option.c => option.c | 0 contrib/less/option.h => option.h | 0 contrib/less/opttbl.c => opttbl.c | 0 contrib/less/os.c => os.c | 0 contrib/less/output.c => output.c | 0 contrib/less/pckeys.h => pckeys.h | 0 contrib/less/position.c => position.c | 0 contrib/less/position.h => position.h | 0 contrib/less/prompt.c => prompt.c | 0 contrib/less/regexp.c => regexp.c | 0 contrib/less/regexp.h => regexp.h | 0 contrib/less/screen.c => screen.c | 0 contrib/less/scrsize.c => scrsize.c | 0 contrib/less/search.c => search.c | 0 contrib/less/signal.c => signal.c | 0 contrib/less/tags.c => tags.c | 0 contrib/less/ttyin.c => ttyin.c | 0 contrib/less/version.c => version.c | 0 78 files changed, 0 insertions(+), 0 deletions(-) rename contrib/less/COPYING => COPYING (100%) rename contrib/less/INSTALL => INSTALL (100%) rename contrib/less/LICENSE => LICENSE (100%) rename contrib/less/Makefile.aut => Makefile.aut (100%) rename contrib/less/Makefile.dsb => Makefile.dsb (100%) rename contrib/less/Makefile.dsg => Makefile.dsg (100%) rename contrib/less/Makefile.dsu => Makefile.dsu (100%) rename contrib/less/Makefile.in => Makefile.in (100%) rename contrib/less/Makefile.o2e => Makefile.o2e (100%) rename contrib/less/Makefile.o9c => Makefile.o9c (100%) rename contrib/less/Makefile.o9u => Makefile.o9u (100%) rename contrib/less/Makefile.wnb => Makefile.wnb (100%) rename contrib/less/Makefile.wnm => Makefile.wnm (100%) rename contrib/less/NEWS => NEWS (100%) rename contrib/less/README => README (100%) rename contrib/less/brac.c => brac.c (100%) rename contrib/less/ch.c => ch.c (100%) rename contrib/less/charset.c => charset.c (100%) rename contrib/less/charset.h => charset.h (100%) rename contrib/less/cmd.h => cmd.h (100%) rename contrib/less/cmdbuf.c => cmdbuf.c (100%) rename contrib/less/command.c => command.c (100%) rename contrib/less/configure => configure (100%) rename contrib/less/configure.ac => configure.ac (100%) rename contrib/less/decode.c => decode.c (100%) rename contrib/less/defines.ds => defines.ds (100%) rename contrib/less/defines.h.in => defines.h.in (100%) rename contrib/less/defines.o2 => defines.o2 (100%) rename contrib/less/defines.o9 => defines.o9 (100%) rename contrib/less/defines.wn => defines.wn (100%) rename contrib/less/edit.c => edit.c (100%) rename contrib/less/filename.c => filename.c (100%) rename contrib/less/forwback.c => forwback.c (100%) rename contrib/less/funcs.h => funcs.h (100%) rename contrib/less/help.c => help.c (100%) rename contrib/less/ifile.c => ifile.c (100%) rename contrib/less/input.c => input.c (100%) rename contrib/less/install.sh => install.sh (100%) rename contrib/less/jump.c => jump.c (100%) rename contrib/less/less.h => less.h (100%) rename contrib/less/less.hlp => less.hlp (100%) rename contrib/less/less.man => less.man (100%) rename contrib/less/less.nro => less.nro (100%) rename contrib/less/lessecho.c => lessecho.c (100%) rename contrib/less/lessecho.man => lessecho.man (100%) rename contrib/less/lessecho.nro => lessecho.nro (100%) rename contrib/less/lesskey.c => lesskey.c (100%) rename contrib/less/lesskey.h => lesskey.h (100%) rename contrib/less/lesskey.man => lesskey.man (100%) rename contrib/less/lesskey.nro => lesskey.nro (100%) rename contrib/less/lglob.h => lglob.h (100%) rename contrib/less/line.c => line.c (100%) rename contrib/less/linenum.c => linenum.c (100%) rename contrib/less/lsystem.c => lsystem.c (100%) rename contrib/less/main.c => main.c (100%) rename contrib/less/mark.c => mark.c (100%) rename contrib/less/mkfuncs.awk => mkfuncs.awk (100%) rename contrib/less/mkhelp.c => mkhelp.c (100%) rename contrib/less/mkinstalldirs => mkinstalldirs (100%) rename contrib/less/optfunc.c => optfunc.c (100%) rename contrib/less/option.c => option.c (100%) rename contrib/less/option.h => option.h (100%) rename contrib/less/opttbl.c => opttbl.c (100%) rename contrib/less/os.c => os.c (100%) rename contrib/less/output.c => output.c (100%) rename contrib/less/pckeys.h => pckeys.h (100%) rename contrib/less/position.c => position.c (100%) rename contrib/less/position.h => position.h (100%) rename contrib/less/prompt.c => prompt.c (100%) rename contrib/less/regexp.c => regexp.c (100%) rename contrib/less/regexp.h => regexp.h (100%) rename contrib/less/screen.c => screen.c (100%) rename contrib/less/scrsize.c => scrsize.c (100%) rename contrib/less/search.c => search.c (100%) rename contrib/less/signal.c => signal.c (100%) rename contrib/less/tags.c => tags.c (100%) rename contrib/less/ttyin.c => ttyin.c (100%) rename contrib/less/version.c => version.c (100%) diff --git a/contrib/less/COPYING b/COPYING similarity index 100% rename from contrib/less/COPYING rename to COPYING diff --git a/contrib/less/INSTALL b/INSTALL similarity index 100% rename from contrib/less/INSTALL rename to INSTALL diff --git a/contrib/less/LICENSE b/LICENSE similarity index 100% rename from contrib/less/LICENSE rename to LICENSE diff --git a/contrib/less/Makefile.aut b/Makefile.aut similarity index 100% rename from contrib/less/Makefile.aut rename to Makefile.aut diff --git a/contrib/less/Makefile.dsb b/Makefile.dsb similarity index 100% rename from contrib/less/Makefile.dsb rename to Makefile.dsb diff --git a/contrib/less/Makefile.dsg b/Makefile.dsg similarity index 100% rename from contrib/less/Makefile.dsg rename to Makefile.dsg diff --git a/contrib/less/Makefile.dsu b/Makefile.dsu similarity index 100% rename from contrib/less/Makefile.dsu rename to Makefile.dsu diff --git a/contrib/less/Makefile.in b/Makefile.in similarity index 100% rename from contrib/less/Makefile.in rename to Makefile.in diff --git a/contrib/less/Makefile.o2e b/Makefile.o2e similarity index 100% rename from contrib/less/Makefile.o2e rename to Makefile.o2e diff --git a/contrib/less/Makefile.o9c b/Makefile.o9c similarity index 100% rename from contrib/less/Makefile.o9c rename to Makefile.o9c diff --git a/contrib/less/Makefile.o9u b/Makefile.o9u similarity index 100% rename from contrib/less/Makefile.o9u rename to Makefile.o9u diff --git a/contrib/less/Makefile.wnb b/Makefile.wnb similarity index 100% rename from contrib/less/Makefile.wnb rename to Makefile.wnb diff --git a/contrib/less/Makefile.wnm b/Makefile.wnm similarity index 100% rename from contrib/less/Makefile.wnm rename to Makefile.wnm diff --git a/contrib/less/NEWS b/NEWS similarity index 100% rename from contrib/less/NEWS rename to NEWS diff --git a/contrib/less/README b/README similarity index 100% rename from contrib/less/README rename to README diff --git a/contrib/less/brac.c b/brac.c similarity index 100% rename from contrib/less/brac.c rename to brac.c diff --git a/contrib/less/ch.c b/ch.c similarity index 100% rename from contrib/less/ch.c rename to ch.c diff --git a/contrib/less/charset.c b/charset.c similarity index 100% rename from contrib/less/charset.c rename to charset.c diff --git a/contrib/less/charset.h b/charset.h similarity index 100% rename from contrib/less/charset.h rename to charset.h diff --git a/contrib/less/cmd.h b/cmd.h similarity index 100% rename from contrib/less/cmd.h rename to cmd.h diff --git a/contrib/less/cmdbuf.c b/cmdbuf.c similarity index 100% rename from contrib/less/cmdbuf.c rename to cmdbuf.c diff --git a/contrib/less/command.c b/command.c similarity index 100% rename from contrib/less/command.c rename to command.c diff --git a/contrib/less/configure b/configure similarity index 100% rename from contrib/less/configure rename to configure diff --git a/contrib/less/configure.ac b/configure.ac similarity index 100% rename from contrib/less/configure.ac rename to configure.ac diff --git a/contrib/less/decode.c b/decode.c similarity index 100% rename from contrib/less/decode.c rename to decode.c diff --git a/contrib/less/defines.ds b/defines.ds similarity index 100% rename from contrib/less/defines.ds rename to defines.ds diff --git a/contrib/less/defines.h.in b/defines.h.in similarity index 100% rename from contrib/less/defines.h.in rename to defines.h.in diff --git a/contrib/less/defines.o2 b/defines.o2 similarity index 100% rename from contrib/less/defines.o2 rename to defines.o2 diff --git a/contrib/less/defines.o9 b/defines.o9 similarity index 100% rename from contrib/less/defines.o9 rename to defines.o9 diff --git a/contrib/less/defines.wn b/defines.wn similarity index 100% rename from contrib/less/defines.wn rename to defines.wn diff --git a/contrib/less/edit.c b/edit.c similarity index 100% rename from contrib/less/edit.c rename to edit.c diff --git a/contrib/less/filename.c b/filename.c similarity index 100% rename from contrib/less/filename.c rename to filename.c diff --git a/contrib/less/forwback.c b/forwback.c similarity index 100% rename from contrib/less/forwback.c rename to forwback.c diff --git a/contrib/less/funcs.h b/funcs.h similarity index 100% rename from contrib/less/funcs.h rename to funcs.h diff --git a/contrib/less/help.c b/help.c similarity index 100% rename from contrib/less/help.c rename to help.c diff --git a/contrib/less/ifile.c b/ifile.c similarity index 100% rename from contrib/less/ifile.c rename to ifile.c diff --git a/contrib/less/input.c b/input.c similarity index 100% rename from contrib/less/input.c rename to input.c diff --git a/contrib/less/install.sh b/install.sh similarity index 100% rename from contrib/less/install.sh rename to install.sh diff --git a/contrib/less/jump.c b/jump.c similarity index 100% rename from contrib/less/jump.c rename to jump.c diff --git a/contrib/less/less.h b/less.h similarity index 100% rename from contrib/less/less.h rename to less.h diff --git a/contrib/less/less.hlp b/less.hlp similarity index 100% rename from contrib/less/less.hlp rename to less.hlp diff --git a/contrib/less/less.man b/less.man similarity index 100% rename from contrib/less/less.man rename to less.man diff --git a/contrib/less/less.nro b/less.nro similarity index 100% rename from contrib/less/less.nro rename to less.nro diff --git a/contrib/less/lessecho.c b/lessecho.c similarity index 100% rename from contrib/less/lessecho.c rename to lessecho.c diff --git a/contrib/less/lessecho.man b/lessecho.man similarity index 100% rename from contrib/less/lessecho.man rename to lessecho.man diff --git a/contrib/less/lessecho.nro b/lessecho.nro similarity index 100% rename from contrib/less/lessecho.nro rename to lessecho.nro diff --git a/contrib/less/lesskey.c b/lesskey.c similarity index 100% rename from contrib/less/lesskey.c rename to lesskey.c diff --git a/contrib/less/lesskey.h b/lesskey.h similarity index 100% rename from contrib/less/lesskey.h rename to lesskey.h diff --git a/contrib/less/lesskey.man b/lesskey.man similarity index 100% rename from contrib/less/lesskey.man rename to lesskey.man diff --git a/contrib/less/lesskey.nro b/lesskey.nro similarity index 100% rename from contrib/less/lesskey.nro rename to lesskey.nro diff --git a/contrib/less/lglob.h b/lglob.h similarity index 100% rename from contrib/less/lglob.h rename to lglob.h diff --git a/contrib/less/line.c b/line.c similarity index 100% rename from contrib/less/line.c rename to line.c diff --git a/contrib/less/linenum.c b/linenum.c similarity index 100% rename from contrib/less/linenum.c rename to linenum.c diff --git a/contrib/less/lsystem.c b/lsystem.c similarity index 100% rename from contrib/less/lsystem.c rename to lsystem.c diff --git a/contrib/less/main.c b/main.c similarity index 100% rename from contrib/less/main.c rename to main.c diff --git a/contrib/less/mark.c b/mark.c similarity index 100% rename from contrib/less/mark.c rename to mark.c diff --git a/contrib/less/mkfuncs.awk b/mkfuncs.awk similarity index 100% rename from contrib/less/mkfuncs.awk rename to mkfuncs.awk diff --git a/contrib/less/mkhelp.c b/mkhelp.c similarity index 100% rename from contrib/less/mkhelp.c rename to mkhelp.c diff --git a/contrib/less/mkinstalldirs b/mkinstalldirs similarity index 100% rename from contrib/less/mkinstalldirs rename to mkinstalldirs diff --git a/contrib/less/optfunc.c b/optfunc.c similarity index 100% rename from contrib/less/optfunc.c rename to optfunc.c diff --git a/contrib/less/option.c b/option.c similarity index 100% rename from contrib/less/option.c rename to option.c diff --git a/contrib/less/option.h b/option.h similarity index 100% rename from contrib/less/option.h rename to option.h diff --git a/contrib/less/opttbl.c b/opttbl.c similarity index 100% rename from contrib/less/opttbl.c rename to opttbl.c diff --git a/contrib/less/os.c b/os.c similarity index 100% rename from contrib/less/os.c rename to os.c diff --git a/contrib/less/output.c b/output.c similarity index 100% rename from contrib/less/output.c rename to output.c diff --git a/contrib/less/pckeys.h b/pckeys.h similarity index 100% rename from contrib/less/pckeys.h rename to pckeys.h diff --git a/contrib/less/position.c b/position.c similarity index 100% rename from contrib/less/position.c rename to position.c diff --git a/contrib/less/position.h b/position.h similarity index 100% rename from contrib/less/position.h rename to position.h diff --git a/contrib/less/prompt.c b/prompt.c similarity index 100% rename from contrib/less/prompt.c rename to prompt.c diff --git a/contrib/less/regexp.c b/regexp.c similarity index 100% rename from contrib/less/regexp.c rename to regexp.c diff --git a/contrib/less/regexp.h b/regexp.h similarity index 100% rename from contrib/less/regexp.h rename to regexp.h diff --git a/contrib/less/screen.c b/screen.c similarity index 100% rename from contrib/less/screen.c rename to screen.c diff --git a/contrib/less/scrsize.c b/scrsize.c similarity index 100% rename from contrib/less/scrsize.c rename to scrsize.c diff --git a/contrib/less/search.c b/search.c similarity index 100% rename from contrib/less/search.c rename to search.c diff --git a/contrib/less/signal.c b/signal.c similarity index 100% rename from contrib/less/signal.c rename to signal.c diff --git a/contrib/less/tags.c b/tags.c similarity index 100% rename from contrib/less/tags.c rename to tags.c diff --git a/contrib/less/ttyin.c b/ttyin.c similarity index 100% rename from contrib/less/ttyin.c rename to ttyin.c diff --git a/contrib/less/version.c b/version.c similarity index 100% rename from contrib/less/version.c rename to version.c From e1193b7bca0eca8d5c2740fdfa576746303bb993 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 8 May 2009 23:45:27 +0000 Subject: [PATCH 056/544] Vendor import of less v429 --- COPYING | 848 +++++++++---- LICENSE | 2 +- Makefile.in | 23 +- NEWS | 56 + README | 12 +- brac.c | 2 +- ch.c | 248 ++-- charset.c | 16 +- charset.h | 2 +- cmd.h | 3 +- cmdbuf.c | 19 +- command.c | 67 +- configure | 3445 +++++++++++++++++++++++++++++--------------------- configure.ac | 2 +- decode.c | 3 +- defines.ds | 2 +- defines.o2 | 2 +- defines.o9 | 2 +- defines.wn | 2 +- edit.c | 2 +- filename.c | 37 +- forwback.c | 52 +- funcs.h | 10 + help.c | 1 + ifile.c | 2 +- input.c | 77 +- install.sh | 2 +- jump.c | 16 +- less.h | 21 +- less.hlp | 1 + less.man | 879 +++++++------ less.nro | 77 +- lessecho.c | 4 +- lessecho.man | 2 +- lessecho.nro | 2 +- lesskey.c | 119 +- lesskey.h | 2 +- lesskey.man | 5 +- lesskey.nro | 5 +- lglob.h | 2 +- line.c | 63 +- linenum.c | 51 +- lsystem.c | 11 +- main.c | 2 +- mark.c | 2 +- mkhelp.c | 2 +- optfunc.c | 8 +- option.c | 2 +- option.h | 2 +- opttbl.c | 2 +- os.c | 2 +- output.c | 213 ++-- pckeys.h | 2 +- position.c | 2 +- position.h | 2 +- prompt.c | 5 +- screen.c | 37 +- scrsize.c | 2 +- search.c | 485 ++++--- signal.c | 24 +- tags.c | 2 +- ttyin.c | 2 +- version.c | 1310 +++++++++---------- 63 files changed, 4847 insertions(+), 3460 deletions(-) diff --git a/COPYING b/COPYING index d10474644415..94a9ed024d38 100644 --- a/COPYING +++ b/COPYING @@ -1,285 +1,626 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. - Preamble + Preamble - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". + TERMS AND CONDITIONS -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. + 0. Definitions. - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. + "This License" refers to version 3 of the GNU General Public License. -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. + A "covered work" means either the unmodified Program or a work based +on the Program. - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: + 1. Source Code. - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. + The Corresponding Source for a work in source code form is that +same work. - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of this License. - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. + 13. Use with the GNU Affero General Public License. -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. + 14. Revised Versions of this License. - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. - NO WARRANTY + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. + 15. Disclaimer of Warranty. - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -287,15 +628,15 @@ free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least +state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) - This program is free software; you can redistribute it and/or modify + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -304,37 +645,30 @@ the "copyright" line and a pointer to where the full notice is found. GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - + along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/LICENSE b/LICENSE index 8112859e8ae8..53915fb3abfd 100644 --- a/LICENSE +++ b/LICENSE @@ -2,7 +2,7 @@ ------------ Less -Copyright (C) 1984-2007 Mark Nudelman +Copyright (C) 1984-2008 Mark Nudelman Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions diff --git a/Makefile.in b/Makefile.in index 287bd8e50608..9d27d4a0ca5e 100644 --- a/Makefile.in +++ b/Makefile.in @@ -14,6 +14,7 @@ CFLAGS = @CFLAGS@ CFLAGS_COMPILE_ONLY = -c LDFLAGS = @LDFLAGS@ CPPFLAGS = @CPPFLAGS@ +EXEEXT = @EXEEXT@ O=o LIBS = @LIBS@ @@ -49,23 +50,23 @@ OBJ = main.${O} screen.${O} brac.${O} ch.${O} charset.${O} cmdbuf.${O} \ output.${O} position.${O} prompt.${O} search.${O} signal.${O} \ tags.${O} ttyin.${O} version.${O} @REGEX_O@ -all: less lesskey lessecho +all: less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT) -less: ${OBJ} +less$(EXEEXT): ${OBJ} ${CC} ${LDFLAGS} -o $@ ${OBJ} ${LIBS} -lesskey: lesskey.${O} version.${O} +lesskey$(EXEEXT): lesskey.${O} version.${O} ${CC} ${LDFLAGS} -o $@ lesskey.${O} version.${O} -lessecho: lessecho.${O} version.${O} +lessecho$(EXEEXT): lessecho.${O} version.${O} ${CC} ${LDFLAGS} -o $@ lessecho.${O} version.${O} ${OBJ}: ${srcdir}/less.h ${srcdir}/funcs.h defines.h install: all ${srcdir}/less.nro ${srcdir}/lesskey.nro ${srcdir}/lessecho.nro installdirs - ${INSTALL_PROGRAM} less ${DESTDIR}${bindir}/${binprefix}less - ${INSTALL_PROGRAM} lesskey ${DESTDIR}${bindir}/${binprefix}lesskey - ${INSTALL_PROGRAM} lessecho ${DESTDIR}${bindir}/${binprefix}lessecho + ${INSTALL_PROGRAM} less$(EXEEXT) ${DESTDIR}${bindir}/${binprefix}less$(EXEEXT) + ${INSTALL_PROGRAM} lesskey$(EXEEXT) ${DESTDIR}${bindir}/${binprefix}lesskey$(EXEEXT) + ${INSTALL_PROGRAM} lessecho$(EXEEXT) ${DESTDIR}${bindir}/${binprefix}lessecho$(EXEEXT) ${INSTALL_DATA} ${srcdir}/less.nro ${DESTDIR}${mandir}/man${manext}/${manprefix}less.${manext} ${INSTALL_DATA} ${srcdir}/lesskey.nro ${DESTDIR}${mandir}/man${manext}/${manprefix}lesskey.${manext} ${INSTALL_DATA} ${srcdir}/lessecho.nro ${DESTDIR}${mandir}/man${manext}/${manprefix}lessecho.${manext} @@ -77,9 +78,9 @@ installdirs: mkinstalldirs ${srcdir}/mkinstalldirs ${DESTDIR}${bindir} ${DESTDIR}${mandir}/man${manext} uninstall: - rm -f ${DESTDIR}${bindir}/${binprefix}less - rm -f ${DESTDIR}${bindir}/${binprefix}lesskey - rm -f ${DESTDIR}${bindir}/${binprefix}lessecho + rm -f ${DESTDIR}${bindir}/${binprefix}less$(EXEEXT) + rm -f ${DESTDIR}${bindir}/${binprefix}lesskey$(EXEEXT) + rm -f ${DESTDIR}${bindir}/${binprefix}lessecho$(EXEEXT) rm -f ${DESTDIR}${mandir}/man${manext}/${manprefix}less.${manext} rm -f ${DESTDIR}${mandir}/man${manext}/${manprefix}lesskey.${manext} rm -f ${DESTDIR}${mandir}/man${manext}/${manprefix}lessecho.${manext} @@ -108,7 +109,7 @@ ${srcdir}/configure: ${srcdir}/configure.ac cd ${srcdir}; autoheader; autoconf clean: - rm -f *.${O} core less lesskey lessecho + rm -f *.${O} core less$(EXEEXT) lesskey$(EXEEXT) lessecho$(EXEEXT) mostlyclean: clean diff --git a/NEWS b/NEWS index e6cec6969bb7..137e2b5236c2 100644 --- a/NEWS +++ b/NEWS @@ -12,6 +12,62 @@ ====================================================================== + Major changes between "less" versions 424 and 429 + +* LESSOPEN pipe will now be used on standard input, if the LESSOPEN + environment variable begins with "|-". + +* The -D option with one number now means use the normal background color. + +* Don't change permissions on history file if it is not a regular file. + +* Fix non-ANSI-compliant code that caused problems with some compilers. + +* Fix binary file detection in UTF-8 mode. + +* Fix display problems with long lines on "ignaw" terminals. + +* Fix problem interrupting the line number calculation for initial prompt. + +* Fix SGR emulation when dealing with multiple attributes (eg. bold+underline). + +* Fix highlight bug when searching for underlined/overstruck text. + +====================================================================== + + Major changes between "less" versions 418 and 424 + +* New "&" command allows filtering of lines based on a pattern. + +* Status column now displays a search match, even if the matched + string is scrolled off screen because -S is in effect. + +* Improve behavior of -F option. + +* Allow CSI character (0x9B) to work in UTF-8 mode. + +* Output carriage return at startup in case terminal doesn't default + to column 1. + +* Fix bug in '' (quote, quote) command after G command. + +====================================================================== + + Major changes between "less" versions 416 and 418 + +* Color escape sequences are now supported in WIN32 build. + +* Makefile now uses EXEEXT feature of autoconf. + +* Fix search bug when using -R and text contains ANSI color escape sequences. + +* Fix crash when using -r with UTF-8 text containing 0x9B bytes. + +* Fix display bug when using ' command to move less than one page forward. + +* Update GPL to version 3. + +====================================================================== Major changes between "less" versions 409 and 416 diff --git a/README b/README index 2cab3474667b..073217fa4b43 100644 --- a/README +++ b/README @@ -1,26 +1,20 @@ - Less, version 416 + Less, version 429 - This is the distribution of less, version 416, released 22 Nov 2007. + This is the distribution of less, version 429, released 11 Apr 2009. This program is part of the GNU project (http://www.gnu.org). This program is free software. You may redistribute it and/or modify it under the terms of either: 1. The GNU General Public License, as published by the Free - Software Foundation; either version 2, or (at your option) any + Software Foundation; either version 3, or (at your option) any later version. A copy of this license is in the file COPYING. or 2. The Less License, in the file LICENSE. Please report any problems to bug-less@gnu.org or markn@greenwoodsoftware.com. See http://www.greenwoodsoftware.com/less for the latest info. - You may also contact the author at: - Mark Nudelman - Greenwood Software - PO Box 2402 - El Granada, CA 94018 - USA ========================================================================= diff --git a/brac.c b/brac.c index 20c7353469b3..2c0bfa4bb66c 100644 --- a/brac.c +++ b/brac.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/ch.c b/ch.c index eb607d593b01..8ad028ba00d1 100644 --- a/ch.c +++ b/ch.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -37,20 +37,19 @@ public int ignore_eoi; * in order from most- to least-recently used. * The circular list is anchored by the file state "thisfile". */ +struct bufnode { + struct bufnode *next, *prev; + struct bufnode *hnext, *hprev; +}; + #define LBUFSIZE 8192 struct buf { - struct buf *next, *prev; - struct buf *hnext, *hprev; + struct bufnode node; BLOCKNUM block; unsigned int datasize; unsigned char data[LBUFSIZE]; }; - -struct buflist { - /* -- Following members must match struct buf */ - struct buf *buf_next, *buf_prev; - struct buf *buf_hnext, *buf_hprev; -}; +#define bufnode_buf(bn) ((struct buf *) bn) /* * The file state is maintained in a filestate structure. @@ -58,8 +57,8 @@ struct buflist { */ #define BUFHASH_SIZE 64 struct filestate { - struct buf *buf_next, *buf_prev; - struct buflist hashtbl[BUFHASH_SIZE]; + struct bufnode buflist; + struct bufnode hashtbl[BUFHASH_SIZE]; int file; int flags; POSITION fpos; @@ -69,8 +68,8 @@ struct filestate { POSITION fsize; }; -#define ch_bufhead thisfile->buf_next -#define ch_buftail thisfile->buf_prev +#define ch_bufhead thisfile->buflist.next +#define ch_buftail thisfile->buflist.prev #define ch_nbufs thisfile->nbufs #define ch_block thisfile->block #define ch_offset thisfile->offset @@ -79,23 +78,48 @@ struct filestate { #define ch_flags thisfile->flags #define ch_file thisfile->file -#define END_OF_CHAIN ((struct buf *)&thisfile->buf_next) -#define END_OF_HCHAIN(h) ((struct buf *)&thisfile->hashtbl[h]) +#define END_OF_CHAIN (&thisfile->buflist) +#define END_OF_HCHAIN(h) (&thisfile->hashtbl[h]) #define BUFHASH(blk) ((blk) & (BUFHASH_SIZE-1)) -#define FOR_BUFS_IN_CHAIN(h,bp) \ - for (bp = thisfile->hashtbl[h].buf_hnext; \ - bp != END_OF_HCHAIN(h); bp = bp->hnext) +/* + * Macros to manipulate the list of buffers in thisfile->buflist. + */ +#define FOR_BUFS(bn) \ + for (bn = ch_bufhead; bn != END_OF_CHAIN; bn = bn->next) -#define HASH_RM(bp) \ - (bp)->hnext->hprev = (bp)->hprev; \ - (bp)->hprev->hnext = (bp)->hnext; +#define BUF_RM(bn) \ + (bn)->next->prev = (bn)->prev; \ + (bn)->prev->next = (bn)->next; -#define HASH_INS(bp,h) \ - (bp)->hnext = thisfile->hashtbl[h].buf_hnext; \ - (bp)->hprev = END_OF_HCHAIN(h); \ - thisfile->hashtbl[h].buf_hnext->hprev = (bp); \ - thisfile->hashtbl[h].buf_hnext = (bp); +#define BUF_INS_HEAD(bn) \ + (bn)->next = ch_bufhead; \ + (bn)->prev = END_OF_CHAIN; \ + ch_bufhead->prev = (bn); \ + ch_bufhead = (bn); + +#define BUF_INS_TAIL(bn) \ + (bn)->next = END_OF_CHAIN; \ + (bn)->prev = ch_buftail; \ + ch_buftail->next = (bn); \ + ch_buftail = (bn); + +/* + * Macros to manipulate the list of buffers in thisfile->hashtbl[n]. + */ +#define FOR_BUFS_IN_CHAIN(h,bn) \ + for (bn = thisfile->hashtbl[h].hnext; \ + bn != END_OF_HCHAIN(h); bn = bn->hnext) + +#define BUF_HASH_RM(bn) \ + (bn)->hnext->hprev = (bn)->hprev; \ + (bn)->hprev->hnext = (bn)->hnext; + +#define BUF_HASH_INS(bn,h) \ + (bn)->hnext = thisfile->hashtbl[h].hnext; \ + (bn)->hprev = END_OF_HCHAIN(h); \ + thisfile->hashtbl[h].hnext->hprev = (bn); \ + thisfile->hashtbl[h].hnext = (bn); static struct filestate *thisfile; static int ch_ungotchar = -1; @@ -119,17 +143,12 @@ static int ch_addbuf(); /* * Get the character pointed to by the read pointer. - * ch_get() is a macro which is more efficient to call - * than fch_get (the function), in the usual case - * that the block desired is at the head of the chain. */ -#define ch_get() ((ch_block == ch_bufhead->block && \ - ch_offset < ch_bufhead->datasize) ? \ - ch_bufhead->data[ch_offset] : fch_get()) int -fch_get() +ch_get() { register struct buf *bp; + register struct bufnode *bn; register int n; register int slept; register int h; @@ -139,52 +158,69 @@ fch_get() if (thisfile == NULL) return (EOI); + /* + * Quick check for the common case where + * the desired char is in the head buffer. + */ + if (ch_bufhead != END_OF_CHAIN) + { + bp = bufnode_buf(ch_bufhead); + if (ch_block == bp->block && ch_offset < bp->datasize) + return bp->data[ch_offset]; + } + slept = FALSE; /* * Look for a buffer holding the desired block. */ h = BUFHASH(ch_block); - FOR_BUFS_IN_CHAIN(h, bp) + FOR_BUFS_IN_CHAIN(h, bn) { + bp = bufnode_buf(bn); if (bp->block == ch_block) { if (ch_offset >= bp->datasize) /* * Need more data in this buffer. */ - goto read_more; + break; goto found; } } - /* - * Block is not in a buffer. - * Take the least recently used buffer - * and read the desired block into it. - * If the LRU buffer has data in it, - * then maybe allocate a new buffer. - */ - if (ch_buftail == END_OF_CHAIN || ch_buftail->block != -1) + if (bn == END_OF_HCHAIN(h)) { /* - * There is no empty buffer to use. - * Allocate a new buffer if: - * 1. We can't seek on this file and -b is not in effect; or - * 2. We haven't allocated the max buffers for this file yet. + * Block is not in a buffer. + * Take the least recently used buffer + * and read the desired block into it. + * If the LRU buffer has data in it, + * then maybe allocate a new buffer. */ - if ((autobuf && !(ch_flags & CH_CANSEEK)) || - (maxbufs < 0 || ch_nbufs < maxbufs)) - if (ch_addbuf()) - /* - * Allocation failed: turn off autobuf. - */ - autobuf = OPT_OFF; + if (ch_buftail == END_OF_CHAIN || + bufnode_buf(ch_buftail)->block != -1) + { + /* + * There is no empty buffer to use. + * Allocate a new buffer if: + * 1. We can't seek on this file and -b is not in effect; or + * 2. We haven't allocated the max buffers for this file yet. + */ + if ((autobuf && !(ch_flags & CH_CANSEEK)) || + (maxbufs < 0 || ch_nbufs < maxbufs)) + if (ch_addbuf()) + /* + * Allocation failed: turn off autobuf. + */ + autobuf = OPT_OFF; + } + bn = ch_buftail; + bp = bufnode_buf(bn); + BUF_HASH_RM(bn); /* Remove from old hash chain. */ + bp->block = ch_block; + bp->datasize = 0; + BUF_HASH_INS(bn, h); /* Insert into new hash chain. */ } - bp = ch_buftail; - HASH_RM(bp); /* Remove from old hash chain. */ - bp->block = ch_block; - bp->datasize = 0; - HASH_INS(bp, h); /* Insert into new hash chain. */ read_more: pos = (ch_block * LBUFSIZE) + bp->datasize; @@ -309,24 +345,20 @@ fch_get() } found: - if (ch_bufhead != bp) + if (ch_bufhead != bn) { /* * Move the buffer to the head of the buffer chain. * This orders the buffer chain, most- to least-recently used. */ - bp->next->prev = bp->prev; - bp->prev->next = bp->next; - bp->next = ch_bufhead; - bp->prev = END_OF_CHAIN; - ch_bufhead->prev = bp; - ch_bufhead = bp; + BUF_RM(bn); + BUF_INS_HEAD(bn); /* * Move to head of hash chain too. */ - HASH_RM(bp); - HASH_INS(bp, h); + BUF_HASH_RM(bn); + BUF_HASH_INS(bn, h); } if (ch_offset >= bp->datasize) @@ -386,6 +418,7 @@ end_logfile() sync_logfile() { register struct buf *bp; + register struct bufnode *bn; int warned = FALSE; BLOCKNUM block; BLOCKNUM nblocks; @@ -393,24 +426,23 @@ sync_logfile() nblocks = (ch_fpos + LBUFSIZE - 1) / LBUFSIZE; for (block = 0; block < nblocks; block++) { - for (bp = ch_bufhead; ; bp = bp->next) + int wrote = FALSE; + FOR_BUFS(bn) { - if (bp == END_OF_CHAIN) - { - if (!warned) - { - error("Warning: log file is incomplete", - NULL_PARG); - warned = TRUE; - } - break; - } + bp = bufnode_buf(bn); if (bp->block == block) { write(logfile, (char *) bp->data, bp->datasize); + wrote = TRUE; break; } } + if (!wrote && !warned) + { + error("Warning: log file is incomplete", + NULL_PARG); + warned = TRUE; + } } } @@ -424,11 +456,13 @@ buffered(block) BLOCKNUM block; { register struct buf *bp; + register struct bufnode *bn; register int h; h = BUFHASH(block); - FOR_BUFS_IN_CHAIN(h, bp) + FOR_BUFS_IN_CHAIN(h, bn) { + bp = bufnode_buf(bn); if (bp->block == block) return (TRUE); } @@ -510,7 +544,8 @@ ch_end_seek() public int ch_beg_seek() { - register struct buf *bp, *firstbp; + register struct bufnode *bn; + register struct bufnode *firstbn; /* * Try a plain ch_seek first. @@ -522,13 +557,15 @@ ch_beg_seek() * Can't get to position 0. * Look thru the buffers for the one closest to position 0. */ - firstbp = bp = ch_bufhead; - if (bp == END_OF_CHAIN) + firstbn = ch_bufhead; + if (firstbn == END_OF_CHAIN) return (1); - while ((bp = bp->next) != END_OF_CHAIN) - if (bp->block < firstbp->block) - firstbp = bp; - ch_block = firstbp->block; + FOR_BUFS(bn) + { + if (bufnode_buf(bn)->block < bufnode_buf(firstbn)->block) + firstbn = bn; + } + ch_block = bufnode_buf(firstbn)->block; ch_offset = 0; return (0); } @@ -628,7 +665,7 @@ ch_setbufspace(bufspace) public void ch_flush() { - register struct buf *bp; + register struct bufnode *bn; if (thisfile == NULL) return; @@ -646,8 +683,10 @@ ch_flush() /* * Initialize all the buffers. */ - for (bp = ch_bufhead; bp != END_OF_CHAIN; bp = bp->next) - bp->block = -1; + FOR_BUFS(bn) + { + bufnode_buf(bn)->block = -1; + } /* * Figure out the size of the file, if we can. @@ -694,6 +733,7 @@ ch_flush() ch_addbuf() { register struct buf *bp; + register struct bufnode *bn; /* * Allocate and initialize a new buffer and link it @@ -704,11 +744,10 @@ ch_addbuf() return (1); ch_nbufs++; bp->block = -1; - bp->next = END_OF_CHAIN; - bp->prev = ch_buftail; - ch_buftail->next = bp; - ch_buftail = bp; - HASH_INS(bp, 0); + bn = &bp->node; + + BUF_INS_TAIL(bn); + BUF_HASH_INS(bn, 0); return (0); } @@ -722,8 +761,8 @@ init_hashtbl() for (h = 0; h < BUFHASH_SIZE; h++) { - thisfile->hashtbl[h].buf_hnext = END_OF_HCHAIN(h); - thisfile->hashtbl[h].buf_hprev = END_OF_HCHAIN(h); + thisfile->hashtbl[h].hnext = END_OF_HCHAIN(h); + thisfile->hashtbl[h].hprev = END_OF_HCHAIN(h); } } @@ -733,14 +772,13 @@ init_hashtbl() static void ch_delbufs() { - register struct buf *bp; + register struct bufnode *bn; while (ch_bufhead != END_OF_CHAIN) { - bp = ch_bufhead; - bp->next->prev = bp->prev; - bp->prev->next = bp->next; - free(bp); + bn = ch_bufhead; + BUF_RM(bn); + free(bufnode_buf(bn)); } ch_nbufs = 0; init_hashtbl(); @@ -786,7 +824,7 @@ ch_init(f, flags) */ thisfile = (struct filestate *) calloc(1, sizeof(struct filestate)); - thisfile->buf_next = thisfile->buf_prev = END_OF_CHAIN; + thisfile->buflist.next = thisfile->buflist.prev = END_OF_CHAIN; thisfile->nbufs = 0; thisfile->flags = 0; thisfile->fpos = 0; @@ -867,6 +905,7 @@ ch_getflags() ch_dump(struct filestate *fs) { struct buf *bp; + struct bufnode *bn; unsigned char *s; if (fs == NULL) @@ -878,8 +917,9 @@ ch_dump(struct filestate *fs) fs->file, fs->flags, fs->fpos, fs->fsize, fs->block, fs->offset); printf(" %d bufs:\n", fs->nbufs); - for (bp = fs->buf_next; bp != (struct buf *)fs; bp = bp->next) + for (bn = fs->next; bn != &fs->buflist; bn = bn->next) { + bp = bufnode_buf(bn); printf("%x: blk %x, size %x \"", bp, bp->block, bp->datasize); for (s = bp->data; s < bp->data + 30; s++) diff --git a/charset.c b/charset.c index 37d344de69f4..04ef8bf12ee6 100644 --- a/charset.c +++ b/charset.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -393,8 +393,10 @@ init_charset() */ public int binary_char(c) - unsigned char c; + LWCHAR c; { + if (utf_mode) + return (is_ubin_char(c)); c &= 0377; return (chardef[c] & IS_BINARY_CHAR); } @@ -404,7 +406,7 @@ binary_char(c) */ public int control_char(c) - int c; + LWCHAR c; { c &= 0377; return (chardef[c] & IS_CONTROL_CHAR); @@ -416,7 +418,7 @@ control_char(c) */ public char * prchar(c) - int c; + LWCHAR c; { /* {{ This buffer can be overrun if LESSBINFMT is a long string. }} */ static char buf[32]; @@ -811,7 +813,11 @@ static struct wchar_range comb_table[] = { * dated 2005-11-30T00:58:48Z */ static struct wchar_range ubin_table[] = { - { 0x0000, 0x001F} /* Cc */, { 0x007F, 0x009F} /* Cc */, + { 0x0000, 0x0007} /* Cc */, + { 0x000B, 0x000C} /* Cc */, + { 0x000E, 0x001A} /* Cc */, + { 0x001C, 0x001F} /* Cc */, + { 0x007F, 0x009F} /* Cc */, #if 0 { 0x00AD, 0x00AD} /* Cf */, #endif diff --git a/charset.h b/charset.h index 548033e1dcbf..57264bcddc76 100644 --- a/charset.h +++ b/charset.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2005-2007 Mark Nudelman + * Copyright (C) 2005-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/cmd.h b/cmd.h index 298d3672cd0b..6153a863b26e 100644 --- a/cmd.h +++ b/cmd.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -65,6 +65,7 @@ #define A_REMOVE_FILE 52 #define A_NEXT_TAG 53 #define A_PREV_TAG 54 +#define A_FILTER 55 #define A_INVALID 100 #define A_NOACTION 101 diff --git a/cmdbuf.c b/cmdbuf.c index ad79ce9b9096..1609ef74a54a 100644 --- a/cmdbuf.c +++ b/cmdbuf.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -662,12 +662,14 @@ set_mlist(mlist, cmdflags) void *mlist; int cmdflags; { +#if CMD_HISTORY curr_mlist = (struct mlist *) mlist; curr_cmdflags = cmdflags; /* Make sure the next up-arrow moves to the last string in the mlist. */ if (curr_mlist != NULL) curr_mlist->curr_mp = curr_mlist; +#endif } #if CMD_HISTORY @@ -1303,6 +1305,7 @@ get_cmdbuf() return (cmdbuf); } +#if CMD_HISTORY /* * Return the last (most recent) string in the current command history. */ @@ -1313,6 +1316,7 @@ cmd_lastpattern() return (NULL); return (curr_mlist->curr_mp->prev->string); } +#endif #if CMD_HISTORY /* @@ -1465,8 +1469,19 @@ save_cmdhist() if (f == NULL) return; #if HAVE_FCHMOD +{ /* Make history file readable only by owner. */ - fchmod(fileno(f), 0600); + int do_chmod = 1; +#if HAVE_STAT + struct stat statbuf; + int r = fstat(fileno(f), &statbuf); + if (r < 0 || !S_ISREG(statbuf.st_mode)) + /* Don't chmod if not a regular file. */ + do_chmod = 0; +#endif + if (do_chmod) + fchmod(fileno(f), 0600); +} #endif fprintf(f, "%s\n", HISTFILE_FIRST_LINE); diff --git a/command.c b/command.c index ef6dfa464e8c..3b15b1e444dc 100644 --- a/command.c +++ b/command.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -25,7 +25,6 @@ extern int erase_char, erase2_char, kill_char; extern int sigs; extern int quit_if_one_screen; extern int squished; -extern int hit_eof; extern int sc_width; extern int sc_height; extern int swindow; @@ -84,7 +83,9 @@ static void multi_search(); static void cmd_exec() { +#if HILITE_SEARCH clear_attn(); +#endif clear_bot(); flush(); } @@ -118,6 +119,11 @@ in_mca() static void mca_search() { +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + mca = A_FILTER; + else +#endif if (search_type & SRCH_FORW) mca = A_F_SEARCH; else @@ -137,6 +143,11 @@ mca_search() if (search_type & SRCH_NO_REGEX) cmd_putstr("Regex-off "); +#if HILITE_SEARCH + if (search_type & SRCH_FILTER) + cmd_putstr("&/"); + else +#endif if (search_type & SRCH_FORW) cmd_putstr("/"); else @@ -195,6 +206,12 @@ exec_mca() case A_B_SEARCH: multi_search(cbuf, (int) number); break; +#if HILITE_SEARCH + case A_FILTER: + search_type ^= SRCH_NO_MATCH; + set_filter_pattern(cbuf, search_type); + break; +#endif case A_FIRSTCMD: /* * Skip leading spaces or + signs in the string. @@ -467,6 +484,7 @@ mca_char(c) case A_F_SEARCH: case A_B_SEARCH: + case A_FILTER: /* * Special case for search commands. * Certain characters as the first char of @@ -486,14 +504,17 @@ mca_char(c) { case CONTROL('E'): /* ignore END of file */ case '*': - flag = SRCH_PAST_EOF; + if (mca != A_FILTER) + flag = SRCH_PAST_EOF; break; case CONTROL('F'): /* FIRST file */ case '@': - flag = SRCH_FIRST_FILE; + if (mca != A_FILTER) + flag = SRCH_FIRST_FILE; break; case CONTROL('K'): /* KEEP position */ - flag = SRCH_NO_MOVE; + if (mca != A_FILTER) + flag = SRCH_NO_MOVE; break; case CONTROL('R'): /* Don't use REGULAR EXPRESSIONS */ flag = SRCH_NO_REGEX; @@ -630,25 +651,20 @@ prompt() bottompos = position(BOTTOM_PLUS_ONE); /* - * If we've hit EOF on the last file, and the -E flag is set - * (or -F is set and this is the first prompt), then quit. - * {{ Relying on "first prompt" to detect a single-screen file - * fails if +G is used, for example. }} + * If we've hit EOF on the last file and the -E flag is set, quit. */ - if ((get_quit_at_eof() == OPT_ONPLUS || quit_if_one_screen) && - hit_eof && !(ch_getflags() & CH_HELPFILE) && + if (get_quit_at_eof() == OPT_ONPLUS && + eof_displayed() && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); - quit_if_one_screen = FALSE; -#if 0 /* This doesn't work well because some "te"s clear the screen. */ + /* - * If the -e flag is set and we've hit EOF on the last file, - * and the file is squished (shorter than the screen), quit. + * If the entire file is displayed and the -F flag is set, quit. */ - if (get_quit_at_eof() && squished && + if (quit_if_one_screen && + entire_file_displayed() && !(ch_getflags() & CH_HELPFILE) && next_ifile(curr_ifile) == NULL_IFILE) quit(QUIT_OK); -#endif #if MSDOS_COMPILER==WIN32C /* @@ -675,6 +691,8 @@ prompt() clear_cmd(); forw_prompt = 0; p = pr_string(); + if (is_filtering()) + putstr("& "); if (p == NULL || *p == '\0') putchr(':'); else @@ -1131,7 +1149,6 @@ commands() cmd_exec(); jump_forw(); ignore_eoi = 1; - hit_eof = 0; while (!sigs) { make_display(); @@ -1308,6 +1325,17 @@ commands() c = getcc(); goto again; + case A_FILTER: +#if HILITE_SEARCH + search_type = SRCH_FORW | SRCH_FILTER; + mca_search(); + c = getcc(); + goto again; +#else + error("Command not available", NULL_PARG); + break; +#endif + case A_AGAIN_SEARCH: /* * Repeat previous search. @@ -1432,7 +1460,7 @@ commands() number = 1; if (edit_next((int) number)) { - if (get_quit_at_eof() && hit_eof && + if (get_quit_at_eof() && eof_displayed() && !(ch_getflags() & CH_HELPFILE)) quit(QUIT_OK); parg.p_string = (number > 1) ? "(N-th) " : ""; @@ -1596,6 +1624,7 @@ commands() if (c == erase_char || c == erase2_char || c == kill_char || c == '\n' || c == '\r') break; + cmd_exec(); gomark(c); break; diff --git a/configure b/configure index 1d3f57aa4ff3..a417a53bfc2e 100755 --- a/configure +++ b/configure @@ -1,9 +1,9 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for less 1. +# Generated by GNU Autoconf 2.63 for less 1. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## @@ -15,7 +15,7 @@ DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST @@ -37,17 +37,45 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } fi # Support unset when possible. @@ -63,8 +91,6 @@ fi # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) -as_nl=' -' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. @@ -87,7 +113,7 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi @@ -100,17 +126,10 @@ PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && @@ -132,7 +151,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | +$as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -158,7 +177,7 @@ else as_have_required=no fi - if test $as_have_required = yes && (eval ": + if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } @@ -240,7 +259,7 @@ IFS=$as_save_IFS if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST @@ -261,7 +280,7 @@ _ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST @@ -341,10 +360,10 @@ fi if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV - do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - done - export CONFIG_SHELL - exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi @@ -413,9 +432,10 @@ fi test \$exitcode = 0") || { echo No shell found that supports shell functions. - echo Please tell autoconf@gnu.org about your system, - echo including any error possibly output before this - echo message + echo Please tell bug-autoconf@gnu.org about your system, + echo including any error possibly output before this message. + echo This can help us improve future autoconf versions. + echo Configuration will now proceed without shell functions. } @@ -451,7 +471,7 @@ test \$exitcode = 0") || { s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems @@ -479,7 +499,6 @@ case `echo -n x` in *) ECHO_N='-n';; esac - if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr @@ -492,19 +511,22 @@ if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir - mkdir conf$$.dir + mkdir conf$$.dir 2>/dev/null fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln + fi else as_ln_s='cp -p' fi @@ -529,10 +551,10 @@ else as_test_x=' eval sh -c '\'' if test -d "$1"; then - test -d "$1/."; + test -d "$1/."; else case $1 in - -*)set "./$1";; + -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi @@ -613,60 +635,67 @@ ac_includes_default="\ # include #endif" -ac_subst_vars='SHELL -PATH_SEPARATOR -PACKAGE_NAME -PACKAGE_TARNAME -PACKAGE_VERSION -PACKAGE_STRING -PACKAGE_BUGREPORT -exec_prefix -prefix -program_transform_name -bindir -sbindir -libexecdir -datarootdir -datadir -sysconfdir -sharedstatedir -localstatedir -includedir -oldincludedir -docdir -infodir -htmldir -dvidir -pdfdir -psdir -libdir -localedir -mandir -DEFS -ECHO_C -ECHO_N -ECHO_T -LIBS -build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -CPPFLAGS -ac_ct_CC -EXEEXT -OBJEXT -CPP -GREP -EGREP -INSTALL_PROGRAM -INSTALL_SCRIPT -INSTALL_DATA -REGEX_O +ac_subst_vars='LTLIBOBJS LIBOBJS -LTLIBOBJS' +REGEX_O +INSTALL_DATA +INSTALL_SCRIPT +INSTALL_PROGRAM +EGREP +GREP +CPP +OBJEXT +EXEEXT +ac_ct_CC +CPPFLAGS +LDFLAGS +CFLAGS +CC +target_alias +host_alias +build_alias +LIBS +ECHO_T +ECHO_N +ECHO_C +DEFS +mandir +localedir +libdir +psdir +pdfdir +dvidir +htmldir +infodir +docdir +oldincludedir +includedir +localstatedir +sharedstatedir +sysconfdir +datadir +datarootdir +libexecdir +sbindir +bindir +program_transform_name +prefix +exec_prefix +PACKAGE_BUGREPORT +PACKAGE_STRING +PACKAGE_VERSION +PACKAGE_TARNAME +PACKAGE_NAME +PATH_SEPARATOR +SHELL' ac_subst_files='' +ac_user_opts=' +enable_option_checking +enable_largefile +with_secure +with_regex +with_editor +' ac_precious_vars='build_alias host_alias target_alias @@ -681,6 +710,8 @@ CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false +ac_unrecognized_opts= +ac_unrecognized_sep= # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null @@ -779,13 +810,21 @@ do datarootdir=$ac_optarg ;; -disable-* | --disable-*) - ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=no ;; + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; @@ -798,13 +837,21 @@ do dvidir=$ac_optarg ;; -enable-* | --enable-*) - ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid feature name: $ac_useropt" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` - eval enable_$ac_feature=\$ac_optarg ;; + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"enable_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval enable_$ac_useropt=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ @@ -995,22 +1042,38 @@ do ac_init_version=: ;; -with-* | --with-*) - ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=\$ac_optarg ;; + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=\$ac_optarg ;; -without-* | --without-*) - ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid package name: $ac_package" >&2 + expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && + { $as_echo "$as_me: error: invalid package name: $ac_useropt" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` - eval with_$ac_package=no ;; + ac_useropt_orig=$ac_useropt + ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` + case $ac_user_opts in + *" +"with_$ac_useropt" +"*) ;; + *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" + ac_unrecognized_sep=', ';; + esac + eval with_$ac_useropt=no ;; --x) # Obsolete; use --with-x. @@ -1030,7 +1093,7 @@ do | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; - -*) { echo "$as_me: error: unrecognized option: $ac_option + -*) { $as_echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; @@ -1039,16 +1102,16 @@ Try \`$0 --help' for more information." >&2 ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && - { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { $as_echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. - echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; @@ -1057,22 +1120,38 @@ done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` - { echo "$as_me: error: missing argument to $ac_option" >&2 + { $as_echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi -# Be sure to have absolute directory names. +if test -n "$ac_unrecognized_opts"; then + case $enable_option_checking in + no) ;; + fatal) { $as_echo "$as_me: error: unrecognized options: $ac_unrecognized_opts" >&2 + { (exit 1); exit 1; }; } ;; + *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; + esac +fi + +# Check all directory arguments for consistency. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var + # Remove trailing slashes. + case $ac_val in + */ ) + ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` + eval $ac_var=\$ac_val;; + esac + # Be sure to have absolute directory names. case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac - { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { $as_echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done @@ -1087,7 +1166,7 @@ target=$target_alias if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe - echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes @@ -1103,10 +1182,10 @@ test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - { echo "$as_me: error: Working directory cannot be determined" >&2 + { $as_echo "$as_me: error: working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - { echo "$as_me: error: pwd does not report name of working directory" >&2 + { $as_echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } @@ -1114,12 +1193,12 @@ test "X$ac_ls_di" = "X$ac_pwd_ls_di" || if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$0" || -$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X"$0" | + ac_confdir=`$as_dirname -- "$as_myself" || +$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_myself" : 'X\(//\)[^/]' \| \ + X"$as_myself" : 'X\(//\)$' \| \ + X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$as_myself" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -1146,12 +1225,12 @@ else fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { $as_echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + cd "$srcdir" && test -r "./$ac_unique_file" || { $as_echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. @@ -1200,9 +1279,9 @@ Configuration: Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -1212,25 +1291,25 @@ for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/less] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/less] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF @@ -1244,6 +1323,7 @@ if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --disable-largefile omit support for large files @@ -1275,15 +1355,17 @@ fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || continue + test -d "$ac_dir" || + { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || + continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -1319,7 +1401,7 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix echo && $SHELL "$ac_srcdir/configure" --help=recursive else - echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done @@ -1329,10 +1411,10 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF less configure 1 -generated by GNU Autoconf 2.61 +generated by GNU Autoconf 2.63 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, -2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -1343,7 +1425,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by less $as_me 1, which was -generated by GNU Autoconf 2.61. Invocation command line was +generated by GNU Autoconf 2.63. Invocation command line was $ $0 $@ @@ -1379,7 +1461,7 @@ for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. - echo "PATH: $as_dir" + $as_echo "PATH: $as_dir" done IFS=$as_save_IFS @@ -1414,7 +1496,7 @@ do | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) - ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; @@ -1466,11 +1548,12 @@ _ASBOX case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac @@ -1500,9 +1583,9 @@ _ASBOX do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - echo "$ac_var='\''$ac_val'\''" + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo @@ -1517,9 +1600,9 @@ _ASBOX do eval ac_val=\$$ac_var case $ac_val in - *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac - echo "$ac_var='\''$ac_val'\''" + $as_echo "$ac_var='\''$ac_val'\''" done | sort echo fi @@ -1535,8 +1618,8 @@ _ASBOX echo fi test "$ac_signal" != 0 && - echo "$as_me: caught signal $ac_signal" - echo "$as_me: exit $exit_status" + $as_echo "$as_me: caught signal $ac_signal" + $as_echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && @@ -1578,21 +1661,24 @@ _ACEOF # Let the site file select an alternate cache file if it wants to. -# Prefer explicitly selected file to automatically selected ones. +# Prefer an explicitly selected file to automatically selected ones. +ac_site_file1=NONE +ac_site_file2=NONE if test -n "$CONFIG_SITE"; then - set x "$CONFIG_SITE" + ac_site_file1=$CONFIG_SITE elif test "x$prefix" != xNONE; then - set x "$prefix/share/config.site" "$prefix/etc/config.site" + ac_site_file1=$prefix/share/config.site + ac_site_file2=$prefix/etc/config.site else - set x "$ac_default_prefix/share/config.site" \ - "$ac_default_prefix/etc/config.site" + ac_site_file1=$ac_default_prefix/share/config.site + ac_site_file2=$ac_default_prefix/etc/config.site fi -shift -for ac_site_file +for ac_site_file in "$ac_site_file1" "$ac_site_file2" do + test "x$ac_site_file" = xNONE && continue if test -r "$ac_site_file"; then - { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 -echo "$as_me: loading site script $ac_site_file" >&6;} + { $as_echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +$as_echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi @@ -1602,16 +1688,16 @@ if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then - { echo "$as_me:$LINENO: loading cache $cache_file" >&5 -echo "$as_me: loading cache $cache_file" >&6;} + { $as_echo "$as_me:$LINENO: loading cache $cache_file" >&5 +$as_echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else - { echo "$as_me:$LINENO: creating cache $cache_file" >&5 -echo "$as_me: creating cache $cache_file" >&6;} + { $as_echo "$as_me:$LINENO: creating cache $cache_file" >&5 +$as_echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi @@ -1625,29 +1711,38 @@ for ac_var in $ac_precious_vars; do eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) - { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) - { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 -echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + { $as_echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 -echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 -echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 -echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: + # differences in whitespace do not lead to failure. + ac_old_val_w=`echo x $ac_old_val` + ac_new_val_w=`echo x $ac_new_val` + if test "$ac_old_val_w" != "$ac_new_val_w"; then + { $as_echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + ac_cache_corrupted=: + else + { $as_echo "$as_me:$LINENO: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 +$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} + eval $ac_var=\$ac_old_val + fi + { $as_echo "$as_me:$LINENO: former value: \`$ac_old_val'" >&5 +$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} + { $as_echo "$as_me:$LINENO: current value: \`$ac_new_val'" >&5 +$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in - *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in @@ -1657,10 +1752,12 @@ echo "$as_me: current value: $ac_new_val" >&2;} fi done if $ac_cache_corrupted; then - { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 -echo "$as_me: error: changes in the environment can compromise the build" >&2;} - { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 -echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} + { $as_echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { $as_echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +$as_echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi @@ -1708,10 +1805,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1724,7 +1821,7 @@ do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1735,11 +1832,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi @@ -1748,10 +1845,10 @@ if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1764,7 +1861,7 @@ do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1775,11 +1872,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi if test "x$ac_ct_CC" = x; then @@ -1787,12 +1884,8 @@ fi else case $cross_compiling:$ac_tool_warned in yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -1805,10 +1898,10 @@ if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1821,7 +1914,7 @@ do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1832,11 +1925,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi @@ -1845,10 +1938,10 @@ fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1866,7 +1959,7 @@ do continue fi ac_cv_prog_CC="cc" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1889,11 +1982,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi @@ -1904,10 +1997,10 @@ if test -z "$CC"; then do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. @@ -1920,7 +2013,7 @@ do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1931,11 +2024,11 @@ fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then - { echo "$as_me:$LINENO: result: $CC" >&5 -echo "${ECHO_T}$CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $CC" >&5 +$as_echo "$CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi @@ -1948,10 +2041,10 @@ if test -z "$CC"; then do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 -{ echo "$as_me:$LINENO: checking for $ac_word" >&5 -echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. @@ -1964,7 +2057,7 @@ do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" - echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done @@ -1975,11 +2068,11 @@ fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then - { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 -echo "${ECHO_T}$ac_ct_CC" >&6; } + { $as_echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 +$as_echo "$ac_ct_CC" >&6; } else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi @@ -1991,12 +2084,8 @@ done else case $cross_compiling:$ac_tool_warned in yes:) -{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&5 -echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools -whose name does not start with the host triplet. If you think this -configuration is useful to you, please write to autoconf@gnu.org." >&2;} +{ $as_echo "$as_me:$LINENO: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC @@ -2006,44 +2095,50 @@ fi fi -test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH +test -z "$CC" && { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 -echo "$as_me: error: no acceptable C compiler found in \$PATH +$as_echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { (exit 1); exit 1; }; }; } # Provide some information about the compiler. -echo "$as_me:$LINENO: checking for C compiler version" >&5 -ac_compiler=`set X $ac_compile; echo $2` +$as_echo "$as_me:$LINENO: checking for C compiler version" >&5 +set X $ac_compile +ac_compiler=$2 { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF @@ -2062,27 +2157,22 @@ main () } _ACEOF ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.exe b.out" +ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -{ echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 -echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } -ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` -# -# List of possible output files, starting from the most likely. -# The algorithm is not robust to junk in `.', hence go to wildcards (a.*) -# only as a last resort. b.out is created by i960 compilers. -ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' -# -# The IRIX 6 linker writes into existing files which may not be -# executable, retaining their permissions. Remove them first so a -# subsequent execution test works. +{ $as_echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +$as_echo_n "checking for C compiler default output file name... " >&6; } +ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` + +# The possible output files: +ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" + ac_rmfiles= for ac_file in $ac_files do case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done @@ -2093,10 +2183,11 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' @@ -2107,7 +2198,7 @@ for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most @@ -2134,25 +2225,27 @@ else ac_file='' fi -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_file" >&5 +$as_echo "$ac_file" >&6; } if test -z "$ac_file"; then - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: C compiler cannot create executables +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 -echo "$as_me: error: C compiler cannot create executables +$as_echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} - { (exit 77); exit 77; }; } + { (exit 77); exit 77; }; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether the C compiler works" >&5 -echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether the C compiler works" >&5 +$as_echo_n "checking whether the C compiler works... " >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then @@ -2161,49 +2254,53 @@ if test "$cross_compiling" != yes; then *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else - { { echo "$as_me:$LINENO: error: cannot run C compiled programs. + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 -echo "$as_me: error: cannot run C compiled programs. +$as_echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { (exit 1); exit 1; }; }; } fi fi fi -{ echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } +{ $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; } -rm -f a.out a.exe conftest$ac_cv_exeext b.out +rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. -{ echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 -echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } -{ echo "$as_me:$LINENO: result: $cross_compiling" >&5 -echo "${ECHO_T}$cross_compiling" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 +$as_echo_n "checking whether we are cross compiling... " >&6; } +{ $as_echo "$as_me:$LINENO: result: $cross_compiling" >&5 +$as_echo "$cross_compiling" >&6; } -{ echo "$as_me:$LINENO: checking for suffix of executables" >&5 -echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for suffix of executables" >&5 +$as_echo_n "checking for suffix of executables... " >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will @@ -2212,31 +2309,33 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else - { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of executables: cannot compile and link +$as_echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { (exit 1); exit 1; }; }; } fi rm -f conftest$ac_cv_exeext -{ echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 -echo "${ECHO_T}$ac_cv_exeext" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 +$as_echo "$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT -{ echo "$as_me:$LINENO: checking for suffix of object files" >&5 -echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for suffix of object files" >&5 +$as_echo_n "checking for suffix of object files... " >&6; } if test "${ac_cv_objext+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -2259,40 +2358,43 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; + *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 -{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile +{ { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 -echo "$as_me: error: cannot compute suffix of object files: cannot compile +$as_echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { (exit 1); exit 1; }; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 -echo "${ECHO_T}$ac_cv_objext" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 +$as_echo "$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT -{ echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 -echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 +$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -2318,20 +2420,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no @@ -2341,15 +2444,19 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 -echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } -GCC=`test $ac_compiler_gnu = yes && echo yes` +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 +$as_echo "$ac_cv_c_compiler_gnu" >&6; } +if test $ac_compiler_gnu = yes; then + GCC=yes +else + GCC= +fi ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS -{ echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 -echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 +$as_echo_n "checking whether $CC accepts -g... " >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes @@ -2376,20 +2483,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" @@ -2414,20 +2522,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag @@ -2453,20 +2562,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -2481,8 +2591,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 +$as_echo "$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then @@ -2498,10 +2608,10 @@ else CFLAGS= fi fi -{ echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 -echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 +$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC @@ -2572,20 +2682,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -2601,15 +2712,15 @@ fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) - { echo "$as_me:$LINENO: result: none needed" >&5 -echo "${ECHO_T}none needed" >&6; } ;; + { $as_echo "$as_me:$LINENO: result: none needed" >&5 +$as_echo "none needed" >&6; } ;; xno) - { echo "$as_me:$LINENO: result: unsupported" >&5 -echo "${ECHO_T}unsupported" >&6; } ;; + { $as_echo "$as_me:$LINENO: result: unsupported" >&5 +$as_echo "unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" - { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 -echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; + { $as_echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 +$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; esac @@ -2620,10 +2731,10 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking for library containing strerror" >&5 -echo $ECHO_N "checking for library containing strerror... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for library containing strerror" >&5 +$as_echo_n "checking for library containing strerror... " >&6; } if test "${ac_cv_search_strerror+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF @@ -2661,26 +2772,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_search_strerror=$ac_res else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_strerror+set}" = set; then @@ -2695,8 +2810,8 @@ fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 -echo "${ECHO_T}$ac_cv_search_strerror" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_strerror" >&5 +$as_echo "$ac_cv_search_strerror" >&6; } ac_res=$ac_cv_search_strerror if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" @@ -2708,15 +2823,15 @@ ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 -echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 +$as_echo_n "checking how to run the C preprocessor... " >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" @@ -2748,20 +2863,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. @@ -2785,13 +2901,14 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err @@ -2799,7 +2916,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. @@ -2824,8 +2941,8 @@ fi else ac_cv_prog_CPP=$CPP fi -{ echo "$as_me:$LINENO: result: $CPP" >&5 -echo "${ECHO_T}$CPP" >&6; } +{ $as_echo "$as_me:$LINENO: result: $CPP" >&5 +$as_echo "$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do @@ -2853,20 +2970,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. @@ -2890,13 +3008,14 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err @@ -2904,7 +3023,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 # Broken: success on invalid input. continue else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. @@ -2920,11 +3039,13 @@ rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else - { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check + { { $as_echo "$as_me:$LINENO: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +{ { $as_echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 -echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check +$as_echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} - { (exit 1); exit 1; }; } + { (exit 1); exit 1; }; }; } fi ac_ext=c @@ -2934,42 +3055,37 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $ ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 -echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 +$as_echo_n "checking for grep that handles long lines and -e... " >&6; } if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - # Extract the first word of "grep ggrep" to use in msg output -if test -z "$GREP"; then -set dummy grep ggrep; ac_prog_name=$2 -if test "${ac_cv_path_GREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else + if test -z "$GREP"; then ac_path_GREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue - # Check for GNU ac_path_GREP and select it if it is found. + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue +# Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - echo 'GREP' >> "conftest.nl" + $as_echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` @@ -2984,74 +3100,60 @@ case `"$ac_path_GREP" --version 2>&1` in rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac - - $ac_path_GREP_found && break 3 + $ac_path_GREP_found && break 3 + done done done - -done IFS=$as_save_IFS - - -fi - -GREP="$ac_cv_path_GREP" -if test -z "$GREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + if test -z "$ac_cv_path_GREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } -fi - + fi else ac_cv_path_GREP=$GREP fi - fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 -echo "${ECHO_T}$ac_cv_path_GREP" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 +$as_echo "$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" -{ echo "$as_me:$LINENO: checking for egrep" >&5 -echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for egrep" >&5 +$as_echo_n "checking for egrep... " >&6; } if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else - # Extract the first word of "egrep" to use in msg output -if test -z "$EGREP"; then -set dummy egrep; ac_prog_name=$2 -if test "${ac_cv_path_EGREP+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else + if test -z "$EGREP"; then ac_path_EGREP_found=false -# Loop through the user's path and test for each of PROGNAME-LIST -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR + # Loop through the user's path and test for each of PROGNAME-LIST + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue - # Check for GNU ac_path_EGREP and select it if it is found. + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" + { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue +# Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" + $as_echo_n 0123456789 >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" - echo 'EGREP' >> "conftest.nl" + $as_echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` @@ -3066,41 +3168,32 @@ case `"$ac_path_EGREP" --version 2>&1` in rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac - - $ac_path_EGREP_found && break 3 + $ac_path_EGREP_found && break 3 + done done done - -done IFS=$as_save_IFS - - -fi - -EGREP="$ac_cv_path_EGREP" -if test -z "$EGREP"; then - { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 -echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} + if test -z "$ac_cv_path_EGREP"; then + { { $as_echo "$as_me:$LINENO: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 +$as_echo "$as_me: error: no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } -fi - + fi else ac_cv_path_EGREP=$EGREP fi - fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 -echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 +$as_echo "$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" if test $ac_cv_c_compiler_gnu = yes; then - { echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 -echo $ECHO_N "checking whether $CC needs -traditional... $ECHO_C" >&6; } + { $as_echo "$as_me:$LINENO: checking whether $CC needs -traditional" >&5 +$as_echo_n "checking whether $CC needs -traditional... " >&6; } if test "${ac_cv_prog_gcc_traditional+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_pattern="Autoconf.*'x'" cat >conftest.$ac_ext <<_ACEOF @@ -3139,8 +3232,8 @@ rm -f conftest* fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 -echo "${ECHO_T}$ac_cv_prog_gcc_traditional" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_prog_gcc_traditional" >&5 +$as_echo "$ac_cv_prog_gcc_traditional" >&6; } if test $ac_cv_prog_gcc_traditional = yes; then CC="$CC -traditional" fi @@ -3163,8 +3256,8 @@ for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do fi done if test -z "$ac_aux_dir"; then - { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 -echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { { $as_echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +$as_echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi @@ -3190,11 +3283,12 @@ ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. -{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 -echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +# Reject install programs that cannot install multiple files. +{ $as_echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +$as_echo_n "checking for a BSD-compatible install... " >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH @@ -3223,17 +3317,29 @@ case $as_dir/ in # program-specific install script used by HP pwplus--don't use. : else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 + rm -rf conftest.one conftest.two conftest.dir + echo one > conftest.one + echo two > conftest.two + mkdir conftest.dir + if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && + test -s conftest.one && test -s conftest.two && + test -s conftest.dir/conftest.one && + test -s conftest.dir/conftest.two + then + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi fi fi done done ;; esac + done IFS=$as_save_IFS +rm -rf conftest.one conftest.two conftest.dir fi if test "${ac_cv_path_install+set}" = set; then @@ -3246,8 +3352,8 @@ fi INSTALL=$ac_install_sh fi fi -{ echo "$as_me:$LINENO: result: $INSTALL" >&5 -echo "${ECHO_T}$INSTALL" >&6; } +{ $as_echo "$as_me:$LINENO: result: $INSTALL" >&5 +$as_echo "$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. @@ -3266,10 +3372,10 @@ fi if test "$enable_largefile" != no; then - { echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 -echo $ECHO_N "checking for special C compiler options needed for large files... $ECHO_C" >&6; } + { $as_echo "$as_me:$LINENO: checking for special C compiler options needed for large files" >&5 +$as_echo_n "checking for special C compiler options needed for large files... " >&6; } if test "${ac_cv_sys_largefile_CC+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_cv_sys_largefile_CC=no if test "$GCC" != yes; then @@ -3306,20 +3412,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3333,20 +3440,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_largefile_CC=' -n32'; break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3359,16 +3467,16 @@ rm -f core conftest.err conftest.$ac_objext rm -f conftest.$ac_ext fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 -echo "${ECHO_T}$ac_cv_sys_largefile_CC" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_largefile_CC" >&5 +$as_echo "$ac_cv_sys_largefile_CC" >&6; } if test "$ac_cv_sys_largefile_CC" != no; then CC=$CC$ac_cv_sys_largefile_CC fi - { echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -echo $ECHO_N "checking for _FILE_OFFSET_BITS value needed for large files... $ECHO_C" >&6; } + { $as_echo "$as_me:$LINENO: checking for _FILE_OFFSET_BITS value needed for large files" >&5 +$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } if test "${ac_cv_sys_file_offset_bits+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF @@ -3400,20 +3508,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=no; break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3450,20 +3559,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_file_offset_bits=64; break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3474,8 +3584,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext break done fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 -echo "${ECHO_T}$ac_cv_sys_file_offset_bits" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_file_offset_bits" >&5 +$as_echo "$ac_cv_sys_file_offset_bits" >&6; } case $ac_cv_sys_file_offset_bits in #( no | unknown) ;; *) @@ -3484,12 +3594,12 @@ cat >>confdefs.h <<_ACEOF _ACEOF ;; esac -rm -f conftest* +rm -rf conftest* if test $ac_cv_sys_file_offset_bits = unknown; then - { echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 -echo $ECHO_N "checking for _LARGE_FILES value needed for large files... $ECHO_C" >&6; } + { $as_echo "$as_me:$LINENO: checking for _LARGE_FILES value needed for large files" >&5 +$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } if test "${ac_cv_sys_large_files+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else while :; do cat >conftest.$ac_ext <<_ACEOF @@ -3521,20 +3631,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=no; break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3571,20 +3682,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_sys_large_files=1; break else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -3595,8 +3707,8 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext break done fi -{ echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 -echo "${ECHO_T}$ac_cv_sys_large_files" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_sys_large_files" >&5 +$as_echo "$ac_cv_sys_large_files" >&6; } case $ac_cv_sys_large_files in #( no | unknown) ;; *) @@ -3605,16 +3717,16 @@ cat >>confdefs.h <<_ACEOF _ACEOF ;; esac -rm -f conftest* +rm -rf conftest* fi fi # Checks for general libraries. -{ echo "$as_me:$LINENO: checking for tgoto in -ltinfo" >&5 -echo $ECHO_N "checking for tgoto in -ltinfo... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for tgoto in -ltinfo" >&5 +$as_echo_n "checking for tgoto in -ltinfo... " >&6; } if test "${ac_cv_lib_tinfo_tgoto+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltinfo $LIBS" @@ -3646,42 +3758,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_tinfo_tgoto=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_tinfo_tgoto=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_tinfo_tgoto" >&5 -echo "${ECHO_T}$ac_cv_lib_tinfo_tgoto" >&6; } -if test $ac_cv_lib_tinfo_tgoto = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_tinfo_tgoto" >&5 +$as_echo "$ac_cv_lib_tinfo_tgoto" >&6; } +if test "x$ac_cv_lib_tinfo_tgoto" = x""yes; then have_tinfo=yes else have_tinfo=no fi -{ echo "$as_me:$LINENO: checking for initscr in -lxcurses" >&5 -echo $ECHO_N "checking for initscr in -lxcurses... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for initscr in -lxcurses" >&5 +$as_echo_n "checking for initscr in -lxcurses... " >&6; } if test "${ac_cv_lib_xcurses_initscr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lxcurses $LIBS" @@ -3713,42 +3829,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_xcurses_initscr=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_xcurses_initscr=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_xcurses_initscr" >&5 -echo "${ECHO_T}$ac_cv_lib_xcurses_initscr" >&6; } -if test $ac_cv_lib_xcurses_initscr = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_xcurses_initscr" >&5 +$as_echo "$ac_cv_lib_xcurses_initscr" >&6; } +if test "x$ac_cv_lib_xcurses_initscr" = x""yes; then have_xcurses=yes else have_xcurses=no fi -{ echo "$as_me:$LINENO: checking for initscr in -lncursesw" >&5 -echo $ECHO_N "checking for initscr in -lncursesw... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for initscr in -lncursesw" >&5 +$as_echo_n "checking for initscr in -lncursesw... " >&6; } if test "${ac_cv_lib_ncursesw_initscr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncursesw $LIBS" @@ -3780,42 +3900,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_ncursesw_initscr=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ncursesw_initscr=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_ncursesw_initscr" >&5 -echo "${ECHO_T}$ac_cv_lib_ncursesw_initscr" >&6; } -if test $ac_cv_lib_ncursesw_initscr = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ncursesw_initscr" >&5 +$as_echo "$ac_cv_lib_ncursesw_initscr" >&6; } +if test "x$ac_cv_lib_ncursesw_initscr" = x""yes; then have_ncursesw=yes else have_ncursesw=no fi -{ echo "$as_me:$LINENO: checking for initscr in -lncurses" >&5 -echo $ECHO_N "checking for initscr in -lncurses... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for initscr in -lncurses" >&5 +$as_echo_n "checking for initscr in -lncurses... " >&6; } if test "${ac_cv_lib_ncurses_initscr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lncurses $LIBS" @@ -3847,42 +3971,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_ncurses_initscr=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ncurses_initscr=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_initscr" >&5 -echo "${ECHO_T}$ac_cv_lib_ncurses_initscr" >&6; } -if test $ac_cv_lib_ncurses_initscr = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_ncurses_initscr" >&5 +$as_echo "$ac_cv_lib_ncurses_initscr" >&6; } +if test "x$ac_cv_lib_ncurses_initscr" = x""yes; then have_ncurses=yes else have_ncurses=no fi -{ echo "$as_me:$LINENO: checking for initscr in -lcurses" >&5 -echo $ECHO_N "checking for initscr in -lcurses... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for initscr in -lcurses" >&5 +$as_echo_n "checking for initscr in -lcurses... " >&6; } if test "${ac_cv_lib_curses_initscr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcurses $LIBS" @@ -3914,42 +4042,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_curses_initscr=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_curses_initscr=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_curses_initscr" >&5 -echo "${ECHO_T}$ac_cv_lib_curses_initscr" >&6; } -if test $ac_cv_lib_curses_initscr = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_curses_initscr" >&5 +$as_echo "$ac_cv_lib_curses_initscr" >&6; } +if test "x$ac_cv_lib_curses_initscr" = x""yes; then have_curses=yes else have_curses=no fi -{ echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5 -echo $ECHO_N "checking for tgetent in -ltermcap... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for tgetent in -ltermcap" >&5 +$as_echo_n "checking for tgetent in -ltermcap... " >&6; } if test "${ac_cv_lib_termcap_tgetent+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermcap $LIBS" @@ -3981,42 +4113,46 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_termcap_tgetent=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_termcap_tgetent=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5 -echo "${ECHO_T}$ac_cv_lib_termcap_tgetent" >&6; } -if test $ac_cv_lib_termcap_tgetent = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_termcap_tgetent" >&5 +$as_echo "$ac_cv_lib_termcap_tgetent" >&6; } +if test "x$ac_cv_lib_termcap_tgetent" = x""yes; then have_termcap=yes else have_termcap=no fi -{ echo "$as_me:$LINENO: checking for tgetent in -ltermlib" >&5 -echo $ECHO_N "checking for tgetent in -ltermlib... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for tgetent in -ltermlib" >&5 +$as_echo_n "checking for tgetent in -ltermlib... " >&6; } if test "${ac_cv_lib_termlib_tgetent+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-ltermlib $LIBS" @@ -4048,33 +4184,37 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_termlib_tgetent=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_termlib_tgetent=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_termlib_tgetent" >&5 -echo "${ECHO_T}$ac_cv_lib_termlib_tgetent" >&6; } -if test $ac_cv_lib_termlib_tgetent = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_termlib_tgetent" >&5 +$as_echo "$ac_cv_lib_termlib_tgetent" >&6; } +if test "x$ac_cv_lib_termlib_tgetent" = x""yes; then have_termlib=yes else have_termlib=no @@ -4083,10 +4223,10 @@ fi # Regular expressions (regcmp) are in -lgen on Solaris 2, # and in -lintl on SCO Unix. -{ echo "$as_me:$LINENO: checking for regcmp in -lgen" >&5 -echo $ECHO_N "checking for regcmp in -lgen... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for regcmp in -lgen" >&5 +$as_echo_n "checking for regcmp in -lgen... " >&6; } if test "${ac_cv_lib_gen_regcmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgen $LIBS" @@ -4118,33 +4258,37 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_gen_regcmp=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gen_regcmp=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_gen_regcmp" >&5 -echo "${ECHO_T}$ac_cv_lib_gen_regcmp" >&6; } -if test $ac_cv_lib_gen_regcmp = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_gen_regcmp" >&5 +$as_echo "$ac_cv_lib_gen_regcmp" >&6; } +if test "x$ac_cv_lib_gen_regcmp" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBGEN 1 _ACEOF @@ -4154,10 +4298,10 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for regcmp in -lintl" >&5 -echo $ECHO_N "checking for regcmp in -lintl... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for regcmp in -lintl" >&5 +$as_echo_n "checking for regcmp in -lintl... " >&6; } if test "${ac_cv_lib_intl_regcmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lintl $LIBS" @@ -4189,33 +4333,37 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_intl_regcmp=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_intl_regcmp=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_regcmp" >&5 -echo "${ECHO_T}$ac_cv_lib_intl_regcmp" >&6; } -if test $ac_cv_lib_intl_regcmp = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_intl_regcmp" >&5 +$as_echo "$ac_cv_lib_intl_regcmp" >&6; } +if test "x$ac_cv_lib_intl_regcmp" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBINTL 1 _ACEOF @@ -4225,10 +4373,10 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for regcmp in -lPW" >&5 -echo $ECHO_N "checking for regcmp in -lPW... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for regcmp in -lPW" >&5 +$as_echo_n "checking for regcmp in -lPW... " >&6; } if test "${ac_cv_lib_PW_regcmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lPW $LIBS" @@ -4260,33 +4408,37 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_PW_regcmp=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_PW_regcmp=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_PW_regcmp" >&5 -echo "${ECHO_T}$ac_cv_lib_PW_regcmp" >&6; } -if test $ac_cv_lib_PW_regcmp = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_PW_regcmp" >&5 +$as_echo "$ac_cv_lib_PW_regcmp" >&6; } +if test "x$ac_cv_lib_PW_regcmp" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPW 1 _ACEOF @@ -4297,8 +4449,8 @@ fi # Checks for terminal libraries -{ echo "$as_me:$LINENO: checking for working terminal libraries" >&5 -echo $ECHO_N "checking for working terminal libraries... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for working terminal libraries" >&5 +$as_echo_n "checking for working terminal libraries... " >&6; } TERMLIBS= # Check for systems where curses is broken. @@ -4341,26 +4493,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4395,26 +4551,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4449,26 +4609,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4503,26 +4667,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4557,26 +4725,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4612,26 +4784,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4668,26 +4844,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4722,26 +4902,30 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then termok=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 termok=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$SAVE_LIBS @@ -4750,19 +4934,19 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ fi if test "x$TERMLIBS" = x; then - { echo "$as_me:$LINENO: result: Cannot find terminal libraries - configure failed" >&5 -echo "${ECHO_T}Cannot find terminal libraries - configure failed" >&6; } + { $as_echo "$as_me:$LINENO: result: Cannot find terminal libraries - configure failed" >&5 +$as_echo "Cannot find terminal libraries - configure failed" >&6; } exit 1 fi -{ echo "$as_me:$LINENO: result: using $TERMLIBS" >&5 -echo "${ECHO_T}using $TERMLIBS" >&6; } +{ $as_echo "$as_me:$LINENO: result: using $TERMLIBS" >&5 +$as_echo "using $TERMLIBS" >&6; } LIBS="$LIBS $TERMLIBS" # Checks for header files. -{ echo "$as_me:$LINENO: checking for ANSI C header files" >&5 -echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for ANSI C header files" >&5 +$as_echo_n "checking for ANSI C header files... " >&6; } if test "${ac_cv_header_stdc+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -4789,20 +4973,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no @@ -4894,37 +5079,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi +rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 -echo "${ECHO_T}$ac_cv_header_stdc" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 +$as_echo "$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF @@ -4946,11 +5134,11 @@ fi for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -4968,20 +5156,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" @@ -4989,12 +5178,15 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_Header'}'` = yes; then +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -5020,20 +5212,21 @@ done for ac_header in ctype.h errno.h fcntl.h limits.h stdio.h stdlib.h string.h termcap.h termio.h termios.h time.h unistd.h values.h sys/ioctl.h sys/stream.h wctype.h do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } + { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } else # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5 +$as_echo_n "checking $ac_header usability... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5049,32 +5242,33 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +$as_echo "$ac_header_compiler" >&6; } # Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5 +$as_echo_n "checking $ac_header presence... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5088,69 +5282,73 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +$as_echo "$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +$as_echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +$as_echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} ;; esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5 +$as_echo_n "checking for $ac_header... " >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else eval "$as_ac_Header=\$ac_header_preproc" fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } +ac_res=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then +as_val=`eval 'as_val=${'$as_ac_Header'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi @@ -5159,10 +5357,10 @@ done # Checks for typedefs, structures, and compiler characteristics. -{ echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5 -echo $ECHO_N "checking whether stat file-mode macros are broken... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether stat file-mode macros are broken" >&5 +$as_echo_n "checking whether stat file-mode macros are broken... " >&6; } if test "${ac_cv_header_stat_broken+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5196,20 +5394,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stat_broken=no else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stat_broken=yes @@ -5217,8 +5416,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 -echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 +$as_echo "$ac_cv_header_stat_broken" >&6; } if test $ac_cv_header_stat_broken = yes; then cat >>confdefs.h <<\_ACEOF @@ -5227,10 +5426,10 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 -echo $ECHO_N "checking for an ANSI C-conforming const... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5 +$as_echo_n "checking for an ANSI C-conforming const... " >&6; } if test "${ac_cv_c_const+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5302,20 +5501,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_c_const=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_c_const=no @@ -5323,36 +5523,34 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 -echo "${ECHO_T}$ac_cv_c_const" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_c_const" >&5 +$as_echo "$ac_cv_c_const" >&6; } if test $ac_cv_c_const = no; then cat >>confdefs.h <<\_ACEOF -#define const +#define const /**/ _ACEOF fi -{ echo "$as_me:$LINENO: checking for off_t" >&5 -echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for off_t" >&5 +$as_echo_n "checking for off_t... " >&6; } if test "${ac_cv_type_off_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF + ac_cv_type_off_t=no +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default -typedef off_t ac__type_new_; int main () { -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; +if (sizeof (off_t)) + return 0; ; return 0; } @@ -5363,30 +5561,73 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - ac_cv_type_off_t=yes + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((off_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_type_off_t=no + ac_cv_type_off_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 -echo "${ECHO_T}$ac_cv_type_off_t" >&6; } -if test $ac_cv_type_off_t = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +$as_echo "$ac_cv_type_off_t" >&6; } +if test "x$ac_cv_type_off_t" = x""yes; then : else @@ -5396,26 +5637,24 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for size_t" >&5 -echo $ECHO_N "checking for size_t... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for size_t" >&5 +$as_echo_n "checking for size_t... " >&6; } if test "${ac_cv_type_size_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF + ac_cv_type_size_t=no +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default -typedef size_t ac__type_new_; int main () { -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; +if (sizeof (size_t)) + return 0; ; return 0; } @@ -5426,30 +5665,73 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - ac_cv_type_size_t=yes + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((size_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_type_size_t=no + ac_cv_type_size_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 -echo "${ECHO_T}$ac_cv_type_size_t" >&6; } -if test $ac_cv_type_size_t = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5 +$as_echo "$ac_cv_type_size_t" >&6; } +if test "x$ac_cv_type_size_t" = x""yes; then : else @@ -5459,10 +5741,10 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 -echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5 +$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; } if test "${ac_cv_header_time+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5489,20 +5771,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_time=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_time=no @@ -5510,8 +5793,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 -echo "${ECHO_T}$ac_cv_header_time" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5 +$as_echo "$ac_cv_header_time" >&6; } if test $ac_cv_header_time = yes; then cat >>confdefs.h <<\_ACEOF @@ -5576,26 +5859,24 @@ fi # Checks for identifiers. -{ echo "$as_me:$LINENO: checking for off_t" >&5 -echo $ECHO_N "checking for off_t... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for off_t" >&5 +$as_echo_n "checking for off_t... " >&6; } if test "${ac_cv_type_off_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF + ac_cv_type_off_t=no +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default -typedef off_t ac__type_new_; int main () { -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; +if (sizeof (off_t)) + return 0; ; return 0; } @@ -5606,30 +5887,73 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - ac_cv_type_off_t=yes + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +int +main () +{ +if (sizeof ((off_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_type_off_t=no + ac_cv_type_off_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 -echo "${ECHO_T}$ac_cv_type_off_t" >&6; } -if test $ac_cv_type_off_t = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_off_t" >&5 +$as_echo "$ac_cv_type_off_t" >&6; } +if test "x$ac_cv_type_off_t" = x""yes; then : else @@ -5639,8 +5963,8 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for void" >&5 -echo $ECHO_N "checking for void... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for void" >&5 +$as_echo_n "checking for void... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5662,33 +5986,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_VOID 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for const" >&5 -echo $ECHO_N "checking for const... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for const" >&5 +$as_echo_n "checking for const... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5710,33 +6035,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_CONST 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for time_t" >&5 -echo $ECHO_N "checking for time_t... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for time_t" >&5 +$as_echo_n "checking for time_t... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5758,33 +6084,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_TIME_T 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for st_ino in struct stat" >&5 -echo $ECHO_N "checking for st_ino in struct stat... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for st_ino in struct stat" >&5 +$as_echo_n "checking for st_ino in struct stat... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -5807,37 +6134,38 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_STAT_INO 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext # Checks for library functions. -{ echo "$as_me:$LINENO: checking return type of signal handlers" >&5 -echo $ECHO_N "checking return type of signal handlers... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking return type of signal handlers" >&5 +$as_echo_n "checking return type of signal handlers... " >&6; } if test "${ac_cv_type_signal+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5862,20 +6190,21 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_type_signal=int else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_type_signal=void @@ -5883,8 +6212,8 @@ fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 -echo "${ECHO_T}$ac_cv_type_signal" >&6; } +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_signal" >&5 +$as_echo "$ac_cv_type_signal" >&6; } cat >>confdefs.h <<_ACEOF #define RETSIGTYPE $ac_cv_type_signal @@ -5902,11 +6231,11 @@ _ACEOF for ac_func in fsync popen _setjmp sigprocmask sigsetmask snprintf stat system fchmod do -as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` -{ echo "$as_me:$LINENO: checking for $ac_func" >&5 -echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } +as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` +{ $as_echo "$as_me:$LINENO: checking for $ac_func" >&5 +$as_echo_n "checking for $ac_func... " >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -5959,35 +6288,42 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then eval "$as_ac_var=yes" else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -ac_res=`eval echo '${'$as_ac_var'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -if test `eval echo '${'$as_ac_var'}'` = yes; then +ac_res=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + { $as_echo "$as_me:$LINENO: result: $ac_res" >&5 +$as_echo "$ac_res" >&6; } +as_val=`eval 'as_val=${'$as_ac_var'} + $as_echo "$as_val"'` + if test "x$as_val" = x""yes; then cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 +#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi @@ -5995,8 +6331,8 @@ done # AC_CHECK_FUNCS may not work for inline functions, so test these separately. -{ echo "$as_me:$LINENO: checking for memcpy" >&5 -echo $ECHO_N "checking for memcpy... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for memcpy" >&5 +$as_echo_n "checking for memcpy... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6021,36 +6357,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_MEMCPY 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for strchr" >&5 -echo $ECHO_N "checking for strchr... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for strchr" >&5 +$as_echo_n "checking for strchr... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6075,36 +6415,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_STRCHR 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for strstr" >&5 -echo $ECHO_N "checking for strstr... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for strstr" >&5 +$as_echo_n "checking for strstr... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6129,39 +6473,43 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_STRSTR 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Some systems have termios.h but not the corresponding functions. -{ echo "$as_me:$LINENO: checking for tcgetattr" >&5 -echo $ECHO_N "checking for tcgetattr... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for tcgetattr" >&5 +$as_echo_n "checking for tcgetattr... " >&6; } if test "${ac_cv_func_tcgetattr+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -6214,32 +6562,36 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_func_tcgetattr=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_tcgetattr=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_tcgetattr" >&5 -echo "${ECHO_T}$ac_cv_func_tcgetattr" >&6; } -if test $ac_cv_func_tcgetattr = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_tcgetattr" >&5 +$as_echo "$ac_cv_func_tcgetattr" >&6; } +if test "x$ac_cv_func_tcgetattr" = x""yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_TERMIOS_FUNCS 1 _ACEOF @@ -6247,8 +6599,8 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for fileno" >&5 -echo $ECHO_N "checking for fileno... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for fileno" >&5 +$as_echo_n "checking for fileno... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6273,36 +6625,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_FILENO 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for strerror" >&5 -echo $ECHO_N "checking for strerror... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for strerror" >&5 +$as_echo_n "checking for strerror... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6333,36 +6689,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_STRERROR 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for sys_errlist" >&5 -echo $ECHO_N "checking for sys_errlist... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for sys_errlist" >&5 +$as_echo_n "checking for sys_errlist... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6384,40 +6744,45 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_SYS_ERRLIST 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for sigset_t" >&5 -echo $ECHO_N "checking for sigset_t... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for sigset_t" >&5 +$as_echo_n "checking for sigset_t... " >&6; } if test "${ac_cv_type_sigset_t+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else - cat >conftest.$ac_ext <<_ACEOF + ac_cv_type_sigset_t=no +cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -6425,14 +6790,11 @@ cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include -typedef sigset_t ac__type_new_; int main () { -if ((ac__type_new_ *) 0) - return 0; -if (sizeof (ac__type_new_)) - return 0; +if (sizeof (sigset_t)) + return 0; ; return 0; } @@ -6443,30 +6805,74 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then - ac_cv_type_sigset_t=yes + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include + +int +main () +{ +if (sizeof ((sigset_t))) + return 0; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + : else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - ac_cv_type_sigset_t=no + ac_cv_type_sigset_t=yes +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +else + $as_echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_type_sigset_t" >&5 -echo "${ECHO_T}$ac_cv_type_sigset_t" >&6; } -if test $ac_cv_type_sigset_t = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_type_sigset_t" >&5 +$as_echo "$ac_cv_type_sigset_t" >&6; } +if test "x$ac_cv_type_sigset_t" = x""yes; then cat >>confdefs.h <<_ACEOF #define HAVE_SIGSET_T 1 @@ -6476,8 +6882,8 @@ _ACEOF fi -{ echo "$as_me:$LINENO: checking for sigemptyset" >&5 -echo $ECHO_N "checking for sigemptyset... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for sigemptyset" >&5 +$as_echo_n "checking for sigemptyset... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6501,37 +6907,41 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_SIGEMPTYSET 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext have_errno=no -{ echo "$as_me:$LINENO: checking for errno" >&5 -echo $ECHO_N "checking for errno... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for errno" >&5 +$as_echo_n "checking for errno... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6556,30 +6966,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes - in errno.h" >&5 -echo "${ECHO_T}yes - in errno.h" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes - in errno.h" >&5 +$as_echo "yes - in errno.h" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_ERRNO 1 _ACEOF have_errno=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test $have_errno = no; then @@ -6607,20 +7021,23 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes - must define" >&5 -echo "${ECHO_T}yes - must define" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes - must define" >&5 +$as_echo "yes - must define" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_ERRNO 1 _ACEOF cat >>confdefs.h <<\_ACEOF @@ -6628,19 +7045,20 @@ _ACEOF _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: checking for locale" >&5 -echo $ECHO_N "checking for locale... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for locale" >&5 +$as_echo_n "checking for locale... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6664,36 +7082,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_LOCALE 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for ctype functions" >&5 -echo $ECHO_N "checking for ctype functions... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for ctype functions" >&5 +$as_echo_n "checking for ctype functions... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6718,36 +7140,40 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_UPPER_LOWER 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext -{ echo "$as_me:$LINENO: checking for wctype functions" >&5 -echo $ECHO_N "checking for wctype functions... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for wctype functions" >&5 +$as_echo_n "checking for wctype functions... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6769,38 +7195,42 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes" >&5 +$as_echo "yes" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_WCTYPE 1 _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext # Checks for external variable ospeed in the termcap library. have_ospeed=no -{ echo "$as_me:$LINENO: checking termcap for ospeed" >&5 -echo $ECHO_N "checking termcap for ospeed... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking termcap for ospeed" >&5 +$as_echo_n "checking termcap for ospeed... " >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF @@ -6829,30 +7259,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes - in termcap.h" >&5 -echo "${ECHO_T}yes - in termcap.h" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes - in termcap.h" >&5 +$as_echo "yes - in termcap.h" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_OSPEED 1 _ACEOF have_ospeed=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext if test $have_ospeed = no; then @@ -6877,20 +7311,23 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: yes - must define" >&5 -echo "${ECHO_T}yes - must define" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: yes - must define" >&5 +$as_echo "yes - must define" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_OSPEED 1 _ACEOF cat >>confdefs.h <<\_ACEOF @@ -6898,13 +7335,14 @@ _ACEOF _ACEOF else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi @@ -6928,8 +7366,8 @@ fi # Checks for regular expression functions. have_regex=no have_posix_regex=unknown -{ echo "$as_me:$LINENO: checking for regcomp" >&5 -echo $ECHO_N "checking for regcomp... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for regcomp" >&5 +$as_echo_n "checking for regcomp... " >&6; } # Select a regular expression library. WANT_REGEX=auto @@ -6972,36 +7410,39 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_try") 2>&5 ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then have_posix_regex=yes else - echo "$as_me: program exited with status $ac_status" >&5 -echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: program exited with status $ac_status" >&5 +$as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) have_posix_regex=no fi +rm -rf conftest.dSYM rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi if test $have_posix_regex = yes; then - { echo "$as_me:$LINENO: result: using POSIX regcomp" >&5 -echo "${ECHO_T}using POSIX regcomp" >&6; } + { $as_echo "$as_me:$LINENO: result: using POSIX regcomp" >&5 +$as_echo "using POSIX regcomp" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_POSIX_REGCOMP 1 _ACEOF @@ -7031,46 +7472,50 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: using POSIX regcomp" >&5 -echo "${ECHO_T}using POSIX regcomp" >&6; } + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: using POSIX regcomp" >&5 +$as_echo "using POSIX regcomp" >&6; } cat >>confdefs.h <<\_ACEOF #define HAVE_POSIX_REGCOMP 1 _ACEOF have_regex=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } + { $as_echo "$as_me:$LINENO: result: no" >&5 +$as_echo "no" >&6; } fi fi fi if test $have_regex = no; then if test $WANT_REGEX = auto -o $WANT_REGEX = pcre; then -{ echo "$as_me:$LINENO: checking for pcre_compile in -lpcre" >&5 -echo $ECHO_N "checking for pcre_compile in -lpcre... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for pcre_compile in -lpcre" >&5 +$as_echo_n "checking for pcre_compile in -lpcre... " >&6; } if test "${ac_cv_lib_pcre_pcre_compile+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpcre $LIBS" @@ -7102,35 +7547,39 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_lib_pcre_pcre_compile=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pcre_pcre_compile=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_pcre_pcre_compile" >&5 -echo "${ECHO_T}$ac_cv_lib_pcre_pcre_compile" >&6; } -if test $ac_cv_lib_pcre_pcre_compile = yes; then - { echo "$as_me:$LINENO: result: using pcre" >&5 -echo "${ECHO_T}using pcre" >&6; }; cat >>confdefs.h <<\_ACEOF +{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_pcre_pcre_compile" >&5 +$as_echo "$ac_cv_lib_pcre_pcre_compile" >&6; } +if test "x$ac_cv_lib_pcre_pcre_compile" = x""yes; then + { $as_echo "$as_me:$LINENO: result: using pcre" >&5 +$as_echo "using pcre" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_PCRE 1 _ACEOF LIBS="$LIBS -lpcre" have_regex=yes @@ -7141,10 +7590,10 @@ fi if test $have_regex = no; then if test $WANT_REGEX = auto -o $WANT_REGEX = regcmp; then -{ echo "$as_me:$LINENO: checking for regcmp" >&5 -echo $ECHO_N "checking for regcmp... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: checking for regcmp" >&5 +$as_echo_n "checking for regcmp... " >&6; } if test "${ac_cv_func_regcmp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -7197,34 +7646,38 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_func_regcmp=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_regcmp=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_regcmp" >&5 -echo "${ECHO_T}$ac_cv_func_regcmp" >&6; } -if test $ac_cv_func_regcmp = yes; then - { echo "$as_me:$LINENO: result: using regcmp" >&5 -echo "${ECHO_T}using regcmp" >&6; }; cat >>confdefs.h <<\_ACEOF +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_regcmp" >&5 +$as_echo "$ac_cv_func_regcmp" >&6; } +if test "x$ac_cv_func_regcmp" = x""yes; then + { $as_echo "$as_me:$LINENO: result: using regcmp" >&5 +$as_echo "using regcmp" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_REGCMP 1 _ACEOF have_regex=yes @@ -7257,30 +7710,34 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - { echo "$as_me:$LINENO: result: using V8 regcomp" >&5 -echo "${ECHO_T}using V8 regcomp" >&6; }; cat >>confdefs.h <<\_ACEOF + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then + { $as_echo "$as_me:$LINENO: result: using V8 regcomp" >&5 +$as_echo "using V8 regcomp" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_V8_REGCOMP 1 _ACEOF have_regex=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi @@ -7288,8 +7745,8 @@ fi if test $have_regex = no && test -f ${srcdir}/regexp.c; then if test $WANT_REGEX = auto -o $WANT_REGEX = regcomp-local; then -{ echo "$as_me:$LINENO: result: using V8 regcomp -- local source" >&5 -echo "${ECHO_T}using V8 regcomp -- local source" >&6; }; cat >>confdefs.h <<\_ACEOF +{ $as_echo "$as_me:$LINENO: result: using V8 regcomp -- local source" >&5 +$as_echo "using V8 regcomp -- local source" >&6; }; cat >>confdefs.h <<\_ACEOF #define HAVE_V8_REGCOMP 1 _ACEOF cat >>confdefs.h <<\_ACEOF @@ -7301,11 +7758,11 @@ fi if test $have_regex = no; then if test $WANT_REGEX = auto -o $WANT_REGEX = re_comp; then -{ echo "$as_me:$LINENO: result: using re_comp" >&5 -echo "${ECHO_T}using re_comp" >&6; }; { echo "$as_me:$LINENO: checking for re_comp" >&5 -echo $ECHO_N "checking for re_comp... $ECHO_C" >&6; } +{ $as_echo "$as_me:$LINENO: result: using re_comp" >&5 +$as_echo "using re_comp" >&6; }; { $as_echo "$as_me:$LINENO: checking for re_comp" >&5 +$as_echo_n "checking for re_comp... " >&6; } if test "${ac_cv_func_re_comp+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + $as_echo_n "(cached) " >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -7358,32 +7815,36 @@ case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 +eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\"" +$as_echo "$ac_try_echo") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 + $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || + $as_test_x conftest$ac_exeext + }; then ac_cv_func_re_comp=yes else - echo "$as_me: failed program was:" >&5 + $as_echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_re_comp=no fi +rm -rf conftest.dSYM rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_re_comp" >&5 -echo "${ECHO_T}$ac_cv_func_re_comp" >&6; } -if test $ac_cv_func_re_comp = yes; then +{ $as_echo "$as_me:$LINENO: result: $ac_cv_func_re_comp" >&5 +$as_echo "$ac_cv_func_re_comp" >&6; } +if test "x$ac_cv_func_re_comp" = x""yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_RE_COMP 1 _ACEOF @@ -7394,8 +7855,8 @@ fi fi if test $have_regex = no; then -{ echo "$as_me:$LINENO: result: cannot find regular expression library" >&5 -echo "${ECHO_T}cannot find regular expression library" >&6; }; cat >>confdefs.h <<\_ACEOF +{ $as_echo "$as_me:$LINENO: result: cannot find regular expression library" >&5 +$as_echo "cannot find regular expression library" >&6; }; cat >>confdefs.h <<\_ACEOF #define NO_REGEX 1 _ACEOF @@ -7448,11 +7909,12 @@ _ACEOF case $ac_val in #( *${as_nl}*) case $ac_var in #( - *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 -echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + *_cv_*) { $as_echo "$as_me:$LINENO: WARNING: cache variable $ac_var contains a newline" >&5 +$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( + BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( *) $as_unset $ac_var ;; esac ;; esac @@ -7485,12 +7947,12 @@ echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && - { echo "$as_me:$LINENO: updating cache $cache_file" >&5 -echo "$as_me: updating cache $cache_file" >&6;} + { $as_echo "$as_me:$LINENO: updating cache $cache_file" >&5 +$as_echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else - { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 -echo "$as_me: not updating unwritable cache $cache_file" >&6;} + { $as_echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache @@ -7506,7 +7968,7 @@ ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`echo "$ac_i" | sed "$ac_script"` + ac_i=`$as_echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" @@ -7519,11 +7981,12 @@ LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} +ac_write_fail=0 ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 -echo "$as_me: creating $CONFIG_STATUS" >&6;} -cat >$CONFIG_STATUS <<_ACEOF +{ $as_echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. @@ -7536,7 +7999,7 @@ ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## @@ -7546,7 +8009,7 @@ DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: - # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST @@ -7568,17 +8031,45 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits +as_nl=' +' +export as_nl +# Printing a long string crashes Solaris 7 /usr/bin/printf. +as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo +as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo +if (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then + as_echo='printf %s\n' + as_echo_n='printf %s' +else + if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then + as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' + as_echo_n='/usr/ucb/echo -n' + else + as_echo_body='eval expr "X$1" : "X\\(.*\\)"' + as_echo_n_body='eval + arg=$1; + case $arg in + *"$as_nl"*) + expr "X$arg" : "X\\(.*\\)$as_nl"; + arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; + esac; + expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" + ' + export as_echo_n_body + as_echo_n='sh -c $as_echo_n_body as_echo' + fi + export as_echo_body + as_echo='sh -c $as_echo_body as_echo' +fi + # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then - echo "#! /bin/sh" >conf$$.sh - echo "exit 0" >>conf$$.sh - chmod +x conf$$.sh - if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then - PATH_SEPARATOR=';' - else - PATH_SEPARATOR=: - fi - rm -f conf$$.sh + PATH_SEPARATOR=: + (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { + (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || + PATH_SEPARATOR=';' + } fi # Support unset when possible. @@ -7594,8 +8085,6 @@ fi # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) -as_nl=' -' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. @@ -7618,7 +8107,7 @@ if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then - echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi @@ -7631,17 +8120,10 @@ PS2='> ' PS4='+ ' # NLS nuisances. -for as_var in \ - LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ - LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ - LC_TELEPHONE LC_TIME -do - if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then - eval $as_var=C; export $as_var - else - ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var - fi -done +LC_ALL=C +export LC_ALL +LANGUAGE=C +export LANGUAGE # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && @@ -7663,7 +8145,7 @@ as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || -echo X/"$0" | +$as_echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q @@ -7714,7 +8196,7 @@ $as_unset CDPATH s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || - { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems @@ -7742,7 +8224,6 @@ case `echo -n x` in *) ECHO_N='-n';; esac - if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr @@ -7755,19 +8236,22 @@ if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir - mkdir conf$$.dir + mkdir conf$$.dir 2>/dev/null fi -echo >conf$$.file -if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -p'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +if (echo >conf$$.file) 2>/dev/null; then + if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else as_ln_s='cp -p' -elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln + fi else as_ln_s='cp -p' fi @@ -7792,10 +8276,10 @@ else as_test_x=' eval sh -c '\'' if test -d "$1"; then - test -d "$1/."; + test -d "$1/."; else case $1 in - -*)set "./$1";; + -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi @@ -7818,7 +8302,7 @@ exec 6>&1 # values after options handling. ac_log=" This file was extended by less $as_me 1, which was -generated by GNU Autoconf 2.61. Invocation command line was +generated by GNU Autoconf 2.63. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -7831,29 +8315,39 @@ on `(hostname || uname -n) 2>/dev/null | sed 1q` _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +case $ac_config_files in *" +"*) set x $ac_config_files; shift; ac_config_files=$*;; +esac + +case $ac_config_headers in *" +"*) set x $ac_config_headers; shift; ac_config_headers=$*;; +esac + + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. -Usage: $0 [OPTIONS] [FILE]... +Usage: $0 [OPTION]... [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit - -q, --quiet do not print progress messages + -q, --quiet, --silent + do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + --header=FILE[:TEMPLATE] + instantiate the configuration header FILE Configuration files: $config_files @@ -7864,24 +8358,24 @@ $config_headers Report bugs to ." _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_version="\\ less config.status 1 -configured by $0, generated by GNU Autoconf 2.61, - with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" +configured by $0, generated by GNU Autoconf 2.63, + with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" -Copyright (C) 2006 Free Software Foundation, Inc. +Copyright (C) 2008 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' +test -n "\$AWK" || AWK=awk _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF -# If no file are specified by the user, then we need to provide default -# value. By we need to know if files were specified by the user. +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +# The default lists apply if the user does not specify any file. ac_need_defaults=: while test $# != 0 do @@ -7903,30 +8397,36 @@ do -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - echo "$ac_cs_version"; exit ;; + $as_echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift - CONFIG_FILES="$CONFIG_FILES $ac_optarg" + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_FILES="$CONFIG_FILES '$ac_optarg'" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift - CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" + case $ac_optarg in + *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + CONFIG_HEADERS="$CONFIG_HEADERS '$ac_optarg'" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header - { echo "$as_me: error: ambiguous option: $1 + { $as_echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) - echo "$ac_cs_usage"; exit ;; + $as_echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. - -*) { echo "$as_me: error: unrecognized option: $1 + -*) { $as_echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; @@ -7945,30 +8445,32 @@ if $ac_cs_silent; then fi _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 if \$ac_cs_recheck; then - echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 - CONFIG_SHELL=$SHELL + set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' export CONFIG_SHELL - exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + exec "\$@" fi _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX - echo "$ac_log" + $as_echo "$ac_log" } >&5 _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # Handling of arguments. for ac_config_target in $ac_config_targets @@ -7977,8 +8479,8 @@ do "defines.h") CONFIG_HEADERS="$CONFIG_HEADERS defines.h" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 -echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + *) { { $as_echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +$as_echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done @@ -8018,117 +8520,143 @@ $debug || (umask 077 && mkdir "$tmp") } || { - echo "$me: cannot create a temporary directory in ." >&2 + $as_echo "$as_me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } -# -# Set up the sed scripts for CONFIG_FILES section. -# - -# No need to generate the scripts if there are no CONFIG_FILES. -# This happens for instance when ./config.status config.h +# Set up the scripts for CONFIG_FILES section. +# No need to generate them if there are no CONFIG_FILES. +# This happens for instance with `./config.status config.h'. if test -n "$CONFIG_FILES"; then + +ac_cr=' ' +ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` +if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then + ac_cs_awk_cr='\\r' +else + ac_cs_awk_cr=$ac_cr +fi + +echo 'BEGIN {' >"$tmp/subs1.awk" && _ACEOF - +{ + echo "cat >conf$$subs.awk <<_ACEOF" && + echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && + echo "_ACEOF" +} >conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } +ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'` ac_delim='%!_!# ' for ac_last_try in false false false false false :; do - cat >conf$$subs.sed <<_ACEOF -SHELL!$SHELL$ac_delim -PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim -PACKAGE_NAME!$PACKAGE_NAME$ac_delim -PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim -PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim -PACKAGE_STRING!$PACKAGE_STRING$ac_delim -PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim -exec_prefix!$exec_prefix$ac_delim -prefix!$prefix$ac_delim -program_transform_name!$program_transform_name$ac_delim -bindir!$bindir$ac_delim -sbindir!$sbindir$ac_delim -libexecdir!$libexecdir$ac_delim -datarootdir!$datarootdir$ac_delim -datadir!$datadir$ac_delim -sysconfdir!$sysconfdir$ac_delim -sharedstatedir!$sharedstatedir$ac_delim -localstatedir!$localstatedir$ac_delim -includedir!$includedir$ac_delim -oldincludedir!$oldincludedir$ac_delim -docdir!$docdir$ac_delim -infodir!$infodir$ac_delim -htmldir!$htmldir$ac_delim -dvidir!$dvidir$ac_delim -pdfdir!$pdfdir$ac_delim -psdir!$psdir$ac_delim -libdir!$libdir$ac_delim -localedir!$localedir$ac_delim -mandir!$mandir$ac_delim -DEFS!$DEFS$ac_delim -ECHO_C!$ECHO_C$ac_delim -ECHO_N!$ECHO_N$ac_delim -ECHO_T!$ECHO_T$ac_delim -LIBS!$LIBS$ac_delim -build_alias!$build_alias$ac_delim -host_alias!$host_alias$ac_delim -target_alias!$target_alias$ac_delim -CC!$CC$ac_delim -CFLAGS!$CFLAGS$ac_delim -LDFLAGS!$LDFLAGS$ac_delim -CPPFLAGS!$CPPFLAGS$ac_delim -ac_ct_CC!$ac_ct_CC$ac_delim -EXEEXT!$EXEEXT$ac_delim -OBJEXT!$OBJEXT$ac_delim -CPP!$CPP$ac_delim -GREP!$GREP$ac_delim -EGREP!$EGREP$ac_delim -INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim -INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim -INSTALL_DATA!$INSTALL_DATA$ac_delim -REGEX_O!$REGEX_O$ac_delim -LIBOBJS!$LIBOBJS$ac_delim -LTLIBOBJS!$LTLIBOBJS$ac_delim -_ACEOF + . ./conf$$subs.sh || + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then + ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` + if test $ac_delim_n = $ac_delim_num; then break elif $ac_last_try; then - { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 -echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done +rm -f conf$$subs.sh -ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` -if test -n "$ac_eof"; then - ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` - ac_eof=`expr $ac_eof + 1` -fi - -cat >>$CONFIG_STATUS <<_ACEOF -cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end -_ACEOF -sed ' -s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g -s/^/s,@/; s/!/@,|#_!!_#|/ -:n -t n -s/'"$ac_delim"'$/,g/; t -s/$/\\/; p -N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n -' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF -:end -s/|#_!!_#|//g -CEOF$ac_eof +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +cat >>"\$tmp/subs1.awk" <<\\_ACAWK && _ACEOF +sed -n ' +h +s/^/S["/; s/!.*/"]=/ +p +g +s/^[^!]*!// +:repl +t repl +s/'"$ac_delim"'$// +t delim +:nl +h +s/\(.\{148\}\).*/\1/ +t more1 +s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ +p +n +b repl +:more1 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t nl +:delim +h +s/\(.\{148\}\).*/\1/ +t more2 +s/["\\]/\\&/g; s/^/"/; s/$/"/ +p +b +:more2 +s/["\\]/\\&/g; s/^/"/; s/$/"\\/ +p +g +s/.\{148\}// +t delim +' >$CONFIG_STATUS || ac_write_fail=1 +rm -f conf$$subs.awk +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +_ACAWK +cat >>"\$tmp/subs1.awk" <<_ACAWK && + for (key in S) S_is_set[key] = 1 + FS = "" +} +{ + line = $ 0 + nfields = split(line, field, "@") + substed = 0 + len = length(field[1]) + for (i = 2; i < nfields; i++) { + key = field[i] + keylen = length(key) + if (S_is_set[key]) { + value = S[key] + line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) + len += length(value) + length(field[++i]) + substed = 1 + } else + len += 1 + keylen + } + + print line +} + +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 +if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then + sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" +else + cat +fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \ + || { { $as_echo "$as_me:$LINENO: error: could not setup config files machinery" >&5 +$as_echo "$as_me: error: could not setup config files machinery" >&2;} + { (exit 1); exit 1; }; } +_ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and @@ -8145,19 +8673,133 @@ s/^[^=]*=[ ]*$// }' fi -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" +# Set up the scripts for CONFIG_HEADERS section. +# No need to generate them if there are no CONFIG_HEADERS. +# This happens for instance with `./config.status Makefile'. +if test -n "$CONFIG_HEADERS"; then +cat >"$tmp/defines.awk" <<\_ACAWK || +BEGIN { +_ACEOF -for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS +# Transform confdefs.h into an awk script `defines.awk', embedded as +# here-document in config.status, that substitutes the proper values into +# config.h.in to produce config.h. + +# Create a delimiter string that does not exist in confdefs.h, to ease +# handling of long lines. +ac_delim='%!_!# ' +for ac_last_try in false false :; do + ac_t=`sed -n "/$ac_delim/p" confdefs.h` + if test -z "$ac_t"; then + break + elif $ac_last_try; then + { { $as_echo "$as_me:$LINENO: error: could not make $CONFIG_HEADERS" >&5 +$as_echo "$as_me: error: could not make $CONFIG_HEADERS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +# For the awk script, D is an array of macro values keyed by name, +# likewise P contains macro parameters if any. Preserve backslash +# newline sequences. + +ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* +sed -n ' +s/.\{148\}/&'"$ac_delim"'/g +t rset +:rset +s/^[ ]*#[ ]*define[ ][ ]*/ / +t def +d +:def +s/\\$// +t bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3"/p +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p +d +:bsnl +s/["\\]/\\&/g +s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ +D["\1"]=" \3\\\\\\n"\\/p +t cont +s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p +t cont +d +:cont +n +s/.\{148\}/&'"$ac_delim"'/g +t clear +:clear +s/\\$// +t bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/"/p +d +:bsnlc +s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p +b cont +' >$CONFIG_STATUS || ac_write_fail=1 + +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + for (key in D) D_is_set[key] = 1 + FS = "" +} +/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { + line = \$ 0 + split(line, arg, " ") + if (arg[1] == "#") { + defundef = arg[2] + mac1 = arg[3] + } else { + defundef = substr(arg[1], 2) + mac1 = arg[2] + } + split(mac1, mac2, "(") #) + macro = mac2[1] + prefix = substr(line, 1, index(line, defundef) - 1) + if (D_is_set[macro]) { + # Preserve the white space surrounding the "#". + print prefix "define", macro P[macro] D[macro] + next + } else { + # Replace #undef with comments. This is necessary, for example, + # in the case of _POSIX_SOURCE, which is predefined and required + # on some systems where configure will not decide to define it. + if (defundef == "undef") { + print "/*", prefix defundef, macro, "*/" + next + } + } +} +{ print } +_ACAWK +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + { { $as_echo "$as_me:$LINENO: error: could not setup config headers machinery" >&5 +$as_echo "$as_me: error: could not setup config headers machinery" >&2;} + { (exit 1); exit 1; }; } +fi # test -n "$CONFIG_HEADERS" + + +eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS " +shift +for ac_tag do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; - :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 -echo "$as_me: error: Invalid tag $ac_tag." >&2;} + :L* | :C*:*) { { $as_echo "$as_me:$LINENO: error: invalid tag $ac_tag" >&5 +$as_echo "$as_me: error: invalid tag $ac_tag" >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; @@ -8186,26 +8828,38 @@ echo "$as_me: error: Invalid tag $ac_tag." >&2;} [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || - { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 -echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { { $as_echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +$as_echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac - ac_file_inputs="$ac_file_inputs $ac_f" + case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac + ac_file_inputs="$ac_file_inputs '$ac_f'" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ - configure_input="Generated from "`IFS=: - echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + configure_input='Generated from '` + $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' + `' by configure.' if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" - { echo "$as_me:$LINENO: creating $ac_file" >&5 -echo "$as_me: creating $ac_file" >&6;} + { $as_echo "$as_me:$LINENO: creating $ac_file" >&5 +$as_echo "$as_me: creating $ac_file" >&6;} fi + # Neutralize special characters interpreted by sed in replacement strings. + case $configure_input in #( + *\&* | *\|* | *\\* ) + ac_sed_conf_input=`$as_echo "$configure_input" | + sed 's/[\\\\&|]/\\\\&/g'`;; #( + *) ac_sed_conf_input=$configure_input;; + esac case $ac_tag in - *:-:* | *:-) cat >"$tmp/stdin";; + *:-:* | *:-) cat >"$tmp/stdin" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; esac ;; esac @@ -8215,7 +8869,7 @@ $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -echo X"$ac_file" | +$as_echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -8241,7 +8895,7 @@ echo X"$ac_file" | as_dirs= while :; do case $as_dir in #( - *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" @@ -8250,7 +8904,7 @@ $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -echo X"$as_dir" | +$as_echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -8271,17 +8925,17 @@ echo X"$as_dir" | test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 -echo "$as_me: error: cannot create directory $as_dir" >&2;} + } || test -d "$as_dir" || { { $as_echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +$as_echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) - ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; @@ -8321,12 +8975,13 @@ ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix esac _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= -case `sed -n '/datarootdir/ { +ac_sed_dataroot=' +/datarootdir/ { p q } @@ -8335,13 +8990,14 @@ case `sed -n '/datarootdir/ { /@infodir@/p /@localedir@/p /@mandir@/p -' $ac_file_inputs` in +' +case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + { $as_echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF -cat >>$CONFIG_STATUS <<_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g @@ -8355,15 +9011,16 @@ _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF - sed "$ac_vpsub +cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 +ac_sed_extra="$ac_vpsub $extrasub _ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s&@configure_input@&$configure_input&;t t +s|@configure_input@|$ac_sed_conf_input|;t t s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@top_build_prefix@&$ac_top_build_prefix&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t @@ -8373,119 +9030,58 @@ s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack -" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out +" +eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && - { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' + { $as_echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 -echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in - -) cat "$tmp/out"; rm -f "$tmp/out";; - *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; - esac + -) cat "$tmp/out" && rm -f "$tmp/out";; + *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";; + esac \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } ;; :H) # # CONFIG_HEADER # -_ACEOF - -# Transform confdefs.h into a sed script `conftest.defines', that -# substitutes the proper values into config.h.in to produce config.h. -rm -f conftest.defines conftest.tail -# First, append a space to every undef/define line, to ease matching. -echo 's/$/ /' >conftest.defines -# Then, protect against being on the right side of a sed subst, or in -# an unquoted here document, in config.status. If some macros were -# called several times there might be several #defines for the same -# symbol, which is useless. But do not sort them, since the last -# AC_DEFINE must be honored. -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -# These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where -# NAME is the cpp macro being defined, VALUE is the value it is being given. -# PARAMS is the parameter list in the macro definition--in most cases, it's -# just an empty string. -ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' -ac_dB='\\)[ (].*,\\1define\\2' -ac_dC=' ' -ac_dD=' ,' - -uniq confdefs.h | - sed -n ' - t rset - :rset - s/^[ ]*#[ ]*define[ ][ ]*// - t ok - d - :ok - s/[\\&,]/\\&/g - s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p - s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p - ' >>conftest.defines - -# Remove the space that was appended to ease matching. -# Then replace #undef with comments. This is necessary, for -# example, in the case of _POSIX_SOURCE, which is predefined and required -# on some systems where configure will not decide to define it. -# (The regexp can be short, since the line contains either #define or #undef.) -echo 's/ $// -s,^[ #]*u.*,/* & */,' >>conftest.defines - -# Break up conftest.defines: -ac_max_sed_lines=50 - -# First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" -# Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" -# Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" -# et cetera. -ac_in='$ac_file_inputs' -ac_out='"$tmp/out1"' -ac_nxt='"$tmp/out2"' - -while : -do - # Write a here document: - cat >>$CONFIG_STATUS <<_ACEOF - # First, check the format of the line: - cat >"\$tmp/defines.sed" <<\\CEOF -/^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def -/^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def -b -:def -_ACEOF - sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS - echo 'CEOF - sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS - ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in - sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail - grep . conftest.tail >/dev/null || break - rm -f conftest.defines - mv conftest.tail conftest.defines -done -rm -f conftest.defines conftest.tail - -echo "ac_result=$ac_in" >>$CONFIG_STATUS -cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then - echo "/* $configure_input */" >"$tmp/config.h" - cat "$ac_result" >>"$tmp/config.h" - if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then - { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 -echo "$as_me: $ac_file is unchanged" >&6;} + { + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" + } >"$tmp/config.h" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } + if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then + { $as_echo "$as_me:$LINENO: $ac_file is unchanged" >&5 +$as_echo "$as_me: $ac_file is unchanged" >&6;} else - rm -f $ac_file - mv "$tmp/config.h" $ac_file + rm -f "$ac_file" + mv "$tmp/config.h" "$ac_file" \ + || { { $as_echo "$as_me:$LINENO: error: could not create $ac_file" >&5 +$as_echo "$as_me: error: could not create $ac_file" >&2;} + { (exit 1); exit 1; }; } fi else - echo "/* $configure_input */" - cat "$ac_result" + $as_echo "/* $configure_input */" \ + && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \ + || { { $as_echo "$as_me:$LINENO: error: could not create -" >&5 +$as_echo "$as_me: error: could not create -" >&2;} + { (exit 1); exit 1; }; } fi - rm -f "$tmp/out12" ;; @@ -8499,6 +9095,11 @@ _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save +test $ac_write_fail = 0 || + { { $as_echo "$as_me:$LINENO: error: write failure creating $CONFIG_STATUS" >&5 +$as_echo "$as_me: error: write failure creating $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. @@ -8520,4 +9121,8 @@ if test "$no_create" != yes; then # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi +if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then + { $as_echo "$as_me:$LINENO: WARNING: unrecognized options: $ac_unrecognized_opts" >&5 +$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;} +fi diff --git a/configure.ac b/configure.ac index 72d340729174..1138e75a3d3c 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ # Process this file with autoconf to produce a configure script. -# Copyright (C) 1984-2007 Mark Nudelman +# Copyright (C) 1984-2008 Mark Nudelman # # You may distribute under the terms of either the GNU General Public # License or the Less License, as specified in the README file. diff --git a/decode.c b/decode.c index ac1668fa5a86..a3e51fd94618 100644 --- a/decode.c +++ b/decode.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -133,6 +133,7 @@ static unsigned char cmdtable[] = ESC,'n',0, A_T_AGAIN_SEARCH, 'N',0, A_REVERSE_SEARCH, ESC,'N',0, A_T_REVERSE_SEARCH, + '&',0, A_FILTER, 'm',0, A_SETMARK, '\'',0, A_GOMARK, CONTROL('X'),CONTROL('X'),0, A_GOMARK, diff --git a/defines.ds b/defines.ds index c98dcffc35b1..fdce109cb882 100644 --- a/defines.ds +++ b/defines.ds @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/defines.o2 b/defines.o2 index 544003809a69..4f23bf18bcfb 100644 --- a/defines.o2 +++ b/defines.o2 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/defines.o9 b/defines.o9 index 50955ba1046a..77aad48398ac 100644 --- a/defines.o9 +++ b/defines.o9 @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/defines.wn b/defines.wn index 7c3194c832b9..6991392245bb 100644 --- a/defines.wn +++ b/defines.wn @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/edit.c b/edit.c index e2e30f2d7af3..b3e5669b85bf 100644 --- a/edit.c +++ b/edit.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/filename.c b/filename.c index aa45b764dab5..72e97971104f 100644 --- a/filename.c +++ b/filename.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -52,6 +52,7 @@ extern int force_open; extern int secure; extern int use_lessopen; extern int ctldisp; +extern int utf_mode; extern IFILE curr_ifile; extern IFILE old_ifile; #if SPACES_IN_FILENAMES @@ -469,23 +470,26 @@ fcomplete(s) bin_file(f) int f; { - int i; int n; int bin_count = 0; - unsigned char data[256]; + char data[256]; + char* p; + char* pend; if (!seekable(f)) return (0); if (lseek(f, (off_t)0, SEEK_SET) == BAD_LSEEK) return (0); n = read(f, data, sizeof(data)); - for (i = 0; i < n; i++) + pend = &data[n]; + for (p = data; p < pend; ) { - char c = data[i]; + LWCHAR c = step_char(&p, +1, pend); if (ctldisp == OPT_ONPLUS && IS_CSI_START(c)) { - while (++i < n && is_ansi_middle(data[i])) - continue; + do { + c = step_char(&p, +1, pend); + } while (p < pend && is_ansi_middle(c)); } else if (binary_char(c)) bin_count++; } @@ -827,20 +831,27 @@ open_altfile(filename, pf, pfd) ch_ungetchar(-1); if ((lessopen = lgetenv("LESSOPEN")) == NULL) return (NULL); - if (strcmp(filename, "-") == 0) - return (NULL); if (*lessopen == '|') { /* * If LESSOPEN starts with a |, it indicates * a "pipe preprocessor". */ -#if HAVE_FILENO - lessopen++; - returnfd = 1; -#else +#if !HAVE_FILENO error("LESSOPEN pipe is not supported", NULL_PARG); return (NULL); +#else + lessopen++; + returnfd = 1; + if (*lessopen == '-') { + /* + * Lessopen preprocessor will accept "-" as a filename. + */ + lessopen++; + } else { + if (strcmp(filename, "-") == 0) + return (NULL); + } #endif } diff --git a/forwback.c b/forwback.c index 7b5bb2d26039..c5bd2568fd06 100644 --- a/forwback.c +++ b/forwback.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -17,7 +17,6 @@ #include "less.h" #include "position.h" -public int hit_eof; /* Keeps track of how many times we hit end of file */ public int screen_trashed; public int squished; public int no_back_scroll = 0; @@ -51,25 +50,47 @@ eof_bell() } /* - * Check to see if the end of file is currently "displayed". + * Check to see if the end of file is currently displayed. */ - static void -eof_check() + public int +eof_displayed() { POSITION pos; if (ignore_eoi) - return; - if (ABORT_SIGS()) - return; + return (0); + + if (ch_length() == NULL_POSITION) + /* + * If the file length is not known, + * we can't possibly be displaying EOF. + */ + return (0); + /* * If the bottom line is empty, we are at EOF. * If the bottom line ends at the file length, * we must be just at EOF. */ pos = position(BOTTOM_PLUS_ONE); - if (pos == NULL_POSITION || pos == ch_length()) - hit_eof++; + return (pos == NULL_POSITION || pos == ch_length()); +} + +/* + * Check to see if the entire file is currently displayed. + */ + public int +entire_file_displayed() +{ + POSITION pos; + + /* Make sure last line of file is displayed. */ + if (!eof_displayed()) + return (0); + + /* Make sure first line of file is displayed. */ + pos = position(0); + return (pos == NULL_POSITION || pos == 0); } /* @@ -251,12 +272,6 @@ forw(n, pos, force, only_last, nblank) forw_prompt = 1; } - if (ignore_eoi) - hit_eof = 0; - else if (eof && !ABORT_SIGS()) - hit_eof++; - else - eof_check(); if (nlines == 0) eof_bell(); else if (do_repaint) @@ -280,7 +295,6 @@ back(n, pos, force, only_last) squish_check(); do_repaint = (n > get_back_scroll() || (only_last && n > sc_height-1)); - hit_eof = 0; while (--n >= 0) { /* @@ -309,7 +323,6 @@ back(n, pos, force, only_last) } } - eof_check(); if (nlines == 0) eof_bell(); else if (do_repaint) @@ -331,7 +344,7 @@ forward(n, force, only_last) { POSITION pos; - if (get_quit_at_eof() && hit_eof && !(ch_getflags() & CH_HELPFILE)) + if (get_quit_at_eof() && eof_displayed() && !(ch_getflags() & CH_HELPFILE)) { /* * If the -e flag is set and we're trying to go @@ -365,7 +378,6 @@ forward(n, force, only_last) } else { eof_bell(); - hit_eof++; return; } } diff --git a/funcs.h b/funcs.h index 649598ee48c0..8cacc507c038 100644 --- a/funcs.h +++ b/funcs.h @@ -30,6 +30,8 @@ public void backspace (); public void putbs (); public char WIN32getch (); + public void WIN32setcolors (); + public void WIN32textout (); public void match_brac (); public void ch_ungetchar (); public void end_logfile (); @@ -122,6 +124,8 @@ public char * bad_file (); public POSITION filesize (); public char * shell_coption (); + public int eof_displayed (); + public int entire_file_displayed (); public void squish_check (); public void forw (); public void back (); @@ -164,6 +168,7 @@ public int pappend (); public int pflushmbc (); public void pdone (); + public void set_status_col (); public int gline (); public void null_line (); public POSITION forw_raw_line (); @@ -246,12 +251,17 @@ public void repaint_hilite (); public void clear_attn (); public void undo_search (); + public void clr_hlist (); public void clr_hilite (); + public void clr_filter (); + public int is_filtered (); public int is_hilited (); public void chg_caseless (); public void chg_hilite (); public int search (); public void prep_hilite (); + public void set_filter_pattern (); + public int is_filtering (); public RETSIGTYPE winch (); public RETSIGTYPE winch (); public void init_signals (); diff --git a/help.c b/help.c index 5f7b1290e8a5..531aa16f29f3 100644 --- a/help.c +++ b/help.c @@ -41,6 +41,7 @@ constant char helpdata[] = { ' ',' ','E','S','C','-','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n', ' ',' ','E','S','C','-','N',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','R','e','p','e','a','t',' ','p','r','e','v','i','o','u','s',' ','s','e','a','r','c','h',',',' ','r','e','v','e','r','s','e',' ','d','i','r','.',' ','&',' ','s','p','a','n','n','i','n','g',' ','f','i','l','e','s','.','\n', ' ',' ','E','S','C','-','u',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','U','n','d','o',' ','(','t','o','g','g','l','e',')',' ','s','e','a','r','c','h',' ','h','i','g','h','l','i','g','h','t','i','n','g','.','\n', +' ',' ','&','_','\b','p','_','\b','a','_','\b','t','_','\b','t','_','\b','e','_','\b','r','_','\b','n',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ','*',' ',' ','D','i','s','p','l','a','y',' ','o','n','l','y',' ','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','\n', ' ',' ',' ',' ',' ',' ',' ',' ','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','-','\n', ' ',' ',' ',' ',' ',' ',' ',' ','S','e','a','r','c','h',' ','p','a','t','t','e','r','n','s',' ','m','a','y',' ','b','e',' ','m','o','d','i','f','i','e','d',' ','b','y',' ','o','n','e',' ','o','r',' ','m','o','r','e',' ','o','f',':','\n', ' ',' ',' ',' ',' ',' ',' ',' ','^','N',' ','o','r',' ','!',' ',' ','S','e','a','r','c','h',' ','f','o','r',' ','N','O','N','-','m','a','t','c','h','i','n','g',' ','l','i','n','e','s','.','\n', diff --git a/ifile.c b/ifile.c index 96e8e603ecaf..00b935027fd3 100644 --- a/ifile.c +++ b/ifile.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/input.c b/input.c index 1129a7b05539..2cfa9bdfa6d8 100644 --- a/input.c +++ b/input.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -53,13 +53,14 @@ forw_line(curr_pos) int endline; int backchars; +get_forw_line: if (curr_pos == NULL_POSITION) { null_line(); return (NULL_POSITION); } #if HILITE_SEARCH - if (hilite_search == OPT_ONPLUS || status_col) + if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) /* * If we are ignoring EOI (command F), only prepare * one line ahead, to avoid getting stuck waiting for @@ -76,6 +77,9 @@ forw_line(curr_pos) return (NULL_POSITION); } + /* + * Step back to the beginning of the line. + */ base_pos = curr_pos; for (;;) { @@ -95,10 +99,14 @@ forw_line(curr_pos) --base_pos; } + /* + * Read forward again to the position we should start at. + */ prewind(); plinenum(base_pos); (void) ch_seek(base_pos); - while (base_pos < curr_pos) + new_pos = base_pos; + while (new_pos < curr_pos) { if (ABORT_SIGS()) { @@ -106,12 +114,12 @@ forw_line(curr_pos) return (NULL_POSITION); } c = ch_forw_get(); - backchars = pappend(c, base_pos); - base_pos++; + backchars = pappend(c, new_pos); + new_pos++; if (backchars > 0) { pshift_all(); - base_pos -= backchars; + new_pos -= backchars; while (--backchars >= 0) (void) ch_back_get(); } @@ -119,6 +127,9 @@ forw_line(curr_pos) (void) pflushmbc(); pshift_all(); + /* + * Read the first character to display. + */ c = ch_forw_get(); if (c == EOI) { @@ -127,6 +138,9 @@ forw_line(curr_pos) } blankline = (c == '\n' || c == '\r'); + /* + * Read each character in the line and append to the line buffer. + */ for (;;) { if (ABORT_SIGS()) @@ -181,7 +195,23 @@ forw_line(curr_pos) } c = ch_forw_get(); } - pdone(endline); + + pdone(endline, c); + +#if HILITE_SEARCH + if (is_filtered(base_pos)) + { + /* + * We don't want to display this line. + * Get the next line. + */ + curr_pos = new_pos; + goto get_forw_line; + } + + if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL)) + set_status_col('*'); +#endif if (squeeze && blankline) { @@ -215,18 +245,19 @@ forw_line(curr_pos) back_line(curr_pos) POSITION curr_pos; { - POSITION new_pos, begin_new_pos; + POSITION new_pos, begin_new_pos, base_pos; int c; int endline; int backchars; +get_back_line: if (curr_pos == NULL_POSITION || curr_pos <= ch_zero()) { null_line(); return (NULL_POSITION); } #if HILITE_SEARCH - if (hilite_search == OPT_ONPLUS || status_col) + if (hilite_search == OPT_ONPLUS || is_filtering() || status_col) prep_hilite((curr_pos < 3*size_linebuf) ? 0 : curr_pos - 3*size_linebuf, curr_pos, -1); #endif @@ -241,9 +272,9 @@ back_line(curr_pos) /* * Find out if the "current" line was blank. */ - (void) ch_forw_get(); /* Skip the newline */ - c = ch_forw_get(); /* First char of "current" line */ - (void) ch_back_get(); /* Restore our position */ + (void) ch_forw_get(); /* Skip the newline */ + c = ch_forw_get(); /* First char of "current" line */ + (void) ch_back_get(); /* Restore our position */ (void) ch_back_get(); if (c == '\n' || c == '\r') @@ -285,7 +316,7 @@ back_line(curr_pos) * This is the newline ending the previous line. * We have hit the beginning of the line. */ - new_pos = ch_tell() + 1; + base_pos = ch_tell() + 1; break; } if (c == EOI) @@ -295,7 +326,7 @@ back_line(curr_pos) * This must be the first line in the file. * This must, of course, be the beginning of the line. */ - new_pos = ch_tell(); + base_pos = ch_tell(); break; } } @@ -309,6 +340,7 @@ back_line(curr_pos) * are much longer than the screen width, * but I don't know of any better way. }} */ + new_pos = base_pos; if (ch_seek(new_pos)) { null_line(); @@ -366,7 +398,22 @@ back_line(curr_pos) } } while (new_pos < curr_pos); - pdone(endline); + pdone(endline, ch_forw_get()); + +#if HILITE_SEARCH + if (is_filtered(base_pos)) + { + /* + * We don't want to display this line. + * Get the previous line. + */ + curr_pos = begin_new_pos; + goto get_back_line; + } + + if (status_col && is_hilited(base_pos, ch_tell()-1, 1, NULL)) + set_status_col('*'); +#endif return (begin_new_pos); } diff --git a/install.sh b/install.sh index 0ff4b6a08e80..41ea84f9e54a 100755 --- a/install.sh +++ b/install.sh @@ -97,7 +97,7 @@ fi # Make a temp file name in the proper directory. dstdir=`dirname $dst` -dsttmp=$dstdir/#inst.$$# +dsttmp=$dstdir/_inst.$$_ # Move or copy the file name to the temp name diff --git a/jump.c b/jump.c index 585d9b209e6d..801a833fdeca 100644 --- a/jump.c +++ b/jump.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -16,7 +16,6 @@ #include "less.h" #include "position.h" -extern int hit_eof; extern int jump_sline; extern int squished; extern int screen_trashed; @@ -38,6 +37,12 @@ jump_forw() error("Cannot seek to end of file", NULL_PARG); return; } + /* + * Note; lastmark will be called later by jump_loc, but it fails + * because the position table has been cleared by pos_clear below. + * So call it here before calling pos_clear. + */ + lastmark(); /* * Position the last line in the file at the last screen line. * Go back one line from the end of the file @@ -194,8 +199,10 @@ jump_loc(pos, sline) forw(nline, position(BOTTOM_PLUS_ONE), 1, 0, 0); else back(-nline, position(TOP), 1, 0); +#if HILITE_SEARCH if (show_attn) repaint_hilite(1); +#endif return; } @@ -233,8 +240,10 @@ jump_loc(pos, sline) * that we can just scroll there after all. */ forw(sc_height-sline+nline-1, bpos, 1, 0, 0); +#if HILITE_SEARCH if (show_attn) repaint_hilite(1); +#endif return; } pos = back_line(pos); @@ -250,7 +259,6 @@ jump_loc(pos, sline) } } lastmark(); - hit_eof = 0; squished = 0; screen_trashed = 0; forw(sc_height-1, pos, 1, 0, sline-nline); @@ -282,8 +290,10 @@ jump_loc(pos, sline) * that we can just scroll there after all. */ back(nline+1, tpos, 1, 0); +#if HILITE_SEARCH if (show_attn) repaint_hilite(1); +#endif return; } } diff --git a/less.h b/less.h index 078ccbbb43f7..a1cc6beb3166 100644 --- a/less.h +++ b/less.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -159,7 +159,7 @@ void free(); #define IS_DIGIT(c) ((c) >= '0' && (c) <= '9') #endif -#define IS_CSI_START(c) ((c) == ESC || ((unsigned char)(c)) == CSI) +#define IS_CSI_START(c) (((LWCHAR)(c)) == ESC || (((LWCHAR)(c)) == CSI)) #ifndef NULL #define NULL 0 @@ -335,14 +335,15 @@ struct textlist #define BS_CONTROL 2 /* \b treated as control char; prints as ^H */ /* How should we search? */ -#define SRCH_FORW (1 << 0) /* Search forward from current position */ -#define SRCH_BACK (1 << 1) /* Search backward from current position */ -#define SRCH_NO_MOVE (1 << 2) /* Highlight, but don't move */ -#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */ -#define SRCH_NO_MATCH (1 << 8) /* Search for non-matching lines */ -#define SRCH_PAST_EOF (1 << 9) /* Search past end-of-file, into next file */ -#define SRCH_FIRST_FILE (1 << 10) /* Search starting at the first file */ -#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */ +#define SRCH_FORW (1 << 0) /* Search forward from current position */ +#define SRCH_BACK (1 << 1) /* Search backward from current position */ +#define SRCH_NO_MOVE (1 << 2) /* Highlight, but don't move */ +#define SRCH_FIND_ALL (1 << 4) /* Find and highlight all matches */ +#define SRCH_NO_MATCH (1 << 8) /* Search for non-matching lines */ +#define SRCH_PAST_EOF (1 << 9) /* Search past end-of-file, into next file */ +#define SRCH_FIRST_FILE (1 << 10) /* Search starting at the first file */ +#define SRCH_NO_REGEX (1 << 12) /* Don't use regular expressions */ +#define SRCH_FILTER (1 << 13) /* Search is for '&' (filter) command */ #define SRCH_REVERSE(t) (((t) & SRCH_FORW) ? \ (((t) & ~SRCH_FORW) | SRCH_BACK) : \ diff --git a/less.hlp b/less.hlp index 18c9968e9950..15ece5a017ce 100644 --- a/less.hlp +++ b/less.hlp @@ -38,6 +38,7 @@ ESC-n * Repeat previous search, spanning files. ESC-N * Repeat previous search, reverse dir. & spanning files. ESC-u Undo (toggle) search highlighting. + &_p_a_t_t_e_r_n * Display only matching lines --------------------------------------------------- Search patterns may be modified by one or more of: ^N or ! Search for NON-matching lines. diff --git a/less.man b/less.man index af19a477fac2..1135830eb3a8 100644 --- a/less.man +++ b/less.man @@ -195,8 +195,8 @@ LESS(1) LESS(1) options. ^K Highlight any text which matches the pattern on the cur- - rent screen, but don't move to the first match (KEEP - current position). + rent screen, but don't move to the first match (KEEP cur- + rent position). ^R Don't interpret regular expression metacharacters; that is, do a simple textual comparison. @@ -257,95 +257,111 @@ LESS(1) LESS(1) (Highlighting can also be disabled by toggling the -G option; in that case search commands do not turn highlighting back on.) + &pattern + Display only lines which match the pattern; lines which do not + match the pattern are not displayed. If pattern is empty (if + you type & immediately followed by ENTER), any filtering is + turned off, and all lines are displayed. While filtering is in + effect, an ampersand is displayed at the beginning of the + prompt, as a reminder that some lines in the file may be hidden. + + Certain characters are special as in the / command: + + ^N or ! + Display only lines which do NOT match the pattern. + + ^R Don't interpret regular expression metacharacters; that + is, do a simple textual comparison. + :e [filename] - Examine a new file. If the filename is missing, the "current" - file (see the :n and :p commands below) from the list of files - in the command line is re-examined. A percent sign (%) in the - filename is replaced by the name of the current file. A pound - sign (#) is replaced by the name of the previously examined - file. However, two consecutive percent signs are simply + Examine a new file. If the filename is missing, the "current" + file (see the :n and :p commands below) from the list of files + in the command line is re-examined. A percent sign (%) in the + filename is replaced by the name of the current file. A pound + sign (#) is replaced by the name of the previously examined + file. However, two consecutive percent signs are simply replaced with a single percent sign. This allows you to enter a - filename that contains a percent sign in the name. Similarly, - two consecutive pound signs are replaced with a single pound - sign. The filename is inserted into the command line list of - files so that it can be seen by subsequent :n and :p commands. + filename that contains a percent sign in the name. Similarly, + two consecutive pound signs are replaced with a single pound + sign. The filename is inserted into the command line list of + files so that it can be seen by subsequent :n and :p commands. If the filename consists of several files, they are all inserted - into the list of files and the first one is examined. If the + into the list of files and the first one is examined. If the filename contains one or more spaces, the entire filename should be enclosed in double quotes (also see the -" option). ^X^V or E - Same as :e. Warning: some systems use ^V as a special literal- - ization character. On such systems, you may not be able to use + Same as :e. Warning: some systems use ^V as a special literal- + ization character. On such systems, you may not be able to use ^V. - :n Examine the next file (from the list of files given in the com- - mand line). If a number N is specified, the N-th next file is + :n Examine the next file (from the list of files given in the com- + mand line). If a number N is specified, the N-th next file is examined. :p Examine the previous file in the command line list. If a number N is specified, the N-th previous file is examined. - :x Examine the first file in the command line list. If a number N + :x Examine the first file in the command line list. If a number N is specified, the N-th file in the list is examined. :d Remove the current file from the list of files. - t Go to the next tag, if there were more than one matches for the + t Go to the next tag, if there were more than one matches for the current tag. See the -t option for more details about tags. - T Go to the previous tag, if there were more than one matches for + T Go to the previous tag, if there were more than one matches for the current tag. = or ^G or :f - Prints some information about the file being viewed, including - its name and the line number and byte offset of the bottom line - being displayed. If possible, it also prints the length of the - file, the number of lines in the file and the percent of the + Prints some information about the file being viewed, including + its name and the line number and byte offset of the bottom line + being displayed. If possible, it also prints the length of the + file, the number of lines in the file and the percent of the file above the last displayed line. - - Followed by one of the command line option letters (see OPTIONS - below), this will change the setting of that option and print a - message describing the new setting. If a ^P (CONTROL-P) is + - Followed by one of the command line option letters (see OPTIONS + below), this will change the setting of that option and print a + message describing the new setting. If a ^P (CONTROL-P) is entered immediately after the dash, the setting of the option is - changed but no message is printed. If the option letter has a - numeric value (such as -b or -h), or a string value (such as -P - or -t), a new value may be entered after the option letter. If - no new value is entered, a message describing the current set- + changed but no message is printed. If the option letter has a + numeric value (such as -b or -h), or a string value (such as -P + or -t), a new value may be entered after the option letter. If + no new value is entered, a message describing the current set- ting is printed and nothing is changed. - -- Like the - command, but takes a long option name (see OPTIONS - below) rather than a single option letter. You must press + -- Like the - command, but takes a long option name (see OPTIONS + below) rather than a single option letter. You must press RETURN after typing the option name. A ^P immediately after the - second dash suppresses printing of a message describing the new + second dash suppresses printing of a message describing the new setting, as in the - command. - -+ Followed by one of the command line option letters this will - reset the option to its default setting and print a message - describing the new setting. (The "-+X" command does the same - thing as "-+X" on the command line.) This does not work for + -+ Followed by one of the command line option letters this will + reset the option to its default setting and print a message + describing the new setting. (The "-+X" command does the same + thing as "-+X" on the command line.) This does not work for string-valued options. - --+ Like the -+ command, but takes a long option name rather than a + --+ Like the -+ command, but takes a long option name rather than a single option letter. - -! Followed by one of the command line option letters, this will - reset the option to the "opposite" of its default setting and - print a message describing the new setting. This does not work + -! Followed by one of the command line option letters, this will + reset the option to the "opposite" of its default setting and + print a message describing the new setting. This does not work for numeric or string-valued options. - --! Like the -! command, but takes a long option name rather than a + --! Like the -! command, but takes a long option name rather than a single option letter. - _ (Underscore.) Followed by one of the command line option let- - ters, this will print a message describing the current setting + _ (Underscore.) Followed by one of the command line option let- + ters, this will print a message describing the current setting of that option. The setting of the option is not changed. __ (Double underscore.) Like the _ (underscore) command, but takes a long option name rather than a single option letter. You must press RETURN after typing the option name. - +cmd Causes the specified cmd to be executed each time a new file is + +cmd Causes the specified cmd to be executed each time a new file is examined. For example, +G causes less to initially display each file starting at the end rather than the beginning. @@ -354,51 +370,51 @@ LESS(1) LESS(1) q or Q or :q or :Q or ZZ Exits less. - The following four commands may or may not be valid, depending on your + The following four commands may or may not be valid, depending on your particular installation. - v Invokes an editor to edit the current file being viewed. The + v Invokes an editor to edit the current file being viewed. The editor is taken from the environment variable VISUAL if defined, - or EDITOR if VISUAL is not defined, or defaults to "vi" if nei- - ther VISUAL nor EDITOR is defined. See also the discussion of + or EDITOR if VISUAL is not defined, or defaults to "vi" if nei- + ther VISUAL nor EDITOR is defined. See also the discussion of LESSEDIT under the section on PROMPTS below. ! shell-command - Invokes a shell to run the shell-command given. A percent sign - (%) in the command is replaced by the name of the current file. + Invokes a shell to run the shell-command given. A percent sign + (%) in the command is replaced by the name of the current file. A pound sign (#) is replaced by the name of the previously exam- - ined file. "!!" repeats the last shell command. "!" with no - shell command simply invokes a shell. On Unix systems, the - shell is taken from the environment variable SHELL, or defaults - to "sh". On MS-DOS and OS/2 systems, the shell is the normal + ined file. "!!" repeats the last shell command. "!" with no + shell command simply invokes a shell. On Unix systems, the + shell is taken from the environment variable SHELL, or defaults + to "sh". On MS-DOS and OS/2 systems, the shell is the normal command processor. | shell-command - represents any mark letter. Pipes a section of the input - file to the given shell command. The section of the file to be - piped is between the first line on the current screen and the - position marked by the letter. may also be ^ or $ to indi- + represents any mark letter. Pipes a section of the input + file to the given shell command. The section of the file to be + piped is between the first line on the current screen and the + position marked by the letter. may also be ^ or $ to indi- cate beginning or end of file respectively. If is . or new- line, the current screen is piped. s filename - Save the input to a file. This only works if the input is a + Save the input to a file. This only works if the input is a pipe, not an ordinary file. OPTIONS - Command line options are described below. Most options may be changed + Command line options are described below. Most options may be changed while less is running, via the "-" command. - Most options may be given in one of two forms: either a dash followed - by a single letter, or two dashes followed by a long option name. A - long option name may be abbreviated as long as the abbreviation is + Most options may be given in one of two forms: either a dash followed + by a single letter, or two dashes followed by a long option name. A + long option name may be abbreviated as long as the abbreviation is unambiguous. For example, --quit-at-eof may be abbreviated --quit, but not --qui, since both --quit-at-eof and --quiet begin with --qui. Some - long option names are in uppercase, such as --QUIT-AT-EOF, as distinct - from --quit-at-eof. Such option names need only have their first let- - ter capitalized; the remainder of the name may be in either case. For + long option names are in uppercase, such as --QUIT-AT-EOF, as distinct + from --quit-at-eof. Such option names need only have their first let- + ter capitalized; the remainder of the name may be in either case. For example, --Quit-at-eof is equivalent to --QUIT-AT-EOF. Options are also taken from the environment variable "LESS". For exam- @@ -411,57 +427,57 @@ LESS(1) LESS(1) LESS="-options"; export LESS - On MS-DOS, you don't need the quotes, but you should replace any per- + On MS-DOS, you don't need the quotes, but you should replace any per- cent signs in the options string by double percent signs. - The environment variable is parsed before the command line, so command - line options override the LESS environment variable. If an option - appears in the LESS variable, it can be reset to its default value on + The environment variable is parsed before the command line, so command + line options override the LESS environment variable. If an option + appears in the LESS variable, it can be reset to its default value on the command line by beginning the command line option with "-+". - For options like -P or -D which take a following string, a dollar sign - ($) must be used to signal the end of the string. For example, to set - two -D options on MS-DOS, you must have a dollar sign between them, + For options like -P or -D which take a following string, a dollar sign + ($) must be used to signal the end of the string. For example, to set + two -D options on MS-DOS, you must have a dollar sign between them, like this: LESS="-Dn9.1$-Ds4.1" -? or --help - This option displays a summary of the commands accepted by less - (the same as the h command). (Depending on how your shell - interprets the question mark, it may be necessary to quote the + This option displays a summary of the commands accepted by less + (the same as the h command). (Depending on how your shell + interprets the question mark, it may be necessary to quote the question mark, thus: "-\?".) -a or --search-skip-screen - Causes searches to start after the last line displayed on the - screen, thus skipping all lines displayed on the screen. By - default, searches start at the second line on the screen (or + Causes searches to start after the last line displayed on the + screen, thus skipping all lines displayed on the screen. By + default, searches start at the second line on the screen (or after the last found line; see the -j option). -bn or --buffers=n - Specifies the amount of buffer space less will use for each - file, in units of kilobytes (1024 bytes). By default 64K of - buffer space is used for each file (unless the file is a pipe; - see the -B option). The -b option specifies instead that n + Specifies the amount of buffer space less will use for each + file, in units of kilobytes (1024 bytes). By default 64K of + buffer space is used for each file (unless the file is a pipe; + see the -B option). The -b option specifies instead that n kilobytes of buffer space should be used for each file. If n is - -1, buffer space is unlimited; that is, the entire file can be + -1, buffer space is unlimited; that is, the entire file can be read into memory. -B or --auto-buffers By default, when data is read from a pipe, buffers are allocated automatically as needed. If a large amount of data is read from - the pipe, this can cause a large amount of memory to be allo- - cated. The -B option disables this automatic allocation of - buffers for pipes, so that only 64K (or the amount of space - specified by the -b option) is used for the pipe. Warning: use - of -B can result in erroneous display, since only the most - recently viewed part of the piped data is kept in memory; any + the pipe, this can cause a large amount of memory to be allo- + cated. The -B option disables this automatic allocation of + buffers for pipes, so that only 64K (or the amount of space + specified by the -b option) is used for the pipe. Warning: use + of -B can result in erroneous display, since only the most + recently viewed part of the piped data is kept in memory; any earlier data is lost. -c or --clear-screen - Causes full screen repaints to be painted from the top line - down. By default, full screen repaints are done by scrolling + Causes full screen repaints to be painted from the top line + down. By default, full screen repaints are done by scrolling from the bottom of the screen. -C or --CLEAR-SCREEN @@ -469,23 +485,24 @@ LESS(1) LESS(1) -d or --dumb The -d option suppresses the error message normally displayed if - the terminal is dumb; that is, lacks some important capability, + the terminal is dumb; that is, lacks some important capability, such as the ability to clear the screen or scroll backward. The - -d option does not otherwise change the behavior of less on a + -d option does not otherwise change the behavior of less on a dumb terminal. -Dxcolor or --color=xcolor [MS-DOS only] Sets the color of the text displayed. x is a sin- - gle character which selects the type of text whose color is - being set: n=normal, s=standout, d=bold, u=underlined, k=blink. - color is a pair of numbers separated by a period. The first - number selects the foreground color and the second selects the - background color of the text. A single number N is the same as - N.0. + gle character which selects the type of text whose color is + being set: n=normal, s=standout, d=bold, u=underlined, k=blink. + color is a pair of numbers separated by a period. The first + number selects the foreground color and the second selects the + background color of the text. A single number N is the same as + N.M, where M is the normal background color. + -e or --quit-at-eof - Causes less to automatically exit the second time it reaches - end-of-file. By default, the only way to exit less is via the + Causes less to automatically exit the second time it reaches + end-of-file. By default, the only way to exit less is via the "q" command. -E or --QUIT-AT-EOF @@ -494,7 +511,7 @@ LESS(1) LESS(1) -f or --force Forces non-regular files to be opened. (A non-regular file is a - directory or a device special file.) Also suppresses the warn- + directory or a device special file.) Also suppresses the warn- ing message when a binary file is opened. By default, less will refuse to open non-regular files. Note that some operating sys- tems will not allow directories to be read, even if -f is set. @@ -504,283 +521,283 @@ LESS(1) LESS(1) played on the first screen. -g or --hilite-search - Normally, less will highlight ALL strings which match the last - search command. The -g option changes this behavior to high- - light only the particular string which was found by the last + Normally, less will highlight ALL strings which match the last + search command. The -g option changes this behavior to high- + light only the particular string which was found by the last search command. This can cause less to run somewhat faster than the default. -G or --HILITE-SEARCH - The -G option suppresses all highlighting of strings found by + The -G option suppresses all highlighting of strings found by search commands. -hn or --max-back-scroll=n - Specifies a maximum number of lines to scroll backward. If it + Specifies a maximum number of lines to scroll backward. If it is necessary to scroll backward more than n lines, the screen is repainted in a forward direction instead. (If the terminal does not have the ability to scroll backward, -h0 is implied.) -i or --ignore-case Causes searches to ignore case; that is, uppercase and lowercase - are considered identical. This option is ignored if any upper- - case letters appear in the search pattern; in other words, if a - pattern contains uppercase letters, then that search does not + are considered identical. This option is ignored if any upper- + case letters appear in the search pattern; in other words, if a + pattern contains uppercase letters, then that search does not ignore case. -I or --IGNORE-CASE - Like -i, but searches ignore case even if the pattern contains + Like -i, but searches ignore case even if the pattern contains uppercase letters. -jn or --jump-target=n - Specifies a line on the screen where the "target" line is to be - positioned. The target line is the line specified by any com- - mand to search for a pattern, jump to a line number, jump to a + Specifies a line on the screen where the "target" line is to be + positioned. The target line is the line specified by any com- + mand to search for a pattern, jump to a line number, jump to a file percentage or jump to a tag. The screen line may be speci- - fied by a number: the top line on the screen is 1, the next is + fied by a number: the top line on the screen is 1, the next is 2, and so on. The number may be negative to specify a line rel- ative to the bottom of the screen: the bottom line on the screen - is -1, the second to the bottom is -2, and so on. Alternately, - the screen line may be specified as a fraction of the height of - the screen, starting with a decimal point: .5 is in the middle - of the screen, .3 is three tenths down from the first line, and - so on. If the line is specified as a fraction, the actual line - number is recalculated if the terminal window is resized, so - that the target line remains at the specified fraction of the - screen height. If any form of the -j option is used, forward - searches begin at the line immediately after the target line, + is -1, the second to the bottom is -2, and so on. Alternately, + the screen line may be specified as a fraction of the height of + the screen, starting with a decimal point: .5 is in the middle + of the screen, .3 is three tenths down from the first line, and + so on. If the line is specified as a fraction, the actual line + number is recalculated if the terminal window is resized, so + that the target line remains at the specified fraction of the + screen height. If any form of the -j option is used, forward + searches begin at the line immediately after the target line, and backward searches begin at the target line. For example, if "-j4" is used, the target line is the fourth line on the screen, so forward searches begin at the fifth line on the screen. -J or --status-column - Displays a status column at the left edge of the screen. The - status column shows the lines that matched the current search. - The status column is also used if the -w or -W option is in + Displays a status column at the left edge of the screen. The + status column shows the lines that matched the current search. + The status column is also used if the -w or -W option is in effect. -kfilename or --lesskey-file=filename - Causes less to open and interpret the named file as a lesskey + Causes less to open and interpret the named file as a lesskey (1) file. Multiple -k options may be specified. If the LESSKEY - or LESSKEY_SYSTEM environment variable is set, or if a lesskey + or LESSKEY_SYSTEM environment variable is set, or if a lesskey file is found in a standard place (see KEY BINDINGS), it is also used as a lesskey file. -K or --quit-on-intr - Causes less to exit immediately when an interrupt character - (usually ^C) is typed. Normally, an interrupt character causes - less to stop whatever it is doing and return to its command - prompt. Note that use of this option makes it impossible to + Causes less to exit immediately when an interrupt character + (usually ^C) is typed. Normally, an interrupt character causes + less to stop whatever it is doing and return to its command + prompt. Note that use of this option makes it impossible to return to the command prompt from the "F" command. -L or --no-lessopen - Ignore the LESSOPEN environment variable (see the INPUT PREPRO- - CESSOR section below). This option can be set from within less, - but it will apply only to files opened subsequently, not to the - file which is currently open. + Ignore the LESSOPEN environment variable (see the INPUT PRE- + PROCESSOR section below). This option can be set from within + less, but it will apply only to files opened subsequently, not + to the file which is currently open. -m or --long-prompt - Causes less to prompt verbosely (like more), with the percent + Causes less to prompt verbosely (like more), with the percent into the file. By default, less prompts with a colon. -M or --LONG-PROMPT Causes less to prompt even more verbosely than more. -n or --line-numbers - Suppresses line numbers. The default (to use line numbers) may - cause less to run more slowly in some cases, especially with a - very large input file. Suppressing line numbers with the -n - option will avoid this problem. Using line numbers means: the + Suppresses line numbers. The default (to use line numbers) may + cause less to run more slowly in some cases, especially with a + very large input file. Suppressing line numbers with the -n + option will avoid this problem. Using line numbers means: the line number will be displayed in the verbose prompt and in the = - command, and the v command will pass the current line number to - the editor (see also the discussion of LESSEDIT in PROMPTS + command, and the v command will pass the current line number to + the editor (see also the discussion of LESSEDIT in PROMPTS below). -N or --LINE-NUMBERS - Causes a line number to be displayed at the beginning of each + Causes a line number to be displayed at the beginning of each line in the display. -ofilename or --log-file=filename - Causes less to copy its input to the named file as it is being + Causes less to copy its input to the named file as it is being viewed. This applies only when the input file is a pipe, not an - ordinary file. If the file already exists, less will ask for + ordinary file. If the file already exists, less will ask for confirmation before overwriting it. -Ofilename or --LOG-FILE=filename The -O option is like -o, but it will overwrite an existing file without asking for confirmation. - If no log file has been specified, the -o and -O options can be - used from within less to specify a log file. Without a file + If no log file has been specified, the -o and -O options can be + used from within less to specify a log file. Without a file name, they will simply report the name of the log file. The "s" command is equivalent to specifying -o from within less. -ppattern or --pattern=pattern - The -p option on the command line is equivalent to specifying - +/pattern; that is, it tells less to start at the first occur- + The -p option on the command line is equivalent to specifying + +/pattern; that is, it tells less to start at the first occur- rence of pattern in the file. -Pprompt or --prompt=prompt - Provides a way to tailor the three prompt styles to your own + Provides a way to tailor the three prompt styles to your own preference. This option would normally be put in the LESS envi- ronment variable, rather than being typed in with each less com- mand. Such an option must either be the last option in the LESS - variable, or be terminated by a dollar sign. -Ps followed by a - string changes the default (short) prompt to that string. -Pm - changes the medium (-m) prompt. -PM changes the long (-M) - prompt. -Ph changes the prompt for the help screen. -P= - changes the message printed by the = command. -Pw changes the - message printed while waiting for data (in the F command). All - prompt strings consist of a sequence of letters and special - escape sequences. See the section on PROMPTS for more details. + variable, or be terminated by a dollar sign. -Ps followed by a + string changes the default (short) prompt to that string. -Pm + changes the medium (-m) prompt. -PM changes the long (-M) + prompt. -Ph changes the prompt for the help screen. -P= + changes the message printed by the = command. -Pw changes the + message printed while waiting for data (in the F command). All + prompt strings consist of a sequence of letters and special + escape sequences. See the section on PROMPTS for more details. -q or --quiet or --silent - Causes moderately "quiet" operation: the terminal bell is not + Causes moderately "quiet" operation: the terminal bell is not rung if an attempt is made to scroll past the end of the file or before the beginning of the file. If the terminal has a "visual - bell", it is used instead. The bell will be rung on certain - other errors, such as typing an invalid character. The default + bell", it is used instead. The bell will be rung on certain + other errors, such as typing an invalid character. The default is to ring the terminal bell in all such cases. -Q or --QUIET or --SILENT - Causes totally "quiet" operation: the terminal bell is never + Causes totally "quiet" operation: the terminal bell is never rung. -r or --raw-control-chars Causes "raw" control characters to be displayed. The default is - to display control characters using the caret notation; for + to display control characters using the caret notation; for example, a control-A (octal 001) is displayed as "^A". Warning: when the -r option is used, less cannot keep track of the actual - appearance of the screen (since this depends on how the screen + appearance of the screen (since this depends on how the screen responds to each type of control character). Thus, various dis- - play problems may result, such as long lines being split in the + play problems may result, such as long lines being split in the wrong place. -R or --RAW-CONTROL-CHARS - Like -r, but only ANSI "color" escape sequences are output in + Like -r, but only ANSI "color" escape sequences are output in "raw" form. Unlike -r, the screen appearance is maintained cor- rectly in most cases. ANSI "color" escape sequences are sequences of the form: ESC [ ... m - where the "..." is zero or more color specification characters - For the purpose of keeping track of screen appearance, ANSI - color escape sequences are assumed to not move the cursor. You - can make less think that characters other than "m" can end ANSI - color escape sequences by setting the environment variable + where the "..." is zero or more color specification characters + For the purpose of keeping track of screen appearance, ANSI + color escape sequences are assumed to not move the cursor. You + can make less think that characters other than "m" can end ANSI + color escape sequences by setting the environment variable LESSANSIENDCHARS to the list of characters which can end a color - escape sequence. And you can make less think that characters - other than the standard ones may appear between the ESC and the - m by setting the environment variable LESSANSIMIDCHARS to the + escape sequence. And you can make less think that characters + other than the standard ones may appear between the ESC and the + m by setting the environment variable LESSANSIMIDCHARS to the list of characters which can appear. -s or --squeeze-blank-lines - Causes consecutive blank lines to be squeezed into a single + Causes consecutive blank lines to be squeezed into a single blank line. This is useful when viewing nroff output. -S or --chop-long-lines - Causes lines longer than the screen width to be chopped rather - than folded. That is, the portion of a long line that does not - fit in the screen width is not shown. The default is to fold + Causes lines longer than the screen width to be chopped rather + than folded. That is, the portion of a long line that does not + fit in the screen width is not shown. The default is to fold long lines; that is, display the remainder on the next line. -ttag or --tag=tag The -t option, followed immediately by a TAG, will edit the file - containing that tag. For this to work, tag information must be - available; for example, there may be a file in the current + containing that tag. For this to work, tag information must be + available; for example, there may be a file in the current directory called "tags", which was previously built by ctags (1) or an equivalent command. If the environment variable LESSGLOB- - ALTAGS is set, it is taken to be the name of a command compati- - ble with global (1), and that command is executed to find the + ALTAGS is set, it is taken to be the name of a command compati- + ble with global (1), and that command is executed to find the tag. (See http://www.gnu.org/software/global/global.html). The - -t option may also be specified from within less (using the - - command) as a way of examining a new file. The command ":t" is + -t option may also be specified from within less (using the - + command) as a way of examining a new file. The command ":t" is equivalent to specifying -t from within less. -Ttagsfile or --tag-file=tagsfile Specifies a tags file to be used instead of "tags". -u or --underline-special - Causes backspaces and carriage returns to be treated as print- - able characters; that is, they are sent to the terminal when + Causes backspaces and carriage returns to be treated as print- + able characters; that is, they are sent to the terminal when they appear in the input. -U or --UNDERLINE-SPECIAL - Causes backspaces, tabs and carriage returns to be treated as - control characters; that is, they are handled as specified by + Causes backspaces, tabs and carriage returns to be treated as + control characters; that is, they are handled as specified by the -r option. - By default, if neither -u nor -U is given, backspaces which - appear adjacent to an underscore character are treated spe- - cially: the underlined text is displayed using the terminal's - hardware underlining capability. Also, backspaces which appear - between two identical characters are treated specially: the - overstruck text is printed using the terminal's hardware bold- - face capability. Other backspaces are deleted, along with the + By default, if neither -u nor -U is given, backspaces which + appear adjacent to an underscore character are treated spe- + cially: the underlined text is displayed using the terminal's + hardware underlining capability. Also, backspaces which appear + between two identical characters are treated specially: the + overstruck text is printed using the terminal's hardware bold- + face capability. Other backspaces are deleted, along with the preceding character. Carriage returns immediately followed by a - newline are deleted. other carriage returns are handled as - specified by the -r option. Text which is overstruck or under- + newline are deleted. other carriage returns are handled as + specified by the -r option. Text which is overstruck or under- lined can be searched for if neither -u nor -U is in effect. -V or --version Displays the version number of less. -w or --hilite-unread - Temporarily highlights the first "new" line after a forward + Temporarily highlights the first "new" line after a forward movement of a full page. The first "new" line is the line imme- - diately following the line previously at the bottom of the + diately following the line previously at the bottom of the screen. Also highlights the target line after a g or p command. - The highlight is removed at the next command which causes move- - ment. The entire line is highlighted, unless the -J option is - in effect, in which case only the status column is highlighted. + The highlight is removed at the next command which causes move- + ment. The entire line is highlighted, unless the -J option is + in effect, in which case only the status column is highlighted. -W or --HILITE-UNREAD Like -w, but temporarily highlights the first new line after any forward movement command larger than one line. -xn,... or --tabs=n,... - Sets tab stops. If only one n is specified, tab stops are set - at multiples of n. If multiple values separated by commas are - specified, tab stops are set at those positions, and then con- - tinue with the same spacing as the last two. For example, - -x9,17 will set tabs at positions 9, 17, 25, 33, etc. The + Sets tab stops. If only one n is specified, tab stops are set + at multiples of n. If multiple values separated by commas are + specified, tab stops are set at those positions, and then con- + tinue with the same spacing as the last two. For example, + -x9,17 will set tabs at positions 9, 17, 25, 33, etc. The default for n is 8. -X or --no-init Disables sending the termcap initialization and deinitialization - strings to the terminal. This is sometimes desirable if the - deinitialization string does something unnecessary, like clear- + strings to the terminal. This is sometimes desirable if the + deinitialization string does something unnecessary, like clear- ing the screen. -yn or --max-forw-scroll=n Specifies a maximum number of lines to scroll forward. If it is - necessary to scroll forward more than n lines, the screen is - repainted instead. The -c or -C option may be used to repaint - from the top of the screen if desired. By default, any forward + necessary to scroll forward more than n lines, the screen is + repainted instead. The -c or -C option may be used to repaint + from the top of the screen if desired. By default, any forward movement causes scrolling. -[z]n or --window=n - Changes the default scrolling window size to n lines. The + Changes the default scrolling window size to n lines. The default is one screenful. The z and w commands can also be used - to change the window size. The "z" may be omitted for compati- + to change the window size. The "z" may be omitted for compati- bility with some versions of more. If the number n is negative, - it indicates n lines less than the current screen size. For + it indicates n lines less than the current screen size. For example, if the screen is 24 lines, -z-4 sets the scrolling win- - dow to 20 lines. If the screen is resized to 40 lines, the + dow to 20 lines. If the screen is resized to 40 lines, the scrolling window automatically changes to 36 lines. -"cc or --quotes=cc - Changes the filename quoting character. This may be necessary - if you are trying to name a file which contains both spaces and - quote characters. Followed by a single character, this changes - the quote character to that character. Filenames containing a + Changes the filename quoting character. This may be necessary + if you are trying to name a file which contains both spaces and + quote characters. Followed by a single character, this changes + the quote character to that character. Filenames containing a space should then be surrounded by that character rather than by - double quotes. Followed by two characters, changes the open - quote to the first character, and the close quote to the second + double quotes. Followed by two characters, changes the open + quote to the first character, and the close quote to the second character. Filenames containing a space should then be preceded - by the open quote character and followed by the close quote - character. Note that even after the quote characters are - changed, this option remains -" (a dash followed by a double + by the open quote character and followed by the close quote + character. Note that even after the quote characters are + changed, this option remains -" (a dash followed by a double quote). -~ or --tilde @@ -790,53 +807,54 @@ LESS(1) LESS(1) -# or --shift Specifies the default number of positions to scroll horizontally - in the RIGHTARROW and LEFTARROW commands. If the number speci- - fied is zero, it sets the default number of positions to one + in the RIGHTARROW and LEFTARROW commands. If the number speci- + fied is zero, it sets the default number of positions to one half of the screen width. --no-keypad - Disables sending the keypad initialization and deinitialization + Disables sending the keypad initialization and deinitialization strings to the terminal. This is sometimes useful if the keypad strings make the numeric keypad behave in an undesirable manner. --follow-name - Normally, if the input file is renamed while an F command is - executing, less will continue to display the contents of the - original file despite its name change. If --follow-name is + Normally, if the input file is renamed while an F command is + executing, less will continue to display the contents of the + original file despite its name change. If --follow-name is specified, during an F command less will periodically attempt to reopen the file by name. If the reopen succeeds and the file is - a different file from the original (which means that a new file - has been created with the same name as the original (now + a different file from the original (which means that a new file + has been created with the same name as the original (now renamed) file), less will display the contents of that new file. - -- A command line argument of "--" marks the end of option argu- - ments. Any arguments following this are interpreted as file- + -- A command line argument of "--" marks the end of option argu- + ments. Any arguments following this are interpreted as file- names. This can be useful when viewing a file whose name begins with a "-" or "+". - + If a command line option begins with +, the remainder of that - option is taken to be an initial command to less. For example, - +G tells less to start at the end of the file rather than the - beginning, and +/xyz tells it to start at the first occurrence - of "xyz" in the file. As a special case, + acts like + + If a command line option begins with +, the remainder of that + option is taken to be an initial command to less. For example, + +G tells less to start at the end of the file rather than the + beginning, and +/xyz tells it to start at the first occurrence + of "xyz" in the file. As a special case, + acts like +g; that is, it starts the display at the specified line - number (however, see the caveat under the "g" command above). - If the option starts with ++, the initial command applies to - every file being viewed, not just the first one. The + command + number (however, see the caveat under the "g" command above). + If the option starts with ++, the initial command applies to + every file being viewed, not just the first one. The + command described previously may also be used to set (or change) an ini- tial command for every file. LINE EDITING - When entering command line at the bottom of the screen (for example, a + When entering command line at the bottom of the screen (for example, a filename for the :e command, or the pattern for a search command), cer- - tain keys can be used to manipulate the command line. Most commands - have an alternate form in [ brackets ] which can be used if a key does - not exist on a particular keyboard. (The bracketed forms do not work - in the MS-DOS version.) Any of these special keys may be entered lit- - erally by preceding it with the "literal" character, either ^V or ^A. - A backslash itself may also be entered literally by entering two back- - slashes. + tain keys can be used to manipulate the command line. Most commands + have an alternate form in [ brackets ] which can be used if a key does + not exist on a particular keyboard. (Note that the forms beginning + with ESC do not work in some MS-DOS and Windows systems because ESC is + the line erase character.) Any of these special keys may be entered + literally by preceding it with the "literal" character, either ^V or + ^A. A backslash itself may also be entered literally by entering two + backslashes. LEFTARROW [ ESC-h ] Move the cursor one space to the left. @@ -1021,6 +1039,11 @@ LESS(1) LESS(1) is no replacement file to clean up. In this case, the replacement file name passed to the LESSCLOSE postprocessor is "-". + For compatibility with previous versions of less, the input pipe is not + used if less is viewing standard input. However, if the character + after the vertical bar is a dash (-), the input pipe is used on stan- + dard input as well as other files. + NATIONAL CHARACTER SETS There are three types of characters in the input file: @@ -1029,25 +1052,25 @@ LESS(1) LESS(1) can be displayed directly to the screen. control characters - should not be displayed directly, but are expected to be found + should not be displayed directly, but are expected to be found in ordinary text files (such as backspace and tab). binary characters - should not be displayed directly and are not expected to be + should not be displayed directly and are not expected to be found in text files. A "character set" is simply a description of which characters are to be - considered normal, control, and binary. The LESSCHARSET environment - variable may be used to select a character set. Possible values for + considered normal, control, and binary. The LESSCHARSET environment + variable may be used to select a character set. Possible values for LESSCHARSET are: - ascii BS, TAB, NL, CR, and formfeed are control characters, all chars - with values between 32 and 126 are normal, and all others are + ascii BS, TAB, NL, CR, and formfeed are control characters, all chars + with values between 32 and 126 are normal, and all others are binary. iso8859 - Selects an ISO 8859 character set. This is the same as ASCII, - except characters between 160 and 255 are treated as normal + Selects an ISO 8859 character set. This is the same as ASCII, + except characters between 160 and 255 are treated as normal characters. latin1 Same as iso8859. @@ -1059,8 +1082,8 @@ LESS(1) LESS(1) ebcdic Selects an EBCDIC character set. IBM-1047 - Selects an EBCDIC character set used by OS/390 Unix Services. - This is the EBCDIC analogue of latin1. You get similar results + Selects an EBCDIC character set used by OS/390 Unix Services. + This is the EBCDIC analogue of latin1. You get similar results by setting either LESSCHARSET=IBM-1047 or LC_CTYPE=en_US in your environment. @@ -1068,29 +1091,29 @@ LESS(1) LESS(1) next Selects a character set appropriate for NeXT computers. - utf-8 Selects the UTF-8 encoding of the ISO 10646 character set. - UTF-8 is special in that it supports multi-byte characters in - the input file. It is the only character set that supports + utf-8 Selects the UTF-8 encoding of the ISO 10646 character set. + UTF-8 is special in that it supports multi-byte characters in + the input file. It is the only character set that supports multi-byte characters. windows - Selects a character set appropriate for Microsoft Windows (cp + Selects a character set appropriate for Microsoft Windows (cp 1251). - In special cases, it may be desired to tailor less to use a character - set other than the ones definable by LESSCHARSET. In this case, the - environment variable LESSCHARDEF can be used to define a character set. - It should be set to a string where each character in the string repre- - sents one character in the character set. The character "." is used - for a normal character, "c" for control, and "b" for binary. A decimal - number may be used for repetition. For example, "bccc4b." would mean - character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are + In rare cases, it may be desired to tailor less to use a character set + other than the ones definable by LESSCHARSET. In this case, the envi- + ronment variable LESSCHARDEF can be used to define a character set. It + should be set to a string where each character in the string represents + one character in the character set. The character "." is used for a + normal character, "c" for control, and "b" for binary. A decimal num- + ber may be used for repetition. For example, "bccc4b." would mean + character 0 is binary, 1, 2 and 3 are control, 4, 5, 6 and 7 are binary, and 8 is normal. All characters after the last are taken to be - the same as the last, so characters 9 through 255 would be normal. - (This is an example, and does not necessarily represent any real char- + the same as the last, so characters 9 through 255 would be normal. + (This is an example, and does not necessarily represent any real char- acter set.) - This table shows the value of LESSCHARDEF which is equivalent to each + This table shows the value of LESSCHARDEF which is equivalent to each of the possible values for LESSCHARSET: ascii 8bcccbcc18b95.b @@ -1104,66 +1127,66 @@ LESS(1) LESS(1) latin1 8bcccbcc18b95.33b. next 8bcccbcc18b95.bb125.bb - If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings - "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_TYPE or + If neither LESSCHARSET nor LESSCHARDEF is set, but any of the strings + "UTF-8", "UTF8", "utf-8" or "utf8" is found in the LC_ALL, LC_TYPE or LANG environment variables, then the default character set is utf-8. - If that string is not found, but your system supports the setlocale - interface, less will use setlocale to determine the character set. - setlocale is controlled by setting the LANG or LC_CTYPE environment + If that string is not found, but your system supports the setlocale + interface, less will use setlocale to determine the character set. + setlocale is controlled by setting the LANG or LC_CTYPE environment variables. - Finally, if the setlocale interface is also not available, the default + Finally, if the setlocale interface is also not available, the default character set is latin1. - Control and binary characters are displayed in standout (reverse + Control and binary characters are displayed in standout (reverse video). Each such character is displayed in caret notation if possible - (e.g. ^A for control-A). Caret notation is used only if inverting the + (e.g. ^A for control-A). Caret notation is used only if inverting the 0100 bit results in a normal printable character. Otherwise, the char- - acter is displayed as a hex number in angle brackets. This format can - be changed by setting the LESSBINFMT environment variable. LESSBINFMT + acter is displayed as a hex number in angle brackets. This format can + be changed by setting the LESSBINFMT environment variable. LESSBINFMT may begin with a "*" and one character to select the display attribute: - "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout, - and "*n" is normal. If LESSBINFMT does not begin with a "*", normal - attribute is assumed. The remainder of LESSBINFMT is a string which - may include one printf-style escape sequence (a % followed by x, X, o, - d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters - are displayed in underlined hexadecimal surrounded by brackets. The - default if no LESSBINFMT is specified is "*s<%X>". The default if no - LESSBINFMT is specified is "*s<%02X>". Warning: the result of expand- + "*k" is blinking, "*d" is bold, "*u" is underlined, "*s" is standout, + and "*n" is normal. If LESSBINFMT does not begin with a "*", normal + attribute is assumed. The remainder of LESSBINFMT is a string which + may include one printf-style escape sequence (a % followed by x, X, o, + d, etc.). For example, if LESSBINFMT is "*u[%x]", binary characters + are displayed in underlined hexadecimal surrounded by brackets. The + default if no LESSBINFMT is specified is "*s<%X>". The default if no + LESSBINFMT is specified is "*s<%02X>". Warning: the result of expand- ing the character via LESSBINFMT must be less than 31 characters. When the character set is utf-8, the LESSUTFBINFMT environment variable acts similarly to LESSBINFMT but it applies to Unicode code points that - were successfully decoded but are unsuitable for display (e.g., unas- - signed code points). Its default value is "". Note that - LESSUTFBINFMT and LESSBINFMT share their display attribute setting - ("*x") so specifying one will affect both; LESSUTFBINFMT is read after - LESSBINFMT so its setting, if any, will have priority. Problematic - octets in a UTF-8 file (octets of a truncated sequence, octets of a - complete but non-shortest form sequence, illegal octets, and stray - trailing octets) are displayed individually using LESSBINFMT so as to + were successfully decoded but are unsuitable for display (e.g., unas- + signed code points). Its default value is "". Note that + LESSUTFBINFMT and LESSBINFMT share their display attribute setting + ("*x") so specifying one will affect both; LESSUTFBINFMT is read after + LESSBINFMT so its setting, if any, will have priority. Problematic + octets in a UTF-8 file (octets of a truncated sequence, octets of a + complete but non-shortest form sequence, illegal octets, and stray + trailing octets) are displayed individually using LESSBINFMT so as to facilitate diagnostic of how the UTF-8 file is ill-formed. PROMPTS - The -P option allows you to tailor the prompt to your preference. The - string given to the -P option replaces the specified prompt string. + The -P option allows you to tailor the prompt to your preference. The + string given to the -P option replaces the specified prompt string. Certain characters in the string are interpreted specially. The prompt - mechanism is rather complicated to provide flexibility, but the ordi- - nary user need not understand the details of constructing personalized + mechanism is rather complicated to provide flexibility, but the ordi- + nary user need not understand the details of constructing personalized prompt strings. - A percent sign followed by a single character is expanded according to + A percent sign followed by a single character is expanded according to what the following character is: - %bX Replaced by the byte offset into the current input file. The b + %bX Replaced by the byte offset into the current input file. The b is followed by a single character (shown as X above) which spec- - ifies the line whose byte offset is to be used. If the charac- - ter is a "t", the byte offset of the top line in the display is + ifies the line whose byte offset is to be used. If the charac- + ter is a "t", the byte offset of the top line in the display is used, an "m" means use the middle line, a "b" means use the bot- - tom line, a "B" means use the line just after the bottom line, - and a "j" means use the "target" line, as specified by the -j + tom line, a "B" means use the line just after the bottom line, + and a "j" means use the "target" line, as specified by the -j option. %B Replaced by the size of the current input file. @@ -1171,39 +1194,39 @@ LESS(1) LESS(1) %c Replaced by the column number of the text appearing in the first column of the screen. - %dX Replaced by the page number of a line in the input file. The + %dX Replaced by the page number of a line in the input file. The line to be used is determined by the X, as with the %b option. - %D Replaced by the number of pages in the input file, or equiva- + %D Replaced by the number of pages in the input file, or equiva- lently, the page number of the last line in the input file. - %E Replaced by the name of the editor (from the VISUAL environment - variable, or the EDITOR environment variable if VISUAL is not + %E Replaced by the name of the editor (from the VISUAL environment + variable, or the EDITOR environment variable if VISUAL is not defined). See the discussion of the LESSEDIT feature below. %f Replaced by the name of the current input file. - %i Replaced by the index of the current file in the list of input + %i Replaced by the index of the current file in the list of input files. - %lX Replaced by the line number of a line in the input file. The + %lX Replaced by the line number of a line in the input file. The line to be used is determined by the X, as with the %b option. - %L Replaced by the line number of the last line in the input file. + %L Replaced by the line number of the last line in the input file. %m Replaced by the total number of input files. - %pX Replaced by the percent into the current input file, based on - byte offsets. The line used is determined by the X as with the + %pX Replaced by the percent into the current input file, based on + byte offsets. The line used is determined by the X as with the %b option. - %PX Replaced by the percent into the current input file, based on - line numbers. The line used is determined by the X as with the + %PX Replaced by the percent into the current input file, based on + line numbers. The line used is determined by the X as with the %b option. %s Same as %B. - %t Causes any trailing spaces to be removed. Usually used at the + %t Causes any trailing spaces to be removed. Usually used at the end of the string, but may appear anywhere. %x Replaced by the name of the next input file in the list. @@ -1211,18 +1234,18 @@ LESS(1) LESS(1) If any item is unknown (for example, the file size if input is a pipe), a question mark is printed instead. - The format of the prompt string can be changed depending on certain - conditions. A question mark followed by a single character acts like - an "IF": depending on the following character, a condition is evalu- - ated. If the condition is true, any characters following the question - mark and condition character, up to a period, are included in the - prompt. If the condition is false, such characters are not included. - A colon appearing between the question mark and the period can be used + The format of the prompt string can be changed depending on certain + conditions. A question mark followed by a single character acts like + an "IF": depending on the following character, a condition is evalu- + ated. If the condition is true, any characters following the question + mark and condition character, up to a period, are included in the + prompt. If the condition is false, such characters are not included. + A colon appearing between the question mark and the period can be used to establish an "ELSE": any characters between the colon and the period - are included in the string if and only if the IF condition is false. + are included in the string if and only if the IF condition is false. Condition characters (which follow a question mark) may be: - ?a True if any characters have been included in the prompt so far. + ?a True if any characters have been included in the prompt so far. ?bX True if the byte offset of the specified line is known. @@ -1234,7 +1257,7 @@ LESS(1) LESS(1) ?e True if at end-of-file. - ?f True if there is an input filename (that is, if input is not a + ?f True if there is an input filename (that is, if input is not a pipe). ?lX True if the line number of the specified line is known. @@ -1245,46 +1268,46 @@ LESS(1) LESS(1) ?n True if this is the first prompt in a new input file. - ?pX True if the percent into the current input file, based on byte + ?pX True if the percent into the current input file, based on byte offsets, of the specified line is known. - ?PX True if the percent into the current input file, based on line + ?PX True if the percent into the current input file, based on line numbers, of the specified line is known. ?s Same as "?B". - ?x True if there is a next input file (that is, if the current + ?x True if there is a next input file (that is, if the current input file is not the last one). - Any characters other than the special ones (question mark, colon, - period, percent, and backslash) become literally part of the prompt. - Any of the special characters may be included in the prompt literally + Any characters other than the special ones (question mark, colon, + period, percent, and backslash) become literally part of the prompt. + Any of the special characters may be included in the prompt literally by preceding it with a backslash. Some examples: ?f%f:Standard input. - This prompt prints the filename, if known; otherwise the string "Stan- + This prompt prints the filename, if known; otherwise the string "Stan- dard input". ?f%f .?ltLine %lt:?pt%pt\%:?btByte %bt:-... - This prompt would print the filename, if known. The filename is fol- - lowed by the line number, if known, otherwise the percent if known, - otherwise the byte offset if known. Otherwise, a dash is printed. - Notice how each question mark has a matching period, and how the % + This prompt would print the filename, if known. The filename is fol- + lowed by the line number, if known, otherwise the percent if known, + otherwise the byte offset if known. Otherwise, a dash is printed. + Notice how each question mark has a matching period, and how the % after the %pt is included literally by escaping it with a backslash. ?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x..%t - This prints the filename if this is the first prompt in a file, fol- - lowed by the "file N of N" message if there is more than one input - file. Then, if we are at end-of-file, the string "(END)" is printed - followed by the name of the next file, if there is one. Finally, any + This prints the filename if this is the first prompt in a file, fol- + lowed by the "file N of N" message if there is more than one input + file. Then, if we are at end-of-file, the string "(END)" is printed + followed by the name of the next file, if there is one. Finally, any trailing spaces are truncated. This is the default prompt. For refer- - ence, here are the defaults for the other two prompts (-m and -M - respectively). Each is broken into two lines here for readability + ence, here are the defaults for the other two prompts (-m and -M + respectively). Each is broken into two lines here for readability only. ?n?f%f .?m(file %i of %m) ..?e(END) ?x- Next\: %x.: @@ -1298,22 +1321,22 @@ LESS(1) LESS(1) ?f%f .?m(file %i of %m) .?ltlines %lt-%lb?L/%L. . byte %bB?s/%s. ?e(END) :?pB%pB\%..%t - The prompt expansion features are also used for another purpose: if an - environment variable LESSEDIT is defined, it is used as the command to - be executed when the v command is invoked. The LESSEDIT string is - expanded in the same way as the prompt strings. The default value for + The prompt expansion features are also used for another purpose: if an + environment variable LESSEDIT is defined, it is used as the command to + be executed when the v command is invoked. The LESSEDIT string is + expanded in the same way as the prompt strings. The default value for LESSEDIT is: %E ?lm+%lm. %f Note that this expands to the editor name, followed by a + and the line - number, followed by the file name. If your editor does not accept the - "+linenumber" syntax, or has other differences in invocation syntax, + number, followed by the file name. If your editor does not accept the + "+linenumber" syntax, or has other differences in invocation syntax, the LESSEDIT variable can be changed to modify this default. SECURITY - When the environment variable LESSSECURE is set to 1, less runs in a + When the environment variable LESSSECURE is set to 1, less runs in a "secure" mode. This means these features are disabled: ! the shell command @@ -1339,54 +1362,54 @@ LESS(1) LESS(1) COMPATIBILITY WITH MORE If the environment variable LESS_IS_MORE is set to 1, or if the program - is invoked via a file link named "more", less behaves (mostly) in con- - formance with the POSIX "more" command specification. In this mode, + is invoked via a file link named "more", less behaves (mostly) in con- + formance with the POSIX "more" command specification. In this mode, less behaves differently in these ways: - The -e option works differently. If the -e option is not set, less - behaves as if the -E option were set. If the -e option is set, less + The -e option works differently. If the -e option is not set, less + behaves as if the -E option were set. If the -e option is set, less behaves as if the -e and -F options were set. - The -m option works differently. If the -m option is not set, the - medium prompt is used, and it is prefixed with the string "--More--". + The -m option works differently. If the -m option is not set, the + medium prompt is used, and it is prefixed with the string "--More--". If the -m option is set, the short prompt is used. - The -n option acts like the -z option. The normal behavior of the -n + The -n option acts like the -z option. The normal behavior of the -n option is unavailable in this mode. - The parameter to the -p option is taken to be a less command rather + The parameter to the -p option is taken to be a less command rather than a search pattern. - The LESS environment variable is ignored, and the MORE environment + The LESS environment variable is ignored, and the MORE environment variable is used in its place. ENVIRONMENT VARIABLES Environment variables may be specified either in the system environment - as usual, or in a lesskey (1) file. If environment variables are - defined in more than one place, variables defined in a local lesskey - file take precedence over variables defined in the system environment, + as usual, or in a lesskey (1) file. If environment variables are + defined in more than one place, variables defined in a local lesskey + file take precedence over variables defined in the system environment, which take precedence over variables defined in the system-wide lesskey file. COLUMNS Sets the number of columns on the screen. Takes precedence over - the number of columns specified by the TERM variable. (But if + the number of columns specified by the TERM variable. (But if you have a windowing system which supports TIOCGWINSZ or - WIOCGETD, the window system's idea of the screen size takes + WIOCGETD, the window system's idea of the screen size takes precedence over the LINES and COLUMNS environment variables.) EDITOR The name of the editor (used for the v command). - HOME Name of the user's home directory (used to find a lesskey file + HOME Name of the user's home directory (used to find a lesskey file on Unix and OS/2 systems). HOMEDRIVE, HOMEPATH - Concatenation of the HOMEDRIVE and HOMEPATH environment vari- + Concatenation of the HOMEDRIVE and HOMEPATH environment vari- ables is the name of the user's home directory if the HOME vari- able is not set (only in the Windows version). - INIT Name of the user's init directory (used to find a lesskey file + INIT Name of the user's init directory (used to find a lesskey file on OS/2 systems). LANG Language for determining the character set. @@ -1397,12 +1420,12 @@ LESS(1) LESS(1) LESS Options which are passed to less automatically. LESSANSIENDCHARS - Characters which may end an ANSI color escape sequence (default + Characters which may end an ANSI color escape sequence (default "m"). LESSANSIMIDCHARS - Characters which may appear between the ESC character and the - end character in an ANSI color escape sequence (default + Characters which may appear between the ESC character and the + end character in an ANSI color escape sequence (default "0123456789;[?!"'#%()*+ ". LESSBINFMT @@ -1419,24 +1442,24 @@ LESS(1) LESS(1) LESSECHO Name of the lessecho program (default "lessecho"). The lessecho - program is needed to expand metacharacters, such as * and ?, in + program is needed to expand metacharacters, such as * and ?, in filenames on Unix systems. LESSEDIT - Editor prototype string (used for the v command). See discus- + Editor prototype string (used for the v command). See discus- sion under PROMPTS. LESSGLOBALTAGS - Name of the command used by the -t option to find global tags. + Name of the command used by the -t option to find global tags. Normally should be set to "global" if your system has the global (1) command. If not set, global tags are not used. LESSHISTFILE - Name of the history file used to remember search commands and - shell commands between invocations of less. If set to "-" or - "/dev/null", a history file is not used. The default is - "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on DOS and - Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini" + Name of the history file used to remember search commands and + shell commands between invocations of less. If set to "-" or + "/dev/null", a history file is not used. The default is + "$HOME/.lesshst" on Unix systems, "$HOME/_lesshst" on DOS and + Windows systems, or "$HOME/lesshst.ini" or "$INIT/lesshst.ini" on OS/2 systems. LESSHISTSIZE @@ -1450,13 +1473,13 @@ LESS(1) LESS(1) Name of the default system-wide lesskey(1) file. LESSMETACHARS - List of characters which are considered "metacharacters" by the + List of characters which are considered "metacharacters" by the shell. LESSMETAESCAPE - Prefix which less will add before each metacharacter in a com- - mand sent to the shell. If LESSMETAESCAPE is an empty string, - commands containing metacharacters will not be passed to the + Prefix which less will add before each metacharacter in a com- + mand sent to the shell. If LESSMETAESCAPE is an empty string, + commands containing metacharacters will not be passed to the shell. LESSOPEN @@ -1466,7 +1489,7 @@ LESS(1) LESS(1) Runs less in "secure" mode. See discussion under SECURITY. LESSSEPARATOR - String to be appended to a directory name in filename comple- + String to be appended to a directory name in filename comple- tion. LESSUTFBINFMT @@ -1475,16 +1498,16 @@ LESS(1) LESS(1) LESS_IS_MORE Emulate the more (1) command. - LINES Sets the number of lines on the screen. Takes precedence over + LINES Sets the number of lines on the screen. Takes precedence over the number of lines specified by the TERM variable. (But if you - have a windowing system which supports TIOCGWINSZ or WIOCGETD, - the window system's idea of the screen size takes precedence + have a windowing system which supports TIOCGWINSZ or WIOCGETD, + the window system's idea of the screen size takes precedence over the LINES and COLUMNS environment variables.) - PATH User's search path (used to find a lesskey file on MS-DOS and + PATH User's search path (used to find a lesskey file on MS-DOS and OS/2 systems). - SHELL The shell used to execute the ! command, as well as to expand + SHELL The shell used to execute the ! command, as well as to expand filenames. TERM The type of terminal on which less is being run. @@ -1496,59 +1519,29 @@ LESS(1) LESS(1) lesskey(1) -WARNINGS - The = command and prompts (unless changed by -P) report the line num- - bers of the lines at the top and bottom of the screen, but the byte and - percent of the line after the one at the bottom of the screen. - - On certain older terminals (the so-called "magic cookie" terminals), - search highlighting will cause an erroneous display. On such termi- - nals, search highlighting is disabled by default to avoid possible - problems. - - When searching in a binary file, text which follows a null byte may not - be found. This problem does not occur when searching with regular - expressions turned off via ^R, and also does not occur when less is - compiled to use the PCRE regular expression library. - - In certain cases, when search highlighting is enabled and a search pat- - tern begins with a ^, more text than the matching string may be high- - lighted. (This problem does not occur when less is compiled to use the - POSIX regular expression package.) - - On some systems, setlocale claims that ASCII characters 0 thru 31 are - control characters rather than binary characters. This causes less to - treat some binary files as ordinary, non-binary files. To workaround - this problem, set the environment variable LESSCHARSET to "ascii" (or - whatever character set is appropriate). - - This manual is too long. - - See http://www.greenwoodsoftware.com/less for the latest list of known - bugs in less. - - COPYRIGHT - Copyright (C) 1984-2007 Mark Nudelman + Copyright (C) 1984-2008 Mark Nudelman - less is part of the GNU project and is free software. You can redis- - tribute it and/or modify it under the terms of either (1) the GNU Gen- - eral Public License as published by the Free Software Foundation; or + less is part of the GNU project and is free software. You can redis- + tribute it and/or modify it under the terms of either (1) the GNU Gen- + eral Public License as published by the Free Software Foundation; or (2) the Less License. See the file README in the less distribution for more details regarding redistribution. You should have received a copy - of the GNU General Public License along with the source for less; see - the file COPYING. If not, write to the Free Software Foundation, 59 - Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also + of the GNU General Public License along with the source for less; see + the file COPYING. If not, write to the Free Software Foundation, 59 + Temple Place, Suite 330, Boston, MA 02111-1307, USA. You should also have received a copy of the Less License; see the file LICENSE. less is distributed in the hope that it will be useful, but WITHOUT ANY - WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- - NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + WARRANTY; without even the implied warranty of MERCHANTABILITY or FIT- + NESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. AUTHOR Mark Nudelman + See http://www.greenwoodsoftware.com/less/bugs.html for the latest list + of known bugs in less. Send bug reports or comments to the above address or to bug-less@gnu.org. For more information, see the less homepage at @@ -1556,4 +1549,4 @@ LESS(1) LESS(1) - Version 416: 22 Nov 2007 LESS(1) + Version 429: 11 Apr 2009 LESS(1) diff --git a/less.nro b/less.nro index d5dfb053498e..ca7958163523 100644 --- a/less.nro +++ b/less.nro @@ -1,4 +1,4 @@ -.TH LESS 1 "Version 416: 22 Nov 2007" +.TH LESS 1 "Version 429: 11 Apr 2009" .SH NAME less \- opposite of more .SH SYNOPSIS @@ -256,6 +256,23 @@ turn highlighting back on. Any search command will also turn highlighting back on. (Highlighting can also be disabled by toggling the \-G option; in that case search commands do not turn highlighting back on.) +.IP "&pattern" +Display only lines which match the pattern; +lines which do not match the pattern are not displayed. +If pattern is empty (if you type & immediately followed by ENTER), +any filtering is turned off, and all lines are displayed. +While filtering is in effect, an ampersand is displayed at the +beginning of the prompt, +as a reminder that some lines in the file may be hidden. +.sp +Certain characters are special as in the / command: +.RS +.IP "^N or !" +Display only lines which do NOT match the pattern. +.IP "^R" +Don't interpret regular expression metacharacters; +that is, do a simple textual comparison. +.RE .IP ":e [filename]" Examine a new file. If the filename is missing, the "current" file (see the :n and :p commands @@ -498,7 +515,9 @@ being set: n=normal, s=standout, d=bold, u=underlined, k=blink. \fIcolor\fP is a pair of numbers separated by a period. The first number selects the foreground color and the second selects the background color of the text. -A single number \fIN\fP is the same as \fIN.0\fP. +A single number \fIN\fP is the same as \fIN.M\fP, +where \fIM\fP is the normal background color. + .IP "\-e or \-\-quit-at-eof" Causes .I less @@ -890,7 +909,8 @@ or the pattern for a search command), certain keys can be used to manipulate the command line. Most commands have an alternate form in [ brackets ] which can be used if a key does not exist on a particular keyboard. -(The bracketed forms do not work in the MS-DOS version.) +(Note that the forms beginning with ESC do not work +in some MS-DOS and Windows systems because ESC is the line erase character.) Any of these special keys may be entered literally by preceding it with the "literal" character, either ^V or ^A. A backslash itself may also be entered literally by entering two backslashes. @@ -1126,6 +1146,14 @@ but it is usually not necessary since there is no replacement file to clean up. In this case, the replacement file name passed to the LESSCLOSE postprocessor is "\-". +.PP +For compatibility with previous versions of +.I less, +the input pipe is not used if +.I less +is viewing standard input. +However, if the character after the vertical bar is a dash (\-), +the input pipe is used on standard input as well as other files. .SH "NATIONAL CHARACTER SETS" There are three types of characters in the input file: @@ -1174,7 +1202,7 @@ It is the only character set that supports multi-byte characters. .IP windows Selects a character set appropriate for Microsoft Windows (cp 1251). .PP -In special cases, it may be desired to tailor +In rare cases, it may be desired to tailor .I less to use a character set other than the ones definable by LESSCHARSET. In this case, the environment variable LESSCHARDEF can be used @@ -1620,45 +1648,8 @@ The name of the editor (used for the v command). .SH "SEE ALSO" lesskey(1) -.SH WARNINGS -The = command and prompts (unless changed by \-P) -report the line numbers of the lines at the top and bottom of the screen, -but the byte and percent of the line after the one at the bottom of the screen. -.PP -On certain older terminals (the so-called "magic cookie" terminals), -search highlighting will cause an erroneous display. -On such terminals, search highlighting is disabled by default -to avoid possible problems. -.PP -When searching in a binary file, text which follows a null byte -may not be found. -This problem does not occur when searching with regular expressions turned -off via ^R, and also does not occur when -.I less -is compiled to use the PCRE regular expression library. -.PP -In certain cases, when search highlighting is enabled and -a search pattern begins with a ^, -more text than the matching string may be highlighted. -(This problem does not occur when less is compiled to use the POSIX -regular expression package.) -.PP -On some systems, -.I setlocale -claims that ASCII characters 0 thru 31 are control characters -rather than binary characters. -This causes -.I less -to treat some binary files as ordinary, non-binary files. -To workaround this problem, set the environment variable -LESSCHARSET to "ascii" (or whatever character set is appropriate). -.PP -This manual is too long. -.PP -See http://www.greenwoodsoftware.com/less for the latest list of known bugs in less. - .SH COPYRIGHT -Copyright (C) 1984-2007 Mark Nudelman +Copyright (C) 1984-2008 Mark Nudelman .PP less is part of the GNU project and is free software. You can redistribute it and/or modify it @@ -1683,6 +1674,8 @@ See the GNU General Public License for more details. .PP Mark Nudelman .br +See http://www.greenwoodsoftware.com/less/bugs.html for the latest list of known bugs in less. +.br Send bug reports or comments to the above address or to .br bug-less@gnu.org. diff --git a/lessecho.c b/lessecho.c index ac42c062e6b1..bb1c152324e9 100644 --- a/lessecho.c +++ b/lessecho.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -28,7 +28,7 @@ #include "less.h" -static char *version = "$Revision: 1.11 $"; +static char *version = "$Revision: 1.12 $"; static int quote_all = 0; static char openquote = '"'; diff --git a/lessecho.man b/lessecho.man index 98f059144b2e..a7820d278f97 100644 --- a/lessecho.man +++ b/lessecho.man @@ -46,4 +46,4 @@ LESSECHO(1) LESSECHO(1) - Version 416: 22 Nov 2007 LESSECHO(1) + Version 429: 11 Apr 2009 LESSECHO(1) diff --git a/lessecho.nro b/lessecho.nro index 05542f79f4ee..be26a8fd9cf9 100644 --- a/lessecho.nro +++ b/lessecho.nro @@ -1,4 +1,4 @@ -.TH LESSECHO 1 "Version 416: 22 Nov 2007" +.TH LESSECHO 1 "Version 429: 11 Apr 2009" .SH NAME lessecho \- expand metacharacters .SH SYNOPSIS diff --git a/lesskey.c b/lesskey.c index 2e95c20dcf51..b56246dcd922 100644 --- a/lesskey.c +++ b/lesskey.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -93,63 +93,64 @@ struct cmdname struct cmdname cmdnames[] = { - { "back-bracket", A_B_BRACKET }, - { "back-line", A_B_LINE }, - { "back-line-force", A_BF_LINE }, - { "back-screen", A_B_SCREEN }, - { "back-scroll", A_B_SCROLL }, - { "back-search", A_B_SEARCH }, - { "back-window", A_B_WINDOW }, - { "debug", A_DEBUG }, - { "digit", A_DIGIT }, - { "display-flag", A_DISP_OPTION }, - { "display-option", A_DISP_OPTION }, - { "end", A_GOEND }, - { "examine", A_EXAMINE }, - { "first-cmd", A_FIRSTCMD }, - { "firstcmd", A_FIRSTCMD }, - { "flush-repaint", A_FREPAINT }, - { "forw-bracket", A_F_BRACKET }, - { "forw-forever", A_F_FOREVER }, - { "forw-line", A_F_LINE }, - { "forw-line-force", A_FF_LINE }, - { "forw-screen", A_F_SCREEN }, - { "forw-screen-force", A_FF_SCREEN }, - { "forw-scroll", A_F_SCROLL }, - { "forw-search", A_F_SEARCH }, - { "forw-window", A_F_WINDOW }, - { "goto-end", A_GOEND }, - { "goto-line", A_GOLINE }, - { "goto-mark", A_GOMARK }, - { "help", A_HELP }, - { "index-file", A_INDEX_FILE }, - { "invalid", A_UINVALID }, - { "left-scroll", A_LSHIFT }, - { "next-file", A_NEXT_FILE }, - { "next-tag", A_NEXT_TAG }, - { "noaction", A_NOACTION }, - { "percent", A_PERCENT }, - { "pipe", A_PIPE }, - { "prev-file", A_PREV_FILE }, - { "prev-tag", A_PREV_TAG }, - { "quit", A_QUIT }, - { "remove-file", A_REMOVE_FILE }, - { "repaint", A_REPAINT }, - { "repaint-flush", A_FREPAINT }, - { "repeat-search", A_AGAIN_SEARCH }, - { "repeat-search-all", A_T_AGAIN_SEARCH }, - { "reverse-search", A_REVERSE_SEARCH }, - { "reverse-search-all", A_T_REVERSE_SEARCH }, - { "right-scroll", A_RSHIFT }, - { "set-mark", A_SETMARK }, - { "shell", A_SHELL }, - { "status", A_STAT }, - { "toggle-flag", A_OPT_TOGGLE }, - { "toggle-option", A_OPT_TOGGLE }, - { "undo-hilite", A_UNDO_SEARCH }, - { "version", A_VERSION }, - { "visual", A_VISUAL }, - { NULL, 0 } + { "back-bracket", A_B_BRACKET }, + { "back-line", A_B_LINE }, + { "back-line-force", A_BF_LINE }, + { "back-screen", A_B_SCREEN }, + { "back-scroll", A_B_SCROLL }, + { "back-search", A_B_SEARCH }, + { "back-window", A_B_WINDOW }, + { "debug", A_DEBUG }, + { "digit", A_DIGIT }, + { "display-flag", A_DISP_OPTION }, + { "display-option", A_DISP_OPTION }, + { "end", A_GOEND }, + { "examine", A_EXAMINE }, + { "filter", A_FILTER }, + { "first-cmd", A_FIRSTCMD }, + { "firstcmd", A_FIRSTCMD }, + { "flush-repaint", A_FREPAINT }, + { "forw-bracket", A_F_BRACKET }, + { "forw-forever", A_F_FOREVER }, + { "forw-line", A_F_LINE }, + { "forw-line-force", A_FF_LINE }, + { "forw-screen", A_F_SCREEN }, + { "forw-screen-force", A_FF_SCREEN }, + { "forw-scroll", A_F_SCROLL }, + { "forw-search", A_F_SEARCH }, + { "forw-window", A_F_WINDOW }, + { "goto-end", A_GOEND }, + { "goto-line", A_GOLINE }, + { "goto-mark", A_GOMARK }, + { "help", A_HELP }, + { "index-file", A_INDEX_FILE }, + { "invalid", A_UINVALID }, + { "left-scroll", A_LSHIFT }, + { "next-file", A_NEXT_FILE }, + { "next-tag", A_NEXT_TAG }, + { "noaction", A_NOACTION }, + { "percent", A_PERCENT }, + { "pipe", A_PIPE }, + { "prev-file", A_PREV_FILE }, + { "prev-tag", A_PREV_TAG }, + { "quit", A_QUIT }, + { "remove-file", A_REMOVE_FILE }, + { "repaint", A_REPAINT }, + { "repaint-flush", A_FREPAINT }, + { "repeat-search", A_AGAIN_SEARCH }, + { "repeat-search-all", A_T_AGAIN_SEARCH }, + { "reverse-search", A_REVERSE_SEARCH }, + { "reverse-search-all", A_T_REVERSE_SEARCH }, + { "right-scroll", A_RSHIFT }, + { "set-mark", A_SETMARK }, + { "shell", A_SHELL }, + { "status", A_STAT }, + { "toggle-flag", A_OPT_TOGGLE }, + { "toggle-option", A_OPT_TOGGLE }, + { "undo-hilite", A_UNDO_SEARCH }, + { "version", A_VERSION }, + { "visual", A_VISUAL }, + { NULL, 0 } }; struct cmdname editnames[] = @@ -539,7 +540,7 @@ add_cmd_str(s) control_line(s) char *s; { -#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)-1) == 0) +#define PREFIX(str,pat) (strncmp(str,pat,strlen(pat)) == 0) if (PREFIX(s, "#line-edit")) { diff --git a/lesskey.h b/lesskey.h index e6601a434ec4..230a21d4b649 100644 --- a/lesskey.h +++ b/lesskey.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/lesskey.man b/lesskey.man index bdc2ebae2bb6..94e5b88cbab8 100644 --- a/lesskey.man +++ b/lesskey.man @@ -183,6 +183,7 @@ LESSKEY(1) LESSKEY(1) \en repeat-search-all N reverse-search \eN reverse-search-all + & filter m set-mark ' goto-mark ^X^X goto-mark @@ -332,7 +333,7 @@ LESSKEY(1) LESSKEY(1) COPYRIGHT - Copyright (C) 2000-2007 Mark Nudelman + Copyright (C) 2000-2008 Mark Nudelman lesskey is part of the GNU project and is free software; you can redis- tribute it and/or modify it under the terms of the GNU General Public @@ -357,4 +358,4 @@ LESSKEY(1) LESSKEY(1) - Version 416: 22 Nov 2007 LESSKEY(1) + Version 429: 11 Apr 2009 LESSKEY(1) diff --git a/lesskey.nro b/lesskey.nro index 47033212b7cf..53b4d58fcb58 100644 --- a/lesskey.nro +++ b/lesskey.nro @@ -1,4 +1,4 @@ -.TH LESSKEY 1 "Version 416: 22 Nov 2007" +.TH LESSKEY 1 "Version 429: 11 Apr 2009" .SH NAME lesskey \- specify key bindings for less .SH SYNOPSIS @@ -200,6 +200,7 @@ default command keys used by less: \een repeat-search-all N reverse-search \eeN reverse-search-all + & filter m set-mark ' goto-mark ^X^X goto-mark @@ -358,7 +359,7 @@ which start with a NUL character (0). This NUL character should be represented as \e340 in a lesskey file. .SH COPYRIGHT -Copyright (C) 2000-2007 Mark Nudelman +Copyright (C) 2000-2008 Mark Nudelman .PP lesskey is part of the GNU project and is free software; you can redistribute it and/or modify it diff --git a/lglob.h b/lglob.h index 8dc677f920d9..914cc1d8134e 100644 --- a/lglob.h +++ b/lglob.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/line.c b/line.c index 08ca3be594db..f1771f55a78d 100644 --- a/line.c +++ b/line.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -35,7 +35,6 @@ static int overstrike; /* Next char should overstrike previous char */ static int last_overstrike = AT_NORMAL; static int is_null_line; /* There is no current line */ static int lmargin; /* Left margin */ -static int line_matches; /* Number of search matches in this line */ static char pendc; static POSITION pendpos; static char *end_ansi_chars; @@ -59,7 +58,6 @@ extern int bl_s_width, bl_e_width; extern int so_s_width, so_e_width; extern int sc_width, sc_height; extern int utf_mode; -extern int oldbot; extern POSITION start_attnpos; extern POSITION end_attnpos; @@ -162,9 +160,6 @@ prewind() lmargin = 0; if (status_col) lmargin += 1; -#if HILITE_SEARCH - line_matches = 0; -#endif } /* @@ -592,7 +587,6 @@ store_char(ch, a, rep, pos) if (a != AT_ANSI) a |= AT_HILITE; } - line_matches += matches; } #endif @@ -600,9 +594,12 @@ store_char(ch, a, rep, pos) { if (!is_ansi_end(ch) && !is_ansi_middle(ch)) { /* Remove whole unrecognized sequence. */ + char *p = &linebuf[curr]; + LWCHAR bch; do { - --curr; - } while (!IS_CSI_START(linebuf[curr])); + bch = step_char(&p, -1, linebuf); + } while (p > linebuf && !IS_CSI_START(bch)); + curr = p - linebuf; return 0; } a = AT_ANSI; /* Will force re-AT_'ing around it. */ @@ -992,8 +989,9 @@ pflushmbc() * Terminate the line in the line buffer. */ public void -pdone(endline) +pdone(endline, nextc) int endline; + int nextc; { int nl; @@ -1037,43 +1035,44 @@ pdone(endline) * the next line is blank. In that case the single newline output for * that blank line would be ignored!) */ - if (!oldbot) - nl = (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON); - else - nl = (column < sc_width || !auto_wrap || ignaw || ctldisp == OPT_ON); - if (nl) + if (column < sc_width || !auto_wrap || (endline && ignaw) || ctldisp == OPT_ON) { linebuf[curr] = '\n'; attr[curr] = AT_NORMAL; curr++; } - else if (ignaw && !auto_wrap && column >= sc_width) + else if (ignaw && column >= sc_width) { /* - * Big horrible kludge. - * No-wrap terminals are too hard to deal with when they get in - * the state where a full screen width of characters have been - * output but the cursor is sitting on the right edge instead - * of at the start of the next line. - * So after we output a full line, we output an extra - * space and backspace to force the cursor to the - * beginning of the next line, like a sane terminal. + * Terminals with "ignaw" don't wrap until they *really* need + * to, i.e. when the character *after* the last one to fit on a + * line is output. But they are too hard to deal with when they + * get in the state where a full screen width of characters + * have been output but the cursor is sitting on the right edge + * instead of at the start of the next line. + * So we nudge them into wrapping by outputting the next + * character plus a backspace. (This wouldn't be right for + * "!auto_wrap" terminals, but they always end up in the + * branch above.) */ - linebuf[curr] = ' '; + linebuf[curr] = nextc; attr[curr++] = AT_NORMAL; linebuf[curr] = '\b'; attr[curr++] = AT_NORMAL; } linebuf[curr] = '\0'; attr[curr] = AT_NORMAL; +} -#if HILITE_SEARCH - if (status_col && line_matches > 0) - { - linebuf[0] = '*'; - attr[0] = AT_NORMAL|AT_HILITE; - } -#endif +/* + * + */ + public void +set_status_col(c) + char c; +{ + linebuf[0] = c; + attr[0] = AT_NORMAL|AT_HILITE; } /* diff --git a/linenum.c b/linenum.c index 184306b8e8bc..ecbfdc2a5c86 100644 --- a/linenum.c +++ b/linenum.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -56,12 +56,10 @@ struct linenum_info * when we have a new one to insert and the table is full. */ -#define NPOOL 50 /* Size of line number pool */ +#define NPOOL 200 /* Size of line number pool */ #define LONGTIME (2) /* In seconds */ -public int lnloop = 0; /* Are we in the line num loop? */ - static struct linenum_info anchor; /* Anchor of the list */ static struct linenum_info *freelist; /* Anchor of the unused entries */ static struct linenum_info pool[NPOOL]; /* The pool itself */ @@ -70,6 +68,7 @@ static struct linenum_info *spare; /* We always keep one spare entry */ extern int linenums; extern int sigs; extern int sc_height; +extern int screen_trashed; /* * Initialize the line number structures. @@ -214,12 +213,6 @@ add_lnum(linenum, pos) longloopmessage() { ierror("Calculating line numbers", NULL_PARG); - /* - * Set the lnloop flag here, so if the user interrupts while - * we are calculating line numbers, the signal handler will - * turn off line numbers (linenums=0). - */ - lnloop = 1; } static int loopcount; @@ -249,6 +242,22 @@ longish() #endif } +/* + * Turn off line numbers because the user has interrupted + * a lengthy line number calculation. + */ + static void +abort_long() +{ + if (linenums == OPT_ONPLUS) + /* + * We were displaying line numbers, so need to repaint. + */ + screen_trashed = 1; + linenums = 0; + error("Line numbers turned off", NULL_PARG); +} + /* * Find the line number associated with a given position. * Return 0 if we can't figure it out. @@ -315,11 +324,14 @@ find_linenum(pos) * Allow a signal to abort this loop. */ cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL); - if (ABORT_SIGS() || cpos == NULL_POSITION) + if (ABORT_SIGS()) { + abort_long(); + return (0); + } + if (cpos == NULL_POSITION) return (0); longish(); } - lnloop = 0; /* * We might as well cache it. */ @@ -344,11 +356,14 @@ find_linenum(pos) * Allow a signal to abort this loop. */ cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL); - if (ABORT_SIGS() || cpos == NULL_POSITION) + if (ABORT_SIGS()) { + abort_long(); + return (0); + } + if (cpos == NULL_POSITION) return (0); longish(); } - lnloop = 0; /* * We might as well cache it. */ @@ -399,7 +414,9 @@ find_pos(linenum) * Allow a signal to abort this loop. */ cpos = forw_raw_line(cpos, (char **)NULL, (int *)NULL); - if (ABORT_SIGS() || cpos == NULL_POSITION) + if (ABORT_SIGS()) + return (NULL_POSITION); + if (cpos == NULL_POSITION) return (NULL_POSITION); } } else @@ -415,7 +432,9 @@ find_pos(linenum) * Allow a signal to abort this loop. */ cpos = back_raw_line(cpos, (char **)NULL, (int *)NULL); - if (ABORT_SIGS() || cpos == NULL_POSITION) + if (ABORT_SIGS()) + return (NULL_POSITION); + if (cpos == NULL_POSITION) return (NULL_POSITION); } } diff --git a/lsystem.c b/lsystem.c index 512bea34dcfb..1d10123e43a5 100644 --- a/lsystem.c +++ b/lsystem.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -49,7 +49,7 @@ lsystem(cmd, donemsg) register char *p; #endif IFILE save_ifile; -#if MSDOS_COMPILER +#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C char cwd[FILENAME_MAX+1]; #endif @@ -68,6 +68,10 @@ lsystem(cmd, donemsg) } #if MSDOS_COMPILER +#if MSDOS_COMPILER==WIN32C + if (*cmd == '\0') + cmd = getenv("COMSPEC"); +#else /* * Working directory is global on MSDOS. * The child might change the working directory, so we @@ -76,6 +80,7 @@ lsystem(cmd, donemsg) * try to "reedit_ifile" it. */ getcwd(cwd, FILENAME_MAX); +#endif #endif /* @@ -192,7 +197,7 @@ lsystem(cmd, donemsg) init(); screen_trashed = 1; -#if MSDOS_COMPILER +#if MSDOS_COMPILER && MSDOS_COMPILER!=WIN32C /* * Restore the previous directory (possibly * changed by the child program we just ran). diff --git a/main.c b/main.c index 36a230e36ac8..a08b409b93de 100644 --- a/main.c +++ b/main.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/mark.c b/mark.c index 870f426e36e6..f43e36b291e3 100644 --- a/mark.c +++ b/mark.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/mkhelp.c b/mkhelp.c index f4a7ea76dcff..d96415c9e094 100644 --- a/mkhelp.c +++ b/mkhelp.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/optfunc.c b/optfunc.c index f296b79368ab..ced83ef9d6e9 100644 --- a/optfunc.c +++ b/optfunc.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -442,7 +442,7 @@ opt__V(type, s) any_display = 1; putstr("less "); putstr(version); - putstr("\nCopyright (C) 1984-2007 Mark Nudelman\n\n"); + putstr("\nCopyright (C) 1984-2008 Mark Nudelman\n\n"); putstr("less comes with NO WARRANTY, to the extent permitted by law.\n"); putstr("For information about the terms of redistribution,\n"); putstr("see the file named README in the less distribution.\n"); @@ -472,14 +472,14 @@ colordesc(s, fg_color, bg_color) return; } if (*s != '.') - bg = 0; + bg = nm_bg_color; else { s++; bg = getnum(&s, "D", &err); if (err) { - error("Missing fg color in -D", NULL_PARG); + error("Missing bg color in -D", NULL_PARG); return; } } diff --git a/option.c b/option.c index 92a8fdd6106b..adfa908b0938 100644 --- a/option.c +++ b/option.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/option.h b/option.h index 3ab7c8f70395..b1ef67a8231a 100644 --- a/option.h +++ b/option.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/opttbl.c b/opttbl.c index 755a93d72ae6..6fc6ac23c7ed 100644 --- a/opttbl.c +++ b/opttbl.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/os.c b/os.c index fef5f9409756..55ee1be152c6 100644 --- a/os.c +++ b/os.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/output.c b/output.c index 9c9d4acf4d8c..a87670f28d49 100644 --- a/output.c +++ b/output.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -31,7 +31,7 @@ extern int any_display; extern int is_tty; extern int oldbot; -#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC extern int ctldisp; extern int nm_fg_color, nm_bg_color; extern int bo_fg_color, bo_bg_color; @@ -102,53 +102,7 @@ flush() n = ob - obuf; if (n == 0) return; -#if MSDOS_COMPILER==WIN32C - if (is_tty && any_display) - { - char *op; - DWORD nwritten = 0; - CONSOLE_SCREEN_BUFFER_INFO scr; - int row; - int col; - int olen; - extern HANDLE con_out; - olen = ob - obuf; - /* - * There is a bug in Win32 WriteConsole() if we're - * writing in the last cell with a different color. - * To avoid color problems in the bottom line, - * we scroll the screen manually, before writing. - */ - GetConsoleScreenBufferInfo(con_out, &scr); - col = scr.dwCursorPosition.X; - row = scr.dwCursorPosition.Y; - for (op = obuf; op < obuf + olen; op++) - { - if (*op == '\n') - { - col = 0; - row++; - } else if (*op == '\r') - { - col = 0; - } else - { - col++; - if (col >= sc_width) - { - col = 0; - row++; - } - } - } - if (row > scr.srWindow.Bottom) - win32_scroll_up(row - scr.srWindow.Bottom); - WriteConsole(con_out, obuf, olen, &nwritten, NULL); - ob = obuf; - return; - } -#else #if MSDOS_COMPILER==MSOFTC if (is_tty && any_display) { @@ -158,12 +112,12 @@ flush() return; } #else -#if MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC +#if MSDOS_COMPILER==WIN32C || MSDOS_COMPILER==BORLANDC || MSDOS_COMPILER==DJGPPC if (is_tty && any_display) { *ob = '\0'; if (ctldisp != OPT_ONPLUS) - cputs(obuf); + WIN32textout(obuf, ob - obuf); else { /* @@ -173,64 +127,70 @@ flush() * the -D command-line option. */ char *anchor, *p, *p_next; - int buflen = ob - obuf; - unsigned char fg, bg, norm_attr; - /* - * Only dark colors mentioned here, so that - * bold has visible effect. - */ + unsigned char fg, bg; + static unsigned char at; +#if MSDOS_COMPILER==WIN32C + /* Screen colors used by 3x and 4x SGR commands. */ + static unsigned char screen_color[] = { + 0, /* BLACK */ + FOREGROUND_RED, + FOREGROUND_GREEN, + FOREGROUND_RED|FOREGROUND_GREEN, + FOREGROUND_BLUE, + FOREGROUND_BLUE|FOREGROUND_RED, + FOREGROUND_BLUE|FOREGROUND_GREEN, + FOREGROUND_BLUE|FOREGROUND_GREEN|FOREGROUND_RED + }; +#else static enum COLORS screen_color[] = { BLACK, RED, GREEN, BROWN, BLUE, MAGENTA, CYAN, LIGHTGRAY }; +#endif - /* Normal text colors are used as baseline. */ - bg = nm_bg_color & 0xf; - fg = nm_fg_color & 0xf; - norm_attr = (bg << 4) | fg; for (anchor = p_next = obuf; - (p_next = memchr (p_next, ESC, - buflen - (p_next - obuf))) - != NULL; ) + (p_next = memchr(p_next, ESC, ob - p_next)) != NULL; ) { p = p_next; - - /* - * Handle the null escape sequence - * (ESC-[m), which is used to restore - * the original color. - */ - if (p[1] == '[' && is_ansi_end(p[2])) + if (p[1] == '[') /* "ESC-[" sequence */ { - textattr(norm_attr); - p += 3; - anchor = p_next = p; - continue; - } - - if (p[1] == '[') /* "Esc-[" sequence */ - { - /* - * If some chars seen since - * the last escape sequence, - * write it out to the screen - * using current text attributes. - */ if (p > anchor) { - *p = '\0'; - cputs (anchor); - *p = ESC; + /* + * If some chars seen since + * the last escape sequence, + * write them out to the screen. + */ + WIN32textout(anchor, p-anchor); anchor = p; } - p += 2; + p += 2; /* Skip the "ESC-[" */ + if (is_ansi_end(*p)) + { + /* + * Handle null escape sequence + * "ESC[m", which restores + * the normal color. + */ + p++; + anchor = p_next = p; + WIN32setcolors(nm_fg_color, nm_bg_color); + continue; + } p_next = p; + + /* + * Select foreground/background colors + * based on the escape sequence. + */ + fg = nm_fg_color; + bg = nm_bg_color; while (!is_ansi_end(*p)) { char *q; long code = strtol(p, &q, 10); - if (!*q) + if (*q == '\0') { /* * Incomplete sequence. @@ -238,15 +198,15 @@ flush() * in the buffer. */ int slop = q - anchor; + /* {{ strcpy args overlap! }} */ strcpy(obuf, anchor); ob = &obuf[slop]; return; } - if (q == p - || code > 49 || code < 0 - || (!is_ansi_end(*q) - && *q != ';')) + if (q == p || + code > 49 || code < 0 || + (!is_ansi_end(*q) && *q != ';')) { p_next = q; break; @@ -256,27 +216,38 @@ flush() switch (code) { + default: + /* case 0: all attrs off */ + fg = nm_fg_color; + bg = nm_bg_color; + at = 0; + break; case 1: /* bold on */ - fg = bo_fg_color; - bg = bo_bg_color; + at |= 1; break; case 3: /* italic on */ - fg = so_fg_color; - bg = so_bg_color; + case 7: /* inverse on */ + at |= 2; break; case 4: /* underline on */ - fg = ul_fg_color; - bg = ul_bg_color; + at |= 4; + break; + case 5: /* slow blink on */ + case 6: /* fast blink on */ + at |= 8; break; case 8: /* concealed on */ fg = (bg & 7) | 8; break; - case 0: /* all attrs off */ - case 22:/* bold off */ - case 23:/* italic off */ - case 24:/* underline off */ - fg = nm_fg_color; - bg = nm_bg_color; + case 22: /* bold off */ + at &= ~1; + break; + case 23: /* italic off */ + case 27: /* inverse off */ + at &= ~2; + break; + case 24: /* underline off */ + at &= ~4; break; case 30: case 31: case 32: case 33: case 34: case 35: @@ -297,26 +268,40 @@ flush() } p = q; } - if (is_ansi_end(*p) && p > p_next) - { - bg &= 15; - fg &= 15; - textattr ((bg << 4)| fg); - p_next = anchor = p + 1; - } else + if (!is_ansi_end(*p) || p == p_next) break; + if (at & 1) + { + fg = bo_fg_color; + bg = bo_bg_color; + } else if (at & 2) + { + fg = so_fg_color; + bg = so_bg_color; + } else if (at & 4) + { + fg = ul_fg_color; + bg = ul_bg_color; + } else if (at & 8) + { + fg = bl_fg_color; + bg = bl_bg_color; + } + fg &= 0xf; + bg &= 0xf; + WIN32setcolors(fg, bg); + p_next = anchor = p + 1; } else p_next++; } /* Output what's left in the buffer. */ - cputs (anchor); + WIN32textout(anchor, ob - anchor); } ob = obuf; return; } #endif -#endif #endif fd = (any_display) ? 1 : 2; if (write(fd, obuf, n) != n) diff --git a/pckeys.h b/pckeys.h index 8683e86d890f..d447d73e6e8d 100644 --- a/pckeys.h +++ b/pckeys.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/position.c b/position.c index da737dc28989..d569a382aa01 100644 --- a/position.c +++ b/position.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/position.h b/position.h index 863707b06c2c..bfae6de27a08 100644 --- a/position.h +++ b/position.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/prompt.c b/prompt.c index 67b5ddcdbfdf..9a3485bb50f5 100644 --- a/prompt.c +++ b/prompt.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -22,7 +22,6 @@ #include "position.h" extern int pr_type; -extern int hit_eof; extern int new_file; extern int sc_width; extern int so_s_width, so_e_width; @@ -196,7 +195,7 @@ cond(c, where) case 'c': return (hshift != 0); case 'e': /* At end of file? */ - return (hit_eof); + return (eof_displayed()); case 'f': /* Filename known? */ return (strcmp(get_filename(curr_ifile), "-") != 0); case 'l': /* Line number known? */ diff --git a/screen.c b/screen.c index 8e3a0607c666..f36424adbb6c 100644 --- a/screen.c +++ b/screen.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -1550,7 +1550,8 @@ init() */ for (i = 1; i < sc_height; i++) putchr('\n'); - } + } else + line_left(); #else #if MSDOS_COMPILER==WIN32C if (!no_init) @@ -1787,7 +1788,7 @@ win32_scroll_up(n) /* Move the source text to the top of the screen. */ new_org.X = rcSrc.Left; - new_org.Y = 0; + /* new_org.Y = rcClip.top; -- doesn't compile under MSVC6 */ /* Fill the right character and attributes. */ fillchar.Char.AsciiChar = ' '; @@ -2469,3 +2470,33 @@ WIN32getch(tty) return ((char)ascii); } #endif + +#if MSDOS_COMPILER +/* + */ + public void +WIN32setcolors(fg, bg) + int fg; + int bg; +{ + SETCOLORS(fg, bg); +} + +/* + */ + public void +WIN32textout(text, len) + char *text; + int len; +{ +#if MSDOS_COMPILER==WIN32C + DWORD written; + WriteConsole(con_out, text, len, &written, NULL); +#else + char c = text[len]; + text[len] = '\0'; + cputs(text); + text[len] = c; +#endif +} +#endif diff --git a/scrsize.c b/scrsize.c index 45cf20a1d797..4e45dd594138 100644 --- a/scrsize.c +++ b/scrsize.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/search.c b/search.c index 3a153808429c..14fc10b181b7 100644 --- a/search.c +++ b/search.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -58,13 +58,13 @@ extern int status_col; extern void * constant ml_search; extern POSITION start_attnpos; extern POSITION end_attnpos; +extern int utf_mode; +extern int screen_trashed; #if HILITE_SEARCH extern int hilite_search; -extern int screen_trashed; extern int size_linebuf; extern int squished; extern int can_goto_line; -extern int utf_mode; static int hide_hilite; static int oldbot; static POSITION prep_startpos; @@ -77,6 +77,7 @@ struct hilite POSITION hl_endpos; }; static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION }; +static struct hilite filter_anchor = { NULL, NULL_POSITION, NULL_POSITION }; #define hl_first hl_next #endif @@ -85,24 +86,28 @@ static struct hilite hilite_anchor = { NULL, NULL_POSITION, NULL_POSITION }; * search pattern. */ #if HAVE_POSIX_REGCOMP -static regex_t *regpattern = NULL; +#define DEFINE_PATTERN(name) static regex_t *name = NULL #endif #if HAVE_PCRE -pcre *regpattern = NULL; +#define DEFINE_PATTERN(name) pcre *name = NULL; #endif #if HAVE_RE_COMP -int re_pattern = 0; +#define DEFINE_PATTERN(name) int name = 0; #endif #if HAVE_REGCMP -static char *cpattern = NULL; +#define DEFINE_PATTERN(name) static char *name = NULL; #endif #if HAVE_V8_REGCOMP -static struct regexp *regpattern = NULL; +#define DEFINE_PATTERN(name) static struct regexp *name = NULL; #endif +DEFINE_PATTERN(search_pattern); +DEFINE_PATTERN(filter_pattern); + static int is_caseless; static int is_ucase_pattern; static int last_search_type; +static int last_filter_type; static char *last_pattern = NULL; #define CVT_TO_LC 01 /* Convert upper-case to lower-case */ @@ -131,7 +136,7 @@ cvt_length(len, ops) } /* - * Convert text. Perform one or more of these transformations: + * Convert text. Perform the transformations specified by ops. */ static void cvt_text(odst, osrc, lenp, ops) @@ -167,8 +172,9 @@ cvt_text(odst, osrc, lenp, ops) } else if ((ops & CVT_ANSI) && IS_CSI_START(ch)) { /* Skip to end of ANSI escape sequence. */ - while (src + 1 != src_end) - if (!is_ansi_middle(*++src)) + src++; /* skip the CSI start char */ + while (src < src_end) + if (!is_ansi_middle(*src++)) break; } else /* Just copy. */ @@ -233,22 +239,22 @@ prev_pattern() if (last_search_type & SRCH_NO_REGEX) return (last_pattern != NULL); #if HAVE_POSIX_REGCOMP - return (regpattern != NULL); + return (search_pattern != NULL); #endif #if HAVE_PCRE - return (regpattern != NULL); + return (search_pattern != NULL); #endif #if HAVE_RE_COMP - return (re_pattern != 0); + return (search_pattern != 0); #endif #if HAVE_REGCMP - return (cpattern != NULL); + return (search_pattern != NULL); #endif #if HAVE_V8_REGCOMP - return (regpattern != NULL); + return (search_pattern != NULL); #endif #if NO_REGEX - return (last_pattern != NULL); + return (search_pattern != NULL); #endif } @@ -382,26 +388,29 @@ undo_search() * Compile a search pattern, for future use by match_pattern. */ static int -compile_pattern2(pattern, search_type) +compile_pattern2(pattern, search_type, comp_pattern) char *pattern; int search_type; + void **comp_pattern; { if ((search_type & SRCH_NO_REGEX) == 0) { #if HAVE_POSIX_REGCOMP - regex_t *s = (regex_t *) ecalloc(1, sizeof(regex_t)); - if (regcomp(s, pattern, REGCOMP_FLAG)) + regex_t *comp = (regex_t *) ecalloc(1, sizeof(regex_t)); + regex_t **pcomp = (regex_t **) comp_pattern; + if (regcomp(comp, pattern, REGCOMP_FLAG)) { - free(s); + free(comp); error("Invalid pattern", NULL_PARG); return (-1); } - if (regpattern != NULL) - regfree(regpattern); - regpattern = s; + if (*pcomp != NULL) + regfree(*pcomp); + *pcomp = comp; #endif #if HAVE_PCRE pcre *comp; + pcre **pcomp = (pcre **) comp_pattern; const char *errstring; int erroffset; PARG parg; @@ -413,31 +422,34 @@ compile_pattern2(pattern, search_type) error("%s", &parg); return (-1); } - regpattern = comp; + *pcomp = comp; #endif #if HAVE_RE_COMP PARG parg; + int *pcomp = (int *) comp_pattern; if ((parg.p_string = re_comp(pattern)) != NULL) { error("%s", &parg); return (-1); } - re_pattern = 1; + *pcomp = 1; #endif #if HAVE_REGCMP - char *s; - if ((s = regcmp(pattern, 0)) == NULL) + char *comp; + char **pcomp = (char **) comp_pattern; + if ((comp = regcmp(pattern, 0)) == NULL) { error("Invalid pattern", NULL_PARG); return (-1); } - if (cpattern != NULL) - free(cpattern); - cpattern = s; + if (pcomp != NULL) + free(*pcomp); + *pcomp = comp; #endif #if HAVE_V8_REGCOMP - struct regexp *s; - if ((s = regcomp(pattern)) == NULL) + struct regexp *comp; + struct regexp **pcomp = (struct regexp **) comp_pattern; + if ((comp = regcomp(pattern)) == NULL) { /* * regcomp has already printed an error message @@ -445,29 +457,35 @@ compile_pattern2(pattern, search_type) */ return (-1); } - if (regpattern != NULL) - free(regpattern); - regpattern = s; + if (*pcomp != NULL) + free(*pcomp); + *pcomp = comp; #endif } - if (last_pattern != NULL) - free(last_pattern); - last_pattern = (char *) calloc(1, strlen(pattern)+1); - if (last_pattern != NULL) - strcpy(last_pattern, pattern); - - last_search_type = search_type; + if (comp_pattern == (void **) &search_pattern) + { + if (last_pattern != NULL) + free(last_pattern); + last_pattern = (char *) calloc(1, strlen(pattern)+1); + if (last_pattern != NULL) + strcpy(last_pattern, pattern); + last_search_type = search_type; + } else + { + last_filter_type = search_type; + } return (0); } /* - * Like compile_pattern, but convert the pattern to lowercase if necessary. + * Like compile_pattern2, but convert the pattern to lowercase if necessary. */ static int -compile_pattern(pattern, search_type) +compile_pattern(pattern, search_type, comp_pattern) char *pattern; int search_type; + void **comp_pattern; { char *cvt_pattern; int result; @@ -479,7 +497,7 @@ compile_pattern(pattern, search_type) cvt_pattern = (char*) ecalloc(1, cvt_length(strlen(pattern), CVT_TO_LC)); cvt_text(cvt_pattern, pattern, (int *)NULL, CVT_TO_LC); } - result = compile_pattern2(cvt_pattern, search_type); + result = compile_pattern2(cvt_pattern, search_type, comp_pattern); if (cvt_pattern != pattern) free(cvt_pattern); return (result); @@ -489,77 +507,138 @@ compile_pattern(pattern, search_type) * Forget that we have a compiled pattern. */ static void -uncompile_pattern() +uncompile_pattern(pattern) + void **pattern; { #if HAVE_POSIX_REGCOMP - if (regpattern != NULL) - regfree(regpattern); - regpattern = NULL; + regex_t **pcomp = (regex_t **) pattern; + if (*pcomp != NULL) + regfree(*pcomp); + *pcomp = NULL; #endif #if HAVE_PCRE - if (regpattern != NULL) - pcre_free(regpattern); - regpattern = NULL; + pcre **pcomp = (pcre **) pattern; + if (*pcomp != NULL) + pcre_free(*pcomp); + *pcomp = NULL; #endif #if HAVE_RE_COMP - re_pattern = 0; + int *pcomp = (int *) pattern; + *pcomp = 0; #endif #if HAVE_REGCMP - if (cpattern != NULL) - free(cpattern); - cpattern = NULL; + char **pcomp = (char **) pattern; + if (*pcomp != NULL) + free(*pcomp); + *pcomp = NULL; #endif #if HAVE_V8_REGCOMP - if (regpattern != NULL) - free(regpattern); - regpattern = NULL; + struct regexp **pcomp = (struct regexp **) pattern; + if (*pcomp != NULL) + free(*pcomp); + *pcomp = NULL; #endif +} + + static void +uncompile_search_pattern() +{ + uncompile_pattern(&search_pattern); last_pattern = NULL; } + static void +uncompile_filter_pattern() +{ + uncompile_pattern(&filter_pattern); +} + +/* + * Is a compiled pattern null? + */ + static int +is_null_pattern(pattern) + void *pattern; +{ +#if HAVE_POSIX_REGCOMP + return (pattern == NULL); +#endif +#if HAVE_PCRE + return (pattern == NULL); +#endif +#if HAVE_RE_COMP + return (pattern == 0); +#endif +#if HAVE_REGCMP + return (pattern == NULL); +#endif +#if HAVE_V8_REGCOMP + return (pattern == NULL); +#endif +} + /* * Perform a pattern match with the previously compiled pattern. * Set sp and ep to the start and end of the matched string. */ static int -match_pattern(line, line_len, sp, ep, notbol) +match_pattern(pattern, line, line_len, sp, ep, notbol, search_type) + void *pattern; char *line; int line_len; char **sp; char **ep; int notbol; + int search_type; { int matched; +#if HAVE_POSIX_REGCOMP + regex_t *spattern = (regex_t *) pattern; +#endif +#if HAVE_PCRE + pcre *spattern = (pcre *) pattern; +#endif +#if HAVE_RE_COMP + int spattern = (int) pattern; +#endif +#if HAVE_REGCMP + char *spattern = (char *) pattern; +#endif +#if HAVE_V8_REGCOMP + struct regexp *spattern = (struct regexp *) pattern; +#endif - if (last_search_type & SRCH_NO_REGEX) + if (search_type & SRCH_NO_REGEX) return (match(last_pattern, strlen(last_pattern), line, line_len, sp, ep)); #if HAVE_POSIX_REGCOMP { regmatch_t rm; int flags = (notbol) ? REG_NOTBOL : 0; - matched = !regexec(regpattern, line, 1, &rm, flags); - if (!matched) - return (0); + matched = !regexec(spattern, line, 1, &rm, flags); + if (matched) + { #ifndef __WATCOMC__ - *sp = line + rm.rm_so; - *ep = line + rm.rm_eo; + *sp = line + rm.rm_so; + *ep = line + rm.rm_eo; #else - *sp = rm.rm_sp; - *ep = rm.rm_ep; + *sp = rm.rm_sp; + *ep = rm.rm_ep; #endif + } } #endif #if HAVE_PCRE { int flags = (notbol) ? PCRE_NOTBOL : 0; int ovector[3]; - matched = pcre_exec(regpattern, NULL, line, line_len, + matched = pcre_exec(spattern, NULL, line, line_len, 0, flags, ovector, 3) >= 0; - if (!matched) - return (0); - *sp = line + ovector[0]; - *ep = line + ovector[1]; + if (matched) + { + *sp = line + ovector[0]; + *ep = line + ovector[1]; + } } #endif #if HAVE_RE_COMP @@ -570,26 +649,28 @@ match_pattern(line, line_len, sp, ep, notbol) *sp = *ep = NULL; #endif #if HAVE_REGCMP - *ep = regex(cpattern, line); + *ep = regex(spattern, line); matched = (*ep != NULL); - if (!matched) - return (0); - *sp = __loc1; + if (matched) + *sp = __loc1; #endif #if HAVE_V8_REGCOMP #if HAVE_REGEXEC2 - matched = regexec2(regpattern, line, notbol); + matched = regexec2(spattern, line, notbol); #else - matched = regexec(regpattern, line); + matched = regexec(spattern, line); #endif - if (!matched) - return (0); - *sp = regpattern->startp[0]; - *ep = regpattern->endp[0]; + if (matched) + { + *sp = spattern->startp[0]; + *ep = spattern->endp[0]; + } #endif #if NO_REGEX matched = match(last_pattern, strlen(last_pattern), line, line_len, sp, ep); #endif + matched = (!(search_type & SRCH_NO_MATCH) && matched) || + ((search_type & SRCH_NO_MATCH) && !matched); return (matched); } @@ -598,20 +679,33 @@ match_pattern(line, line_len, sp, ep, notbol) * Clear the hilite list. */ public void -clr_hilite() +clr_hlist(anchor) + struct hilite *anchor; { struct hilite *hl; struct hilite *nexthl; - for (hl = hilite_anchor.hl_first; hl != NULL; hl = nexthl) + for (hl = anchor->hl_first; hl != NULL; hl = nexthl) { nexthl = hl->hl_next; free((void*)hl); } - hilite_anchor.hl_first = NULL; + anchor->hl_first = NULL; prep_startpos = prep_endpos = NULL_POSITION; } + public void +clr_hilite() +{ + clr_hlist(&hilite_anchor); +} + + public void +clr_filter() +{ + clr_hlist(&filter_anchor); +} + /* * Should any characters in a specified range be highlighted? */ @@ -634,6 +728,30 @@ is_hilited_range(pos, epos) return (0); } +/* + * Is a line "filtered" -- that is, should it be hidden? + */ + public int +is_filtered(pos) + POSITION pos; +{ + struct hilite *hl; + + if (ch_getflags() & CH_HELPFILE) + return (0); + + /* + * Look at each filter and see if the start position + * equals the start position of the line. + */ + for (hl = filter_anchor.hl_first; hl != NULL; hl = hl->hl_next) + { + if (hl->hl_startpos == pos) + return (1); + } + return (0); +} + /* * Should any characters in a specified range be highlighted? * If nohide is nonzero, don't consider hide_hilite. @@ -741,6 +859,8 @@ adj_hilite(anchor, linepos, cvt_ops) int checkstart; POSITION opos; POSITION npos; + POSITION hl_opos; + POSITION hl_npos; LWCHAR ch; int ncwidth; @@ -755,8 +875,12 @@ adj_hilite(anchor, linepos, cvt_ops) line_end = line + line_len; opos = npos = linepos; hl = anchor->hl_first; + if (hl == NULL) + return; + hl_opos = hl_npos = hl->hl_startpos; checkstart = TRUE; - while (hl != NULL) + + while (hl != NULL && line < line_end) { /* * See if we need to adjust the current hl_startpos or @@ -765,22 +889,6 @@ adj_hilite(anchor, linepos, cvt_ops) * The hilite list must be sorted thus: * startpos[0] < endpos[0] <= startpos[1] < endpos[1] <= etc. */ - if (checkstart && hl->hl_startpos == opos) - { - hl->hl_startpos = npos; - checkstart = FALSE; - continue; /* {{ not really necessary }} */ - } else if (!checkstart && hl->hl_endpos == opos) - { - hl->hl_endpos = npos; - checkstart = TRUE; - hl = hl->hl_next; - continue; /* {{ necessary }} */ - } - if (line == line_end) - break; - - /* Get the next char from the line. */ oline = line; ch = step_char(&line, +1, line_end); ncwidth = line - oline; @@ -806,10 +914,12 @@ adj_hilite(anchor, linepos, cvt_ops) } else if ((cvt_ops & CVT_ANSI) && IS_CSI_START(ch)) { /* Skip to end of ANSI escape sequence. */ + line++; /* skip the CSI start char */ + npos++; while (line < line_end) { npos++; - if (!is_ansi_middle(*++line)) + if (!is_ansi_middle(*line++)) break; } } else @@ -817,6 +927,32 @@ adj_hilite(anchor, linepos, cvt_ops) /* Ordinary unprocessed character. */ opos += ncwidth; } + + if (opos == hl_opos) { + /* Adjust highlight position. */ + hl_npos = npos; + } + if (opos > hl_opos) + { + /* + * We've moved past the highlight position; store the + * adjusted highlight position and move to the next highlight. + */ + if (checkstart) + { + hl->hl_startpos = hl_npos; + hl_opos = hl->hl_endpos; + checkstart = FALSE; + } else + { + hl->hl_endpos = hl_npos; + hl = hl->hl_next; + if (hl != NULL) + hl_opos = hl->hl_startpos; + checkstart = TRUE; + } + hl_npos = npos; + } } } @@ -880,7 +1016,7 @@ hilite_line(linepos, line, line_len, sp, ep, cvt_ops) searchp++; else /* end of line */ break; - } while (match_pattern(searchp, line_end - searchp, &sp, &ep, 1)); + } while (match_pattern(search_pattern, searchp, line_end - searchp, &sp, &ep, 1, last_search_type)); /* * If there were backspaces in the original line, they @@ -918,7 +1054,7 @@ chg_caseless() * Pattern did have uppercase. * Discard the pattern; we can't change search caselessness now. */ - uncompile_pattern(); + uncompile_search_pattern(); } #if HILITE_SEARCH @@ -1126,6 +1262,9 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) add_lnum(linenum, pos); oldpos = pos; + if (is_filtered(linepos)) + continue; + /* * If it's a caseless search, convert the line to lowercase. * If we're doing backspace processing, delete backspaces. @@ -1134,61 +1273,80 @@ search_range(pos, endpos, search_type, matches, maxlines, plinepos, pendpos) cline = calloc(1, cvt_length(line_len, cvt_ops)); cvt_text(cline, line, &line_len, cvt_ops); +#if HILITE_SEARCH + /* + * Check to see if the line matches the filter pattern. + * If so, add an entry to the filter list. + */ + if ((search_type & SRCH_FIND_ALL) && + !is_null_pattern(filter_pattern)) + { + int line_filter = match_pattern(filter_pattern, + cline, line_len, &sp, &ep, 0, last_filter_type); + if (line_filter) + { + struct hilite *hl = (struct hilite *) + ecalloc(1, sizeof(struct hilite)); + hl->hl_startpos = linepos; + hl->hl_endpos = pos; + add_hilite(&filter_anchor, hl); + } + } +#endif + /* * Test the next line to see if we have a match. * We are successful if we either want a match and got one, * or if we want a non-match and got one. */ - line_match = match_pattern(cline, line_len, &sp, &ep, 0); - line_match = (!(search_type & SRCH_NO_MATCH) && line_match) || - ((search_type & SRCH_NO_MATCH) && !line_match); - if (!line_match) + if (!is_null_pattern(search_pattern)) { - free(cline); - continue; - } - /* - * Got a match. - */ - if (search_type & SRCH_FIND_ALL) - { -#if HILITE_SEARCH - /* - * We are supposed to find all matches in the range. - * Just add the matches in this line to the - * hilite list and keep searching. - */ + line_match = match_pattern(search_pattern, + cline, line_len, &sp, &ep, 0, search_type); if (line_match) - hilite_line(linepos, cline, line_len, sp, ep, cvt_ops); -#endif - free(cline); - } else if (--matches <= 0) - { - /* - * Found the one match we're looking for. - * Return it. - */ -#if HILITE_SEARCH - if (hilite_search == OPT_ON) { /* - * Clear the hilite list and add only - * the matches in this one line. + * Got a match. */ - clr_hilite(); - if (line_match) + if (search_type & SRCH_FIND_ALL) + { +#if HILITE_SEARCH + /* + * We are supposed to find all matches in the range. + * Just add the matches in this line to the + * hilite list and keep searching. + */ hilite_line(linepos, cline, line_len, sp, ep, cvt_ops); - } #endif - free(cline); - if (plinepos != NULL) - *plinepos = linepos; - return (0); + } else if (--matches <= 0) + { + /* + * Found the one match we're looking for. + * Return it. + */ +#if HILITE_SEARCH + if (hilite_search == OPT_ON) + { + /* + * Clear the hilite list and add only + * the matches in this one line. + */ + clr_hilite(); + hilite_line(linepos, cline, line_len, sp, ep, cvt_ops); + } +#endif + free(cline); + if (plinepos != NULL) + *plinepos = linepos; + return (0); + } + } } + free(cline); } } - /* +/* * search for a pattern in history. If found, compile that pattern. */ static int @@ -1203,7 +1361,7 @@ hist_pattern(search_type) if (pattern == NULL) return (0); - if (compile_pattern(pattern, search_type) < 0) + if (compile_pattern(pattern, search_type, &search_pattern) < 0) return (0); is_ucase_pattern = is_ucase(pattern); @@ -1239,7 +1397,6 @@ search(search_type, pattern, n) int n; { POSITION pos; - int result; if (pattern == NULL || *pattern == '\0') { @@ -1282,7 +1439,7 @@ search(search_type, pattern, n) /* * Compile the pattern. */ - if (compile_pattern(pattern, search_type) < 0) + if (compile_pattern(pattern, search_type, &search_pattern) < 0) return (-1); /* * Ignore case if -I is set OR @@ -1396,7 +1553,7 @@ prep_hilite(spos, epos, maxlines) */ #define SEARCH_MORE (3*size_linebuf) - if (!prev_pattern()) + if (!prev_pattern() && !is_filtering()) return; /* @@ -1427,6 +1584,7 @@ prep_hilite(spos, epos, maxlines) * Discard the old prep region and start a new one. */ clr_hilite(); + clr_filter(); if (epos != NULL_POSITION) epos += SEARCH_MORE; nprep_startpos = spos; @@ -1498,6 +1656,33 @@ prep_hilite(spos, epos, maxlines) prep_startpos = nprep_startpos; prep_endpos = nprep_endpos; } + +/* + * Set the pattern to be used for line filtering. + */ + public void +set_filter_pattern(pattern, search_type) + char *pattern; + int search_type; +{ + clr_filter(); + if (pattern == NULL || *pattern == '\0') + uncompile_filter_pattern(); + else + compile_pattern(pattern, search_type, &filter_pattern); + screen_trashed = 1; +} + +/* + * Is there a line filter in effect? + */ + public int +is_filtering() +{ + if (ch_getflags() & CH_HELPFILE) + return (0); + return !is_null_pattern(filter_pattern); +} #endif /* diff --git a/signal.c b/signal.c index ce3714c7061c..8f694f869e01 100644 --- a/signal.c +++ b/signal.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -44,6 +44,7 @@ extern long jump_sline_fraction; u_interrupt(type) int type; { + bell(); #if OS2 LSIGNAL(SIGINT, SIG_ACK); #endif @@ -59,7 +60,7 @@ u_interrupt(type) getkey(); #endif if (reading) - intread(); + intread(); /* May longjmp */ } #ifdef SIGTSTP @@ -251,24 +252,5 @@ psignals() { if (quit_on_intr) quit(QUIT_OK); - bell(); - /* - * {{ You may wish to replace the bell() with - * error("Interrupt", NULL_PARG); }} - */ - - /* - * If we were interrupted while in the "calculating - * line numbers" loop, turn off line numbers. - */ - if (lnloop) - { - lnloop = 0; - if (linenums == 2) - screen_trashed = 1; - linenums = 0; - error("Line numbers turned off", NULL_PARG); - } - } } diff --git a/tags.c b/tags.c index ab00faf004d1..04fa362bd724 100644 --- a/tags.c +++ b/tags.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/ttyin.c b/ttyin.c index 0cb427bc2dd9..cde3756ddc01 100644 --- a/ttyin.c +++ b/ttyin.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. diff --git a/version.c b/version.c index bce2f82c07cf..21566851b50f 100644 --- a/version.c +++ b/version.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 1984-2007 Mark Nudelman + * Copyright (C) 1984-2008 Mark Nudelman * * You may distribute under the terms of either the GNU General Public * License or the Less License, as specified in the README file. @@ -12,696 +12,714 @@ /* ----------------------- CHANGE HISTORY -------------------------- - 1/29/84 Allowed use on standard input - 2/1/84 Added E, N, P commands - 4/17/84 Added '=' command, 'stop' signal handling - 4/20/84 Added line folding -v2 4/27/84 Fixed '=' command to use BOTTOM_PLUS_ONE, - instead of TOP, added 'p' & 'v' commands -v3 5/3/84 Added -m and -t options, '-' command -v4 5/3/84 Added LESS environment variable -v5 5/3/84 New comments, fixed '-' command slightly -v6 5/15/84 Added -Q, visual bell -v7 5/24/84 Fixed jump_back(n) bug: n should count real - lines, not folded lines. Also allow number on G command. -v8 5/30/84 Re-do -q and -Q commands -v9 9/25/84 Added "+" argument -v10 10/10/84 Fixed bug in -b argument processing -v11 10/18/84 Made error() ring bell if \n not entered. + 1/29/84 Allowed use on standard input + 2/1/84 Added E, N, P commands + 4/17/84 Added '=' command, 'stop' signal handling + 4/20/84 Added line folding +v2 4/27/84 Fixed '=' command to use BOTTOM_PLUS_ONE, + instead of TOP, added 'p' & 'v' commands +v3 5/3/84 Added -m and -t options, '-' command +v4 5/3/84 Added LESS environment variable +v5 5/3/84 New comments, fixed '-' command slightly +v6 5/15/84 Added -Q, visual bell +v7 5/24/84 Fixed jump_back(n) bug: n should count real + lines, not folded lines. Also allow number on G command. +v8 5/30/84 Re-do -q and -Q commands +v9 9/25/84 Added "+" argument +v10 10/10/84 Fixed bug in -b argument processing +v11 10/18/84 Made error() ring bell if \n not entered. ----------------------------------------------------------------- -v12 2/13/85 Reorganized signal handling and made portable to 4.2bsd. -v13 2/16/85 Reword error message for '-' command. -v14 2/22/85 Added -bf and -bp variants of -b. -v15 2/25/85 Miscellaneous changes. -v16 3/13/85 Added -u flag for backspace processing. -v17 4/13/85 Added j and k commands, changed -t default. -v18 4/20/85 Rewrote signal handling code. -v19 5/2/85 Got rid of "verbose" eq_message(). - Made search() scroll in some cases. -v20 5/21/85 Fixed screen.c ioctls for System V. -v21 5/23/85 Fixed some first_cmd bugs. -v22 5/24/85 Added support for no RECOMP nor REGCMP. -v23 5/25/85 Miscellanous changes and prettying up. - Posted to USENET. +v12 2/13/85 Reorganized signal handling and made portable to 4.2bsd. +v13 2/16/85 Reword error message for '-' command. +v14 2/22/85 Added -bf and -bp variants of -b. +v15 2/25/85 Miscellaneous changes. +v16 3/13/85 Added -u flag for backspace processing. +v17 4/13/85 Added j and k commands, changed -t default. +v18 4/20/85 Rewrote signal handling code. +v19 5/2/85 Got rid of "verbose" eq_message(). + Made search() scroll in some cases. +v20 5/21/85 Fixed screen.c ioctls for System V. +v21 5/23/85 Fixed some first_cmd bugs. +v22 5/24/85 Added support for no RECOMP nor REGCMP. +v23 5/25/85 Miscellanous changes and prettying up. + Posted to USENET. ----------------------------------------------------------------- -v24 6/3/85 Added ti,te terminal init & de-init. - (Thanks to Mike Kersenbrock) -v25 6/8/85 Added -U flag, standout mode underlining. -v26 6/9/85 Added -M flag. - Use underline termcap (us) if it exists. -v27 6/15/85 Renamed some variables to make unique in - 6 chars. Minor fix to -m. -v28 6/28/85 Fixed right margin bug. -v29 6/28/85 Incorporated M.Rose's changes to signal.c -v30 6/29/85 Fixed stupid bug in argument processing. -v31 7/15/85 Added -p flag, changed repaint algorithm. - Added kludge for magic cookie terminals. -v32 7/16/85 Added cat_file if output not a tty. -v33 7/23/85 Added -e flag and EDITOR. -v34 7/26/85 Added -s flag. -v35 7/27/85 Rewrote option handling; added option.c. -v36 7/29/85 Fixed -e flag to work if not last file. -v37 8/10/85 Added -x flag. -v38 8/19/85 Changed prompting; created prompt.c. -v39 8/24/85 (Not -p) does not initially clear screen. -v40 8/26/85 Added "skipping" indicator in forw(). - Posted to USENET. +v24 6/3/85 Added ti,te terminal init & de-init. + (Thanks to Mike Kersenbrock) +v25 6/8/85 Added -U flag, standout mode underlining. +v26 6/9/85 Added -M flag. + Use underline termcap (us) if it exists. +v27 6/15/85 Renamed some variables to make unique in + 6 chars. Minor fix to -m. +v28 6/28/85 Fixed right margin bug. +v29 6/28/85 Incorporated M.Rose's changes to signal.c +v30 6/29/85 Fixed stupid bug in argument processing. +v31 7/15/85 Added -p flag, changed repaint algorithm. + Added kludge for magic cookie terminals. +v32 7/16/85 Added cat_file if output not a tty. +v33 7/23/85 Added -e flag and EDITOR. +v34 7/26/85 Added -s flag. +v35 7/27/85 Rewrote option handling; added option.c. +v36 7/29/85 Fixed -e flag to work if not last file. +v37 8/10/85 Added -x flag. +v38 8/19/85 Changed prompting; created prompt.c. +v39 8/24/85 (Not -p) does not initially clear screen. +v40 8/26/85 Added "skipping" indicator in forw(). + Posted to USENET. ----------------------------------------------------------------- -v41 9/17/85 ONLY_RETURN, control char commands, - faster search, other minor fixes. -v42 9/25/85 Added ++ command line syntax; - ch_fsize for pipes. -v43 10/15/85 Added -h flag, changed prim.c algorithms. -v44 10/16/85 Made END print in all cases of eof; - ignore SIGTTOU after receiv ing SIGTSTP. -v45 10/16/85 Never print backspaces unless -u. -v46 10/24/85 Backwards scroll in jump_loc. -v47 10/30/85 Fixed bug in edit(): *first_cmd==0 -v48 11/16/85 Use TIOCSETN instead of TIOCSETP. - Added marks (m and ' commands). - Posted to USENET. +v41 9/17/85 ONLY_RETURN, control char commands, + faster search, other minor fixes. +v42 9/25/85 Added ++ command line syntax; + ch_fsize for pipes. +v43 10/15/85 Added -h flag, changed prim.c algorithms. +v44 10/16/85 Made END print in all cases of eof; + ignore SIGTTOU after receiv ing SIGTSTP. +v45 10/16/85 Never print backspaces unless -u. +v46 10/24/85 Backwards scroll in jump_loc. +v47 10/30/85 Fixed bug in edit(): *first_cmd==0 +v48 11/16/85 Use TIOCSETN instead of TIOCSETP. + Added marks (m and ' commands). + Posted to USENET. ----------------------------------------------------------------- -v49 1/9/86 Fixed bug: signal didn't clear mcc. -v50 1/15/86 Added ' (quote) to gomark. -v51 1/16/86 Added + cmd, fixed problem if first_cmd - fails, made g cmd sort of "work" on pipes - ev en if bof is no longer buffered. -v52 1/17/86 Made short files work better. -v53 1/20/86 Added -P option. -v54 1/20/86 Changed help to use HELPFILE. -v55 1/23/86 Messages work better if not tty output. -v56 1/24/86 Added -l option. -v57 1/31/86 Fixed -l to get confirmation before - ov erwriting an existing file. -v58 8/28/86 Added filename globbing. -v59 9/15/86 Fixed some bugs with very long filenames. -v60 9/26/86 Incorporated changes from Leith (Casey) - Leedom for boldface and -z option. -v61 9/26/86 Got rid of annoying repaints after ! cmd. - Posted to USENET. +v49 1/9/86 Fixed bug: signal didn't clear mcc. +v50 1/15/86 Added ' (quote) to gomark. +v51 1/16/86 Added + cmd, fixed problem if first_cmd + fails, made g cmd sort of "work" on pipes + ev en if bof is no longer buffered. +v52 1/17/86 Made short files work better. +v53 1/20/86 Added -P option. +v54 1/20/86 Changed help to use HELPFILE. +v55 1/23/86 Messages work better if not tty output. +v56 1/24/86 Added -l option. +v57 1/31/86 Fixed -l to get confirmation before + ov erwriting an existing file. +v58 8/28/86 Added filename globbing. +v59 9/15/86 Fixed some bugs with very long filenames. +v60 9/26/86 Incorporated changes from Leith (Casey) + Leedom for boldface and -z option. +v61 9/26/86 Got rid of annoying repaints after ! cmd. + Posted to USENET. ----------------------------------------------------------------- -v62 12/23/86 Added is_directory(); change -z default to - -1 instead of 24; cat-and-exit if -e and - file is less than a screenful. -v63 1/8/87 Fixed bug in cat-and-exit if > 1 file. -v64 1/12/87 Changed puts/putstr, putc/putchr, - getc/getchr to av oid name conflict with - stdio functions. -v65 1/26/87 Allowed '-' command to change NUMBER - v alued options (thanks to Gary Puckering) -v66 2/13/87 Fixed bug: prepaint should use force=1. -v67 2/24/87 Added !! and % expansion to ! command. -v68 2/25/87 Added SIGWINCH and TIOCGWINSZ support; - changed is_directory to bad_file. - (thanks to J. Robert Ward) -v69 2/25/87 Added SIGWIND and WIOCGETD (for Unix PC). -v70 3/13/87 Changed help cmd from 'h' to 'H'; better - error msgs in bad_file, errno_message. -v71 5/11/87 Changed -p to -c, made triple -c/-C - for clear-eol like more's -c. -v72 6/26/87 Added -E, -L, use $SHELL in lsystem(). - (thanks to Stev e Spearman) -v73 6/26/87 Allow Examine "#" for previous file. - Posted to USENET 8/25/87. +v62 12/23/86 Added is_directory(); change -z default to + -1 instead of 24; cat-and-exit if -e and + file is less than a screenful. +v63 1/8/87 Fixed bug in cat-and-exit if > 1 file. +v64 1/12/87 Changed puts/putstr, putc/putchr, + getc/getchr to av oid name conflict with + stdio functions. +v65 1/26/87 Allowed '-' command to change NUMBER + v alued options (thanks to Gary Puckering) +v66 2/13/87 Fixed bug: prepaint should use force=1. +v67 2/24/87 Added !! and % expansion to ! command. +v68 2/25/87 Added SIGWINCH and TIOCGWINSZ support; + changed is_directory to bad_file. + (thanks to J. Robert Ward) +v69 2/25/87 Added SIGWIND and WIOCGETD (for Unix PC). +v70 3/13/87 Changed help cmd from 'h' to 'H'; better + error msgs in bad_file, errno_message. +v71 5/11/87 Changed -p to -c, made triple -c/-C + for clear-eol like more's -c. +v72 6/26/87 Added -E, -L, use $SHELL in lsystem(). + (thanks to Stev e Spearman) +v73 6/26/87 Allow Examine "#" for previous file. + Posted to USENET 8/25/87. ----------------------------------------------------------------- -v74 9/18/87 Fix conflict in EOF symbol with stdio.h, - Make os.c more portable to BSD. -v75 9/23/87 Fix problems in get_term (thanks to - Paul Eggert); new backwards scrolling in - jump_loc (thanks to Marion Hakanson). -v76 9/23/87 Added -i flag; allow single "!" to - inv oke a shell (thanks to Franco Barber). -v77 9/24/87 Added -n flag and line number support. -v78 9/25/87 Fixed problem with prompts longer than - the screen width. -v79 9/29/87 Added the _ command. -v80 10/6/87 Allow signal to break out of linenum scan. -v81 10/6/87 Allow -b to be changed from within less. -v82 10/7/87 Add cmd_decode to use a table for key - binding (thanks to Dav id Nason). -v83 10/9/87 Allow .less file for user-defined keys. -v84 10/11/87 Fix -e/-E problems (thanks to Felix Lee). -v85 10/15/87 Search now keeps track of line numbers. -v86 10/20/87 Added -B option and autobuf; fixed - "pipe error" bug. -v87 3/1/88 Fix bug re BSD signals while reading file. -v88 3/12/88 Use new format for -P option (thanks to - der Mouse), allow "+-c" without message, - fix bug re BSD hangup. -v89 3/18/88 Turn off line numbers if linenum scan - is interrupted. -v90 3/30/88 Allow -P from within less. -v91 3/30/88 Added tags file support (new -t option) - (thanks to Brian Campbell). -v92 4/4/88 Added -+option syntax. -v93 4/11/88 Add support for slow input (thanks to - Joe Orost & apologies for taking almost - 3 years to get this in!) -v94 4/11/88 Redo reading/signal stuff. -v95 4/20/88 Repaint screen better after signal. -v96 4/21/88 Add /! and ?! commands. -v97 5/17/88 Allow -l/-L from within less. - Eliminate some static arrays (use calloc). - Posted to USENET. +v74 9/18/87 Fix conflict in EOF symbol with stdio.h, + Make os.c more portable to BSD. +v75 9/23/87 Fix problems in get_term (thanks to + Paul Eggert); new backwards scrolling in + jump_loc (thanks to Marion Hakanson). +v76 9/23/87 Added -i flag; allow single "!" to + inv oke a shell (thanks to Franco Barber). +v77 9/24/87 Added -n flag and line number support. +v78 9/25/87 Fixed problem with prompts longer than + the screen width. +v79 9/29/87 Added the _ command. +v80 10/6/87 Allow signal to break out of linenum scan. +v81 10/6/87 Allow -b to be changed from within less. +v82 10/7/87 Add cmd_decode to use a table for key + binding (thanks to Dav id Nason). +v83 10/9/87 Allow .less file for user-defined keys. +v84 10/11/87 Fix -e/-E problems (thanks to Felix Lee). +v85 10/15/87 Search now keeps track of line numbers. +v86 10/20/87 Added -B option and autobuf; fixed + "pipe error" bug. +v87 3/1/88 Fix bug re BSD signals while reading file. +v88 3/12/88 Use new format for -P option (thanks to + der Mouse), allow "+-c" without message, + fix bug re BSD hangup. +v89 3/18/88 Turn off line numbers if linenum scan + is interrupted. +v90 3/30/88 Allow -P from within less. +v91 3/30/88 Added tags file support (new -t option) + (thanks to Brian Campbell). +v92 4/4/88 Added -+option syntax. +v93 4/11/88 Add support for slow input (thanks to + Joe Orost & apologies for taking almost + 3 years to get this in!) +v94 4/11/88 Redo reading/signal stuff. +v95 4/20/88 Repaint screen better after signal. +v96 4/21/88 Add /! and ?! commands. +v97 5/17/88 Allow -l/-L from within less. + Eliminate some static arrays (use calloc). + Posted to USENET. ----------------------------------------------------------------- -v98 10/14/88 Fix incorrect calloc call; uninitialized - var in exec_mca; core dump on unknown TERM. - Make v cmd work if past last line of file. - Fix some signal bugs. -v99 10/29/88 Allow space between -X and string, - when X is a string-valued option. -v100 1/5/89 Fix globbing bug when $SHELL not set; - allow spaces after -t command. -v101 1/6/89 Fix problem with long (truncated) lines - in tags file (thanks to Neil Dixon). -v102 1/6/89 Fix bug with E# when no prev file; - allow spaces after -l command. -v103 3/14/89 Add -N, -f and -? options. Add z and w - commands. Add %L for prompt strings. -v104 3/16/89 Added EDITPROTO. -v105 3/20/89 Fix bug in find_linenum which cached - incorrectly on long lines. -v106 3/31/89 Added -k option and multiple lesskey - files. -v107 4/27/89 Add 8-bit char support and -g option. - Split option code into 3 files. -v108 5/5/89 Allocate position table dynamically - (thanks to Paul Eggert); change % command - from "percent" to vi-style brace finder. -v109 5/10/89 Added ESC-% command, split prim.c. -v110 5/24/89 Fixed bug in + option; fixed repaint bug - under Sun windows (thanks to Paul Eggert). -v111 5/25/89 Generalized # and % expansion; use - calloc for some error messages. -v112 5/30/89 Get rid of ESC-%, add {}()[] commands. -v113 5/31/89 Optimize lseeks (thanks to Paul Eggert). -v114 7/25/89 Added ESC-/ and ESC-/! commands. -v115 7/26/89 Added ESC-n command. -v116 7/31/89 Added find_pos to optimize g command. -v117 8/1/89 Change -f option to -r. -v118 8/2/89 Save positions for all previous files, - not just the immediately previous one. -v119 8/7/89 Save marks across file boundaries. - Add file handle stuff. -v120 8/11/89 Add :ta command. -v121 8/16/89 Add -f option. -v122 8/30/89 Fix performance with many buffers. -v123 8/31/89 Verbose prompts for string options. - Posted beta to USENET. +v98 10/14/88 Fix incorrect calloc call; uninitialized + var in exec_mca; core dump on unknown TERM. + Make v cmd work if past last line of file. + Fix some signal bugs. +v99 10/29/88 Allow space between -X and string, + when X is a string-valued option. +v100 1/5/89 Fix globbing bug when $SHELL not set; + allow spaces after -t command. +v101 1/6/89 Fix problem with long (truncated) lines + in tags file (thanks to Neil Dixon). +v102 1/6/89 Fix bug with E# when no prev file; + allow spaces after -l command. +v103 3/14/89 Add -N, -f and -? options. Add z and w + commands. Add %L for prompt strings. +v104 3/16/89 Added EDITPROTO. +v105 3/20/89 Fix bug in find_linenum which cached + incorrectly on long lines. +v106 3/31/89 Added -k option and multiple lesskey + files. +v107 4/27/89 Add 8-bit char support and -g option. + Split option code into 3 files. +v108 5/5/89 Allocate position table dynamically + (thanks to Paul Eggert); change % command + from "percent" to vi-style brace finder. +v109 5/10/89 Added ESC-% command, split prim.c. +v110 5/24/89 Fixed bug in + option; fixed repaint bug + under Sun windows (thanks to Paul Eggert). +v111 5/25/89 Generalized # and % expansion; use + calloc for some error messages. +v112 5/30/89 Get rid of ESC-%, add {}()[] commands. +v113 5/31/89 Optimize lseeks (thanks to Paul Eggert). +v114 7/25/89 Added ESC-/ and ESC-/! commands. +v115 7/26/89 Added ESC-n command. +v116 7/31/89 Added find_pos to optimize g command. +v117 8/1/89 Change -f option to -r. +v118 8/2/89 Save positions for all previous files, + not just the immediately previous one. +v119 8/7/89 Save marks across file boundaries. + Add file handle stuff. +v120 8/11/89 Add :ta command. +v121 8/16/89 Add -f option. +v122 8/30/89 Fix performance with many buffers. +v123 8/31/89 Verbose prompts for string options. + Posted beta to USENET. ----------------------------------------------------------------- -v124 9/18/89 Reorganize search commands, - N = rev, ESC-n = span, add ESC-N. -v125 9/18/89 Fix tab bug (thanks to Alex Liu). - Fix EOF bug when both -w and -c. -v126 10/25/89 Add -j option. -v127 10/27/89 Fix problems with blank lines before BOF. -v128 10/27/89 Add %bj, etc. to prompt strings. -v129 11/3/89 Add -+,-- commands; add set-option and - unset-option to lesskey. -v130 11/6/89 Generalize A_EXTRA to string, remove - set-option, unset-option from lesskey. -v131 11/7/89 Changed name of EDITPROTO to LESSEDIT. -v132 11/8/89 Allow editing of command prefix. -v133 11/16/89 Add -y option (thanks to Jeff Sullivan). -v134 12/1/89 Glob filenames in the -l command. -v135 12/5/89 Combined {}()[] commands into one, and - added ESC-^F and ESC-^B commands. -v136 1/20/90 Added -S, -R flags. Added | command. - Added warning for binary files. (thanks - to Richard Brittain and J. Sullivan). -v137 1/21/90 Rewrote horrible pappend code. - Added * notation for hi-bit chars. -v138 1/24/90 Fix magic cookie terminal handling. - Get rid of "cleanup" loop in ch_get. -v139 1/27/90 Added MSDOS support. (many thanks - to Richard Brittain). -v140 2/7/90 Editing a new file adds it to the - command line list. -v141 2/8/90 Add edit_list for editing >1 file. -v142 2/10/90 Add :x command. -v143 2/11/90 Add * and @ modifies to search cmds. - Change ESC-/ cmd from /@* to / *. -v144 3/1/90 Messed around with ch_zero; - no real change. -v145 3/2/90 Added -R and -v/-V for MSDOS; - renamed FILENAME to avoid conflict. -v146 3/5/90 Pull cmdbuf functions out of command.c -v147 3/7/90 Implement ?@; fix multi-file edit bugs. -v148 3/29/90 Fixed bug in :e then :e#. -v149 4/3/90 Change error,ierror,query to use PARG. -v150 4/6/90 Add LESS_CHARSET, LESS_CHARDEF. -v151 4/13/90 Remove -g option; clean up ispipe. -v152 4/14/90 lsystem() closes input file, for - editors which require exclusive open. -v153 4/18/90 Fix bug if SHELL unset; - fix bug in overstrike control char. -v154 4/25/90 Output to fd 2 via buffer. -v155 4/30/90 Ignore -i if uppercase in pattern - (thanks to Michael Rendell.) -v156 5/3/90 Remove scroll limits in forw() & back(); - causes problems with -c. -v157 5/4/90 Forward search starts at next real line - (not screen line) after jump target. -v158 6/14/90 Added F command. -v159 7/29/90 Fix bug in exiting: output not flushed. -v160 7/29/90 Clear screen before initial output w/ -c. -v161 7/29/90 Add -T flag. -v162 8/14/90 Fix bug with +F on command line. -v163 8/21/90 Added LESSBINFMT variable. -v164 9/5/90 Added -p, LINES, COLUMNS and - unset mark ' == BOF, for 1003.2 D5. -v165 9/6/90 At EOF with -c set, don't display empty - screen when try to page forward. -v166 9/6/90 Fix G when final line in file wraps. -v167 9/11/90 Translate CR/LF -> LF for 1003.2. -v168 9/13/90 Return to curr file if "tag not found". -v169 12/12/90 G goes to EOF even if file has grown. -v170 1/17/91 Add optimization for BSD _setjmp; - fix #include ioctl.h TERMIO problem. - (thanks to Paul Eggert) - Posted to USENET. +v124 9/18/89 Reorganize search commands, + N = rev, ESC-n = span, add ESC-N. +v125 9/18/89 Fix tab bug (thanks to Alex Liu). + Fix EOF bug when both -w and -c. +v126 10/25/89 Add -j option. +v127 10/27/89 Fix problems with blank lines before BOF. +v128 10/27/89 Add %bj, etc. to prompt strings. +v129 11/3/89 Add -+,-- commands; add set-option and + unset-option to lesskey. +v130 11/6/89 Generalize A_EXTRA to string, remove + set-option, unset-option from lesskey. +v131 11/7/89 Changed name of EDITPROTO to LESSEDIT. +v132 11/8/89 Allow editing of command prefix. +v133 11/16/89 Add -y option (thanks to Jeff Sullivan). +v134 12/1/89 Glob filenames in the -l command. +v135 12/5/89 Combined {}()[] commands into one, and + added ESC-^F and ESC-^B commands. +v136 1/20/90 Added -S, -R flags. Added | command. + Added warning for binary files. (thanks + to Richard Brittain and J. Sullivan). +v137 1/21/90 Rewrote horrible pappend code. + Added * notation for hi-bit chars. +v138 1/24/90 Fix magic cookie terminal handling. + Get rid of "cleanup" loop in ch_get. +v139 1/27/90 Added MSDOS support. (many thanks + to Richard Brittain). +v140 2/7/90 Editing a new file adds it to the + command line list. +v141 2/8/90 Add edit_list for editing >1 file. +v142 2/10/90 Add :x command. +v143 2/11/90 Add * and @ modifies to search cmds. + Change ESC-/ cmd from /@* to / *. +v144 3/1/90 Messed around with ch_zero; + no real change. +v145 3/2/90 Added -R and -v/-V for MSDOS; + renamed FILENAME to avoid conflict. +v146 3/5/90 Pull cmdbuf functions out of command.c +v147 3/7/90 Implement ?@; fix multi-file edit bugs. +v148 3/29/90 Fixed bug in :e then :e#. +v149 4/3/90 Change error,ierror,query to use PARG. +v150 4/6/90 Add LESS_CHARSET, LESS_CHARDEF. +v151 4/13/90 Remove -g option; clean up ispipe. +v152 4/14/90 lsystem() closes input file, for + editors which require exclusive open. +v153 4/18/90 Fix bug if SHELL unset; + fix bug in overstrike control char. +v154 4/25/90 Output to fd 2 via buffer. +v155 4/30/90 Ignore -i if uppercase in pattern + (thanks to Michael Rendell.) +v156 5/3/90 Remove scroll limits in forw() & back(); + causes problems with -c. +v157 5/4/90 Forward search starts at next real line + (not screen line) after jump target. +v158 6/14/90 Added F command. +v159 7/29/90 Fix bug in exiting: output not flushed. +v160 7/29/90 Clear screen before initial output w/ -c. +v161 7/29/90 Add -T flag. +v162 8/14/90 Fix bug with +F on command line. +v163 8/21/90 Added LESSBINFMT variable. +v164 9/5/90 Added -p, LINES, COLUMNS and + unset mark ' == BOF, for 1003.2 D5. +v165 9/6/90 At EOF with -c set, don't display empty + screen when try to page forward. +v166 9/6/90 Fix G when final line in file wraps. +v167 9/11/90 Translate CR/LF -> LF for 1003.2. +v168 9/13/90 Return to curr file if "tag not found". +v169 12/12/90 G goes to EOF even if file has grown. +v170 1/17/91 Add optimization for BSD _setjmp; + fix #include ioctl.h TERMIO problem. + (thanks to Paul Eggert) + Posted to USENET. ----------------------------------------------------------------- -v171 3/6/91 Fix -? bug in get_filename. -v172 3/15/91 Fix G bug in empty file. - Fix bug with ?\n and -i and uppercase - pattern at EOF! - (thanks to Paul Eggert) -v173 3/17/91 Change N cmd to not permanently change - direction. (thanks to Brian Matthews) -v174 3/18/91 Fix bug with namelogfile not getting - cleared when change files. -v175 3/18/91 Fix bug with ++cmd on command line. - (thanks to Jim Meyering) -v176 4/2/91 Change | to not force current screen, - include marked line, start/end from - top of screen. Improve search speed. - (thanks to Don Mears) -v177 4/2/91 Add LESSHELP variable. - Fix bug with F command with -e. - Try /dev/tty for input before using fd 2. - Patches posted to USENET 4/2/91. +v171 3/6/91 Fix -? bug in get_filename. +v172 3/15/91 Fix G bug in empty file. + Fix bug with ?\n and -i and uppercase + pattern at EOF! + (thanks to Paul Eggert) +v173 3/17/91 Change N cmd to not permanently change + direction. (thanks to Brian Matthews) +v174 3/18/91 Fix bug with namelogfile not getting + cleared when change files. +v175 3/18/91 Fix bug with ++cmd on command line. + (thanks to Jim Meyering) +v176 4/2/91 Change | to not force current screen, + include marked line, start/end from + top of screen. Improve search speed. + (thanks to Don Mears) +v177 4/2/91 Add LESSHELP variable. + Fix bug with F command with -e. + Try /dev/tty for input before using fd 2. + Patches posted to USENET 4/2/91. ----------------------------------------------------------------- -v178 4/8/91 Fixed bug in globbing logfile name. - (thanks to Jim Meyering) -v179 4/9/91 Allow negative -z for screen-relative. -v180 4/9/91 Clear to eos rather than eol if "db"; - don't use "sr" if "da". - (thanks to Tor Lillqvist) -v181 4/18/91 Fixed bug with "negative" chars 80 - FF. - (thanks to Benny Sander Hofmann) -v182 5/16/91 Fixed bug with attribute at EOL. - (thanks to Brian Matthews) -v183 6/1/91 Rewrite linstall to do smart config. -v184 7/11/91 Process \b in searches based on -u - rather than -i. -v185 7/11/91 -Pxxx sets short prompt; assume SIGWINCH - after a SIGSTOP. (thanks to Ken Laprade) +v178 4/8/91 Fixed bug in globbing logfile name. + (thanks to Jim Meyering) +v179 4/9/91 Allow negative -z for screen-relative. +v180 4/9/91 Clear to eos rather than eol if "db"; + don't use "sr" if "da". + (thanks to Tor Lillqvist) +v181 4/18/91 Fixed bug with "negative" chars 80 - FF. + (thanks to Benny Sander Hofmann) +v182 5/16/91 Fixed bug with attribute at EOL. + (thanks to Brian Matthews) +v183 6/1/91 Rewrite linstall to do smart config. +v184 7/11/91 Process \b in searches based on -u + rather than -i. +v185 7/11/91 -Pxxx sets short prompt; assume SIGWINCH + after a SIGSTOP. (thanks to Ken Laprade) ----------------------------------------------------------------- -v186 4/20/92 Port to MS-DOS (Microsoft C). -v187 4/23/92 Added -D option & TAB_COMPLETE_FILENAME. -v188 4/28/92 Added command line editing features. -v189 12/8/92 Fix mem overrun in anscreen.c:init; - fix edit_list to recover from bin file. -v190 2/13/93 Make TAB enter one filename at a time; - create ^L with old TAB functionality. -v191 3/10/93 Defer creating "flash" page for MS-DOS. -v192 9/6/93 Add BACK-TAB. -v193 9/17/93 Simplify binary_file handling. -v194 1/4/94 Add rudiments of alt_filename handling. -v195 1/11/94 Port back to Unix; support keypad. +v186 4/20/92 Port to MS-DOS (Microsoft C). +v187 4/23/92 Added -D option & TAB_COMPLETE_FILENAME. +v188 4/28/92 Added command line editing features. +v189 12/8/92 Fix mem overrun in anscreen.c:init; + fix edit_list to recover from bin file. +v190 2/13/93 Make TAB enter one filename at a time; + create ^L with old TAB functionality. +v191 3/10/93 Defer creating "flash" page for MS-DOS. +v192 9/6/93 Add BACK-TAB. +v193 9/17/93 Simplify binary_file handling. +v194 1/4/94 Add rudiments of alt_filename handling. +v195 1/11/94 Port back to Unix; support keypad. ----------------------------------------------------------------- -v196 6/7/94 Fix bug with bad filename; fix IFILE - type problem. (thanks to David MacKenzie) -v197 6/7/94 Fix bug with .less tables inserted wrong. -v198 6/23/94 Use autoconf installation technology. - (thanks to David MacKenzie) -v199 6/29/94 Fix MS-DOS build (thanks to Tim Wiegman). -v200 7/25/94 Clean up copyright, minor fixes. - Posted to prep.ai.mit.edu +v196 6/7/94 Fix bug with bad filename; fix IFILE + type problem. (thanks to David MacKenzie) +v197 6/7/94 Fix bug with .less tables inserted wrong. +v198 6/23/94 Use autoconf installation technology. + (thanks to David MacKenzie) +v199 6/29/94 Fix MS-DOS build (thanks to Tim Wiegman). +v200 7/25/94 Clean up copyright, minor fixes. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v201 7/27/94 Check for no memcpy; add casts to calloc; - look for regcmp in libgen.a. - (thanks to Kaveh Ghazi). -v202 7/28/94 Fix bug in edit_next/edit_prev with - non-existant files. -v203 8/2/94 Fix a variety of configuration bugs on - various systems. (thanks to Sakai - Kiyotaka, Harald Koenig, Bjorn Brox, - Teemu Rantanen, and Thorsten Lockert) -v204 8/3/94 Use strerror if available. - (thanks to J.T. Conklin) -v205 8/5/94 Fix bug in finding "me" termcap entry. - (thanks to Andreas Stolcke) -8/10/94 v205+: Change BUFSIZ to LBUFSIZE to avoid name - conflict with stdio.h. - Posted to prep.ai.mit.edu +v201 7/27/94 Check for no memcpy; add casts to calloc; + look for regcmp in libgen.a. + (thanks to Kaveh Ghazi). +v202 7/28/94 Fix bug in edit_next/edit_prev with + non-existant files. +v203 8/2/94 Fix a variety of configuration bugs on + various systems. (thanks to Sakai + Kiyotaka, Harald Koenig, Bjorn Brox, + Teemu Rantanen, and Thorsten Lockert) +v204 8/3/94 Use strerror if available. + (thanks to J.T. Conklin) +v205 8/5/94 Fix bug in finding "me" termcap entry. + (thanks to Andreas Stolcke) +8/10/94 v205+: Change BUFSIZ to LBUFSIZE to avoid name + conflict with stdio.h. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v206 8/10/94 Use initial_scrpos for -t to avoid - displaying first page before init(). - (thanks to Dominique Petitpierre) -v207 8/12/94 Fix bug if stdout is not tty. -v208 8/16/94 Fix bug in close_altfile if goto err1 - in edit_ifile. (Thanks to M.J. Hewitt) -v209 8/16/94 Change scroll to wscroll to avoid - conflict with library function. -v210 8/16/94 Fix bug with bold on 8 bit chars. - (thanks to Vitor Duarte) -v211 8/16/94 Don't quit on EOI in jump_loc / forw. -v212 8/18/94 Use time_t if available. -v213 8/20/94 Allow ospeed to be defined in termcap.h. -v214 8/20/94 Added HILITE_SEARCH, -F, ESC-u cmd. - (thanks to Paul Lew and Bob Byrnes) -v215 8/23/94 Fix -i toggle behavior. -v216 8/23/94 Process BS in all searches, not only -u. -v217 8/24/94 Added -X flag. -v218 8/24/94 Reimplement undo_search. -v219 8/24/94 Find tags marked with line number - instead of pattern. -v220 8/24/94 Stay at same position after SIG_WINCH. -v221 8/24/94 Fix bug in file percentage in big file. -v222 8/25/94 Do better if can't reopen current file. -v223 8/27/94 Support setlocale. - (thanks to Robert Joop) -v224 8/29/94 Revert v216: process BS in search - only if -u. -v225 9/6/94 Rewrite undo_search again: toggle. -v226 9/15/94 Configuration fixes. - (thanks to David MacKenzie) -v227 9/19/94 Fixed strerror config problem. - Posted to prep.ai.mit.edu +v206 8/10/94 Use initial_scrpos for -t to avoid + displaying first page before init(). + (thanks to Dominique Petitpierre) +v207 8/12/94 Fix bug if stdout is not tty. +v208 8/16/94 Fix bug in close_altfile if goto err1 + in edit_ifile. (Thanks to M.J. Hewitt) +v209 8/16/94 Change scroll to wscroll to avoid + conflict with library function. +v210 8/16/94 Fix bug with bold on 8 bit chars. + (thanks to Vitor Duarte) +v211 8/16/94 Don't quit on EOI in jump_loc / forw. +v212 8/18/94 Use time_t if available. +v213 8/20/94 Allow ospeed to be defined in termcap.h. +v214 8/20/94 Added HILITE_SEARCH, -F, ESC-u cmd. + (thanks to Paul Lew and Bob Byrnes) +v215 8/23/94 Fix -i toggle behavior. +v216 8/23/94 Process BS in all searches, not only -u. +v217 8/24/94 Added -X flag. +v218 8/24/94 Reimplement undo_search. +v219 8/24/94 Find tags marked with line number + instead of pattern. +v220 8/24/94 Stay at same position after SIG_WINCH. +v221 8/24/94 Fix bug in file percentage in big file. +v222 8/25/94 Do better if can't reopen current file. +v223 8/27/94 Support setlocale. + (thanks to Robert Joop) +v224 8/29/94 Revert v216: process BS in search + only if -u. +v225 9/6/94 Rewrite undo_search again: toggle. +v226 9/15/94 Configuration fixes. + (thanks to David MacKenzie) +v227 9/19/94 Fixed strerror config problem. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v228 9/21/94 Fix bug in signals: repeated calls to - get_editkeys overflowed st_edittable. -v229 9/21/94 Fix "Nothing to search" error if -a - and SRCH_PAST_EOF. -v230 9/21/94 Don't print extra error msg in search - after regerror(). -v231 9/22/94 Fix hilite bug if search matches 0 chars. - (thanks to John Polstra) -v232 9/23/94 Deal with weird systems that have - termios.h but not tcgetattr(). - Posted to prep.ai.mit.edu +v228 9/21/94 Fix bug in signals: repeated calls to + get_editkeys overflowed st_edittable. +v229 9/21/94 Fix "Nothing to search" error if -a + and SRCH_PAST_EOF. +v230 9/21/94 Don't print extra error msg in search + after regerror(). +v231 9/22/94 Fix hilite bug if search matches 0 chars. + (thanks to John Polstra) +v232 9/23/94 Deal with weird systems that have + termios.h but not tcgetattr(). + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v233 9/26/94 Use get_term() instead of pos_init() in - psignals to re-get lower_left termcap. - (Thanks to John Malecki) -v234 9/26/94 Make MIDDLE closer to middle of screen. -v235 9/27/94 Use local strchr if system doesn't have. -v236 9/28/94 Don't use libucb; use libterm if - libtermcap & libcurses doesn't work. - (Fix for Solaris; thanks to Frank Kaefer) -v237 9/30/94 Use system isupper() etc if provided. - Posted to prep.ai.mit.edu +v233 9/26/94 Use get_term() instead of pos_init() in + psignals to re-get lower_left termcap. + (Thanks to John Malecki) +v234 9/26/94 Make MIDDLE closer to middle of screen. +v235 9/27/94 Use local strchr if system doesn't have. +v236 9/28/94 Don't use libucb; use libterm if + libtermcap & libcurses doesn't work. + (Fix for Solaris; thanks to Frank Kaefer) +v237 9/30/94 Use system isupper() etc if provided. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v238 10/6/94 Make binary non-blinking if LESSBINFMT - is set to a string without a *. -v239 10/7/94 Don't let delimit_word run back past - beginning of cmdbuf. -v240 10/10/94 Don't write into termcap buffer. - (Thanks to Benoit Speckel) -v241 10/13/94 New lesskey file format. - Don't expand filenames in search command. -v242 10/14/94 Allow lesskey specification of "literal". -v243 10/14/94 Add #stop command to lesskey. -v244 10/16/94 Add -f flag to lesskey. -v245 10/25/94 Allow TAB_COMPLETE_FILENAME to be undefd. -v246 10/27/94 Move help file to /usr/local/share. -v247 10/27/94 Add -V option. -v248 11/5/94 Add -V option to lesskey. -v249 11/5/94 Remove -f flag from lesskey; default - input file is ~/.lesskey.in, not stdin. -v250 11/7/94 Lesskey input file "-" means stdin. -v251 11/9/94 Convert cfgetospeed result to ospeed. - (Thanks to Andrew Chernov) -v252 11/16/94 Change default lesskey input file from - .lesskey.in to .lesskey. - Posted to prep.ai.mit.edu +v238 10/6/94 Make binary non-blinking if LESSBINFMT + is set to a string without a *. +v239 10/7/94 Don't let delimit_word run back past + beginning of cmdbuf. +v240 10/10/94 Don't write into termcap buffer. + (Thanks to Benoit Speckel) +v241 10/13/94 New lesskey file format. + Don't expand filenames in search command. +v242 10/14/94 Allow lesskey specification of "literal". +v243 10/14/94 Add #stop command to lesskey. +v244 10/16/94 Add -f flag to lesskey. +v245 10/25/94 Allow TAB_COMPLETE_FILENAME to be undefd. +v246 10/27/94 Move help file to /usr/local/share. +v247 10/27/94 Add -V option. +v248 11/5/94 Add -V option to lesskey. +v249 11/5/94 Remove -f flag from lesskey; default + input file is ~/.lesskey.in, not stdin. +v250 11/7/94 Lesskey input file "-" means stdin. +v251 11/9/94 Convert cfgetospeed result to ospeed. + (Thanks to Andrew Chernov) +v252 11/16/94 Change default lesskey input file from + .lesskey.in to .lesskey. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v253 11/21/94 Fix bug when tags file has a backslash. -v254 12/6/94 Fix -k option. -v255 12/8/94 Add #define EXAMINE to disable :e etc. -v256 12/10/94 Change highlighting: only highlite search - results (but now it is reliable). -v257 12/10/94 Add goto_line and repaint_highlight - to optimize highlight repaints. -v258 12/12/94 Fixup in hilite_line if BS_SPECIAL. -v259 12/12/94 Convert to autoconf 2.0. -v260 12/13/94 Add SECURE define. -v261 12/14/94 Use system WERASE char as EC_W_BACKSPACE. -v262 12/16/94 Add -g/-G flag and screen_hilite. -v263 12/20/94 Reimplement/optimize -G flag behavior. -v264 12/23/94 Allow EXTRA string after line-edit cmd - in lesskey file. -v265 12/24/94 Add LESSOPEN=|cmd syntax. -v266 12/26/94 Add -I flag. -v267 12/28/94 Formalize the four-byte header emitted - by a LESSOPEN pipe. -v268 12/28/94 Get rid of four-byte header. -v269 1/2/95 Close alt file before open new one. - Avoids multiple popen(). -v270 1/3/95 Use VISUAL; use S_ISDIR/S_ISREG; fix - config problem with Solaris POSIX regcomp. -v271 1/4/95 Don't quit on read error. -v272 1/5/95 Get rid of -L. -v273 1/6/95 Fix ch_ungetchar bug; don't call - LESSOPEN on a pipe. -v274 1/6/95 Ported to OS/2 (thanks to Kai Uwe Rommel) -v275 1/18/95 Fix bug if toggle -G at EOF. -v276 1/30/95 Fix OS/2 version. -v277 1/31/95 Add "next" charset; don't display ^X - for X > 128. -v278 2/14/95 Change default for -G. - Posted to prep.ai.mit.edu +v253 11/21/94 Fix bug when tags file has a backslash. +v254 12/6/94 Fix -k option. +v255 12/8/94 Add #define EXAMINE to disable :e etc. +v256 12/10/94 Change highlighting: only highlite search + results (but now it is reliable). +v257 12/10/94 Add goto_line and repaint_highlight + to optimize highlight repaints. +v258 12/12/94 Fixup in hilite_line if BS_SPECIAL. +v259 12/12/94 Convert to autoconf 2.0. +v260 12/13/94 Add SECURE define. +v261 12/14/94 Use system WERASE char as EC_W_BACKSPACE. +v262 12/16/94 Add -g/-G flag and screen_hilite. +v263 12/20/94 Reimplement/optimize -G flag behavior. +v264 12/23/94 Allow EXTRA string after line-edit cmd + in lesskey file. +v265 12/24/94 Add LESSOPEN=|cmd syntax. +v266 12/26/94 Add -I flag. +v267 12/28/94 Formalize the four-byte header emitted + by a LESSOPEN pipe. +v268 12/28/94 Get rid of four-byte header. +v269 1/2/95 Close alt file before open new one. + Avoids multiple popen(). +v270 1/3/95 Use VISUAL; use S_ISDIR/S_ISREG; fix + config problem with Solaris POSIX regcomp. +v271 1/4/95 Don't quit on read error. +v272 1/5/95 Get rid of -L. +v273 1/6/95 Fix ch_ungetchar bug; don't call + LESSOPEN on a pipe. +v274 1/6/95 Ported to OS/2 (thanks to Kai Uwe Rommel) +v275 1/18/95 Fix bug if toggle -G at EOF. +v276 1/30/95 Fix OS/2 version. +v277 1/31/95 Add "next" charset; don't display ^X + for X > 128. +v278 2/14/95 Change default for -G. + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v279 2/22/95 Add GNU options --help, --version. - Minor config fixes. -v280 2/24/95 Clean up calls to glob(); don't set # - if we can't open the new file. -v281 2/24/95 Repeat search should turn on hilites. -v282 3/2/95 Minor fixes. -v283 3/2/95 Fix homefile; make OS2 look in $HOME. -v284 3/2/95 Error if "v" on LESSOPENed file; - "%" figures out file size on pipe. -v285 3/7/95 Don't set # in lsystem; - lesskey try $HOME first. -v286 3/7/95 Reformat change history (too much free time?). -v287 3/8/95 Fix hilite bug if overstrike multiple chars. -v288 3/8/95 Allow lesskey to override get_editkey keys. -v289 3/9/95 Fix adj_hilite bug when line gets processed by - hilite_line more than once. -v290 3/9/95 Make configure automatically. Fix Sequent problem - with incompatible sigsetmask(). - Posted to prep.ai.mit.edu +v279 2/22/95 Add GNU options --help, --version. + Minor config fixes. +v280 2/24/95 Clean up calls to glob(); don't set # + if we can't open the new file. +v281 2/24/95 Repeat search should turn on hilites. +v282 3/2/95 Minor fixes. +v283 3/2/95 Fix homefile; make OS2 look in $HOME. +v284 3/2/95 Error if "v" on LESSOPENed file; + "%" figures out file size on pipe. +v285 3/7/95 Don't set # in lsystem; + lesskey try $HOME first. +v286 3/7/95 Reformat change history (too much free time?). +v287 3/8/95 Fix hilite bug if overstrike multiple chars. +v288 3/8/95 Allow lesskey to override get_editkey keys. +v289 3/9/95 Fix adj_hilite bug when line gets processed by + hilite_line more than once. +v290 3/9/95 Make configure automatically. Fix Sequent problem + with incompatible sigsetmask(). + Posted to prep.ai.mit.edu ----------------------------------------------------------------- -v291 3/21/95 Add #env to lesskey. Fix MS-DOS build. - Posted to simtel. +v291 3/21/95 Add #env to lesskey. Fix MS-DOS build. + Posted to simtel. ----------------------------------------------------------------- -v292 4/24/95 Add MS-DOS support for Borland C. - Fix arrow keys in MS-DOS versions. -v293 4/28/95 Add auto-versioning stuff to make dist. -v294 5/12/95 Fix Borland build. -v295 1/20/96 Fix search on squished file; add /@@. -v296 1/23/96 Allow cmdbuf larger than screen width. -v297 1/24/96 Don't call termcap if tgetent fails; - add #defines for buffers. -v298 1/24/96 Change @@ to ^K. - Add alternate search modifiers ^N, ^F, ^E. -v299 1/25/96 Fix percent overflow in jump_percent (thanks to Brent Wiese); - don't send "ti" after shell command till RETURN pressed. -v300 1/25/96 Change -U to print tabs as ^I. -v301 1/30/96 Make hilites work in cmd F output. -v302 1/31/96 Fix cmd F to notice window-change signals. -v303 1/31/96 Add ESC-SPACE command. -v304 2/1/96 Add ^R search modifier; add LESSSECURE. -v305 2/2/96 Workaround Linux /proc kernel bug; add LESSKEY. -v306 3/16/96 Minor fixes. -v307 3/25/96 Allow cmd line arg "--"; fix DOS & OS/2 defines.h. -v308 4/4/96 Port to OS-9 (thanks to Boisy Pitre); fix -d. -v309 4/9/96 Fix OS-9 version; fix tags bug with "$". -v310 4/10/96 Get rid of HELPFILE. -v311 4/22/96 Add Windows32 support; merge doscreen.c into screen.c. -v312 4/24/96 Don't quit after "cannot reopen" error. -v313 4/25/96 Added horizontal scrolling. -v314 4/26/96 Modified -e to quit on reaching end of a squished file. -v315 4/26/96 Fix "!;TAB" bug. -v316 5/2/96 Make "|a" when (a < curr screen) go to end of curr screen. -v317 5/14/96 Various fixes for the MS-DOS and OS/2 builds. - Added ## and %% handling for filenames -v318 5/29/96 Port to OS-9 Microware compiler; minor fixes - (thanks to Martin Gregorie). -v319 7/8/96 Fix Windows port (thanks to Jeff Paquette). -v320 7/11/96 Final fixes for Windows port. -v321 7/18/96 Minor fixes. - Posted to Web page. +v292 4/24/95 Add MS-DOS support for Borland C. + Fix arrow keys in MS-DOS versions. +v293 4/28/95 Add auto-versioning stuff to make dist. +v294 5/12/95 Fix Borland build. +v295 1/20/96 Fix search on squished file; add /@@. +v296 1/23/96 Allow cmdbuf larger than screen width. +v297 1/24/96 Don't call termcap if tgetent fails; + add #defines for buffers. +v298 1/24/96 Change @@ to ^K. + Add alternate search modifiers ^N, ^F, ^E. +v299 1/25/96 Fix percent overflow in jump_percent (thanks to Brent Wiese); + don't send "ti" after shell command till RETURN pressed. +v300 1/25/96 Change -U to print tabs as ^I. +v301 1/30/96 Make hilites work in cmd F output. +v302 1/31/96 Fix cmd F to notice window-change signals. +v303 1/31/96 Add ESC-SPACE command. +v304 2/1/96 Add ^R search modifier; add LESSSECURE. +v305 2/2/96 Workaround Linux /proc kernel bug; add LESSKEY. +v306 3/16/96 Minor fixes. +v307 3/25/96 Allow cmd line arg "--"; fix DOS & OS/2 defines.h. +v308 4/4/96 Port to OS-9 (thanks to Boisy Pitre); fix -d. +v309 4/9/96 Fix OS-9 version; fix tags bug with "$". +v310 4/10/96 Get rid of HELPFILE. +v311 4/22/96 Add Windows32 support; merge doscreen.c into screen.c. +v312 4/24/96 Don't quit after "cannot reopen" error. +v313 4/25/96 Added horizontal scrolling. +v314 4/26/96 Modified -e to quit on reaching end of a squished file. +v315 4/26/96 Fix "!;TAB" bug. +v316 5/2/96 Make "|a" when (a < curr screen) go to end of curr screen. +v317 5/14/96 Various fixes for the MS-DOS and OS/2 builds. + Added ## and %% handling for filenames +v318 5/29/96 Port to OS-9 Microware compiler; minor fixes + (thanks to Martin Gregorie). +v319 7/8/96 Fix Windows port (thanks to Jeff Paquette). +v320 7/11/96 Final fixes for Windows port. +v321 7/18/96 Minor fixes. + Posted to Web page. ----------------------------------------------------------------- -v322 8/13/96 Fix bug in shell escape from help file; add support for - Microsoft Visual C under Windows; numerous small fixes. -v323 8/19/96 Fixes for Windows version (thanks to Simon Munton); - fix for Linux library weirdness (thanks to Jim Diamond); - port to DJGPP (thanks to Eli Zaretskii). -v324 8/21/96 Add support for spaces in filenames (thanks to Simon Munton). -v325 8/21/96 Add lessecho, for spaces in filenames under Unix. -v326 8/27/96 Fix DJGPP version. -v327 9/1/96 Reorganize lglob, make spaces in filenames work better in Unix. -v328 10/7/96 Append / to directory name in filename completion. - Fix MS-DOS and OS-9 versions. -v329 10/11/96 Fix more MS-DOS bugs; add LESSSEPARATOR; add -" option. - Add LESSMETACHARS, LESSMETAESCAPE. -v330 10/21/96 Minor fixes. - Posted to Web page. +v322 8/13/96 Fix bug in shell escape from help file; add support for + Microsoft Visual C under Windows; numerous small fixes. +v323 8/19/96 Fixes for Windows version (thanks to Simon Munton); + fix for Linux library weirdness (thanks to Jim Diamond); + port to DJGPP (thanks to Eli Zaretskii). +v324 8/21/96 Add support for spaces in filenames (thanks to Simon Munton). +v325 8/21/96 Add lessecho, for spaces in filenames under Unix. +v326 8/27/96 Fix DJGPP version. +v327 9/1/96 Reorganize lglob, make spaces in filenames work better in Unix. +v328 10/7/96 Append / to directory name in filename completion. + Fix MS-DOS and OS-9 versions. +v329 10/11/96 Fix more MS-DOS bugs; add LESSSEPARATOR; add -" option. + Add LESSMETACHARS, LESSMETAESCAPE. +v330 10/21/96 Minor fixes. + Posted to Web page. ----------------------------------------------------------------- -v331 4/22/97 Various Windows fixes (thanks to Gurusamy Sarathy). -v332 4/22/97 Enter filenames from cmd line into edit history. - Posted to Web page. +v331 4/22/97 Various Windows fixes (thanks to Gurusamy Sarathy). +v332 4/22/97 Enter filenames from cmd line into edit history. + Posted to Web page. ----------------------------------------------------------------- -v333 3/4/99 Changed -w to highlite new line after forward movement. -v334 3/9/99 Avoid overflowing prompt buffer; add %d and %D. -v335 3/20/99 Add EBCDIC support (thanks to Thomas Dorner). - Use HOMEDRIVE/HOMEPATH on Windows (thanks to Preston Bannister). - Posted to Web page. +v333 3/4/99 Changed -w to highlite new line after forward movement. +v334 3/9/99 Avoid overflowing prompt buffer; add %d and %D. +v335 3/20/99 Add EBCDIC support (thanks to Thomas Dorner). + Use HOMEDRIVE/HOMEPATH on Windows (thanks to Preston Bannister). + Posted to Web page. ----------------------------------------------------------------- -v336 4/8/99 Fix installation bugs. -v337 4/9/99 Fix another installation bug. - Posted to Web page. +v336 4/8/99 Fix installation bugs. +v337 4/9/99 Fix another installation bug. + Posted to Web page. ----------------------------------------------------------------- -v338 4/13/99 Add support for long option names. -v339 4/18/99 Add \k, long option names to lesskey. Add -^P. Add :d. -v340 4/21/99 Add regexec2. Fix Windows build. - Posted to Web page. +v338 4/13/99 Add support for long option names. +v339 4/18/99 Add \k, long option names to lesskey. Add -^P. Add :d. +v340 4/21/99 Add regexec2. Fix Windows build. + Posted to Web page. ----------------------------------------------------------------- v341 5/6/99 Add -F option; %c & ?c prompt escapes. - (Thanks to Michele Maltoni) + (Thanks to Michele Maltoni) v342 7/22/99 Add system-wide lesskey file; allow GPL or Less License. -v343 9/23/99 Support UTF-8 (Thanks to Robert Brady). - Add %P and ?P in prompts. -v344 10/27/99 -w highlights target line of g and p commands. -v345 10/29/99 Make -R pass thru ESC but not other control chars. - Posted to Web page. +v343 9/23/99 Support UTF-8 (Thanks to Robert Brady). + Add %P and ?P in prompts. +v344 10/27/99 -w highlights target line of g and p commands. +v345 10/29/99 Make -R pass thru ESC but not other control chars. + Posted to Web page. ----------------------------------------------------------------- v346 11/4/99 Fix bugs in long option processing; R cmd should clear hilites. - Posted to Web page. + Posted to Web page. ----------------------------------------------------------------- -v347 12/13/99 Fixes for DJGPP version (thanks to Eli Zaretskii). -v348 12/28/99 Fix deleting file with marks (thanks to Dimitar Jekov). - Fix color problem in DJGPP version (thanks to Eli Zaretskii). -v349 1/24/00 Fix minor DJGPP bugs; check environment vars for UTF-8; - add --with-editor (thanks to Eli, Markus Kuhn, Thomas Schoepf). -v350 3/1/00 Fix clear-while-standout bug. -v351 3/5/00 Change -M and = prompts to show top & bottom line number. - Posted to Web page. +v347 12/13/99 Fixes for DJGPP version (thanks to Eli Zaretskii). +v348 12/28/99 Fix deleting file with marks (thanks to Dimitar Jekov). + Fix color problem in DJGPP version (thanks to Eli Zaretskii). +v349 1/24/00 Fix minor DJGPP bugs; check environment vars for UTF-8; + add --with-editor (thanks to Eli, Markus Kuhn, Thomas Schoepf). +v350 3/1/00 Fix clear-while-standout bug. +v351 3/5/00 Change -M and = prompts to show top & bottom line number. + Posted to Web page. ----------------------------------------------------------------- -v352 3/8/00 Fix scan_option NULL dereference. +v352 3/8/00 Fix scan_option NULL dereference. ----------------------------------------------------------------- -v353 3/20/00 Fix SECURE compile bug, allow space after numeric option. -v354 3/23/00 Add support for PCRE; add --with-regex configure option. +v353 3/20/00 Fix SECURE compile bug, allow space after numeric option. +v354 3/23/00 Add support for PCRE; add --with-regex configure option. ----------------------------------------------------------------- -v355 6/28/00 Add -# option (thanks to Andy Levinson). -v356 7/5/00 Add -J option. -v357 7/6/00 Support sigprocmask. +v355 6/28/00 Add -# option (thanks to Andy Levinson). +v356 7/5/00 Add -J option. +v357 7/6/00 Support sigprocmask. ----------------------------------------------------------------- -v358 7/8/00 Fix problems with #stop in lesskey file. - Posted to Web page. +v358 7/8/00 Fix problems with #stop in lesskey file. + Posted to Web page. ----------------------------------------------------------------- -v359 9/10/00 Fixes for Win32 display problems (thanks to Maurizio Vairani). -v360 1/17/01 Move sysless to etc. -v361 12/4/01 Add IBM-1047 charset & EBCDIC fixes (thanks to Thomas Dorner). - Fix 32 bit dependencies (thanks to Paul Eggert). - Fix UTF-8 overstriking (thanks to Robert Brady). -v362 12/4/01 Make status column show search targets. -v363 12/6/01 Add --no-keypad option. - Add variable width tabstops (thanks to Peter Samuelson). -v364 12/10/01 Better handling of very long lines in input; - Fix horizontal shifting of colored text. -v365 12/11/01 Fix overstriking of tabs; - Add support for global(1) and multiple tag matches - (thanks to Shigio Yamaguchi and Tim Vanderhoek). -v366 12/11/01 Fixes for OS/2 (thanks to Kyosuke Tokoro). -v367 12/13/01 Allow -D and -x options to terminate without dollar sign; - Right/left arrow when entering N are shift cmds, not line edit. -v368 12/18/01 Update lesskey commands. -v370 12/23/01 Fix tags error messages. - Posted to Web page. +v359 9/10/00 Fixes for Win32 display problems (thanks to Maurizio Vairani). +v360 1/17/01 Move sysless to etc. +v361 12/4/01 Add IBM-1047 charset & EBCDIC fixes (thanks to Thomas Dorner). + Fix 32 bit dependencies (thanks to Paul Eggert). + Fix UTF-8 overstriking (thanks to Robert Brady). +v362 12/4/01 Make status column show search targets. +v363 12/6/01 Add --no-keypad option. + Add variable width tabstops (thanks to Peter Samuelson). +v364 12/10/01 Better handling of very long lines in input; + Fix horizontal shifting of colored text. +v365 12/11/01 Fix overstriking of tabs; + Add support for global(1) and multiple tag matches + (thanks to Shigio Yamaguchi and Tim Vanderhoek). +v366 12/11/01 Fixes for OS/2 (thanks to Kyosuke Tokoro). +v367 12/13/01 Allow -D and -x options to terminate without dollar sign; + Right/left arrow when entering N are shift cmds, not line edit. +v368 12/18/01 Update lesskey commands. +v370 12/23/01 Fix tags error messages. + Posted to Web page. ----------------------------------------------------------------- -v371 12/26/01 Fix new_file bug; use popen in Windows version; - fix some compiler warnings. -v372 12/29/01 Make -b be in units of 1K. -v373 1/14/02 Improve handling of filenames containing shell metachars. -v374 2/7/02 Fix memory leak; fix bug in -x argument parsing. -v375 4/7/02 Fix searching for SGR sequences; fix SECURE build; - add SGR support to DJGPP version (thanks to Eli Zaretskii). -v376 6/10/02 Fix bug in overstriking mulitbyte UTF-8 characters - (thanks to Jungshik Shin). - Posted to Web page. +v371 12/26/01 Fix new_file bug; use popen in Windows version; + fix some compiler warnings. +v372 12/29/01 Make -b be in units of 1K. +v373 1/14/02 Improve handling of filenames containing shell metachars. +v374 2/7/02 Fix memory leak; fix bug in -x argument parsing. +v375 4/7/02 Fix searching for SGR sequences; fix SECURE build; + add SGR support to DJGPP version (thanks to Eli Zaretskii). +v376 6/10/02 Fix bug in overstriking mulitbyte UTF-8 characters + (thanks to Jungshik Shin). + Posted to Web page. ----------------------------------------------------------------- -v377 9/10/02 Fix bug in Windows version when file contains CR; - fix bug in search highlights with -R; - make initial buffer limit really be 64K not unlimited. -v378 9/30/02 Misc bug fixes and compiler warning cleanup. - Posted to Web page. +v377 9/10/02 Fix bug in Windows version when file contains CR; + fix bug in search highlights with -R; + make initial buffer limit really be 64K not unlimited. +v378 9/30/02 Misc bug fixes and compiler warning cleanup. + Posted to Web page. ----------------------------------------------------------------- -v379 11/23/02 Add -L option; fix bug with ctrl-K in lesskey files; - improve UTF-8 overstriking and underscore overstriking; - fix minor man page problems; change to autoconf 2.54. -v380 11/24/02 Make LINENUM same as POSITION. -v381 11/28/02 Make -N use 7 columns for line number if possible. +v379 11/23/02 Add -L option; fix bug with ctrl-K in lesskey files; + improve UTF-8 overstriking and underscore overstriking; + fix minor man page problems; change to autoconf 2.54. +v380 11/24/02 Make LINENUM same as POSITION. +v381 11/28/02 Make -N use 7 columns for line number if possible. ----------------------------------------------------------------- -v382 2/3/04 Remove copyrighted code. +v382 2/3/04 Remove copyrighted code. ----------------------------------------------------------------- -v383 2/16/04 Add history file; add -K option; improve UTF-8 handling; - fix some signed char bugs (thanks to Christian Biere); - fix some upper/lower case bugs (thanks to Bjoern Jacke); - add erase2 char (thanks to David Lawrence); - add windows charset (thanks to Dimitar Zhekov). -v384 2/20/04 Improvements in UTF-8 handling. -v385 2/23/04 Fix UTF-8 output bug. +v383 2/16/04 Add history file; add -K option; improve UTF-8 handling; + fix some signed char bugs (thanks to Christian Biere); + fix some upper/lower case bugs (thanks to Bjoern Jacke); + add erase2 char (thanks to David Lawrence); + add windows charset (thanks to Dimitar Zhekov). +v384 2/20/04 Improvements in UTF-8 handling. +v385 2/23/04 Fix UTF-8 output bug. ----------------------------------------------------------------- -v386 9/13/05 Improvements to UTF-8 shift & color (thanks to Charles Levert); - protect against invalid LESSOPEN and LESSCLOSE values. -v387 9/14/05 Update Charles Levert's UTF-8 patch. -v388 9/14/05 Change history behavior; change most sprintf calls to snprintf. -v389 9/14/05 Fix copy & paste with long lines; improve performance of - expand_linebuf; fix crash in init_mlist; -v390 9/15/05 Show search matches in status column even if -G is set. +v386 9/13/05 Improvements to UTF-8 shift & color (thanks to Charles Levert); + protect against invalid LESSOPEN and LESSCLOSE values. +v387 9/14/05 Update Charles Levert's UTF-8 patch. +v388 9/14/05 Change history behavior; change most sprintf calls to snprintf. +v389 9/14/05 Fix copy & paste with long lines; improve performance of + expand_linebuf; fix crash in init_mlist; +v390 9/15/05 Show search matches in status column even if -G is set. ----------------------------------------------------------------- -v391 9/17/05 Fix bugs. -v392 10/14/05 Fix line wrapping bug. -v393 10/19/05 Allow multiple attributes per char; fix bold+underline bug - (thanks again to Charles Levert). -v394 11/8/05 Fix prompt bug; fix compile problem in Windows build. +v391 9/17/05 Fix bugs. +v392 10/14/05 Fix line wrapping bug. +v393 10/19/05 Allow multiple attributes per char; fix bold+underline bug + (thanks again to Charles Levert). +v394 11/8/05 Fix prompt bug; fix compile problem in Windows build. ----------------------------------------------------------------- -v395 1/12/07 Update Unicode tables (thanks to Charles Levert); - don't chmod if LESSHISTFILE = /dev/null; - make -f work for directories; support DESTDIR in Makefile; - fix sigset_t detection in configure; - make "t" cmd traverse tags in correct order -v396 1/13/07 Add compatibility with POSIX more. -v397 3/21/07 Allow decimal point in number for % command; - Allow decimal point in number for -j option; - Allow n command to fetch last search pattern from history - (thanks to arno). -v398 3/22/07 Don't rewrite history file if not necessary; - fix bug when filenames contain "$". -v399 3/22/07 Don't move to bottom of screen at startup; - don't output extraneous newlines. -v400 3/23/07 Allow search to find pattern after null byte (PCRE and no-regex) - (thanks to Michael Constant). +v395 1/12/07 Update Unicode tables (thanks to Charles Levert); + don't chmod if LESSHISTFILE = /dev/null; + make -f work for directories; support DESTDIR in Makefile; + fix sigset_t detection in configure; + make "t" cmd traverse tags in correct order +v396 1/13/07 Add compatibility with POSIX more. +v397 3/21/07 Allow decimal point in number for % command; + Allow decimal point in number for -j option; + Allow n command to fetch last search pattern from history + (thanks to arno). +v398 3/22/07 Don't rewrite history file if not necessary; + fix bug when filenames contain "$". +v399 3/22/07 Don't move to bottom of screen at startup; + don't output extraneous newlines. +v400 3/23/07 Allow search to find pattern after null byte (PCRE and no-regex) + (thanks to Michael Constant). ----------------------------------------------------------------- -v401 3/24/07 Minor documentation fixes. -v402 3/30/07 Fix autoconf bug when memcpy etc are inline; - fix bug in terminating number following -j option. -v403 5/25/07 Fix Windows build. -v404 6/5/07 Fix display bug with F command and long lines. -v405 6/17/07 Fix display bug when using -w option. -v406 6/17/07 Fix secure build. -v407 8/16/07 Fix bugs; support CSI chars. -v408 10/1/07 Fix bug in -i with non-ASCII chars. -v409 10/12/07 Fix crash when viewing text with invalid UTF-8 sequences. -v411 11/6/07 Fix case-insensitive searching with non-ASCII text. -v412 11/6/07 Use symbolic SEEK constants. -v413 11/6/07 Fix search highlight bug with non-ASCII text. -v414 11/6/07 Fix display bug with no-wrap terminals. -v415 11/14/07 Add --follow-name option. -v416 11/22/07 Fix crash when searching text with invalid UTF-8 sequences. +v401 3/24/07 Minor documentation fixes. +v402 3/30/07 Fix autoconf bug when memcpy etc are inline; + fix bug in terminating number following -j option. +v403 5/25/07 Fix Windows build. +v404 6/5/07 Fix display bug with F command and long lines. +v405 6/17/07 Fix display bug when using -w option. +v406 6/17/07 Fix secure build. +v407 8/16/07 Fix bugs; support CSI chars. +v408 10/1/07 Fix bug in -i with non-ASCII chars. +v409 10/12/07 Fix crash when viewing text with invalid UTF-8 sequences. +v411 11/6/07 Fix case-insensitive searching with non-ASCII text. +v412 11/6/07 Use symbolic SEEK constants. +v413 11/6/07 Fix search highlight bug with non-ASCII text. +v414 11/6/07 Fix display bug with no-wrap terminals. +v415 11/14/07 Add --follow-name option. +v416 11/22/07 Fix crash when searching text with invalid UTF-8 sequences. +v417 12/31/07 Don't support single-char CSI in UTF-8 mode; + fix bug with -R and invalid CSI sequences; + fix bug searching text with SGR sequences with -r; + emulate SGR sequences in WIN32 build. +v418 12/31/07 Clean up. +----------------------------------------------------------------- +v419 1/16/08 Make CSI char 0x9B work in UTF-8 mode (thanks to Colin Watson). +v420 2/24/08 Add & command; fix -F option; fix '' after G. +v421 2/24/08 Ignore filtered lines when searching. +v422 3/2/08 Output CR at startup. +v423 5/27/08 Clean up. +v424 6/16/08 Fix compile bug with pcre; don't filter help file. +v425 7/14/08 Fix non-ANSI code in list handling in ch.c. +v426 10/27/08 Fix ignaw terminal handling (thanks to Per Hedeland); + fix binary file detection in UTF-8 mode. +v427 3/16/09 A few Win32 fixes (thanks to Jason Hood). +v428 3/30/09 Add "|-" syntax to LESSOPEN. +v429 4/10/09 Fix search highlighting bug with underlined text. */ -char version[] = "416"; +char version[] = "429"; From 8569258bf82637b8e913b6c8d59a25d639faa98b Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 9 May 2009 01:45:55 +0000 Subject: [PATCH 057/544] - rename atomic.S and crc32.c to avoid collisions when linking zfs in to the kernel - update Makefile - ifdef out acl_{alloc, free}, they aren't used by zfs and conflict with existing in-kernel routines --- sys/cddl/contrib/opensolaris/common/acl/acl_common.c | 2 ++ .../common/atomic/amd64/{atomic.S => opensolaris_atomic.S} | 0 .../common/atomic/i386/{atomic.S => opensolaris_atomic.S} | 0 .../common/atomic/ia64/{atomic.S => opensolaris_atomic.S} | 0 .../common/atomic/sparc64/{atomic.S => opensolaris_atomic.S} | 0 .../uts/common/zmod/{crc32.c => opensolaris_crc32.c} | 0 sys/modules/zfs/Makefile | 4 ++-- 7 files changed, 4 insertions(+), 2 deletions(-) rename sys/cddl/contrib/opensolaris/common/atomic/amd64/{atomic.S => opensolaris_atomic.S} (100%) rename sys/cddl/contrib/opensolaris/common/atomic/i386/{atomic.S => opensolaris_atomic.S} (100%) rename sys/cddl/contrib/opensolaris/common/atomic/ia64/{atomic.S => opensolaris_atomic.S} (100%) rename sys/cddl/contrib/opensolaris/common/atomic/sparc64/{atomic.S => opensolaris_atomic.S} (100%) rename sys/cddl/contrib/opensolaris/uts/common/zmod/{crc32.c => opensolaris_crc32.c} (100%) diff --git a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c index e6b678079635..8d0cc85f341c 100644 --- a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c +++ b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c @@ -424,6 +424,7 @@ cacl_free(void *ptr, size_t size) #endif } +#ifndef __FreeBSD__ acl_t * acl_alloc(enum acl_type type) { @@ -469,6 +470,7 @@ acl_free(acl_t *aclp) cacl_free(aclp, sizeof (acl_t)); } +#endif static uint32_t access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow) diff --git a/sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S similarity index 100% rename from sys/cddl/contrib/opensolaris/common/atomic/amd64/atomic.S rename to sys/cddl/contrib/opensolaris/common/atomic/amd64/opensolaris_atomic.S diff --git a/sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S similarity index 100% rename from sys/cddl/contrib/opensolaris/common/atomic/i386/atomic.S rename to sys/cddl/contrib/opensolaris/common/atomic/i386/opensolaris_atomic.S diff --git a/sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S similarity index 100% rename from sys/cddl/contrib/opensolaris/common/atomic/ia64/atomic.S rename to sys/cddl/contrib/opensolaris/common/atomic/ia64/opensolaris_atomic.S diff --git a/sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S b/sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S similarity index 100% rename from sys/cddl/contrib/opensolaris/common/atomic/sparc64/atomic.S rename to sys/cddl/contrib/opensolaris/common/atomic/sparc64/opensolaris_atomic.S diff --git a/sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c b/sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c similarity index 100% rename from sys/cddl/contrib/opensolaris/uts/common/zmod/crc32.c rename to sys/cddl/contrib/opensolaris/uts/common/zmod/opensolaris_crc32.c diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 7ac0237d59ee..4f399a8f3b32 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -28,7 +28,7 @@ SRCS+= opensolaris_zone.c .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" || ${MACHINE_ARCH} == "sparc64" .PATH: ${SUNW}/common/atomic/${MACHINE_ARCH} -SRCS+= atomic.S +SRCS+= opensolaris_atomic.S .else .PATH: ${.CURDIR}/../../cddl/compat/opensolaris/kern SRCS+= opensolaris_atomic.c @@ -51,7 +51,7 @@ SRCS+= xdr_mem.c .PATH: ${SUNW}/uts/common/zmod SRCS+= adler32.c -SRCS+= crc32.c +SRCS+= opensolaris_crc32.c SRCS+= deflate.c SRCS+= inffast.c SRCS+= inflate.c From 5f17ebf94db5ebbc7fdcff60e598498df6f9e2bd Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Sat, 9 May 2009 05:07:36 +0000 Subject: [PATCH 058/544] Convert IPFW_DEFAULT_TO_ACCEPT into a loader tunable 'net.inet.ip.fw.default_to_accept'. The current value can also be queried via a read-only sysctl of the same name. Requested by: plosher MFC after: 1 week --- sys/netinet/ip_fw2.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index ab65f3515c21..af70451ddd9a 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -127,6 +127,11 @@ static struct callout ipfw_timeout; static int verbose_limit; #endif +#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT +static int default_to_accept = 1; +#else +static int default_to_accept; +#endif static uma_zone_t ipfw_dyn_rule_zone; /* @@ -190,6 +195,9 @@ SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, default_rule, CTLFLAG_RD, NULL, IPFW_DEFAULT_RULE, "The default/max possible rule number."); SYSCTL_UINT(_net_inet_ip_fw, OID_AUTO, tables_max, CTLFLAG_RD, NULL, IPFW_TABLES_MAX, "The maximum number of tables."); +SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, default_to_accept, CTLFLAG_RDTUN, + &default_to_accept, 0, "Make the default rule accept all packets."); +TUNABLE_INT("net.inet.ip.fw.default_to_accept", &default_to_accept); #endif /* SYSCTL_NODE */ /* @@ -4636,11 +4644,7 @@ ipfw_init(void) default_rule.set = RESVD_SET; default_rule.cmd[0].len = 1; - default_rule.cmd[0].opcode = -#ifdef IPFIREWALL_DEFAULT_TO_ACCEPT - 1 ? O_ACCEPT : -#endif - O_DENY; + default_rule.cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY; error = add_rule(&V_layer3_chain, &default_rule); if (error != 0) { From 3f9fc7fea003e4538c3e356406f5a5d7b7d54c89 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 9 May 2009 05:39:35 +0000 Subject: [PATCH 059/544] atomic.S has been renamed opensolaris_atomic.S to avoid collisions --- cddl/lib/libzpool/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cddl/lib/libzpool/Makefile b/cddl/lib/libzpool/Makefile index 54ab6c01b2ae..fec99d92f1d8 100644 --- a/cddl/lib/libzpool/Makefile +++ b/cddl/lib/libzpool/Makefile @@ -13,7 +13,7 @@ # ATOMIC_SRCS .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" .PATH: ${.CURDIR}/../../../sys/cddl/contrib/opensolaris/common/atomic/${MACHINE_ARCH} -ATOMIC_SRCS= atomic.S +ATOMIC_SRCS= opensolaris_atomic.S .else .PATH: ${.CURDIR}/../../../sys/cddl/compat/opensolaris/kern ATOMIC_SRCS= opensolaris_atomic.c From 126b14f7e87fe56edcdf33be5ff6925de5c0290c Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 9 May 2009 05:45:13 +0000 Subject: [PATCH 060/544] fix atomic.S rename and vimage breakage The latter was pointed out by Artem Belevich --- sys/modules/opensolaris/Makefile | 7 ++++--- sys/modules/zfs/Makefile | 1 - 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/modules/opensolaris/Makefile b/sys/modules/opensolaris/Makefile index a1df2a857ddb..a0f08fbfa356 100644 --- a/sys/modules/opensolaris/Makefile +++ b/sys/modules/opensolaris/Makefile @@ -5,15 +5,16 @@ KMOD= opensolaris SRCS= opensolaris.c \ opensolaris_cmn_err.c \ - opensolaris_kmem.c + opensolaris_kmem.c \ + opensolaris_misc.c .if ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "amd64" || ${MACHINE_ARCH} == "ia64" || ${MACHINE_ARCH} == "sparc64" .PATH: ${.CURDIR}/../../cddl/contrib/opensolaris/common/atomic/${MACHINE_ARCH} -SRCS+= atomic.S +SRCS+= opensolaris_atomic.S .else SRCS+= opensolaris_atomic.c .endif - + CFLAGS+= -I${.CURDIR}/../../cddl/compat/opensolaris \ -I${.CURDIR}/../../cddl/contrib/opensolaris/uts/common \ -I${.CURDIR}/../.. diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 4f399a8f3b32..87b6ea1820cf 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -20,7 +20,6 @@ SRCS+= opensolaris_kmem.c SRCS+= opensolaris_kobj.c SRCS+= opensolaris_kstat.c SRCS+= opensolaris_lookup.c -SRCS+= opensolaris_misc.c SRCS+= opensolaris_policy.c SRCS+= opensolaris_string.c SRCS+= opensolaris_vfs.c From 0d53a17bde39ba28d38165317ae4b0a6098a8e78 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 9 May 2009 08:30:44 +0000 Subject: [PATCH 061/544] Fix a race involving vnode_pager_input_smlfs(). Specifically, in the case that vnode_pager_input_smlfs() zeroes the page, it should not mark the page as valid until after the page is zeroed. Otherwise, the page could be mapped for read access (e.g., by vm_map_pmap_enter()) before the page is zeroed. Reviewed by: tegge Eliminate gratuitous clearing of the page's dirty mask by vnode_pager_input_smlfs(). Instead, assert that the page is clean. Reviewed by: tegge Eliminate some blank lines. Eliminate pointless calls to pmap_clear_modify() and vm_page_undirty() from vnode_pager_input_old(). The page is not mapped. Therefore, it cannot have any page table entries that are modified. Eliminate an incorrect comment from vnode_pager_generic_getpages(). --- sys/vm/vnode_pager.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-) diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 19c2c336517f..3d6909b29377 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -476,7 +476,7 @@ vnode_pager_input_smlfs(object, m) vm_object_t object; vm_page_t m; { - int i; + int bits, i; struct vnode *vp; struct bufobj *bo; struct buf *bp; @@ -498,7 +498,8 @@ vnode_pager_input_smlfs(object, m) for (i = 0; i < PAGE_SIZE / bsize; i++) { vm_ooffset_t address; - if (vm_page_bits(i * bsize, bsize) & m->valid) + bits = vm_page_bits(i * bsize, bsize); + if (m->valid & bits) continue; address = IDX_TO_OFF(m->pindex) + i * bsize; @@ -543,30 +544,21 @@ vnode_pager_input_smlfs(object, m) relpbuf(bp, &vnode_pbuf_freecnt); if (error) break; - - VM_OBJECT_LOCK(object); - vm_page_lock_queues(); - vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize); - vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(object); - } else { - VM_OBJECT_LOCK(object); - vm_page_lock_queues(); - vm_page_set_validclean(m, (i * bsize) & PAGE_MASK, bsize); - vm_page_unlock_queues(); - VM_OBJECT_UNLOCK(object); + } else bzero((caddr_t)sf_buf_kva(sf) + i * bsize, bsize); - } + KASSERT((m->dirty & bits) == 0, + ("vnode_pager_input_smlfs: page %p is dirty", m)); + VM_OBJECT_LOCK(object); + m->valid |= bits; + VM_OBJECT_UNLOCK(object); } sf_buf_free(sf); if (error) { return VM_PAGER_ERROR; } return VM_PAGER_OK; - } - /* * old style vnode pager input routine */ @@ -627,10 +619,7 @@ vnode_pager_input_old(object, m) VM_OBJECT_LOCK(object); } - vm_page_lock_queues(); - pmap_clear_modify(m); - vm_page_undirty(m); - vm_page_unlock_queues(); + KASSERT(m->dirty == 0, ("vnode_pager_input_old: page %p is dirty", m)); if (!error) m->valid = VM_PAGE_BITS_ALL; return error ? VM_PAGER_ERROR : VM_PAGER_OK; @@ -960,8 +949,6 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage) */ vm_page_set_validclean(mt, 0, object->un_pager.vnp.vnp_size - tfoff); - /* handled by vm_fault now */ - /* vm_page_zero_invalid(mt, FALSE); */ } if (i != reqpage) { From f31b4b6a80dd9b62bc2e876c2b9ab9e67d913f94 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 9 May 2009 15:09:40 +0000 Subject: [PATCH 062/544] Add support for old TTY ioctls to kdump. At first I allowed ioctl_compat.h to be included, but it just returned an empty file. I had to do this, to keep kdump happy. I really want to raise a compiler error when including this header, so now it will just throw an error if you don't set COMPAT_43TTY. --- sys/sys/ioctl_compat.h | 4 ---- usr.bin/kdump/mkioctls | 1 + 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/sys/ioctl_compat.h b/sys/sys/ioctl_compat.h index 4164c89f4cc0..f4a9af62da25 100644 --- a/sys/sys/ioctl_compat.h +++ b/sys/sys/ioctl_compat.h @@ -38,8 +38,6 @@ #ifndef _SYS_IOCTL_COMPAT_H_ #define _SYS_IOCTL_COMPAT_H_ -#ifdef _KERNEL - #ifndef COMPAT_43TTY #error "Definitions not available without TTY ioctl compat." #endif @@ -151,6 +149,4 @@ struct sgttyb { #define TIOCGLTC _IOR('t',116,struct ltchars)/* get local special chars*/ #define OTIOCCONS _IO('t', 98) /* for hp300 -- sans int arg */ -#endif /* _KERNEL */ - #endif /* !_SYS_IOCTL_COMPAT_H_ */ diff --git a/usr.bin/kdump/mkioctls b/usr.bin/kdump/mkioctls index cad3c962aec1..1f99c5a23c08 100644 --- a/usr.bin/kdump/mkioctls +++ b/usr.bin/kdump/mkioctls @@ -37,6 +37,7 @@ awk -v x="$ioctl_includes" 'BEGIN {print x}' | BEGIN { print "/* XXX obnoxious prerequisites. */" print "#define COMPAT_43" + print "#define COMPAT_43TTY" print "#include " print "#include " print "#include " From b4bf93f82a7dce11e8e0141e8febdb2847d45c10 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sat, 9 May 2009 15:41:22 +0000 Subject: [PATCH 063/544] Work around non-standard behaviour of rpcbind in some versions of Linux (FC4?). Submitted by: zachary dot loafman at isilon dot com --- sys/nlm/nlm_prot_impl.c | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index d9472a4fe7b7..1ddaf3e6ba15 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -312,6 +312,7 @@ nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) enum clnt_stat stat = RPC_SUCCESS; int rpcvers = RPCBVERS4; bool_t do_tcp = FALSE; + bool_t tryagain = FALSE; struct portmap mapping; u_short port = 0; @@ -373,14 +374,7 @@ nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) stat = CLNT_CALL(rpcb, (rpcprog_t) RPCBPROC_GETADDR, (xdrproc_t) xdr_rpcb, &parms, (xdrproc_t) xdr_wrapstring, &uaddr, timo); - if (stat == RPC_PROGVERSMISMATCH) { - if (rpcvers == RPCBVERS4) - rpcvers = RPCBVERS; - else if (rpcvers == RPCBVERS) - rpcvers = PMAPVERS; - CLNT_CONTROL(rpcb, CLSET_VERS, &rpcvers); - goto again; - } else if (stat == RPC_SUCCESS) { + if (stat == RPC_SUCCESS) { /* * We have a reply from the remote RPCBIND - turn it * into an appropriate address and make a new client @@ -391,13 +385,22 @@ nlm_get_rpc(struct sockaddr *sa, rpcprog_t prog, rpcvers_t vers) struct netbuf *a; a = __rpc_uaddr2taddr_af(ss.ss_family, uaddr); if (!a) { - CLNT_DESTROY(rpcb); - return (NULL); + tryagain = TRUE; + } else { + tryagain = FALSE; + memcpy(&ss, a->buf, a->len); + free(a->buf, M_RPC); + free(a, M_RPC); + xdr_free((xdrproc_t) xdr_wrapstring, &uaddr); } - memcpy(&ss, a->buf, a->len); - free(a->buf, M_RPC); - free(a, M_RPC); - xdr_free((xdrproc_t) xdr_wrapstring, &uaddr); + } + if (tryagain || stat == RPC_PROGVERSMISMATCH) { + if (rpcvers == RPCBVERS4) + rpcvers = RPCBVERS; + else if (rpcvers == RPCBVERS) + rpcvers = PMAPVERS; + CLNT_CONTROL(rpcb, CLSET_VERS, &rpcvers); + goto again; } break; case PMAPVERS: From ba521305e8cdd40178ce2798a5aa7ddf75f23443 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 9 May 2009 16:42:57 +0000 Subject: [PATCH 064/544] TTYs don't necessarily use /dev/ttyxx. Submitted by: csjp --- lib/libc/gen/ttyname.3 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/lib/libc/gen/ttyname.3 b/lib/libc/gen/ttyname.3 index ada580f6e978..c7b8cbcd3c84 100644 --- a/lib/libc/gen/ttyname.3 +++ b/lib/libc/gen/ttyname.3 @@ -57,11 +57,10 @@ These descriptors are not related to the standard .Dv FILE typedef, but refer to the special device files found in .Pa /dev -and named -.Pa /dev/tty Ns Ar xx and for which an entry exists in the initialization file -.Pa /etc/ttys . +.Pa /etc/ttys +or pseudo-terminals. (See .Xr ttys 5 . ) .Pp From ec54a3a337eb89b4023d9d915a97a527e65fa633 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 May 2009 17:47:42 +0000 Subject: [PATCH 065/544] Unmark the ASR Compat IOCTLs as BURN_BRIDGES, per scottl@ --- sys/dev/asr/asr.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/asr/asr.c b/sys/dev/asr/asr.c index 8cda0a953e46..2bc5e2277246 100644 --- a/sys/dev/asr/asr.c +++ b/sys/dev/asr/asr.c @@ -142,11 +142,9 @@ #include "opt_asr.h" #include -#ifndef BURN_BRIDGES #if defined(ASR_COMPAT) #define ASR_IOCTL_COMPAT #endif /* ASR_COMPAT */ -#endif /* !BURN_BRIDGES */ #endif #include From 5679fe195787816af8648fbe2c21cf47b4f0272f Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Sat, 9 May 2009 18:09:17 +0000 Subject: [PATCH 066/544] Do not embed struct ucred into larger netcred parent structures. Credential might need to hang around longer than its parent and be used outside of mnt_explock scope controlling netcred lifetime. Use separate reference-counted ucred allocated separately instead. While there, extend mnt_explock coverage in vfs_stdexpcheck and clean-up some unused declarations in new NFS code. Reported by: John Hickey PR: kern/133439 Reviewed by: dfr, kib --- sys/fs/nfs/nfsport.h | 10 ------- sys/fs/nfsserver/nfs_nfsdport.c | 14 +++------- sys/fs/nfsserver/nfs_nfsdsocket.c | 2 ++ sys/kern/vfs_export.c | 44 +++++++++++++++++-------------- sys/nfsserver/nfs_srvsubs.c | 3 +++ sys/nlm/nlm_prot_impl.c | 5 +++- sys/ufs/ufs/ufs_extern.h | 1 - 7 files changed, 37 insertions(+), 42 deletions(-) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index e4b3d0a06db4..c1c93a59c9c3 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -445,16 +445,6 @@ int nfsmsleep(void *, void *, int, const char *, struct timespec *); */ #define VT_NFSV4ROOT "nfsv4root" -/* - * XXX - not in any system .h file, just vfs_export.c - * Network address lookup element - */ -struct netcred { - struct radix_node netc_rnodes[2]; - int netc_exflags; - struct ucred netc_anon; -}; - /* * Define whatever it takes to do a vn_rdwr(). */ diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 6d391736646e..09a1d73ac9da 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2565,6 +2565,8 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, if (nd->nd_repstat) vput(*vpp); } + if (credanon != NULL) + crfree(credanon); if (nd->nd_repstat) { if (startwrite) vn_finished_write(mp); @@ -2597,16 +2599,6 @@ fp_getfvp(struct thread *p, int fd, struct file **fpp, struct vnode **vpp) return (0); } -/* - * Network export information - */ -struct netexport { - struct netcred ne_defexported; /* Default export */ - struct radix_node_head *ne_rtable[AF_MAX+1]; /* Individual exports */ -}; - -struct netexport nfsv4root_export; - /* * Called from newnfssvc() to update the exports list. Just call * vfs_export(). This has to be done, since the v4 root fake fs isn't @@ -2861,6 +2853,8 @@ nfsvno_v4rootexport(struct nfsrv_descript *nd) return (NFSERR_PROGUNAVAIL); if ((exflags & MNT_EXGSSONLY)) nd->nd_flag |= ND_EXGSSONLY; + if (credanon != NULL) + crfree(credanon); return (0); } diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index 29592a964d58..a9c7e8031cd5 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -870,6 +870,8 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, if (!nd->nd_repstat) nd->nd_repstat = nfsd_excred(nd, &nes, credanon); + if (credanon != NULL) + crfree(credanon); if (!nd->nd_repstat) { if (vpnes.nes_vfslocked) nfsvno_unlockvfs(mp); diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 486f4ce67eaf..8e3464611ad7 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -68,7 +68,7 @@ static struct netcred *vfs_export_lookup(struct mount *, struct sockaddr *); struct netcred { struct radix_node netc_rnodes[2]; int netc_exflags; - struct ucred netc_anon; + struct ucred *netc_anon; int netc_numsecflavors; int netc_secflavors[MAXSECFLAVORS]; }; @@ -83,7 +83,7 @@ struct netexport { /* * Build hash lists of net addresses and hang them off the mount point. - * Called by ufs_mount() to set up the lists of export addresses. + * Called by vfs_export() to set up the lists of export addresses. */ static int vfs_hang_addrlist(struct mount *mp, struct netexport *nep, @@ -118,15 +118,14 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep, } np = &nep->ne_defexported; np->netc_exflags = argp->ex_flags; - bzero(&np->netc_anon, sizeof(np->netc_anon)); - np->netc_anon.cr_uid = argp->ex_anon.cr_uid; - np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; - bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, - sizeof(np->netc_anon.cr_groups)); + np->netc_anon = crget(); + np->netc_anon->cr_uid = argp->ex_anon.cr_uid; + np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups; + bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups, + sizeof(np->netc_anon->cr_groups)); np->netc_numsecflavors = argp->ex_numsecflavors; bcopy(argp->ex_secflavors, np->netc_secflavors, sizeof(np->netc_secflavors)); - refcount_init(&np->netc_anon.cr_ref, 1); MNT_ILOCK(mp); mp->mnt_flag |= MNT_DEFEXPORTED; MNT_IUNLOCK(mp); @@ -204,15 +203,14 @@ vfs_hang_addrlist(struct mount *mp, struct netexport *nep, goto out; } np->netc_exflags = argp->ex_flags; - bzero(&np->netc_anon, sizeof(np->netc_anon)); - np->netc_anon.cr_uid = argp->ex_anon.cr_uid; - np->netc_anon.cr_ngroups = argp->ex_anon.cr_ngroups; - bcopy(argp->ex_anon.cr_groups, np->netc_anon.cr_groups, - sizeof(np->netc_anon.cr_groups)); + np->netc_anon = crget(); + np->netc_anon->cr_uid = argp->ex_anon.cr_uid; + np->netc_anon->cr_ngroups = argp->ex_anon.cr_ngroups; + bcopy(argp->ex_anon.cr_groups, np->netc_anon->cr_groups, + sizeof(np->netc_anon->cr_groups)); np->netc_numsecflavors = argp->ex_numsecflavors; bcopy(argp->ex_secflavors, np->netc_secflavors, sizeof(np->netc_secflavors)); - refcount_init(&np->netc_anon.cr_ref, 1); return (0); out: free(np, M_NETADDR); @@ -267,9 +265,9 @@ vfs_export(struct mount *mp, struct export_args *argp) || argp->ex_numsecflavors >= MAXSECFLAVORS) return (EINVAL); - nep = mp->mnt_export; error = 0; lockmgr(&mp->mnt_explock, LK_EXCLUSIVE, NULL); + nep = mp->mnt_export; if (argp->ex_flags & MNT_DELEXPORT) { if (nep == NULL) { error = ENOENT; @@ -375,8 +373,9 @@ vfs_setpublicfs(struct mount *mp, struct netexport *nep, * If an indexfile was specified, pull it in. */ if (argp->ex_indexfile != NULL) { - nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP, - M_WAITOK); + if (nfs_pub.np_index != NULL) + nfs_pub.np_index = malloc(MAXNAMLEN + 1, M_TEMP, + M_WAITOK); error = copyinstr(argp->ex_indexfile, nfs_pub.np_index, MAXNAMLEN, (size_t *)0); if (!error) { @@ -392,6 +391,7 @@ vfs_setpublicfs(struct mount *mp, struct netexport *nep, } if (error) { free(nfs_pub.np_index, M_TEMP); + nfs_pub.np_index = NULL; return (error); } } @@ -461,15 +461,19 @@ vfs_stdcheckexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, lockmgr(&mp->mnt_explock, LK_SHARED, NULL); np = vfs_export_lookup(mp, nam); - lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); - if (np == NULL) + if (np == NULL) { + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); + *credanonp = NULL; return (EACCES); + } *extflagsp = np->netc_exflags; - *credanonp = &np->netc_anon; + if ((*credanonp = np->netc_anon) != NULL) + crhold(*credanonp); if (numsecflavors) *numsecflavors = np->netc_numsecflavors; if (secflavors) *secflavors = np->netc_secflavors; + lockmgr(&mp->mnt_explock, LK_RELEASE, NULL); return (0); } diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c index d1544639a14d..3f546644e0cc 100644 --- a/sys/nfsserver/nfs_srvsubs.c +++ b/sys/nfsserver/nfs_srvsubs.c @@ -1193,6 +1193,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp, if (!lockflag) VOP_UNLOCK(*vpp, 0); out: + if (credanon != NULL) + crfree(credanon); + if (error) { VFS_UNLOCK_GIANT(vfslocked); } else diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index 1ddaf3e6ba15..a46d4327b0b0 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -1752,7 +1752,8 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, } if (cred->cr_uid == 0 || (exflags & MNT_EXPORTANON)) { crfree(cred); - cred = crhold(credanon); + cred = credanon; + credanon = NULL; } /* @@ -1772,6 +1773,8 @@ nlm_get_vfs_state(struct nlm_host *host, struct svc_req *rqstp, out: if (cred) crfree(cred); + if (credanon) + crfree(credanon); return (error); } diff --git a/sys/ufs/ufs/ufs_extern.h b/sys/ufs/ufs/ufs_extern.h index 2cb98016edab..b2e4a9757305 100644 --- a/sys/ufs/ufs/ufs_extern.h +++ b/sys/ufs/ufs/ufs_extern.h @@ -38,7 +38,6 @@ struct direct; struct indir; struct inode; struct mount; -struct netcred; struct thread; struct sockaddr; struct ucred; From deb1daa82ef3a5992bbdc44885fe729e0373ebed Mon Sep 17 00:00:00 2001 From: Ollivier Robert Date: Sat, 9 May 2009 18:09:18 +0000 Subject: [PATCH 067/544] Remove reference to nonexistant manpage. PR: ports/131898 Submitted by: Niclas Zeising Prodded by: sbruno --- share/man/man4/iwn.4 | 1 - 1 file changed, 1 deletion(-) diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4 index 26f1627a9ca1..a2d2dcfac156 100644 --- a/share/man/man4/iwn.4 +++ b/share/man/man4/iwn.4 @@ -146,7 +146,6 @@ failed. This should not happen. .El .Sh SEE ALSO -.Xr iwnfw 4 , .Xr pci 4 , .Xr wlan 4 , .Xr wlan_ccmp 4 , From 71ce264c94e2661f560d6fea494dec209f8dbad3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 May 2009 18:25:58 +0000 Subject: [PATCH 068/544] Implement RFC 5095 more fully. Rather than marking this no-op code as BURN_BRIDGES, just remove it. Adjust comments. Reviewed by: dwhite, emaste, battlez --- sys/netinet6/ip6_output.c | 29 +++-------------------------- sys/netinet6/route6.c | 9 --------- 2 files changed, 3 insertions(+), 35 deletions(-) diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index 61804ecddfc6..8f2e632c51b0 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -435,34 +435,11 @@ skip_ipsec2:; #endif /* IPSEC */ /* - * If there is a routing header, replace the destination address field - * with the first hop of the routing header. + * If there is a routing header, discard the packet. */ if (exthdrs.ip6e_rthdr) { - struct ip6_rthdr *rh = - (struct ip6_rthdr *)(mtod(exthdrs.ip6e_rthdr, - struct ip6_rthdr *)); - - /* - * While this switch may look gratuitous, leave it in - * in favour of RH2 implementations, etc. - */ - switch (rh->ip6r_type) { -#ifndef BURN_BRIDGES - case IPV6_RTHDR_TYPE_0: - /* - * According to RFC 5095 we should not implement - * it in any way but we may want to give the user - * a hint for now. - */ - log(LOG_INFO, "[%s:%d] IPv6 Type 0 Routing Headers are " - "deprecated.\n", __func__, __LINE__); - /* FALLTHROUGH */ -#endif - default: /* is it possible? */ - error = EINVAL; - goto bad; - } + error = EINVAL; + goto bad; } /* Source address validation */ diff --git a/sys/netinet6/route6.c b/sys/netinet6/route6.c index 9bf4f3b1ff2c..64f057e2516c 100644 --- a/sys/netinet6/route6.c +++ b/sys/netinet6/route6.c @@ -95,15 +95,6 @@ route6_input(struct mbuf **mp, int *offp, int proto) * in favour of RH2 implementations, etc. */ switch (rh->ip6r_type) { -#ifndef BURN_BRIDGES - case IPV6_RTHDR_TYPE_0: - /* - * According to RFC 5095, 3. Deprecation of RH0, - * we must handle RH0 like the default (unknown - * routing header type) case. - */ - /* FALLTHROUGH */ -#endif default: /* Unknown routing header type. */ if (rh->ip6r_segleft == 0) { From 573a04c930437224b71d9b8c31f06e058c0350a0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 May 2009 18:50:01 +0000 Subject: [PATCH 069/544] Remove bogus comment. --- sys/netinet/in_var.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h index 84eb8ebb8371..2b59e929b5f4 100644 --- a/sys/netinet/in_var.h +++ b/sys/netinet/in_var.h @@ -336,7 +336,7 @@ SYSCTL_DECL(_net_inet_raw); LIST_HEAD(in_multihead, in_multi); /* XXX unused */ #ifdef VIMAGE_GLOBALS extern struct in_multihead in_multihead; -#endif /* BURN_BRIDGES */ +#endif /* * Lock macros for IPv4 layer multicast address lists. IPv4 lock goes From 82431678fce5c893ef9c7418ad6d998ad4187de6 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 18:53:07 +0000 Subject: [PATCH 070/544] update to v3.1 --- sys/contrib/dev/iwi/ipw2200-bss.fw.uu | 7601 +++++++++++---------- sys/contrib/dev/iwi/ipw2200-ibss.fw.uu | 7072 ++++++++++--------- sys/contrib/dev/iwi/ipw2200-sniffer.fw.uu | 421 +- 3 files changed, 7549 insertions(+), 7545 deletions(-) diff --git a/sys/contrib/dev/iwi/ipw2200-bss.fw.uu b/sys/contrib/dev/iwi/ipw2200-bss.fw.uu index 93ed68ce34c7..a818a267d64c 100644 --- a/sys/contrib/dev/iwi/ipw2200-bss.fw.uu +++ b/sys/contrib/dev/iwi/ipw2200-bss.fw.uu @@ -1,213 +1,216 @@ -/*- - * TERMS AND CONDITIONS - * IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE - * - * Do not use or load this firmware (the "Software") until you have carefully read - * the following terms and conditions. By loading or using the Software, you agree - * to the terms of this Agreement. If you do not wish to so agree, do not install - * or use the Software. - * - * LICENSEES: - * - * Please note: - * - * * If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, - * applies. - * * If you are an Original Equipment Manufacturer (OEM), Independent Hardware - * Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement - * applies - * - * -------------------------------------------------------------------------------- - * - * For OEMs, IHVs, and ISVs: - * - * LICENSE. This Software is licensed for use only in conjunction with Intel - * component products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. Subject to the terms of this Agreement, - * Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up - * license under Intel's copyrights to: (i) copy the Software internally for your - * own development and maintenance purposes; (ii) copy and distribute the Software - * to your end-users, but only under a license agreement with terms at least as - * restrictive as those contained in Intel's Final, Single User License Agreement, - * attached as Exhibit A; and (iii) modify, copy and distribute the end-user - * documentation which may accompany the Software, but only in association with - * the Software. - * - * If you are not the final manufacturer or vendor of a computer system or software - * program incorporating the Software, then you may transfer a copy of the - * Software, including any related documentation (modified or unmodified) to your - * recipient for use in accordance with the terms of this Agreement, provided such - * recipient agrees to be fully bound by the terms hereof. You shall not otherwise - * assign, sublicense, lease, or in any other way transfer or disclose Software to - * any third party. You may not, nor may you assist any other person or entity to - * modify, translate, convert to another programming language, decompile, reverse - * engineer, or disassemble any portion of the Software or otherwise attempt to - * derive source code from any object code modules of the Software or any internal - * data files generated by the Software. Your rights to redistribute the Software - * shall be contingent upon your installation of this Agreement in its entirety in - * the same directory as the Software. - * - * CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything - * to the contrary hereunder, solely with respect to the requirements for - * compliance with the terms hereunder, any contractors or consultants that You - * use to perform the work or otherwise assist You in the development or products - * using this Software shall be deemed to be End Users and accordingly, upon - * receipt of the Software, shall be bound by the terms of Exhibit A, Software - * License Agreement. No additional agreement between You and such consultants or - * contractors is required under this Agreement to detail such compliance. - * - * TRADEMARKS. Except as expressly provided herein, you shall not use Intel's - * name in any publications, advertisements, or other announcements without - * Intel's prior written consent. You do not have any rights to use any Intel - * trademarks or logos. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if - * any, are owned by Intel or its suppliers and licensors and may be protected by - * copyright, trademark, patent and trade secret law and international treaties. - * Any rights, express or implied, in the intellectual property embodied in the - * foregoing, other than those specified in this Agreement, are reserved by Intel - * and its suppliers and licensors or otherwise as set forth in any applicable - * open source license agreement. You will keep the Software free of liens, - * attachments, and other encumbrances. You agree not to remove any proprietary - * notices and/or any labels from the Software and accompanying materials without - * prior written approval by Intel - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS - * BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND - * (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST - * INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE - * INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR - * SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS - * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT - * EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR - * INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE - * OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. - * - * EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH - * FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND - * LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR - * OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant - * or assume responsibility for the accuracy or completeness of any information, - * text, graphics, links or other items contained within the Software. You assume - * all liability, financial or otherwise, associated with Your use or disposition - * of the Software. - * - * APPLICABLE LAW. Claims arising under this Agreement shall be governed by the - * laws of State of California], excluding its principles of conflict of laws and - * the United Nations Convention on Contracts for the Sale of Goods. - * - * WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of - * this Agreement shall be effective unless in writing and signed by an officer of - * Intel. No failure or delay in exercising any right, power, or remedy under - * this Agreement shall operate as a waiver of any such right, power or remedy. - * Without limiting the foregoing, terms and conditions on any purchase orders or - * similar materials submitted by you to Intel, and any terms contained in IntelÂ’s - * standard acknowledgment form that are in conflict with these terms, shall be of - * no force or effect. - * - * SEVERABILITY. If any provision of this Agreement is held by a court of - * competent jurisdiction to be contrary to law, such provision shall be changed - * and interpreted so as to best accomplish the objectives of the original - * provision to the fullest extent allowed by law and the remaining provisions of - * this Agreement shall remain in full force and effect. - * - * EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to - * applicable import and export regulations of the United States and of the - * countries in which each party transacts business, specifically including U.S. - * Export Administration Act and Export Administration Regulations. Each party - * shall comply with such laws and regulations, as well as all other laws and - * regulations applicable to the Software. Without limiting the generality of the - * foregoing, each party agrees that it will not export, re-export, transfer or - * divert any of the Software or the direct programs thereof to any restricted - * place or party in accordance with U.S. export regulations. Note that Software - * containing encryption may be subject to additional restrictions. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - * - * TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate - * its terms. Upon termination, you will immediately destroy the Software or - * return all copies of the Software to Intel. - * - * -------------------------------------------------------------------------------- - * - * EXHIBIT "A" - * - * SOFTWARE LICENSE AGREEMENT (Final, Single User) - * - * IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. - * - * Do not use or load this firmware image (the "Software") until you have carefully - * read the following terms and conditions. By loading or using the Software, you - * agree to the terms of this Agreement. If you do not wish to so agree, do not - * install or use the Software. - * - * LICENSE. You may copy and use the Software, subject to these conditions: - * 1. This Software is licensed for use only in conjunction with Intel component - * products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. - * 2. You may not copy, modify, rent, sell, distribute or transfer any part of the - * Software except as provided in this Agreement, and you agree to prevent - * unauthorized copying of the Software. - * 3. You may not reverse engineer, decompile, or disassemble the Software. - * 4. You may not sublicense the Software. - * 5. The Software may contain the software or other property of third party - * suppliers. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software - * remains with Intel or its suppliers. The Software is copyrighted and protected - * by the laws of the United States and other countries, and international treaty - * provisions. You may not remove any copyright notices from the Software. Intel - * may make changes to the Software, or items referenced therein, at any time - * without notice, but is not obligated to support or update the Software. Except - * as otherwise expressly provided, Intel grants no express or implied right under - * Intel patents, copyrights, trademarks, or other intellectual property rights. - * You may transfer the Software only if a copy of this license accompanies the - * Software and the recipient agrees to be fully bound by these terms. - * - * EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED - * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING - * WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR - * PURPOSE. Intel does not warrant or assume responsibility for the accuracy or - * completeness of any information, text, graphics, links or other items contained - * within the Software. - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR - * ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS - * INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO - * USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR - * IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE - * LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY - * BETWEEN JURISDICTIONS. - * - * TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if - * you violate its terms. Upon termination, you will immediately destroy the - * Software. - * - * APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the - * laws of California, excluding its principles of conflict of laws and the United - * Nations Convention on Contracts for the Sale of Goods. You may not export the - * Software in violation of applicable export laws and regulations. Intel is not - * obligated under any other agreements unless they are in writing and signed by - * an authorized representative - * of Intel. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - */ -#define IWI_FW_VERSION 3.0 + TERMS AND CONDITIONS + IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE + +Do not use or load this firmware (the "Software") until you have carefully read +the following terms and conditions. By loading or using the Software, you agree +to the terms of this Agreement. If you do not wish to so agree, do not install +or use the Software. + +LICENSEES: + +Please note: + +* If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, + applies. +* If you are an Original Equipment Manufacturer (OEM), Independent Hardware + Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement + applies + +-------------------------------------------------------------------------------- + +For OEMs, IHVs, and ISVs: + +LICENSE. This Software is licensed for use only in conjunction with Intel +component products. Use of the Software in conjunction with non-Intel component +products is not licensed hereunder. Subject to the terms of this Agreement, +Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up +license under Intel's copyrights to: (i) copy the Software internally for your +own development and maintenance purposes; (ii) copy and distribute the Software +to your end-users, but only under a license agreement with terms at least as +restrictive as those contained in Intel's Final, Single User License Agreement, +attached as Exhibit A; and (iii) modify, copy and distribute the end-user +documentation which may accompany the Software, but only in association with +the Software. + +If you are not the final manufacturer or vendor of a computer system or software +program incorporating the Software, then you may transfer a copy of the +Software, including any related documentation (modified or unmodified) to your +recipient for use in accordance with the terms of this Agreement, provided such +recipient agrees to be fully bound by the terms hereof. You shall not otherwise +assign, sublicense, lease, or in any other way transfer or disclose Software to +any third party. You may not, nor may you assist any other person or entity to +modify, translate, convert to another programming language, decompile, reverse +engineer, or disassemble any portion of the Software or otherwise attempt to +derive source code from any object code modules of the Software or any internal +data files generated by the Software. Your rights to redistribute the Software +shall be contingent upon your installation of this Agreement in its entirety in +the same directory as the Software. + +CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything +to the contrary hereunder, solely with respect to the requirements for +compliance with the terms hereunder, any contractors or consultants that You +use to perform the work or otherwise assist You in the development or products +using this Software shall be deemed to be End Users and accordingly, upon +receipt of the Software, shall be bound by the terms of Exhibit A, Software +License Agreement. No additional agreement between You and such consultants or +contractors is required under this Agreement to detail such compliance. + +TRADEMARKS. Except as expressly provided herein, you shall not use Intel's +name in any publications, advertisements, or other announcements without +Intel's prior written consent. You do not have any rights to use any Intel +trademarks or logos. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if +any, are owned by Intel or its suppliers and licensors and may be protected by +copyright, trademark, patent and trade secret law and international treaties. +Any rights, express or implied, in the intellectual property embodied in the +foregoing, other than those specified in this Agreement, are reserved by Intel +and its suppliers and licensors or otherwise as set forth in any applicable +open source license agreement. You will keep the Software free of liens, +attachments, and other encumbrances. You agree not to remove any proprietary +notices and/or any labels from the Software and accompanying materials without +prior written approval by Intel + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS +BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND +(INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST +INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE +INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR +SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT +EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR +INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE +OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. + +EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH +FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND +LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR +OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant +or assume responsibility for the accuracy or completeness of any information, +text, graphics, links or other items contained within the Software. You assume +all liability, financial or otherwise, associated with Your use or disposition +of the Software. + +APPLICABLE LAW. Claims arising under this Agreement shall be governed by the +laws of State of California], excluding its principles of conflict of laws and +the United Nations Convention on Contracts for the Sale of Goods. + +WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of +this Agreement shall be effective unless in writing and signed by an officer of +Intel. No failure or delay in exercising any right, power, or remedy under +this Agreement shall operate as a waiver of any such right, power or remedy. +Without limiting the foregoing, terms and conditions on any purchase orders or +similar materials submitted by you to Intel, and any terms contained in IntelÂ’s +standard acknowledgment form that are in conflict with these terms, shall be of +no force or effect. + +SEVERABILITY. If any provision of this Agreement is held by a court of +competent jurisdiction to be contrary to law, such provision shall be changed +and interpreted so as to best accomplish the objectives of the original +provision to the fullest extent allowed by law and the remaining provisions of +this Agreement shall remain in full force and effect. + +EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to +applicable import and export regulations of the United States and of the +countries in which each party transacts business, specifically including U.S. +Export Administration Act and Export Administration Regulations. Each party +shall comply with such laws and regulations, as well as all other laws and +regulations applicable to the Software. Without limiting the generality of the +foregoing, each party agrees that it will not export, re-export, transfer or +divert any of the Software or the direct programs thereof to any restricted +place or party in accordance with U.S. export regulations. Note that Software +containing encryption may be subject to additional restrictions. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + +TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate +its terms. Upon termination, you will immediately destroy the Software or +return all copies of the Software to Intel. + +-------------------------------------------------------------------------------- + +EXHIBIT "A" + +SOFTWARE LICENSE AGREEMENT (Final, Single User) + +IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. + +Do not use or load this firmware image (the "Software") until you have carefully +read the following terms and conditions. By loading or using the Software, you +agree to the terms of this Agreement. If you do not wish to so agree, do not +install or use the Software. + +LICENSE. You may copy and use the Software, subject to these conditions: +1. This Software is licensed for use only in conjunction with Intel component + products. Use of the Software in conjunction with non-Intel component + products is not licensed hereunder. +2. You may not copy, modify, rent, sell, distribute or transfer any part of the + Software except as provided in this Agreement, and you agree to prevent + unauthorized copying of the Software. +3. You may not reverse engineer, decompile, or disassemble the Software. +4. You may not sublicense the Software. +5. The Software may contain the software or other property of third party + suppliers. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software +remains with Intel or its suppliers. The Software is copyrighted and protected +by the laws of the United States and other countries, and international treaty +provisions. You may not remove any copyright notices from the Software. Intel +may make changes to the Software, or items referenced therein, at any time +without notice, but is not obligated to support or update the Software. Except +as otherwise expressly provided, Intel grants no express or implied right under +Intel patents, copyrights, trademarks, or other intellectual property rights. +You may transfer the Software only if a copy of this license accompanies the +Software and the recipient agrees to be fully bound by these terms. + +EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED +"AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING +WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR +PURPOSE. Intel does not warrant or assume responsibility for the accuracy or +completeness of any information, text, graphics, links or other items contained +within the Software. + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR +ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS +INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO +USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR +IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE +LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY +BETWEEN JURISDICTIONS. + +TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if +you violate its terms. Upon termination, you will immediately destroy the +Software. + +APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the +laws of California, excluding its principles of conflict of laws and the United +Nations Convention on Contracts for the Sale of Goods. You may not export the +Software in violation of applicable export laws and regulations. Intel is not +obligated under any other agreements unless they are in writing and signed by +an authorized representative +of Intel. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + + + + + +#define IWI_FW_VERSION 3.1 begin 644 ipw2200-bss.fw -M```#`$`9``#&/P``D)$"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` +M`0`#`$`9``!^/P``Y)$"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` M_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P`` M'S@5````4````!0&````@`\X`'X?$@(```D``0\X`/X?8`#^/V``_E]@`/Y_ M8`#^GV``_K]@`/[?8`#^_V``_A]A`/X_80#^7V$`_G]A`/Z?80#^OV$`_M]A @@ -351,11 +354,11 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M```'L`L`%@`$`!0`&P````!@$&)3H```!6X`:@)P*$$!$`Z0P(8!8"A!Q(L` +M```'L`4`"0`&``L`!`````!@$&)4H```!6X`:@)P*$$!$`Z0P(8!8"A!Q(L` M8!!!_F`100!J&4KP:H!*`6I`2@``0%`CH```FK#,L%*QHK$_LLBRY++XL@`` M`&"I0$!0,:```)NP^[!`6D`:(54"8`#7*$%!4```_]`&`)R00>`6`&R2$> -M!&`#R2(0MH\(``T`%P`'S`;8(E$``");04IIH"RP3K/(L,BP4+-2LV&S<;/T +M!&`#R2(0MX\(``T`%P`'S`;8(E$``");04IIH"RP3K/(L,BP4+-2LV&S<;/T MM/FTR+#(L(JWR+#(L#*U-+4VMP+]6I4`$?`LBBMP!@4$`A42(?`L[8H,BP3K/(L,BP4+`TL%"P4+!0L%"P MR+#(L(JWR+#(L%"P4+!0L,BP4+!0L%"P4+!-L\BP3;-0L%"P4+!0L#2PR+!0 ML,BP4+!0L!;<1=W]@I2(_8($@_V"/X/]@@WW)`&HM2I.X M+ELA(>?)E(@N6R$AX\FVN(!0_!_@R"!0(3,*R0+B?[$#8,A`6U`A-`+(#+(' -MLA]0(3,/R%!1(3(,R,Y0(3`)R2$S!LD(&T`;SD#P;#:.4K$`8!-`CU`A,03) +MLA]0(3,/R%!1(3(,R,Y0(3`)R2$S!LD(&T`;SD#P;#>.4K$`8!-`CU`A,03) M(3,"R0(!0]!F`0`-@0$`*8*5``[19 +M&4-*#\8.R;&"4"$P*,@B5/&!%P`8SD>.8&!>0(!0]!F`0`-@0$`*8*5``[19 M#\P.Q%`A,`7((P\C#@)@0$``9,1$(+``'P+)`16#0(90`!\"R0$5AD`D#H)@ M"K$@L`!B`&9V4!<`!\P`8'9`#U"+0!!0C$!V4`$1=D"#4`$1@T`!`%M0[QE; M0`&S``!+#P``$5'*0`!@R%`#'P3(+EM`(!O(%&2%9MR$#P`/&01D%P`8R!,D"8$!`\K(!8$!`SUH!'@+((+#]@I2(_8($@_V"(+`$W:8/`6!`0""P -M+ELA(0+)`0``8!!B'J)/4!D`@@$:41<`!0"Y;(2''R1I1`Q_[S@$`4%`` M'PO)45!24EQ47587``7,`&!00!5@R[8!`,BP(E$LL`-@R[8":E5+0%#P04%0 @@ -394,7 +397,7 @@ M8$!`!6#+M@%D`&888.&$$&YVDPQD#T4;6P(:&TM8#UD."&Y_DQM;`!@;2U@/ M60XB411`(E$50!)NKFPB40`!BY,B419`(E$70")1&$``'P+(\K0%'_[."VX9 M;")1``&;DR!0(3`$R1]0QQD?0"!J54L4;D!L(E$``:B3`6I52R!0(38$R11J M3TJULPEJ3TH*8`!D`FY";*H!``$0```!$````1!@N9,`8*5``6I52QM;_A@; -M2R!0(3,%R`%@4&209N&$(%`(&;Z/7V209N&$#&[6DQM;`1H;2R1DA6;AA-R$ +M2R!0(3,%R`%@4&209N&$(%`(&;^/7V209N&$#&[6DQM;`1H;2R1DA6;AA-R$ M(3`$R`D`(3``R"!0`1D;6_X8&TMM9-)FX8044"$P%L@54"9DTF;AA!1N\Y,4 M4"$Q#<@;6P$:&TL64!MDA6;AA!=0'&2%9N&$W(0``"!J54LO43)4%``O00%J M54L.;@V4&UL]2B!0(3,DR,Y:(24AR4!:!1X>R00>',D!8!M;_A@;2U]DD&;A @@ -403,19 +406,19 @@ M(%`!&0$?#,D$9`]%&T<%9`]%+UOS&"]+A6HO2Y"T`N+4`2];\Q@O2Q!N390@ M4"$S*,C.6B$E!\E`6@4>`LA:M`0>'\@`8!M;/4K^&!M+7V209N%'X44``.%! MX4,6;F>4&UL!&AM+)&2%9N%'X44``.%!X4,0;G.4/5H;2PKB>K0A-0?)#&0/ M11M'#60/18:T#&0/10=D&T4.9`]%0%H$'@3(CUHA(07)`6HO2P5J+TL`8*50 -MDZ2@M`!@$&(@HP*]`&`08B.MUK*QLMBQG[$\L2!0A0$0&#A*'U`@,`;)`VHA +MDZ2@M`!@$&+XH@*]`&`08OVLUK*QLMBQG[$\L2!0A0$0&#A*'U`@,`;)`VHA M,0+(!6JMM`!JDTH(#P[B`V2!9MR$^&#_8A0`J@$`9A4``V2!9N&$Y[0$9(%F MW(3^8/]B%`"O`0$8J@$`9A4`!&2!9N&$N`$9`(4!!62!9MR$_&#_8A0``QBJ M`0!F%0`%9(%FX83GM.)'XD7D5>-7`0#A1^%%``#A0>%#`0!9#\P.6`\!:E9+ M`&!>0`)@0$`&8,NV!F1*L%D.`6!`0`=@R[8`:E1*(E$":E5+A0$#&8(!0V`0 -M`(8!J`$P&;V/``&0`0%J54O"CX8!(E$0'QC)`!\&R04?$LP-'Q#.`Q$":E5+ +M`(8!J`$P&;Z/``&0`0%J54O#CX8!(E$0'QC)`!\&R04?$LP-'Q#.`Q$":E5+ M``$-;B)1``$;E0%J54L#;B)1(94(8,NV!&1*L`%J5$H0;@)J54LB40`!+)4! M:E5+([4!9$JP`61*L")1A0$B50\9.Z4_M4*U2[5MM0ANU86CM0%HP0%)#@AN M$&TB40`!1Y6CM0%HP0%)#@``$%$14R)5(E<0`!!!$4,241-3(E4B5Q$`$D$3 M0Q11%5,B52)7$0`4015#%E$74R)5(E<1`!9!%T,"9(ZU`6C!`4D.```041%3 M(E4B5Q(`$$$10Q)1$U,B52)7$P`201-#%%$54R)5(E<3`!1!%4,641=3(E4B M5Q,`%D$70P)D$%$14Q``$$$10Q)1$U,`9!$`$D$30Q11%5,1`!1!%4,641=3 -M$0`601=#`&"H`;V/IZ6JM;&UKK4,;M6%20_3M0ENU86YM4@.````;=B%"6W8 +M$0`601=#`&"H`;Z/IZ6JM;&UKK4,;M6%20_3M0ENU86YM4@.````;=B%"6W8 MA0QMV(4!:,$!20](#P-MV(4!:,$!_F`#0?]@!$$%00%HP0%+#P``"%$A,P?( M`%$#00%1!$$"405!$&#+MB)1U94!``-N(E$``=F5`0`LL!1@*$%!4"A!X&P@ M;D`!*$'DE01N*$'HE2!J54L"4"A!`U`H00Q0*$$-4`%J54O`ABA!Q(O@;"!N @@ -439,61 +442,61 @@ M(E4)P14`A0$+``$5"@`%`6&7`0`6`&6W(E,.``H`0`$B50G!%0"%`0L``14* M``4!;IH`1D`&0`9`!D``QD!`*@!&`"(`0$`++`@8%5!`&!B0`%@ M54$`8,Y`Q$",@"UD%P`"S)FW++"0#R)1(E%!0`!L`VXB40`!GY>,@$-D%P`) MSP!4`58>%1<`!,\!8*E`^[``8*E``VP#;B)1``&REP10(3<$R,Y0`1O.0`-0 -MCT`A-2W)!5`A-0[)#@"]CS`9"@`":E5+0`&$092/`6I52[:.Z[>>C@1:0"(+ -MR`50(38$R1!DA$7;MPADA$6VCOFW0R()R4$B`LGYMP50(38#R`ADZ+<09(1% -MD0_YM\10(3`$R2(/(@XD#V!185,/9!``8$%A0R)1)`[$4"$P`L@7OP9L#&XB +MCT`A-2W)!5`A-0[)#@"^CS`9"@`":E5+0`&$096/`6I52[>.Z[>?C@1:0"(+ +MR`50(38$R1!DA$7;MPADA$6WCOFW0R()R4$B`LGYMP50(38#R`ADZ+<09(1% +MD0_YM\10(3`$R2(/(@XD#V!185,/9!``8$%A0R)1)`[$4"$P`L@8OP9L#&XB M50(!_Y<"4`<9`!\&R0$5@@$8`!@`$``@:E5+0&00`(8!0`%!`4(!0P%'`0%J M54LG0"A"*40J1BM.`FI52R)1P$`!:E5+03(3R`!0`5($$8=`B$*!0@!:`12O -M`0)@54'!;")1``$PF`%J54M&N`)J54O!;!=N(E$``3J8`6I52P!@@4#*BPV. -M(@\B#B0/`6"M0`!@$&(@6B$G!L@$6B$@!EH'R0>O!%HA(`9:`LD3KSBO``"$ -M2L10(3`"R%Z_@%#T&8!`&%!D,`S(`FI52\!0`6I52T`R!.N!%HA(`9:`LGOKA2O``"$ +M2L10(3`"R%^_@%#T&8!`&%!D,`S(`FI52\!0`6I52T`R!GL(]TN&BQ@%`A,A/)Q@]+#P``&%$94\8. M`&07`!;(@%`$&X!`3U`:05Y0@!M>0`$`Q@]+#P``&%$94\8.`&07``3)@%#[ M&8!``0!>4"$U6,B`4"$R`LEPL8!0(3,"R'"Q7E`A,!K)`1M>0%Q075(K5!<` M!,T2``@`S[@`9(U0CE(7``/*`N!(`C4".0BM0+$``8%Q`74"-4(Y2+%05 M``!D%P`JR5Y0(30-]"2EH"'@3(.E0[5F6YAU2(5@1:(2`& -M4!3(AP$$:CE*`&`08CVN```)``-:(2("R6`18!'>5-]6$`!"5!(`C[D%:JM* -M6+X&6@5@K4``8!!B$Z\```!@J`$9`(4!DA"VCQ``1500`-Y4WU80`$I:`AX" +M4!3(AP$$:CE*`&`08AFN```)``-:(2("R6`18!'>5-]6$`!"5!(`C[D%:JM* +M6;X&6@5@K4``8!!B[ZX```!@J`$9`(4!DA"WCQ``1500`-Y4WU80`$I:`AX" MR`ZZWD#?0MQL!&Y%`4!+FIF/6B$A"\D":E5+Q&P,;D4!0$NDF0%J54NRN09N MKFQ%`4!+K)D`8$)0M[D#XD90M[E#4!<1`0\`:JQ*RXP$8$!``&""0(]:(2$" -MR2"PAU2(5@!@$&(DK@!@$&+VJ[^+AU2(5@90`&JF2A:\```!9`!F!F#AA*^/ +MR2"PAU2(5@!@$&(`K@!@$&+0J[^+AU2(5@90`&JF2A:\```!9`!F!F#AA+"/ M`FI52P!@PD##0@%J54N!4"$R+L@*4`M2`UHA)0C)"&00`(%:(28%R2$G`\D$ -M9!``"``Z0#M"!E`6X@%JJTI8OI`!`^)%5/VY0E00`!``$``(`(10&0"%`9(0 -MMH\/`!``$``NN@)J2DJ$4$2Y+KH#4"$W)\@5XH10A0$@4"$W!\@&6@A@K4`` -M8!!B$Z\``*@!&0"%`9(0MH]%5!``+KJ$4`!J2DI$N0D`0E00``)J54O"0,-" +M9!``"``Z0#M"!E`6X@%JJTI9OI`!`^)%5/VY0E00`!``$``(`(10&0"%`9(0 +MMX\/`!``$``NN@)J2DJ$4$2Y+KH#4"$W)\@5XH10A0$@4"$W!\@&6@A@K4`` +M8!!B[ZX``*@!&0"%`9(0MX]%5!``+KJ$4`!J2DI$N0D`0E00``)J54O"0,-" M`6I52X%:(24"R,BY`FI52\!L0`$!:E5+0$%!,A+(I0^*-`3(:5`0&VE``%H! M%*\!`FI52T`!0$%,F@%J54O]NH%0`FI52Q=N0@%`15::(30&R`)N0@%`15R: M9KHA,07(!FY"`4!%8YH!:E5+@5HA)A+("&H"8%5!X&RO`4`!0$%PF@%@54&) M4(I2J@$2`)P.D@^9NB$G`\@$:FRZ(2`(R0-:(29$R8E0BE*PC?VZ\%%`0?%1 -M0$'R44!!!5*_C\`90$$"_J[0U`7$0$/!6I` +M=T(D#L10_1G$0&R/`6`_CL"&*$'$BP)@0$#%CB"P`^)&4">[0U`7$0$/!6I` M2@!JK$K+C`5@0$``8()`(+"&8`JQ$;$`:JQ*RXS\W/G5C(`>9!<`];H;L&8F=#(0\B47!!(E%Q02)1$$B47E!(E%Z02)1>T$B47Q! -M(E%]02)1?D$B47]!D0\":E5+P&P8;B)1``&EFP%J54L89.&+#8XB#R(.)`^! +M(E%]02)1?D$B47]!D0\":E5+P&P8;B)1``&EFP%J54L89.&+#HXB#R(.)`^! M4/,9(2("R`0;@4`@8%5!8E`A,0%@54$"R=*Y=K(`#@$.`@X##@$````$VP!J M*$O$NP$``FI52\!0P5(!:E5+&&2%`0@>",B-`4,@!<@>9(%J`AJ!2HT!(2*! M6@+(!!J!2@!0`5(2``1:(20&R`)D$@"!6A`:@4J)0(I"`%`!4@1D$``#6B$E M'\D$6D,B!\@$9!``@5I`&H%*$[Q`(@?("&00`(%:`1J!2A.\0B('R`AD$`"! M6B`:@4H3O`1D$`"!6H`:@4J'0(A"`0"%`0%@`&(``.%#X4$``.%#X4.H`1IN -M(9R'`<=.`UH*&``>!,D@6B$G(,D$6B$@'!,D@6B$G(,D$6B$@'`LC[&0X`J`$!9(!FX82" -M`0T`EP$(``%J.4H`8!!B/:X```D``&2`9N&$J`'^&00;`V2`9N&$Q%`A,`+( -M:K]9#B];@!HO2P!@QD#9O13B+UOS&"]+(%HA(`?)GHT/6_P8`1H/2Z"\ZFHO +M`0T`EP$(``%J.4H`8!!B&:X```D``&2`9N&$J`'^&00;`V2`9N&$Q%`A,`+( +M:[]9#B];@!HO2P!@QD#9O13B+UOS&"]+(%HA(`?)GHT/6_P8`1H/2Z"\ZFHO M2P];_!@!&@]+H+PO6_,8+TOJ:B]+#UO\&`(:#TLC;J&`'PL8/2@X811E'2@_&#@%D`&888`!B``#A1^%%``#A0>%#```@ -M8%5!`&!B0`%@54&L4$VM`0``8!!B(*@`8!!BXJ@`8!!B,ZL``,8/2@X#XD=0 -M7KU$4`45&$$90TH/Q@[.4"$U!.H&!KO81@/XX*L0```60`9@!@X819 M#@%@QD#9O2]1@!LO02];\Q@O2R!0(3`#R9Z-@[WJ:B]+(VZ$G009P/'U`A-!+( M4%$A,@_(SE`A,`S)(3('R2$Q!`6!50<90"ZZ#O':]@5`":E5+ -M(30)R")5`@$B50(!`FXB51>>(KXA,0?(!FXB50(!'9XB52)5X!D`'P[)`6I5 -M2PAJ(3<"R`1J`F151:\!X&PB50(!+Y[!6@%D544!`+KX;8))! -M@[X88))!@[X28))!@[X,8))!@[X)8))!@[X&8))!@[X)8))!"0`"9!``&`"& -MO@-@DD$)``)D$`"009%#P0\`````T@&049%3`600`!@`&`"J`1``"```8*M0 -MF*XSN?BY`&`08B*G?[D&8F=#(0\/42`;#T%P;01N(E$``<)!IIX`8F=#(0\, -M;B)1``'"0:Z>#U'?&0]!`0"$#P``\%%P0?%1<4'R47)!D0\!````Q%`"&\1` -MQ%`!&\1`+5`"&RU`.]PZU2%1"Q\WR"(/(@XD#R)1C(`B9!<`+,T2`");PTK$ -M6B$A`\G#6D%*(E4B5P!$`487`![,(E$"0"$W&LA+#\)4"%$7``G,%,X&40=3 -MP%3!5A<`!$%``7E!0`%Z04`! -M>T%``7Q!0`%]04`!?D%``7]!`0``8%Q`74!>0"M0+$`!`*X!$&I52T`!`6I5 -M2P$`&0`9`!D`&0`!`!@`&``8`!@``0`````````````````````````````` +M#@];WQ@/2S6[(%`A,P7)`60`9@!@X83#N@```&3'4!D`A0$08%5!&^*J$+>/ +M"@`08%5!@&#E04`!YD$*8-)BX4/A04(!X47A1R-@TF+A0^%!``#A1>%'%&[Y +MG0B^@&#E01Q0YD$%8()BX4/A01U4X47A1RAN!YX!8%5!QE`,KH.\=KV!4`)J +M54LA-`G((E4"`2)5`@$";B)5&)XCOB$Q!\@&;B)5`@$>GB)5(E7@&0`?#LD! +M:E5+"&HA-P+(!&H"9%5%KP'@;")5`@$PGL%:`61510$`MP%``4$!`1&^`0`! +M`0$!`,Y4`&(/`$`9%0``9,Y$`0`I9"IFBU",4A<`!^`V"200D``F00`)!!D4/!#P````#2`9!1D5,!9!``&``8`*H!$``(``!@ +MJU"9KC.Y^+D`8!!B_*9_N09B9T,A#P]1(!L/07!M!&XB40`!PD&GG@!B9T,A +M#PQN(E$``<)!KYX/4=\9#T$!`(0/``#P47!!\5%Q0?)14%``7I! +M0`%[04`!?$%``7U!0`%^04`!?T$!``!@7$!=0%Y`*U`L0`$`K@$0:E5+0`$! +M:E5+`0`9`!D`&0`9``$`&``8`!@`&``!```````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````!)#\8/20_&#@!O -M`&P`:@4!6Y`@:E5+!&YP;`!J!0%BD`)J54NP;E%L`&H%`6F0`6I52P!@S4!F -M8$M`(&I52P!@84`(:E5+&&#/0$!@SD``8.U`!V#L0`)@ZT`!:E5+'F!N0`!@ -M;T`:8*-``&I02R];[QB`&B]+`6`H00%@*$%:8"A!T6`H00-@*$$);@!@*$&; -MD`1NT&Q``2A!GY``8"A!*$$`8!!B"Z`(:E5+'^IH8)!B$X*%`-3&``8`/!"C+$! -M:E5+"&!H50AJ54L7`/G.:&"08A."R$#)0L%`;&"08A."RT#,0@%D@6;B1^)% -MY%'C4Q@`&`#P0AD`8!F"`0A@54'!4)\9%0#!0$=@D&(3@N1`Y4)"8)!B$X(9 -M`!D`XT(!8(%B$X*%`1@`&`#F0J@!&0`9`!D`&0`#&>!``1\,R3A@D&(3@N=` -MZ$(68)!B$X(_&>E`'[$W8)!B$X+G0.A"%F"08A."&``8`.E"`&``9.-4Z5`5 -M$1(`YD#K5!``A0$_&`!@J`$8`(4!`!#UCN14Y587``//`6KJ2N90[%00`(4! -M/Q@P'@+,,&H`8*@!&`"%`0`0]8[G5.A6%P`$S^I:`AKJ2@%J54L68)!B$X*% -M`1@`&``.`#\9VD`_&-M*`6"!8A."&``8`!@`&``.``,903`#R-I09K';4`AJ -M54L`9,]4%P`'S.I:(2`1R2$A#\F,L0AJ54O!6B$D%LGJ6B$@!LDA(03)*FR] -MCQ:S!M,N6R$A`LA_L1:S!.(!:E5+.;(.;+V/.;(!:E5+'U`@,"7)(3$#R05@ -MEK$#8`-D@688@M0!U`$4;IR1`6"!8N)#XD'D4>-3&``8``AD547N0@%J54L? -M4"$Q`\D#8+"Q!6`#9(%F&(((9%5%`FR]CPAJ54M9#@]1_!D/00```AL/01M; -M`QH;2R];\Q@O2Q!NQY$%:B]+`6`$9(%F&((!9%5%'U`(9%5%(#`'R0%D(3$" -MR`)DD`'>L<%0WH\.``!B!62!9AB"`61511]:("`#R01D%0`^0`A@54'+4'\9 -M`!$*`$`!RD#O0"9DA688@ED/`6I52Q!N^I$;6_X8&TL!8%!DD&88@A!N`Y(; -M6P<:&TLI8(5B$X(A,?S((3`"R(6Q60X,;+V/%K/B0^)!Y%'C4P$`X4?A10`` -MX4'A0P$``````.Q0[5(!$>Q`[4((8%5!`&#J0`%@54$`;+V/0%`%'P?)!!\% -MR2!0(3,"R*BP+EM#(/[(#.(68)!B$X*%`=^/#@`_&=I`/QC;2DNR`&"A8A." -MA0%_&-M*!.(2;+V/4;(0;+V/X&S)CP)@6$#%0FE0$!EI0%M0(34)R-\96T#& -M#TH.`&`801E!Q@Y>4"$V#4+\97D"-4(Y27%1=5A<`!,\`8%Q`74`K4"Q` -M`MFG#YL.F@Z3#@+3>K($X@!@@6*%LFE0`AMI0`)@@6(3@H\!`N*YLB$P!,DA -M,P+)C[(,O0!D@6;B1^)%Y%7C5Z=$J$:%`0X`"A\(R10?"B``#&#TH. -M`&`#XD=0B+-$4!A!&4-*#\8.#N(?6B`@!L@#9(%F8%!A4AB"(F329J)0&((` -M8).Y`PZ`4/L9@$""4`$;@D``8!-`-U#^&3=`!.($;+V/K;,6;+V/`MVPLTZT -M2%%J0$`P!,D`#@$.QK?\&71`VH^'`4A;:TI(46Q`2%%M0'!0<5($9!(`0R`$ -MR``.`0_(M[T!#P!2$.Z.:UHA)@+("!$7``3-``\!#LBW=%!!,A#(V(\)'P+. -MYK,*%>"CW[=VN/:X1KF%N86Y``X!#\:W85#\&8(!/E`'&14`/D`X:EA+!0\" -MTO:SW+T`+6WM`"UP[3FL^:SR+0`M?&TM[3ZM+>TYK/FLTG&`61E1#*Z"&`#9&1$ -MK;H(;M!!P)0]M6E0"!MI0$;&M[0`8'5``PYI4`0;:4`94"$T")\\`8&9` -M2[H&;DA1*$'001J52%$H00\9T$%(42A!`!G001E:(2`(R6M00C`1R"$B`\@A -M-@W(!<,A(`+)/+4##B$@!\D&QP3$(2$#R3RUS+D88&=``0X"#FE0(3(+R'AL -M"&Y(42A!``%&E6=0"!%G0$BV:E",&8@?#LA(42A!GD!!-0/(!&#%0$A3*$.? -M0F=0`A%G0!SGQ5`A,AK)&<8"TVZU%NI+#P``&%$%'Q'.`--OM5D.#.8,Q@#S -M`6"J0`!@$&)MK0```6!80'RUS+D`:G5*:UHA)C;(S%H!'@7)&5HA(P;(2+8: -M6B$A`LA(M@!@$T`$;D=L`F!504A1``&2E0%@54%&41)`(3`LR;>U`FI52T=0 -M2%))5$I6`6I52Z!M*$$``2A#`0$H10(!*$>8`6=:!!!G2B$U=<@`:A-*@&IU -M2DBV`FI52TI0P!D8`!@`#@!#9!``A@%``0%J54L30-JE`L=(MH4!&0`9`)9D -M$``*`$`!(2$$R0,9$T#7M3`9V(\30`%D547:I9RUWK4XN^&U@&IU2DBV#U'? -M&0]!`FI52P1N1VQ"`2A%Z)6@10)J54MB5&-61U!(4F)`8T(7`$A1*$%(4RA# -M9%1E5F1`94(!:E5+"L@7``C(``\"#Y8/DP\0:I1+#+8`#I,.`@[%4"$R"L@) -MP0!@$T!G4`819T"`8'5`2+9(52A%AD5(52A%AT5G4`@19T#%#C!J=4K%#TBV -MVH\P&88!#U'?&0]!Q0X"#Y8/DP\`:G5*Q0_%#L4/`FI52T`!`6I52P`?E$$% -MR(!J=4J3#@(.!&Y(42A!0I9G4`019T`"YTNV\K9G5`1@$``(`'!0<5(7``// -M`&!6MA(`#```ZSD.I`^=#G50@!\%R1-00C`"R+.[#0"P0Y]!`&07`!7)G0\3 -MQ)E1FE.;09Q#F@\-Q'50`!\*R`)J54O3C@%J54N;#Y@/0&!U0`+3D[834$,P -M$L@1P`CJ`L=\MDL/```840,*$&R -MC)*WW+?8CPL1$&I52X8!10$!9%5%IU"H4@5D$`"J`2NW`6!30+6^:5`A-0/( -M"V`-MP-@`N8-MP)@R(DH0;*,`&!H4&E:(2,#R"$AW7*$$H0[!0*$&Q4"A!LE`H00!@*$$!:E5+(&!5 -M00%@,T`!8%5!65`H05I0*$$`8"A!IXPH0;*,:5`A,SC)(34VR1E0(34SR#+F -M`FI52^A4`6I52P%HP0%+#P``$%$7``/+$@!TMX4!_V`2`*H!$`!95%I6$``" -M$0@`20YX4'E2$``001%#`&1Z4'M2$0`201-#?%!]4A$`%$$50WY0?U(1`!9! -M%T,!:,$!20\84`0?(,AI4"$R+L@A-2S)`&`"4]V/"```40%3V(\5`(AD$V87 -M``+."0"009%#3V"20<$/`````-(!D%&14W)`:W2%%"`1<` -M`\CBE^RW`PY>QAA0`1\$R0(?`LE*N-1L!FY(40`!]9<"W?NW=;@`TUD.`N8` -MN'2X`/,$8*I``&`08FVM``#48-!`.%#10`!@TD#30LY0`1O.0-!L"FY``4!! -M$Y@#XD=4&KA$5`$/`6"L0`!@$&+,K```SE#^&,*$&RC%D/S`Z3N0#3*>9H4!D`A0&2$.Z.`^)%5%6X0E00`()'5!```V0DND14$``%9!(`J@$2`%54$@`851E7%P`#S!A!&4-*#\8. -M`0#4;`-N2%$``2A!T$%&04A1``$H0=!!1D$TF@O=95!"JJ*TN[2BM**T`+4` -MM=RT/+6^NN90YU(!$>9`YT)I6@$/M%1(42A!T$%&0;14M59(4RA#T$-&0R$F -M`\G40-5"%P`'R>10Y5(!$>1`Y4(!#K942%$H0=!!1D&W5M2/1D,A)@/)UD#7 -M0A<``LD!#KA42%$H0=!!1D&Y5M2/1D,A)@/)V$#90A<``LD!#@!N`&PUW690 -MC*H9M:*TW[2IN@"U`0\`:DA1*$'_'PW(!6Y(42A!_Q\"R0$.(=V8F@+"!FH! -M#JFZ`V1F1+1L`VX!#U>Z8U"KJJ*T`+4`Z[!#GT&=#P+VL;J=#@K=9%"WJJ*T -MHK2BM+^TU;3NM":U.@XY#I:Y%,25#^B*U;K^4/]2`1'^0/]"`6#-0)]1L%,, -M``!D%P#PR55@XHH`TS=:(2`"R9T.F8FGC"A!LHS-2@/F!(H3O=6Y`L25#P#7 -M*$'DF@;$`MGHNIL.F@Z3#@$`U^<"YO.ZY/;QNL50(3("R0+'L+8`\PU@JD`` -M8!!B;:T``%N_!`[0;`IN10%`2P.;!@[.4`$;SD`34$,P!\@.P'5: -M4`\9QT'&0=!!`�D``A48:F2["0``9,=%QD4"9%5%@$"!0D)DRT75#ZH! -M(&`2``(5@D`!9%5%!F[4;$`!QT'&072;`F1510U@`FY';$(!*$710=)!`17' -M1<9%?9M)5"A%2EHH2P1N2%4H1=%!TD$!%<=%QD6*FPY@T4'208%2QT.`4,=! -M@5((``!@QD$!8,9!`61516=0"!%G0`)D547`&`!BJ`$9`!D`A@$0;D`!Q4&M -MFP%D545(M@%D545P4'%2!!5G5!(`L$.?0=$/-U`!&S=``F1510!B@E`,``!@ -MT$'&FP%D546=#WRVP!@`8*@!&``8``X`A0&O`1)0A0$9`!D`FF00`+H!"@!` -M`0!B(2$/R8<9$!L;00]1(!M`&P]!T0X``-`/`FI52UE@Q$$!8,-!`6I5 -M2P!0`5(@9!(`%FH(``10(30+R`)N54_84`\9Q$'#00D``A48:B&\"0``9,1% -MPT4"9%5%@$"!0D)DR44@9,U'S44@$\!FY``4!!T$%:G$`!0$$/&=!!0`%` -M00`9T$$!9%5%!%`A-`S(`F151=A00$$/&=!!V5!`00!@T$%XO`)D547@;`AN -M0`%`07J11XU,'X@\` -M(%`A,`\`!,@8`!@`#@#_&0+BX;P8`!@`[[P(``T`$``,``$4`!X'R0T`%F[K -MO.N<#`"ZO`T`"&151>U:`61510`>#,CT0`X`@!OU0`AD544!:NU*`61510N] -M_$`.`(`;_4``8`AD547M0`%D544!``%@@6(3@B$Q`LG-L@#J`N(6O5D.&U'G -M&1M!#U'?&0]!`6I62P5@I4``8!!B`Z0``%D/S`X@:E5+`&`S4`%J54L!'V'( -M`&`@:E5+,T`!:E5+.;W,6@$>5\A6Q57F*>)56@`>4<@#8(%B$X)70E9`^!D: -M6B`E`LD#&P-D@688@M0!("4"R=0!N(P:6B`E"LE74E90^!D%&P-D@688@M0! -MU`&XC%=25E`#9(%F&(*.O01@@6(3@E="5D#^&0$;!&2!9AB"!6"!8A."E4*4 -M0/P9`1L%9(%F&(((:,$!N(R54I10_!D"&P5D@688@@AHP0&XC%=25E`$9(%F -M&(*54I10!62!9AB"_XF3N0`."^I+#U50!!%50`/B15":O4)0`A5)0'!0<5(. -M9!<`1%# -MDU`A,`/(&0`5OF%0`QD.`!D`&0`.``%D%0`!9(!FX4?A1>%!X4.GOH"^```& -M4,=`_8Z/6B$C!LDA(03(Q%HA(`W)`&2`9AB"`&`'4AD`&0`.``$;`62`9AB" -M%+D``+@!`&JO`0H?!LD4'PG)-Q\+R5>^#P`8`!@`&`!VO@\`&``8`':^#P`8 -M`!@`&``8`%V^`6JO`0\`&``8`!@`D$&10PMJDDO!#P````#2`9!5D5>26Y)1 -MO0$`'P/("0!VOB$@!<@`:@,?`LZ`&@D``1$(`#E0>:X!``!@$&)MK`!@$&)O -MJ0D``F2`9AB"#```8&%0V(\$&0!D8505``<9"AX"R/L9#@"H`0%D@&88@H(! -M#0"7`0@`N`$`:CE*/XX)``!D@&88@J@!_AD$&P-D@&88@@!@`&1)4%54$@#' -M#DH.`NJQOLI`$U'K0!11[$`54>U` -M%E'N0!=1[T`&4;!`!U&Q0`A1LD`!:E5+4U#1K@>Z!+=``:-!0`&D04`!I4%` -M`:9!0`&G04`!J$%``:E!0`&J04`!JT%``:Q!0`&M04`!KD%``:]!`0"N`1!J -M54M``0%J54L!`*X!0&I52T`!00$(:E5+`0`;6_X8&TL.`!@`&``8`!@`%0`! -M`````&"H`1D`!1\<6CG.0[\```!@J`$IX@```&"H`1M:&0`9KR2_(;\PORV_ -M*K\GOS:_,[\#8"$F*LD!8"$E)\D+8"$D),D)8"$C(JM1@T$`X4-%``&!K -M6B$B`LB1B-)`TT(`NQ@`&``@`!P`'``8`"P`)``O5!4`85I`&*H!%0`O0&A0 -M+D`!``E@*$%!4"A!"&!50>Y0*$'O4"A!`6!500IN`&`H08:?:%`H02!0(3,0 -MR#Y0(34-R!]0(#`*R0A@54'P4"A![U`H00%@54&GOV!0*$%A4`7B03`#R-I0 -MIK_;4"A!!6X`8"A!J9\@4"$S!,@^4"$U`LEA4"A!`&`H02Y0*$$O4"A!`&`N -M0"]``0`@8%5!MP%``4$!`1&^`0`!`0$!8%5!`0"W`4`!00$!$;X!``$!`0$` -M2%$H0=!!2%,H0]!#`0`9`!D`&0`9``$`&``8`!@`&``!`````````$@````` -M`!\X&`````#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^ -M_Q\`_O\?`/[_'P#^_Q\`_O\?```?.!4```!0````0``"``"`#S@`?A\2`@`` -M"0`!#S@`_A]@`/X_8`#^7V``_G]@`/Z?8`#^OV``_M]@`/[_8`#^'V$`_C]A -M`/Y?80#^?V$`_I]A`/Z_80#^WV$`_O]A`/X?8@#^/V(`_E]B`/Y_8@#^GV(` -M_K]B`/[?8@#^_V(`_A]C`/X_8P!\GV,DZ@(`$'Z.4P!\7V,@TP(`(&1`*`#^ -M?V,`_O\?(`$`(`1^CE,0_I]A("H`(``8CE,@`0`@!'Z.4Q3^GV$@)P`@`!B. -M4R`!`"`$?HY3&/Z?82`D`"``&(Y3(`$`(`1^CE,<_I]A("$`(``8CE,@`0`@ -M!'Z.4R#^GV$@'@`@`!B.4R`!`"`$?HY3)/Z?82`;`"``&(Y3(`$`(`1^CE,H -M_I]A(!@`(``8CE,@`0`@!'Z.4RS^GV$@%0`@`!B.4R`!`"`$?HY3,/Z?82`2 -M`"``&(Y3(`$`(`1^CE,T_I]A(`\`(``8CE,@`0`@!'Z.4SC^GV$@#``@`!B. -M4R`!`"`$?HY3//Z?82`)`"``&(Y3(`$`(`1^CE-`_I]A(`8`(``8CE,@`0`@ -M!'Z.4T3^GV$@`P`@`!B.4R`!`"`$?HY32/Z?80`8CE-$-`X00#(.$#PP#A`X -M+@X0-"P.$#`J#A`L*`X0*"8.$"0D#A`@(@X0'"`.$!@>#A`4'`X0$!H.$``8 -M3D$`-@40(($/.``8;D,@%0`@$/Z?8:`3`"`4_I]A(!(`(!C^GV&@$``@'/Z? -M82`/`"`@_I]AH`T`("3^GV$@#``@*/Z?8:`*`"`L_I]A(`D`(##^GV&@!P`@ -M-/Z?82`&`"`X_I]AH`0`(#S^GV$@`P`@0/Z?8:`!`"!$_I]A2/Z?840`3@M` -M`"X+/``."S@`[@HT`,X*,`"N"BP`C@HH`&X*)`!."B``+@H<``X*&`#N"10` -MS@D0`*X)!(#M"R"`#S@(&&X#J'Z.4Q`^#A"`D0`HH+DZ*!!^CE,0?HY#`*H` -M(*A^CE,```X0!`(.$`@^#A`0?HY3`(XN*!!^CD,(`.X+@-4`(/___W____]_ -M____?____W____]_____?____W____]_____?____W____]_____?____W__ -M__]_____?____W____]_____?____W____]_J'Z.4Q`^#A"`?P`HH/HZ*!!^ -MCE,0?HY#`)@`(/___W____]_____?____W____]_____?____W____]_____ +M`````````````````````````````````````````````````$D/Q@])#\8. +M`&\`;`!J!0%8&Y` +M`&!O0!I@HT``:E!++UOO&(`:+TL!8"A!`6`H06!@*$'18"A!`V`H00EN`&`H +M09R0!&[0;$`!*$&@D`!@*$$H00!@$&(+H`AJ54L?ZFA@D&+K@84!R$#)0A`8 +M(3<"R4!@(&"XL*H!%0#!0&E@D&+K@11XU,8`!@`\$*- +ML0%J54L(8&A5"&I52Q<`^-3&``8`/!"&0!@&8(!"&!50<%0GQD5`,%`1V"08NN!Y$#E0D)@D&+K +M@1D`&0#C0@%@@6+K@84!&``8`.9"J`$9`!D`&0`9``,9X$`!'PS).&"08NN! +MYT#H0A9@D&+K@3\9Z4`@L3=@D&+K@>=`Z$(68)!BZX$8`!@`Z4(`8`!DXU3I +M4!41$@#F0.M4$`"%`3\8`&"H`1@`A0$`$-&.Y%3E5A<``\\!:NI*YE#L5!`` +MA0$_&#`>`LPP:@!@J`$8`(4!`!#1CN=4Z%87``3/ZEH"&NI*`6I52Q9@D&+K +M@84!&``8``X`/QG:0#\8VTH!8(%BZX$8`!@`&``8``X``QE!,`/(VE!GL=M0 +M"&I52P!DSU07``?,ZEHA(!')(2$/R8VQ"&I52\%:(206R>I:(2`&R2$A!,DJ +M;)F/[K(&TRY;(2$"R("Q[K($X@%J54L1L@YLF8\1L@)LF8\(:E5+60X/4?P9 +M#T$```(;#T$;6P,:&TLO6_,8+TL0;I^1!6HO2P%@!&2!9O"!`61511]0"&15 +M12`P!\D!9"$Q`L@"9)`!MK'!4+J/#@``8@5D@6;P@0%D544?6B`@`\D$9!4` +M/D`(8%5!RU!_&0`1"@!``11 +MXU,!`.%'X44``.%!X4,!``````#L4.U2`1'L0.U""&!500!@ZD`!8%5!`&R9 +MCT!0!1\'R00?!RYKP`9(%FXD?B1>15XU>G1*A&A0$.``H?",D4'PG) +M-Q\*R6X?#\FEL@D`M8^4L@D`MH^4L@D`NX\0`!@`$`"TCY2R"0"[CQ``&``0 +M`+6/(2<"R`$5E++_9`]F%``.9!<`3LPF9`EF%P!*SG!`<4*X`0/BM(\/&6A` +M#.(A,`K)!.(&;)F/J[(4;)F/XFREC^ZR`6"!8NN!%N(A/_+(03($R`-D543` +MLD(R!,@'9%5$P+(`9%5$NX]@0KN/#@`#&6%`V+(`9%5$(3';R"$T(LD8`&!" +MM8\A,P/)0!O5LK\90QD@&V%`'U`@,`C)85#\&0\`DU`9`!4`84`+W6J]!.(& +M;)F/ZK(4;)F/XFREC^ZR<+D`:`%J54M9#M0!`6"E0`!@$&(#I```6`]9#\P. +M5^+4`0@/`6"!8NN!&0`9`!D`!AD!&X(!`V"!8N)#XD$``.118$#X&>-384(5 +M`!]:("`$R`-D@6;P@2)@TF+K@:)`(F329@!@\($`#@!@#6(*``1J`&X!8(%B +MZX&[CPX`_QD(``T`$``,``$4`!X&R0T`%FXVDPP`)[-N5&]6HU`0``@`#0#X +M0/E"%P`0S`L``14*``!D%P#=R`3!``\>;"6S]E#W4@$1]D#W0EBS`&#(0`!@ +M$&('H@``Q@]*#@!@`^)'4&"S1%`801E#2@_&#@[B'UH@(`;(`V2!9F!085+P +M@2)DTF:B4/"!`&!MN0,.@%#[&8!`@E`!&X)``&`30#=0_ADW0`3B!&R9CX6S +M%FR9CP+=B+,FM$A1:D!`,`3)``X!#J"W_!ET0+:/AP%(6VM*2%%L0$A1;4!P +M4'%2!&02`$,@!,@`#@$/HK>]`0\`4A#*CFM:(28"R`@1%P`$S0`/`0ZBMW10 +M03(0R+2/"1\"SKZS"A6XH[FW4+C0N""Y7[E?N0`.`0^@MV%0_!F"`3Y0!QD5 +M`#Y`.&I82P4/`M+.L[:W.0]5CP$.`@YP4'%2!&02`"A!*$,/42`;#T'1#M`. +M(&3/1\]%<%!Q4@1D$@`6:@@`:E",&8@?"<@)``)D$@`(%TKFP`:LQ*3K2M +MCT(!0P$7``/(3918M`,.5[2MCU:4SMUT4$`R"LD('Q3)B!\2R<@?$,E('P[) +MOK,!#FE00!MI0!A0:Z0``'JT>K1[M!>U%K4!#AA0=*0``'JT>K3HM.BT[;2F +MN710M(\/&7^DV+2/M-BTC[38M)NTOK.^LZ"TV+3)M(^TTK2/M+ZSOK-)Q@%D +M940,N@A@`V1D1(>Z"&[009B4%[5I4`@;:4!&QH^T`&!U0`,.:5`$&VE`&5`A +M-`G)#F`$9&1$A[H.;M!!KI07M09D940,N@)@9D`EN@O#:5`A,B;(&5`A-@+) +MW+1I4"`;:4`"8`5D9$2'NM!!T$$7M1E0(30"R,^T`P[8M`+&L;38M!E0(32[ +MR`+&L;38M!I:(23/R1:U&EHA(^')%K4:6B$DX,D6M1I:(2/#R1:U&5`A-`/) +M(3&P(;DA1*$$``2"59U`($6=`(K9J4(P9B!\.R$A1*$&> +M0$$U`\@$8,5`2%,H0Y]"9U`"$6=`'.?%4"$R&LD9Q@+32+46ZDL/```8404? +M$!<9&T%U4!4``^5`&ZZVP!NNMIT. +ME0^"`0]1WQF_&0]!D`&9B8&,*$'*M@!D@@&=#FE0(3(AR2$S',D#8!4`@@$` +M8!-0N8\5`**)@8PH08R,;+>VM[2/"Q$0:E5+A@%%`0%D546G4*A2!600`*H! +M!;V`V`"YN>V`F"BB2A!C(P`8&A0:5HA(P/((2'= +MR=SB<%1Q5AD`AP&%`0)@JT``8!!B7*X```!@55`0``@`O0&B$,J.#P`2`%E` +M6D((``)J54OH4.E2$@``9`-NZFPH02A#0`%!`1,`$95(0`!!!$4,`9'I0>U(1`!)!$T-\4'U2 +M$0`4015#?E!_4A$`%D$70P%HP0%)#QA0!!\@R&E0(3(NR"$U+,D`8`)3N8\( +M``!1`5.TCQ4`B&039A<``LX)`)!!D4-/8))!P0\`````T@&049%3V\.@XY#@O#!.(( +M;)F/J;<8;)F/Z&REC]F)[K(`TP7FZFREC]Z)M+>ON=F)[;SZ;*6/IKFN;`9N +M`P\#ZTA1P+=(44(!%P`#R+R7QK<##E[&&%`!'P3)`A\"R22XU&P&;DA1``'/ +MEP+=U;=/N`#360X"YMJW3K@`\P1@JD``8!!B;:T``-1@T$`X4-%``--" +MSE`!&\Y`T&P*;D`!0$'MEP/B1U3TMT14`0\!8*Q``&`08LRL``#.4/X9SD!9 +M#F%0_!F"`3Y0!QD5`#Y`58\08"A!*$-J4"A!:U`H06Q0*$%M4"A!KFP&;D`! +M*$$4F-1L!FY``2A!&9BD#P-@@8PH08R,60_,#FVY`-,IYFA0&0"%`9(0RHX# +MXD54+[A"5!``AP$050!F`&)+#P``$%$7``3+$@"%`4*XA0'_8!(`J@$0`(4! +MJ@&X`1(`5502`,8/2@X801E#2@_&#NV\K[EPN0%@2X^N;`9N`P\#ZTA16;A( +M44(!%P`#R%687[@##L8/2P\#XD=49;A$5!A1&5/&#A<`*,S-N&A:!&"M0.N^ +MJ`$9``7BA0%#?T54A[@9`!D`&0!A6A!D544A)@+)!!&&`4`!,!\"R`%B`6I5 +M2T)4$``/`&Q0;5(7``/*R&"0N!(``0!KB-)`TT+4;`9N2%$``9:8`-,UW3/F +M`L?!N`,.`/,'8*I``&`08FVM``#$8-!`.%#10-!L"FY%`4!+K)C.4`$;SD`! +M#P/B1U2WN$14!&"L0`!@$&+,K```SE#^&M"F"J0`!@$&)MK0```&`08@-J0$K$6B$@`LA=K]*IWHGMO*^YKFP&;@,/ +M2%%"`1<``\@CF2JY`PX`TS/F`L=9N4!0!1\%R0!@;$!M0%FY)`X`8'9`=T"! +M4"$R(,D/4(M`$%",0,10`1DM0,1"`&`08L&N````8!!B;*\```%@SE0/`$`9 +M%0"!C"A!C(P"8$!``&!L0&U`WHGMO`!@$&(XJZ^Y#P`0'P/(`P_!LZRS`PX` +M#W!0<5((9!(`#``RM@!@$&(@H`!@$&)!H6E0(30%R`!@:4`$8'NY`&`"Y@$; +M$UH"'A?(-UHA(!3(`.&=#@AN`&0H18:9&UOG&!M+=505``/E0!N2N<`;#UO? +M&+\8#TL"YP(;"L25#P+FH+F5#QANU`&>F754%0`!:E9+E0\!``]1WQD/03H. +M.0X`TP/FWHGMO`!F$%5+#P``$%$7``3+$@"%`;^YA0'_8!(`J@$0`(4!Q@]* +M#@/B7F#%N6QAJ@$2`%54$@`801E#2@_&#EM0(!M;0`3B"FR9C]:Y&FR9C^YL +MI8_MO``.`0X"#@,.`0``8%-`D;X`9DL/```041<`!,L2`(4!\+F%`?]@$@"J +M`1``A0%L4&U2(3\8R<8/2@X%XD=4$``#9/ZY1%00``5D$@"J`1(`5502`!A5 +M&5<7``/,&$$90TH/Q@X!`-1L`VY(40`!*$'0049!2%$``2A!T$%&00Z:"]UE +M4!RJ>K23M'JT>K38M-BTM+06M9BZYE#G4@$1YD#G0FE:`0^T5$A1*$'0049! +MM%2U5DA3*$/00T9#(28#R=1`U4(7``?)Y%#E4@$1Y$#E0@$.ME1(42A!T$%& +M0;=6L(]&0R$F`\G60-="%P`"R0$.N%1(42A!T$%&0;E6L(]&0R$F`\G80-E" +M%P`"R0$.`&X`;#7=9E!FJO.T>K2WM(.ZV+0!#P!J2%$H0?\?#<@%;DA1*$'_ +M'P+)`0XAW7*:`L(&:@$.@[H#9&9$M&P#;@$/,;IC4(6J>K38M`#KL$.?09T/ +M`O:+NIT."MUD4)&J>K1ZM'JTE[2MM,:T`+4Z#CD.<+D4Q)4/PHJONOY0_U(! +M$?Y`_T(!8,U`GU&P4PP``&07`/#)56"\B@#3-UHA(`+)G0YSB8&,*$&,C,U* +M`^;>B>V\K[D"Q)4/`-*M@#S#6"J0`!@$&)MK0``-[\$#M!L"FY%`4!+W9H&#LY0`1O.0!-0 +M0S`'R`[`=5IP'A3)`F!F0!'$=5!`'P[)];IP:G5*_KH":E5+KXX!:E5+FP^8 +M#T!@=4#%4"$R`\@##A&[`^)'5`>[1%0!#P=@K$``8!!BSZP``,Y0_AG.0(JV +M=5`@&W5`&U'G&1`;&T$/42`;0!L/00)J54M98,=!`6#&00%J54MP4'%2+&02 +M`!9J"`!J4(P9B!\,R)Y0#QG'0<9!T$$`8-!!"0`"%1AJ/KL)``!DQT7&10)D +M546`0(%"0F3+1=4/J@$@8!(``A6"0`%D544&;M1L0`''0<9!3IL"9%5%#6`" +M;D=L0@$H1=%!TD$!%<=%QD57FTE4*$5*6BA+!&Y(52A%T4'200$5QT7&162; +M#F#10=)!@5+'0X!0QT&!4@@``&#&00%@QD$!9%5%9U`($6=``F151<`8`&*H +M`1D`&0"&`1!N0`'%08>;`61512*V`61517!0<5($%6=4$@"P0Y]!T0\W4`$; +M-T`"9%5%`&*"4`P``�:";`61519T/5K;`&`!@J`$8`!@`#@"%`:\!$E"% +M`1D`&0":9!``N@$*`$`!`&(A(0_)AP$#&1<``\@`:@$`N`$9`!D``QD7``C( +M`6H!`!D`&0`9`!D`NKN`:G5*`0```!M1YQD0&QM!#U$@&T`;#T'1#@``T`\" +M:E5+66#$00%@PT$!:E5+`%`!4B!D$@`6:@@`!%`A-`O(`FY53]A0#QG$0<-! +M"0`"%1AJ^[L)``!DQ$7#10)D546`0(%"0F3)12!DS4?-12`1S$/,0=4/J@$@ +M8!(``A6"0-(/`O\.O```````````T$?01!L"&Y``4!!5)SG;+4!!&Y``<1!PT$!%*X!6ISA4,1!PT'@ +M4,1!PT&!4L1#@%#$08%2"```8,-!`6##0=$/`&*"4`P``LU:`61510`>!,D%;M0!H)Q'8-)B`6JHO`%@ +M@6+B0^)!Y%'C4P?B#P`@4"$P#P`$R!@`&``.`/\9`N*[O!@`&`#)O`@`#0`0 +M``P``10`'@?)#0`6;L6\Q9P,`)2\#0`(9%5%[5H!9%5%`!X,R/1`#@"`&_5` +M"&1510%J[4H!9%5%Y;S\0`X`@!O]0`!@"&151>U``61510$``6"!8NN!(3$" +MR:6R`.H"XO"\60X;4><9&T$/4=\9#T$!:E9+!6"E0`!@$&(#I```60_,#B!J +M54L`8#-0`6I52P$?8<@`8"!J54LS0`%J54L3O8IXE5:`!Y1 +MR`-@@6+K@5="5D#X&1I:("4"R0,;`V2!9O"!U`$@)0+)U`&2C!I:("4*R5=2 +M5E#X&04;`V2!9O"!U`'4`9*,5U)64`-D@6;P@6B]!&"!8NN!5T)60/X9`1L$ +M9(%F\($%8(%BZX&50I1`_!D!&P5D@6;P@0AHP0&2C)52E%#\&0(;!62!9O"! +M"&C!`9*,5U)64`1D@6;P@952E%`%9(%F\('9B6VY``X+ZDL/55`$$55``^)% +M4'2]0E`"%4E`<%!Q4@YD%P!%R$!0!1\HR`/B15""O4)0`15)0(%0(3("R8.^ +M"E`+4@1D$`"!6B$G`\DA)@/(!&28O2$@`\DA)0/("&00``@`85`#6B$B`\F_ +M&:&]0!MA0`90QT#1O00?&<@$6B$@!LD@6B$G`\E%4+"]0E`"%4E`85`#6B$B +M`\F_&;F]0!MA0(=4B%8&4,=`U+UP4'%2%&07``YD`<@#XD50R;U"4`$524!H +M6@!@K4#KOJ@!QT"%`2WBV+T$6B$@A0$HR=F.J@&/6B$A!LDA(P3(Q%HA(!W) +ME0$`9(!FX4?A10``X4'A0Y-0(3`#R!D`\+UA4`,9#@`9`!D`#@`!9!4``62` +M9N%'X44``.%!X4.#OER^```&4,=`V8Z/6B$C!LDA(03(Q%HA(`W)`&2`9O"! +M`&`'4AD`&0`.``$;`62`9O"![K@``+@!`&JO`0H?!LD4'PG)-Q\+R3.^#P`8 +M`!@`&`!2O@\`&``8`%*^#P`8`!@`&``8`#F^`6JO`0\`&``8`!@`D$&10PMJ +MDDO!#P````#2`9!5D5>26Y)1O0$`'P/("0!2OB$@!<@`:@,?`LZ`&@D``1$( +M`#E05:X!``!@$&)MK`!@$&)OJ0D``F2`9O"!#```8&%0M(\$&0!D8505``<9 +M"AX"R/L9#@"H`0%D@&;P@8(!#0"7`0@`N`$`:CE*&XX)``!D@&;P@:@!_AD$ +M&P-D@&;P@0!@`&1)4%54$@#'#DH.`NJ-OLI`$U'K0!11[$`54>U`%E'N0!=1[T`&4;!`!U&Q0`A1LD`!:E5+4U"M +MKN&YWK9``:-!0`&D04`!I4%``:9!0`&G04`!J$%``:E!0`&J04`!JT%``:Q! +M0`&M04`!KD%``:]!`0"N`1!J54M``0%J54L!`*X!0&I52T`!00$(:E5+`0`; +M6_X8&TL.`!@`&``8`!@`%0`!`````&"H`1D`!1\<6CG.'[\```!@J`$IX@`` +M`&"H`1M:&0#UK@"__;X,OPF_!K\#OQ*_#[\#8"$F*LD!8"$E)\D+8"$D),D) +M8"$C(JM1@T$`X4-%``&!K6B$B`LAKB-)`TT+:NA@`&``@`!P`'``8`"P` +M)``O5!4`85I`&*H!%0`O0&A0+D`!``E@*$%!4"A!"&!50>Y0*$'O4"A!`6!5 +M00IN`&`H06*?:%`H02!0(3,0R#Y0(34-R!]0(#`*R0A@54'P4"A![U`H00%@ +M54&#OV!0*$%A4`7B03`#R-I0@K_;4"A!!6X`8"A!A9\@4"$S!,@^4"$U`LEA +M4"A!`&`H02Y0*$$O4"A!`&`N0"]``0`@8%5!MP%``4$!`1&^`0`!`0$!8%5! +M`0"W`4`!00$!$;X!``$!`0$`2%$H0=!!2%,H0]!#`0`9`!D`&0`9``$`&``8 +M`!@`&``!`````````$@``````!\X&`````#^_Q\`_O\?`/[_'P#^_Q\`_O\? +M`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?```?.!4```!0 +M````-``"``"`#S@`?A\2`@``"0`!#S@`_A]@`/X_8`#^7V``_G]@`/Z?8`#^ +MOV``_M]@`/[_8`#^'V$`_C]A`/Y?80#^?V$`_I]A`/Z_80#^WV$`_O]A`/X? +M8@#^/V(`_E]B`/Y_8@#^GV(`_K]B`/[?8@#^_V(`_A]C`/X_8P!\GV.$Z@(` +M$'Z.4P!\7V.`TP(`(&1`*`#^?V,`_O\?(`$`(`1^CE,0_I]A("H`(``8CE,@ +M`0`@!'Z.4Q3^GV$@)P`@`!B.4R`!`"`$?HY3&/Z?82`D`"``&(Y3(`$`(`1^ +MCE,<_I]A("$`(``8CE,@`0`@!'Z.4R#^GV$@'@`@`!B.4R`!`"`$?HY3)/Z? +M82`;`"``&(Y3(`$`(`1^CE,H_I]A(!@`(``8CE,@`0`@!'Z.4RS^GV$@%0`@ +M`!B.4R`!`"`$?HY3,/Z?82`2`"``&(Y3(`$`(`1^CE,T_I]A(`\`(``8CE,@ +M`0`@!'Z.4SC^GV$@#``@`!B.4R`!`"`$?HY3//Z?82`)`"``&(Y3(`$`(`1^ +MCE-`_I]A(`8`(``8CE,@`0`@!'Z.4T3^GV$@`P`@`!B.4R`!`"`$?HY32/Z? +M80`8CE-$-`X00#(.$#PP#A`X+@X0-"P.$#`J#A`L*`X0*"8.$"0D#A`@(@X0 +M'"`.$!@>#A`4'`X0$!H.$``83D$`-@40(($/.``8;D,@%0`@$/Z?8:`3`"`4 +M_I]A(!(`(!C^GV&@$``@'/Z?82`/`"`@_I]AH`T`("3^GV$@#``@*/Z?8:`* +M`"`L_I]A(`D`(##^GV&@!P`@-/Z?82`&`"`X_I]AH`0`(#S^GV$@`P`@0/Z? +M8:`!`"!$_I]A2/Z?840`3@M``"X+/``."S@`[@HT`,X*,`"N"BP`C@HH`&X* +M)`!."B``+@H<``X*&`#N"10`S@D0`*X)!(#M"R"`#S@(&&X#J'Z.4Q`^#A"` +MD0`HH*$Z*!!^CE,0?HY#`*H`(*A^CE,```X0!`(.$`@^#A`0?HY3`'$N*!!^ +MCD,(`.X+@-4`(/___W____]_____?____W____]_____?____W____]_____ M?____W____]_____?____W____]_____?____W____]_____?____W____]_ -MJ'Z.4Q`^#A``<@`HH"\[*!!^CE,0?HY#@(H`(/___W____]_____?____W__ +MJ'Z.4Q`^#A"`?P`HH.(Z*!!^CE,0?HY#`)@`(/___W____]_____?____W__ M__]_____?____W____]_____?____W____]_____?____W____]_____?___ -M_W____]_____?____W____]_J'Z.4Q`^#A"`9``HH+XZ*!!^CE,0?HY#`'T` +M_W____]_____?____W____]_J'Z.4Q`^#A``<@`HH!<[*!!^CE,0?HY#@(H` M(/___W____]_____?____W____]_____?____W____]_____?____W____]_ -M____?____W____]_____?____W____]_____?____W____]_J'Z.4Q`^#A`` -M5P`H(%XZ*!!^CE,0?HY#@&\`(`@X#1#\_Q]@`'P_8&`%```$D$`(`'KA5P20 -M8`B!`0`@!`0`$2#]_R<$!@`1`'P_8"3J`@`$_B!`2`(-$`!\7V```@``3`0- -M$`#^GV!0"`T0`(0@0`3^($#\_R!@!`(-$`"`#S@``!\X:P$`````'SAO`0`` -M```?.',!`````!\X=P$`````'SA[`0`````?.'\!`````!\X@P$`````'SB' -M`0`````````````!@+\?____?____W____]_`8"_'____W____]_____?P&` -MOQ____]_____?____W\!@+\?____?____W____]_`8"_'____W____]_____ -M?P&`OQ____]_____?____W\!@+\?____?____W____]_`8"_'____W____]_ -M____?P:`OQ\0``T(`'K@5X'^_R<$@+\?____?PP`#1`$`&`(&`"`"`'^84`$ -M!@`0"`"`"S`(#1```"X(`/K@5P()`"`$`.X+"`!N"PP`3@L0`"X+%``."Q@` -M[@H<`,X*(`"N"B0`C@HH`&X*+`!."C``+@HT``X*.`#N"3P`S@E``*X)(($/ -M.$1^CD,$``X(`H`?$@@`+@@#@A\2#`".#Q``[@L4`*X+&`!N"QP`3@L@`"X+ -M)``."R@`[@HL`,X*,`"N"C0`C@HX`&X*/`!."D``+@I$``X*2`#N"4P`S@E0 -M`*X)5`"."5@`;@F(``X(`7[@KUP`3@E@`"X)9``."6@`[@AL`,X(<`"N"'0` -MC@AX`&X(?`!."(``+@B,``X($H`?$H0`#@@@@0XXJ'Z.0P#\[V/____[`($/ -M.`#\[VL````$`($/.`#\#V`````$`/SO8_____L`@0\X`(#O:P"!#S@`_`]@ -M````!`"!#S@@@`\X`"``"""`#S@`@``2@`(.$(0`#A````T(>`8.$`!ZX%=\ -M!`X0(0H`(`%^`$````T05!@.$%@6#A!<%`X08!(.$&00#A!H#@X0;`P.$'`* -M#A!T"`X0`J!?"0.@/PD,>`X0!!0.$`@2#A"(<@X0C'8.$""`#S@4.@X0```- -M$`P`+0A4&`X0`/K@5U@6#A`!"0`@7!0.$&`2#A!D$`X0:`X.$&P,#A!P"@X0 -M=`@.$`*@7PD#H#\)#'@.$`04#A`($@X0B'(.$(QV#A`4.@X0"+@`$""`#S@( -M`(T+((`/.*A^CD,$@+\?____?P``#0@!>@!0```-$`$-`"`$``X(`H`?$@@` -M+@@#@A\2#`".#Q``[@L4`*X+5`"."5@`;@F(``X(`7[@KUP`3@E@`"X)9``. -M"6@`[@AL`,X(<`"N"'0`C@AX`&X(?`!."(``+@B,``X($H`?$H0`#@@@@0XX -MJ'Z.0PP`#0@`>N!7*`!-"*$<`"``>N%7$`"-""(!`"``">!7@@T`(`@`@`L$ -M``X(`H`?$@@`+@@#@A\2#`".#Q``[@L4`*X+5`"."5@`;@F(``X(`7[@KUP` -M3@E@`"X)9``."6@`[@AL`,X(<`"N"'0`C@AX`&X(?`!."(``+@B,``X($H`? -M$H0`#@@@@0XXJ'Z.0P@`X`@!_M]@`(P#$!BV`Q``Q!,G`,04)H#$#``30@` -M>N%7`/[_8`$!`"`8!``0,`X-$`P.#1``A_\GD&4``("ZC`$(!`X0+``-"#`` -M30@!?@!``'KA5RP`#1`,``X0$`(.$!0$#A`8!@X0'`@.$"`*#A`D#`X0*`X. -M$"P0#A`P$@X0-!0.$#@6#A`\&`X00'@.$`*@7PD#H#\)`*`?"404#A!($@X0 -M3!`.$%!R#A!4=@X06#X.$!!^CE.`DCHH$'Z.0U``#@@!?N"O1`!."4@`+@E, -M``X)`I0?$@.2'Q(9?N2(`("C'Q``+@@4`$X(&`!N"%0`#@@2@!\2'`".""`` -MK@@D`,X(*`#N""P`#@DP`"X)-`!."3@`;@D\`(X)0`".#PP`#@A8`.X+(0,` -M(`#^/V`!>D%0,`0-$`(!`"`!_C]@-`(-$$``#0@``$`(`'KA5X$!`"`!_C]@ -M(`0`($0"#1`\`$T(!'X`0``%X%=```T0`@$`(#@`30A`!`T0`/K@5P$/`"`` -M``X(!``N"`@`3@@0/@X0@(K_+T0`30@`>N%7*`"-"($#`"`!?H)`*`@-$`!\ -M'V!8UP(`H($B*!!^CE,0?HY#-`!-"`!ZX5@`0`@`/X?80'^'V$`A$!0`!`$206!`%`!_M]@(/Z?9X`"`#```0!``((@ -M2`"%X%<&#`!`!H0@4`#^_V`#>N17`H`#4`%ZY&<"@B-0`($/./^%'Q@@@0\X -M`/X_8!``8`C\_V%@N/YA4`#\`1`!`````/Z_8`2*`1`(B@$0#(H!$!"*`1`` -M_,!H````#!2,`1`8B@$0'+0!$""*`1`DB@$0*(H!$"R*`1`PB@$0-(H!$#B* -M`1`\B@$00(H!$$2*`1!(B@$03(H!$%"*`1!4B@$06(H!$%R*`1!@B@$09(H! -M$&B*`1!LB@$0<(H!$'2*`1!XB@$0?(H!$("*`1"$B@$0B(H!$(R*`1"0B@$0 -ME(H!$)B*`1"H%G!)"`"*#X_R<$B`$1`?X@4`%^8%```0`P`92`"`&(01$`@0\X -M((`/.!#^'Q(@@`\X1_X?$B!ZX5<``(!@!0\`(`-ZX&<``(!@`0,`(``"0A`! -M?H)``WKB9_]_04!"_O\G``)"$`3^GV<`@F!@``$`,`"&84``AF%``()A:`C^ -MGV<`AB%@``$`,`""($``@B!``(8@:``$@1D`!(8?`WY!8``!`#```@(0!'Z" -M0*`!`"``>N%7``"`8`!ZX5?_?T%``8`/.``"0A``>N%7_W]!0"&`#S@!?H)` -MH/W_)P`"0A`@%0`@$/Z?8:`3`"`4_I]A(!(`(!C^GV&@$``@'/Z?82`/`"`@ -M_I]AH`T`("3^GV$@#``@*/Z?8:`*`"`L_I]A(`D`(##^GV&@!P`@-/Z?82`& -M`"`X_I]AH`0`(#S^GV$@`P`@0/Z?8:`!`"!$_I]A2/Z?840`3@M``"X+/``. -M"S@`[@HT`,X*,`"N"BP`C@HH`&X*)`!."B``+@H<``X*&`#N"10`S@D0`*X) -M!(#M"P@8;@,@@`\X!'Z.0P"#0&``_C]@@1,`("0(`"```>!'`?[?8(4%`"`& -M%*`8`?ZB0""*GE<`"@"`@@(`,``!`$``@B!(`(7@5P8,`$`&A"!0`($/.*`! -M`"``_A]A`?X?80"$0%``$`1)!8$`4/__OV`&%*`8`?ZB0""*GE<`"@"``?[? -M8(("`#```0!``((@2`"%X%<&#`!`!H0@4`#^WV`#>N17`@`#4`%ZY&<"`B-0 -M`($/.```(&`@@0\X__\?8``#X%?_?V%`#@(`(`"$@$``">!7____?X4&`"`` -M!>%G____?P&`#S@``(!@`(1`"``$0A`!?H)``/KA5___84`A@`\X`?X@0*#\ -M_R<`A$`(``7A9____W\!@`\X`H9````&@$$`^N%7__]A0"&`#S@`!$80(/W_ -M)P*&0`!$-`X00#(.$#PP#A`X+@X0-"P.$#`J#A`L*`X0*"8.$"0D#A`@(@X0 -M'"`.$!@>#A`4'`X0(($/.!`:#A!$`$X+0``N"SP`#@LX`.X*-`#."C``K@HL -M`(X**`!N"B0`3@H@`"X*'``."A@`[@D4`,X)(($/.!``K@D``!\(6+4"``"` -M#S@`?%]@4+8"``@!(0@"_B"``(``0``$`$`0!0`(((`/.`@!`1```!\(\*P" -M`""`#S@`#@`8```?"/"L`@``?`!@`/\``""`#S@(?@"(```?"/"L`@``@`\X -M!#X.$`##_2\`"!\(8KP"``)ZX%<,[OTG`+X/8`!\7V`,R0(`(`!7@OO_)Q4%@P@`B$`0#GK@5P%^`%`)``!0`(!!$""`#S@``$$0!#X. -M$("W_2\``>!G@0$`(`"&0A"@W_TG``A#$`",H1D`?-]A`,4"`&0'AQ``#&(9 -M9@F'$``0!%%D"T<)9@LG"6H+!PAL"X<(H`0`(``0Y&``$(1@`!`$8``:0D$` -M#*49`!8@00",9!D!_N-``(SC&!GZXU>*"@`@"O[CIP"<'$!P!8`(``GA5XOX -M_R=Q!8`(``GA5PGW_R=R!8`(`(G@5XOU_R=S!8`(`(G@5PGT_R=T!8`(``GB -M9P*)X5<"\O\G=@N`""#R_R=X"P`(;`F'$&H!AQ!H#X<09A.'$&05AQ``FD(0 -MH,7])P`60Q```$!@````4`!\7V$`Q0(```S#4`!\?V``P0(`$X4A"22!`0D@ -M#0`@`(JB4`#\@D``PP(`5`1B"``'X5<+"0`@501B"``'X5>)!P`@5@1B"`"' -MX%<+!@`@5P1B"`"'X%>)!``@6`IB"``,Y!@`C^%7B0(`(%H*8@@`A^-7"0$` -M(%P`8@@`@`%``7[#0`S^HD``$^-7B_+_)R"`#SA@`040``(`4``"`!@@@`\X -M``!!$`0^#A`@D?TO-/Z?80```&(`@N!A``2A80"B*%(@L3LH_*,-$``!X&<` -M',=1H@<`()W^?YH`2?XO(-4@*```P&$`@B!0H.@@*/S_34```>!G`0,`(`"^ -M#V``?%]@<,@"`*"[-R@7_BE`@/__)P```%`@C"8H^/\M0`CZYE>!`0`@^($- -M"``!X&>!#@`@`'Q?8GBS`@"510D(``'@9P$#`"``O@]@`'Q?8'#(`@`@LC!G@@0`("#S'2@`F@9@`#@/*``@"&"@ -MH1HH`)XG8*"(#R@`F@9@@`$`(``@"&"@GAHH`)XG8)4C212`E#LH``'@9X(+ -M`""@,/XO`!P'8("Y("C\@2T(H,T@*/S_34```>!G`0,`(`"^#V``?%]@<,@" -M`*"@-R@Z_BE`@/__)_R!#0@``>!G`0,`(`"^#V``?%]@<,@"`""<-R@\_BE` -M@/__)Z"1_2!G`8`/.`%^7Q#GL0(``'P? -M8`"````@5PP@`/Y`$`!\'V``$````%D,(`0^#A``^_PO`#+_+P`!X&>!)OTG -M`!T5*(`E_2<$/@X0H/?\+P``(&``?!]@`-@"`*"I_B\!_E]@``0?".RQ`@`` -M>N!7`'P?8``$```!`0`@@$H,*``>_2>`30PH`!W])X"L'2`$/@X0@.[\+Z!] -M!2@!!@`(`*,X*`-ZX%<"&?TG`";_+P]ZX(>$%_TG`-8%*(`6_2<$/@X0`.O\ -M+P!\/V!P!@(8`/.`"``!``?>!7``$```:`#SB`_A]`((`/.`"``!`$/@X0@,'\+P`9 -M%"B`=C@H`.W\)P!\/V`8L`(`(.,Q(`G^7V`$/@X0`+W\+P$$@`D`!"`("'Z& -M@0"8(&@"!(`)$'Z&@0"8(&@#!(`)&'Z&@0"8(&@@EQN!7`?X?8*`&%"@"``!0`-S^+P5ZX%>%TOPG@-_^ -M+P]ZX(<$T?PG`'P?8%BM`@"@M1`H`((@4(#._"<`?#]@W*\"``$$0`@@Q#$@ -M`GY!0`!\/V!PK@(``01`"*#!,2`"?D%`!#X.$("@_"\``*!A`00`"`!\WV%8 -MK0(`(P!'$`"$!@B@S?XO(@!'$`5ZX%>%`@`@@-#^+P]ZX(<#'`=@HZ<0*`." -M(%`@Z1(H`80&"(#!_"<``"`(``(?$!BT`@`$`"`(``(?$!RT`@`(`"`(``(? -M$""T`@`,`"`(``(?$"2T`@`0`"`(``(?$"BT`@`4`"`(``(?$/2V`@`8`"`( -M``(?$/RV`@`<`"`((```"``"'Q#XM@(````?$/"V`@``9AH@``@`"```'Q`, -M]P(`@-42(`0^#A"`AOPO``"@80`$``@!?B!0'_X`B``"`$```@`8``Y`&`'Z -M`&"A`@`@`82&"`1^(H``CH`8(`$`(##^?V`#_G]@`'S?89RN`@``'$%`!`0A -M"`"&H'`$"D$0`X0F"`'ZX&"`0`@('T3*``` -M`%``_D80(/(4*``N!7@GO\)P!\/V`0L0(``(@` -M"`&`'W``@(`0`'P?8````0"`I0LH`'?\)P0^#A``3/PO``"@80'^'V``?-]A -MZ;$"````1Q``!!\(Z+$"```!X&>"`0`@(&X3*````%``?D<0H/44*`":!F`` -M@`8(`7X`8```GQ`0L0(``'/^+P%ZX%!G`'S?85"H`@"!!``@ -M!_X?8`!\/V`@`8<0!#X.$(`L_"\``*!A``0`"`A^ -M((`"A`8(``(`:`!]X%<``0``(04`(``N!7`?G_)P!\/V!*`@``(+@V*`"^#V``GN=1`((@4"`!`"`! -MA&8(`?X@0`"'X%>*`P`@`((&0`0$0`@``@=``@0`"``!X5>!^_\G`?[_80$& -M1Q`!A$8(!/X&0"`P,2@"?B=``$#^+P5ZX%>%.?PG@(T4*`"?YV>"SQ$H`'R_ -M85BM`@!LB`8(H"82*`""(%"`/_XO#WK@AP0T_"<`F@9@(!80*`""(%``,OPG -M`'W@5P$!``"!Y_\G`'W@5P`"``"!Y/\G`'W@5P$"``"!Y/\G@.;_)P0^#A`` -M`?PO"00@"`+ZX%<`?+]A6*T"`*("`"```,!A````4!^`1A`@`0`@`((@4!^" -M1A`)!`<(``!?$"RQ`@!@A`8(``'@9X$!`"`$_@!H'X!&$``.(!@`!`<(`GK@ -M9P$"`"`(_@!H'X!&$``.(!@`!`<(!'K@9P$"`"`0_@!H'X!&$``.(!@`!`<( -M"'K@9P$!`"`@_@!H'X!&$`,$)P@9A`8(`(/@9P)\`&@!````0@(`(!F`1A#^ -M?P!@&8!&$``.`!@$!"<(`(/@9P)\`&@"`````7P`8/W___\9@$80``X@&`,$ -M!P@``>!G`?X`:`'\`&#^____&8!&$``.0!@1!"<(&H0&"`"#X&<"?`!H&``` -M`$("`"`:@$80YW\`8!J`1A``#@`8$`0G"`"#X&?"`@`@"'X`:!$$)P@`@^!G -M@@$`(/=_`&`:@$80``X`&`4$)P@`@^!G!'XA:`%\(6#[____&8)&$`".0!@& -M!"<(`(/@9PA^(6@!?"%@]____QF"1A``CD`8!P0G"`"#X&<"?`!H`0````%\ -M`&#^____&H!&$``.(!@(!`<(``'@9P+^`&@!_`!@_?___QJ`1A`*!"<(((0& -M"`"#X&<"?`!H!````$("`"`@@$80^W\`8""`1A``#@`8"P0G"`"#X&<"?`!H -M"`````%\`&#W____((!&$`($!PAR@$80``0?"/S7`@```>!G`04`(-]_`6`9 -M@$800X0&"`%ZX%<"?>!7`@````G^'V`"?!]@0````""`1A`"!`<((.G]+W*` -M1A`%>N!7A0(`(`#L_2\/>N"'`YH&8"/##R@#@B!0``0'"`X$)P@``%\03*<" -M``!\7V!-IP(```)!$`1ZX&<"@^!G`0,`(`'^'V!+_C]@`?Y_8`+^GV"@D"@""XH`H0&"`"W^R<$/@X0`(C[+P"]_2\%>N!7AK/[)X#` -M"BB`LOLG!#X.$*"$^R\``"!@``0`"`&$0`@@7`0H`OX@0(`W-R@#>N!7@JW[ -M)X"Z_2\/>N"'!*S[)X!J!"@`J_LG(-XM(`""(%``?#]@!+`"``$$0`B@GS`@ -M`GY!0`!\'V``(````-8*(```0`@$`(`(``1"4!=^X:<(`&`(`/*\8`"(05`/ -M?N&G#```"`#R7&``!@!0"W[@IP`*`4``<@!``(``$""`#S@```!0!#X.$"!R -M^R_\?X!@`'Q?8'BS`@"2"2$(`'R_80`$`````@)`!'Y@0`"0`1@`&^!7D@>! -M$*L#`""0`X$0````4)`!@1``@B!0!'YB0`"0`1B2!X$0`)O@5XL#`"``?%]@ -M<,@"``!\/V!W`0``H*HU*`"^#V"`__\G`!O@5XN.^R<`O@]@`'Q?8'#(`@"@ -MIC4HO/X_0(#__R<$/@X0(%W[+Q3^GV&`>N!7"P,`(`"^#V``?%]@+-("`""A -M-2B,_C]@@/__)P```$``#@`8`7X`:/Z!C1!I_A^``OX_8/[_34"@C2\H`(9A -M4````%`@E?LG%/Z?800^#A"@6_LO+/Z?80``H&$`@N!A```@"`0```@``B!` -M"(`&"``"($`,@`8(``(@0!"`!@@`@"!0%(`&"`"`(%`8@`8(`(`@4!R`!@@` -M@`!0`'P_8,JT!G -M`?X?8""`#S@"``!0!#X.$*`W^R\'_A]@()4@*`'^/V``!!\(7+4"``%ZX%<` -M?+]A(/8"``("`"``@`8(*WX`:"!=^R<`@`80@%8#**#?`B@!_A]@``@?""R] -M`@``?>!7(T(``(("`"`D_A]@H(H@*`""(%"@V@(H````4`"A`RB`]O\G!#X. -M$"`X^R]L_I]A]OY_0@``X&&`_C]B`'R_8>R_`@`%HT80!*-&$`>C1A`&HT80 -M":-&$`BC1A`@`0`@`!S'40%^QT$$>N=7"@\`(``:!T`4!0`(`GX'@@J!1A#` -M_TU`!/\&0`""(%`@K@`H`"!!0``!X&?@_TU"`@8`(`3_!D`!_C]@H*H`*``@ -M24```>!G@?7_)P"^#V``?%]@A-("`*!:-2@%_BE`@/__)P"^#V``?%]@A-(" -M`*!7-2@!_BE`@/__)Y[^'V`%@480!(%&$`>!1A`&@480":-&$`BC1A`@`0`@ -M!/[?80%^QT$(>N=7"@\`(``:!T`0!0`(`GX'@@J!1A#`_TU`!/\&0`""(%`@ -MF0`H`"!!0``!X&?@_RU"`@8`(`3_!D`!_C]@H)4`*`"@2$```>!G@?7_)P"^ -M#V``?%]@A-("`*!%-2@5_BE`@/__)P"^#V``?%]@A-("`*!"-2@1_BE`@/__ -M)\#_#4``GB=@(#<`*"#_1D```>!G`0,`(`"^#V``?%]@A-("`*`\-2@9_BE` -M@/__)P```%"@,?LG;/Z?800^#A"@`/LO:/Z?84/^7X(``,!A@/X?8`!\_V'L -MOP(`"8%'$`B!1Q`@`0`@`)JF40'^ID$$^N97"@\`(`">!D`8!0`(`OX&@@J! -M1Q#`_TU`!/\'0`""(%`@>P`H`"!!0``!X&?@_RU"`@8`(`3_!T`!_C]@H'<` -M*`"@2$```>!G@?7_)P"^#V``?%]@A-("`*`G-2@*?BE`@/__)P"^#V``?%]@ -MA-("`*`D-2@&?BE`@/__)Y[^'V`)@4<0"(%'$"`!`"`$_K]A`?ZF00CZYE<* -M#P`@`)X&0!0%``@"_@:""H%'$,#_34`$_P=``((@4"!H`"@`($%```'@9^#_ -M+4("!@`@!/\'0`'^/V"@9``H`*!(0``!X&>!]?\G`+X/8`!\7V"$T@(`H!0U -M*!I^*4"`__\G`+X/8`!\7V"$T@(`H!$U*!9^*4"`__\GP/\-0``<)V`@!@`H -M*/]'0``!X&!G@0,`(`!\ -M7V"$T@(``'P_8),!``"@`34H`+X/8(#__R<@_@=`_/\M0"!E_R\$_D9```'@ -M9P$#`"``O@]@`'Q?8(32`@"@^S0HS/X_0(#__R?X@2T(``)'$/R!+0@!`D<0 -M(/'Z)R3^GV$$/@X0(+GZ+R3^GV$`?!]B``(````!P&$`?!]@(/8"``)]YUN!G@B@`(!]_ -M"$`@@"\H='XH0*"^+"@"_A]@($\`*``!G`0,`(`"^#V``?%]@A-(" -M`"#G-"AZ?BA`@/__)P!\_V'LOP(`#/V'$``$````?!]@&9````+^/V`,_T=` -M(-,N*`"&85"@`1A`F@$80(`0`(`"" -M(%``_!Q`,N`"``("0```G@!`!`5`$`'^`$``#B`8!/K@5XO[_R<,H8<0`'P? -M8!F0```"_C]@#/]'0*#`+B@`AF%0()3_+_[_#4```>!G`0,`(`"^#V``?%]@ -MA-("`*#*-"B:?BA`@/__)_Z%#0@H@$80_X4-""F`1A`@`P`H`!P'8)#^'T`@ -M62\HHGXH0""]^BR_`@```>!G`0``4`)\ -M'V`"`````H%&$`!\7V!TT@(``OX?8`/^/V`"_V9`(!!G`'R_8>R_`@"B -M`@`@:?[_@87^'V`<@480(`(`(!3^/V`E_A]@'(%&$!;^/V``@T80H+8N*`"" -M(%``?%]@$,H"`$S^!T`"_C]@(((N*`"&85``?-]A;-,"``Q_!T`,_C]@(,(N -M*``$05`"_A]@`_X_8`A_1T``_V9`H.4N*``(@E`"_@=``OX_8`[_1D"@>2XH -M`(9A4!?^!T`"_C]@$/]&0"!W+B@`AF%0H&SZ)P```%`$/@X0`$#Z+P!\7V!L -MTP(```'@9P)]X%YU$" -M_>A7`0````$#`"``O@]@`'Q?8)S2`@"@:#0HXOX_8(#__R<````(`GK@9P)2 -M`"`9?@E`H/@N*.G^/V`@-RPH`OX?8"!?`B@`H@A@H+S^+PG^'V```>!G`'S? -M89#3`@"!`@`@`+X/8//^/V`@7C0H#']'0(#__R>@[0$H]/\-0``!X&>!`@`@ -M`+X/8/?^/V"@630H#']'0(#__R?XB4T(``X!&!!^((#TB0T(``(`0`A^`(@` -M#"`8"'X!D!!^0(#VB0T(`(+@IP`$`$`(?@"(``P`&`#R/&```."G`((<0""K -M$RCL_RU```'@9X$"`"``O@]@`7XI0*!,-"@,?T=`@/__)^R!#0@`?!]B',`" -M``-^X*<`\AQ@H&;[+P7^/V#L@0T0"_X?8/*!C1`#_@E``OX_8/+_34`@-BXH -M`(9A4"`$`"``FJ91Z($-".R!+0@`@>!7A@``(``%Z`D!_@9```Z@&0;ZYE>* -M&P`@!9H?4`&`'X``'@!``0%($``!2!`"_A]@`_X_8`!_1T``?VA`H)0N*``( -M@E`@D_XO"?X?8``!X&<"#P`@H,!G@@\`(/B)30@`#@$8$'X@ -M@/2)#0@``@!`"'X`B``,(!@(?@&0$'Y`@/:)#0@`@N"G``0`0`A^`(@`#``8 -M`/(\8```X*<`@AQ`H(<3*.C_+4```>!G@>?_)P"^#V`G?BE`("DT*`Q_1T"` -M__\G`+X/8!-^*4"@)C0H#']'0(#__R<`O@]@%WXI0"`D-"@,?T=`@/__)P$? -M2!``'T@0`*((0`!\`$`.X`(`,1Y`$#`>0!``H^AG`0``4`)\'V`"````"`%( -M$`7^'V`#_C]@!']'0`A_:$"@=2XH``B"4`!\7V`2R@(`3/X)0`+^/V`@"2XH -M`(9A4`!H*B@@#0(H````4)#^'T`@J"XHH?X_0*`*^B=$_I]A!#X.$`#4^2\` -M?/]AD-,"```!X&<"?>!7`0````$#`"``O@]@`'P_8$\!```@#30H#/]'0(#_ -M_R<``*!!`'P?8@[@`@`P?LA!`OX?8`/^/V``_T=``!IG0*!B+B@`"()0`OX? -M8`/^/V`"_T=``!IG0*!?+B@`"()0`*`&0#`$``@``!\0;)@"`(#J^2<$/@X0 -MH+OY+RS^GV$`@J!AH%G^+P`.`!@``>!G`0,`(`"^#V``?%]@L-("`*#[,RBZ -M_C]@@/__)R"+`2CT_PU```'@9P$#`"``O@]@`'Q?8+#2`@"@]C,HOOX_8(#_ -M_R?XB4T(``X!&!!^((#TB0T(``(`0`AZX(<$?`!H````_P5^`)``#"`8``/@ -M5P$#`"``O@]@`'Q?8+#2`@"@[3,HR_X_8(#__R<(?@&0``X`&!!^0(#VB0T( -M``0`0`AZX(<$?`!H````_P5^0)``#`$8``'A5P$#`"``O@]@`'Q?8+#2`@"@ -MY#,HU_X_8(#__R<`@N"G`/(\8```X*<`@AQ`H#P3*`":)F```>!G`0,`(`"^ -M#V``?%]@L-("`*#=,RC@_C]@@/__)R#6^2!G``HA -M"$$!`"`""@$(!`H!"`"!X%<)@`!0#`(`4""`#S@`$``8!#X.$`"/^2\`?!]@ -M(/8"``````@$>N!GUOZ_08*W^2=S_P9`(&0N*(W^)D"@HBLH`OX?8``$'PA1 -MM0(``WK@5P$!`"`1>N!7"P@`(*`&`"``BJ)0`/P"0#S``@``!0`(`OY"@`!\ -M?V`@X`(`_O\A0`"$($"@!``H`(1!0`'^`D``#J`8!?KB5POY_R>0_A]`H%8N -M**+^)D``J/DG``"?"%2U`@`"`&(````"0`$$``@`A^%G``H`&`$!X&``(`-0.P#`!`!?L=!`)X? -M4``*X!D">N=7"A,`("J+!@@"_C]@`!X`0/Z!C1``?!]@!M(``/[_34`@@BTH -M`(9A4`!\'V`^D````OX_8.;_34`@?RTH`(9A4`'^'V"@BO\O^/\M0``!X&<" -M!@`@`OX?8""(_R_T_RU```$`8@'N_R<`?%]@L-("``!\/V`)`0``H(4S*`"^ -M#V"`__\G`+X/8`!\7V"PT@(`H((S*(/^/T"`__\G\($M".R!30@`A`!```,A -M4`=^`(!!!``@`?X?8@`P^R^@T1(HZ/\M0"J+!@CH@2T(``(`4"J!AA``(`A@ -M('+Y)SS^GV$$/@X0H#KY+SS^GV$`GN=1`'R_83S``@`LBP8(`?[?8>:!C1`` -M?!]@!M(```+^/V#F_TU`H&,M*`"&85`@!0`@`"`(4O2!#0CX@2T(`(`@4`)^ -M"(``@`U`[`,`$`%^"$(`G!]0``S`&0)ZZ%<*$``@+HD&"`+^/V``'`!`_H&- -M$`!\'V`^D```_O]-0*!8+2@`AF%0`_X?8"!D_R_X_RU```'@9P(&`"`$_A]@ -MH&'_+_3_+4```>!A`?'_)P!\7V"PT@(``'P_8$4!```@7S,H`+X/8(#__R<` -MO@]@`'Q?8+#2`@`@7#,HH?X_0(#__R?P@2T([(%-"`"$`$```R%0!WX`@$$' -M`"`!_O]A@`G[+R"K$BCH_RU`Z($-""Z))@@`@`!0+H&&$`!\'V`^D````OX_ -M8"[_1D`@0RTH`(9A4*#6_R<`G@=@!#X.$(`.^2^/_O]!``'`80!\'V`@]@(` -M`GWG5P$````!`P`@`+X/8`!\7V"PT@(`H$DS*,G^)T"`__\G````"`1ZX&<" -M+_DG`?X'0*#9+2CW_C]`(!@K*`+^'V``"!\(++T"``'^/V``?>!7(T(```&" -M(%!]_A]@`_X@0*`D`"@`'$=@H`$`(`":IE$!_@9```Z@&0/ZYE<*"0`@@)O_ -M+P`!X&>"!``@@,'_+P`!X&``'Q?8#S``@`J -M"P$(`/P@0`[@`@`(@(`0+@D!"`J`@!"0_A]`H,`M*(+^/X``%/DG!#X.$`#C -M^"\`?']@/,`"```!X&!7(T(```(#`"``?%]@D,@"``'^ -M'V`"_C]@H.XL*`"&85`!_@A`#/X_8!#_1D`@["PH`(9A4!?^"$`$_C]@)/]& -M0*#I+"@`AF%0//X(0`3^/V`<_T9`(.!7(T(```3^'V`"?!]@`P````/^ -M/V``_T9`"/]F0*`J+2@`"()0`'P?8!?2```"_C]@%/]&0""^+"@`AF%0:?X? -M@`+^/V`6_T9`H+LL*`"&85"`&BDH@*[X)P0^#A``A_@O`'R_82R]`@``B"8( -M:?[_@0#]X%=G(/X?8`)\'V`B````!(%&$`#]X%"AO@GH-?_+P":!F"@^?PO"?X? -M8``!X&!7(T(``*)`_R\"F@9@`+K^+P!U^"<$/@X0@%+X+P`` -MX&$`?+]A4+8"``B!!@@!>N!7`!S'4:)T^"?]_C]"DOX?0*`<+2@!_BA`@'7Z -M+P5ZX%>%`P`@@/X.*`MZX%>&`0`@*_\(0*`4`"`0_BA``?[?88"$+R@(@08( -M`GX`@``:`$`2!0`(`7KG5PB!!A#!YBXH`?X?8`!\'V(PO0(`H"W_+P``"`@@ -MD/\O```("`!\/V`.X`(``(H`"`*`@!```!\02)@"``B!!@@"?@"``!H`0!,% -M``@(@080($`<*`+^'V`!^N=7`7P?8%BM`@"A/@PH`8(@4`%ZYU!G`00`(`"^#V``?%]@+-("`*!C,BAA_C]@@/__)R!(^"!G -M`3KX)P"^#V``?%]@+-("`"!3,BC>_C]@@/__)P0^#A``"?@O`(/@9P!\OV!@ -MOP(`@0$`(!R!(@@`@^!G`@,`(`"^#V``?%]@+-("`*!+,BAW_C]@@/__)P($ -M0`@"?D%0``Y!&*`?(B@%?@!`H`T;*`#_`D```>!G`2OX)P"^#V``?%]@+-(" -M`"!$,BA\_C]@@/__)P0^#A`@_?"`P`@`'Q?8$#2`@``?#]@ -M%P$``"`^,B@`O@]@@/__)P($(`@"_B!0`(Y`&`5^`$"@$2(H]/\M0/R)+0B` -M^N!G`OP`:`#_``!"`@`@_(&-$`".`!C\@8T0`(X`&!!^((#ZB0T(`'R_80[@ -M`@```@!```P@&`"`AA```A\01)@"`"!5_B\!_A]@`WK@5XP!`""`T@`H`(H& -M"`2`AA"3_A]`(,`L*)[^/T"@)?@G(/Z?800^#A``[/T+*`&"(%"0_A]`(+0L*#]^*$"`"/@G`'Q_8`[@`@"@`P`@`((@4(#^ -M7V``A@!`)`1`$"H$0!`!_@!```X@&`;ZX%<+_/\G``@?""R]`@``?>!7(T(` -M``("`"``@B!0"(*!$"`"`""`_A]@#OX_8`B"@1"'_A]@"H"!$`R"@1`.@($0 -MH`0`(````%`"?B"```B"4`"&0$`0"($0@/X_8!("@1`!?@!```X`&`5ZX%<+ -M^_\G(/X?8#"`01`Q@$$0,H!!$""`#S@S@$$0``'@9P)\7V"(R`(``7Q?8(S( -M`@``?!]@%](```3^/V`@]BL@`(9A4`0^#A`@P__T9`(-DK*`"&85"@W_!7(T(```(#`"#X@0T(@/X_8`@:@!`*`H`0#!J` -M$`X"@!"1_A]`H$\L*"E^)T#\@0T(]($M"*`<""@,?@!`H++W)R3^GV$```!` -M``!?$"J[`@``@`\X!#X.$("&]R\```!B`()@8@"B*%(@%@`@`)[G40+^OV$# -M?@=``GX`D``*(!@`>N=7"H(@4/G[X%<+?#]@^?___P?^`$``#@`8!7Y`@`/^ -M!H``!`!``WX`0`"HIT$`J(="``!*$`+^`(````=0`H`_4`"*`!@1>N!7"0-) -M$`L#`"``?#]@:0$``*`X+"@+_A]@$/X?8`D!21``>N!7B@(`(`O^'V`@-2PH -MM_X_0````%`)`4D0`"H`0!`%``@!_BA"`8!&$`+^YT$%^NA7"A@`(`!\GV(@ -MNP(``R+(`0!\7V*`P`(``GKG5P!\OV*\TP(`#`(`(`+^'V``(HA!``!&$`+^ -MWV&U>^=7B@$`(+7_WV$`(HA!`!Q&$-A[YU>)W_\GR'OG5PP)`"``_`E`;-4" -M```'(`@0!P`(`GX`0`"``%``"L`:$'X'0``L`$``"L`9!?X?8"`?+"@`HBA@ -M!?X?8*`=+"@`+"M@H-;_)P/^OV'">^=7"9JF4:D!`"`>?@=``?Z_82Q^!T"@ -MTO\G``K`&8```"B`)V`@H@TH__]-0``!X&<`?#]B(+P"`('U_R<`O@]@`'Q?8-C(`@`@7C$H -MH?X_8(#__R<@5/!7($(```$^`2``!!\(4;4"`!)ZX%`Q?\G!#X.$(`,]R\`?!]@ -M(/8"``````@0>N!G`'P_8LS5`@""+O!G`'S?80#!`@`"(@`@`)?E9T$!`"!JA`8(:X0& -M"````$``'`!`/`4`"'"`!A!T@`80;(0&"``<`$"H!0`(>(`&$#@%!PA*>N!7 -M1'YG0`)\9T`(`````(8!"`P'!Q!\@`80$`4'"`+ZY5<"_>57`0````($`"`, -MAB$($89!"(2$!A`2AD$(@((&$(B$!A"@$``@$X9!"%!ZX%>,"P`@:H0F"`[^ -M0%``#B$8!_K@5Y"$1A"+`@`@'_K@5XH!`"`!_D!```XA&)"$1A``HB!`((<@ -M"`""0!@2!R<(``/A5PD#`"``@B!0C((&$(B"!A"$@@80(`8`((""!A`DAB$( -M*89!"(2$!A`JAD$(@((&$(B$!A`KAD$(H`$`((R$!A"`@"8($`4'"```?PA4 -MM0(`BX1!"`A^@8"*A$$(``AA:`",01@`!I\05.$"```*GP@.X`(`%`4'$!@) -M!Q`E?N&G"/Y^%7BP$`(-Q[X5=,+0`@`?Y_8-U[X5>+`0`@X7OA5\PJ`"`"_G]@ -MXGOA5XL!`"#F>^%73"@`(`/^?V#G>^%7BP$`(.M[X5?,)0`@!/Y_8.Q[X5>+ -M`0`@\'OA5TPC`"`%_G]@\7OA5XL!`"#U>^%7S"``(`;^?V#V>^%7BP$`(/I[ -MX5=,'@`@!_Y_8/M[X5>+`0`@!7KA5\P;`"`(_G]@!GKA5XL!`"`*>N%73!D` -M(`G^?V`+>N%7BP$`(`]ZX5?,%@`@"OY_8!!ZX5>+`0`@%'KA5TP4`"`+_G]@ -M%7KA5XL!`"`9>N%7S!$`(`S^?V`:>N%7BP$`(!YZX5=,#P`@#?Y_8!]ZX5>+ -M`0`@(WKA5\P,`"`._G]@)'KA5XL!`"`H>N%73`H`(`_^?V`I>N%7BP$`("UZ -MX5?,!P`@$/Y_8"YZX5>+`0`@,GKA5TP%`"`1_G]@,WKA5XL!`"`W>N%7S`(` -M(!+^?V`X>N%7*@$`(!/^?V``AF%0`)?E9R@'!Q`""0`@:H1&"`YZX5<+`0`@ -M('KA5PP$`"`A>N%7BP$`("MZX5?,`P`@`?Y?8"MZX557`@````'Z_R=0>N!7C"L`(`"7Y6<`!$%0 -M@@<`(&J$9@@._@%0``X`&`=ZX%<`HHA@"P(`(!]ZX%<+?`!``0````L.`!@` -M"`!`(`<`")"&1A`!?@!0D8!&$`'ZY5<"`P`@;(1F"`"B`4``!P`(D(9&$`%^ -M`%"1@$80`OKE5P($`"!KA&8(`*(!0!`'``@!?H!0``H"&)&(1A"@`0`@D(9& -M$)"$9@B1A@8(``2_".2O`@`#_($`++L"``'ZXE<"`@`@``9_""J[`@``!^)7 -M"H:!8)*(1A``">!7"P!@8`H(8F``">!7E(0&$*$"`""3AD80``?B5P(!`"`` -M"$!0E(0&$"`3%RB8_H9`D88&"(2`)@B4@$8(DX9F""`0%RB<_H9`D88&"(B` -M)@B4@$8(DX9F""`-%RB@_H9`D88&"(R`)@B4@$8(DX9F""`*%RBD_H9`D88& -M"'R`)@B4@$8(DX9F""`'%RBH_H9`@(`F"'"`!@IT@"8)>(`&"7R`9@B$@.8( -MB(#&"(R`1@DP`:<(`'S_80##`@``E^5GN/]'0"(%`"`T`8<(:H0&""%ZX%>+ -M`0`@*WK@5RP!`"`<_P=`@'X'0"`!`"`$`0<0!`4'$`"@`$``"B!`F(`&"`@% -M!Q```D!``)(#0``*($"<@`8(K(0&$``"X$``$@-```H@0*"`!@BPC@80``+` -M0``2!4``"B!`I(`&"+2,!A```J!``)`!0``(($"H@`8(``(`0`"7Y6>\@`80 -MH@X`(+B*!A!JA"8(()WX+P`$`6"L@"8(``(`0*R`!A"P@`8(()KX+VJ$)@BP -M@"8(``(`0+"`!A"T@`8(()?X+VJ$)@BT@"8(``(`0+2`!A"X@`8(()3X+VJ$ -M)@BX@"8(K(!&"``"H$"XB@80L(#F"+2`Q@B\@`8($`4G"%#ZX%<,*0`@@(`& -M"4UZX5>8@&8(20(`($W^/V``>N%7"@$`(`""(%"L@@803?KC5TD"`"!-_C]@ -M`/KC5PH!`"``@B!0L((&$$UZXU=)`@`@3?X_8`!ZXU<*`0`@`((@4+2"!A!- -M^N)720(`($W^/V``^N)7"@$`(`""(%"X@@8037K@5TD"`"!-_A]@`'K@5PH! -M`"````!0O(`&$)&&!@@`?)]@Z.`"``"0(4"@C?@O``A"8)&&!@B<@"8(A(!& -M"`"$($"@BO@O`7Y"0)&&!@B@@"8(B(!&"`"$($"@A_@O`GY"0)&&!@BD@"8( -MC(!&"`"$($"@A/@O`WY"0)&&!@BH@"8(?(!&"`"$($"@@?@O!'Y"0*`#`"`` -M@B!0`XA@``+^0(``?`%`_)@"```&`!`!_B!`!?K@5PO\_R>L@$8(L(#F"+2` -MQ@BX@*8(O(`&"`0!)PD`!(%``HAD``!\_V$@NP(``(9'$`"(A$`!!((("`$' -M"0&(1Q``CD-!`I3D`&J$)@@"CD<0`)3D0`&$XP@`C@4:`XY'$``,XT`"CL0` -M!(Q'$`".Q$`!!,,(!8Q'$`"*PD`"C*0`!HI'$`",I$`!A*((!XI'$```H$`" -M"@0`"(!'$``*!$`!!``(`'^G0`F`1Q``(`A@H#3X+P%_QT``!0<(:H0F"`"` -M1Q`!!0<(L(!&"`&`1Q`"A&<(`X2'"``@"&``?Z=`H"[X+P%_QT``!0<(:H0F -M"`*`1Q`!!0<(M(!&"`.`1Q`$A&<(!82'"``@"&``?Z=`H"CX+P%_QT``!0<( -M:H0F"`2`1Q`!!0<(N(!&"`6`1Q`&A&<(!X2'"``@"&``?Z=`H"+X+P%_QT`` -M!0<(!H!'$`$%!P@'@$<0P(`&"`%^`$"@EOXOP(`&$``#]B<$/@X0(-WU+RC^ -MGV$`?!]B;-4"``!\'V`@]@(`````"`!\OV&`P`(`$'K@9RC_YD&B8@`@R_X_ -M0@"9"2@``N!7`GW@5P(` -M``"!"@`@`WK@5X('`"``($)`(`)7"@"@8``$'PA0M0(```'@9P!\ -M7V#HX`(``@P`(`"&85"@!0`@!X?&"``*@!@`A(%!`(X`0#`'``@`"$80``'B -M5PP(`F``A(%!``!&$`'^84`%^N%7"A4`(`#\`4"\TP(`"`4`"````U``@>)7 -M`"#H8(GV_R>@]O\G`(J"8````%``?!]AO-,"``>'Y@B@!``@`*#`0`"*81@` -M!(!!``9&$`")X5<,AH%@``2`00`(1A`!?@!``!!@0`B%80@$>N!7`(9C4(H" -M`"``A^)70`>#"`GX_R<@^/\G`(IB8`"'XE<)BJ$8``2`05`'8P@`"D80`(?B -M5PR*8F``!(!!``9&$``*'P@.X`(``(IG"`"`(5$0BP8($HL&"0`2X*<4B^8( -M`)`+^O\G(/K]+P#_!D"@I_4G*/Z?800^#A``9O4O`'P?8"#V`@`` -M```($'K@9X*0]2>`,@DH`'K@5PD#`"``O@]@`'Q?8-C(`@`@J"\H@/X_8(#_ -M_R>`4`DH@%'^+X"*]2<$/@X0`%_U+P!\OV'DO0(``X4&"`%ZX%>"`0`@`(4& -M"`%ZX%%G`X%& -M$($&`"@```!0!(%&$```7Q!8GP(`((+U)QS^GV$,`"`(`/P`0.@!```4!``( -M``(`0*#F_R<>?@!`!#X.$"!#]2\@_I]AEOX?0"`5*BBU_C]@`'R_8>2]`@`! -MA08(`((@4""^"RC__TU```'@9X(*`""`!/8O``#@80&%!@@%@480H)@/*`"" -M(%`!A08(``!?$)2M`@``"!\(++T"``!]X%N!7 -M`C[U)P*%!@C_?P!```_@'R(\]2<"@480`-'_+P'^'V`@.O4G!(%&$`0^#A`@ -M$/4O'/Z?80``P&$```!0__K@5_R!#1`L!``@`(*@80!\7V!4T@(``'P_8-\! -M``"@3"\H`+X/8(#__R<`CD88_/\-0*`J+R@"_C]@_/\-0""V'BB`_C]@`'P? -M8-2^`@#\@4T(!/X_8``<9V"@.1XH`)J&8(`@`"`$/@X0H`#U+QS^GV$``,!A -M`(*@80"`!@C^_RU`H(N=7`1@`(``!X&<"`0`@`OK@5P(3`"#]A2T(H/<=*````%````!0`)HF8*!% -M'BC__TU`_X4-"``!X&*/__34#_A0T(``'@9X$(`"``@`8( -MH)(>*(#^/V`!>N!7`>C_)P"^#V``?%]@5-("`*`G+RBC_C]@@/__)P"^#V`` -M?%]@5-("`*`D+RB%_C]@@/__)Z`<]2<<_I]A!#X.$*#<]"\<_I]A``"@80`$ -M(`@@LRDH%OX?8````%"@!1XH`((@4`%ZX%N!7`0,`(`"^#V`` -M?%]@5-("`"`.+RC8_C]@@/__)P```%``@B!0(!$>*/S_34#\@0T(H'$>*(#^ -M/V```>!G`@,`(`"^#V``?%]@5-("`*`&+RC;_C]@@/__)_R!+0@@F"DH%OX? -M8`"$!@@@O_\O_/\M0"!F'BC\@0T(``'@9P$.`"`,>N!7!0,`(`"^#V``?%]@ -M5-("`*#]+BCH_C]@@/__)P)^`(``?$``>+("``"$!@@!_C]@`GK@5P&"(%`` -M!>%G@0$`(`!]X5<`!`(`!0,`(`"^#V``?%]@5-("`*#T+BCN_C]@@/__)R`" -M`3@`F@9@_($-"/O_+4"@.#,H^O]-0/J%+0B@KATH````4````%#\_RU`H/P= -M*/G_34#YA0T(``'@9P$%`"#\@0T((%(>*(#^/V```>!G@@(`(``L$"@``>!G -M`KX/8$)"+RB#_C]`(.#T)QS^GV$$/@X0H*GT+S3^GV$``,!A``0@""!V*2@8 -M_A]@(&WU+Y?^/T(``>!G@08`((#,,B@``>!G,/X_@((!`"`8@``(``'@9P$# -M`"``O@]@`'Q?8%32`@"@VBXHD/X_0(#__R<```!0(,`=*`""(%`!>N!7`0,` -M(`"^#V``?%]@5-("`"#5+BB1_C]`@/__)P```%``@B!0(-@=*/S_34#\@0T( -MH#@>*(#^/V```>!G`@H`((`2$"@``>!G`KX/8,(H+RB6_C]`````4*"S'2@` -M@B!0`7K@5P$#`"``O@]@`'Q?8%32`@"@R"XH`?XH0(#__R<```!0`((@4*#+ -M'2C\_TU`_($-""`L'BB`_C]@``'@9P(#`"``O@]@`'Q?8%32`@`@P2XH!?XH -M0(#__R<`!`<(('O_+_S_+4`!!`<(_84-"@`!Z%<.?BA`"0$`(``#X%<+`P`@ -M`+X/8`!\7V!4T@(`(+DN*!/^*$"`__\G_($-"/O_+4`@_C(H^O]-0/N%#0@! -M>N!7`0,`(`"^#V``?%]@5-("`*"R+BBB_C]`@/__)Z`1'BC\@0T(``&@80(# -M`"``O@]@`'Q?8%32`@"@K2XHI/X_0(#__R<,@.8)`)_G9P(#`"``O@]@`'Q? -M8%32`@`@J2XHI?X_0(#__R<#!`<(!H!'$`($!P@%@$<0`00'"``@(%`3A`<( -M``(`0!.`1Q`+!`<($8!'$`L$!PB_?T!@`7KA5Y]^(&`!!P`@@OK@5PL!`""& -M^N!7#`4`(*!ZX%<"?>!7X`````$#`"``O@]@`'Q?8%32`@`@FBXHMOX_0(#_ -M_R!G`BP`((#*#R@``>!G@2H`(`"^#V"@'0`@6_XH0(!D`R@``>!G(@(`(`'^ -M'V`@QQ0H!/X?8`+^'V`0@$<0^H5-"/S_#4"@7RXH`_X_8/R!+0B@F!TH```` -M4(!P]B\```!B`)H&8"`$#2CT_RU`````4!"`1Q#T@0T(``'@9X(=`"``(>AG -M`0$`(`)ZZ%>.&``@`+X/8`!\7V!4T@(`('0N*)G^*$"`__\G"P0G"*`%*2@: -M_A]@^H4M"*`O'2@```!0````4/S_+4"@?1TH\_]-0/.%#0@``>!G`1$`(/R! -M#0@@TQTH@/X_8``!X&>"#@`@`*T/*``!X&!V`@ -M4_0G-/Z?80%ZX%>!YO\G`GK@5P'R_R<`O@]@`'Q?8%32`@"@5BXHH?XH0(#_ -M_R<$/@X0("OT+T3^GV'"_A^#``!@8@""P&$`!$%B`(:A8@`(XF&@V/0O`(K" -M8@``X&*@EO@O&/X?8`!\/V(`B`(``'R?8GBS`@"0"0H*$/X?8``BB$$`'>=G -M``!&$*(#`"``(JA!`+X/8`!\7V!PR`(`($(H`(`(`Z"1A!`^N=G`0$` -M(/^!'W`!?@!``'P`8/__#P#\@0T0_(4-"!C^/V`5@$80_84-"`'^7V`6@$80 -M_H4-"!>`1A"4!0H(`8!&$`(B"`"@$RTH`"QK8""D]"\`K@M@(`WT)T3^GV$$ -M/@X0(-+S+R#^GV'\_PU`^/\M0"#J`BCT_TU`%/X_8/R!#0@@F_0O``*`$``` -MH&'\@0T(``!?")RP`@"@2!0H"OX_8*"9]"\`F@9@(`CT)R#^GV$$/@X0(-GS -M+S3^GV$`)$E2_*4-$`!\'V*,W@(````("``D7Q#2K`(`#`#@"2"?`2@`G@=@ -M'("G"9W^GYHPI$80,:1&$!R`)P@`?-]A6*T"`!&$``@@?@!H$8!`$!R`)P@2 -MA``(\W\`8!*`0!`$_A]@(H"'$%((!PA(@(805`@'"$J`AA`^!`<(``'@9P%\ -M/V)@L0(`P0D`($S^9D(!>N!7`0,`(`"^#V``?%]@7,@"`"#W+2@'?BI`@/__ -M)P!\/V)@L0(`0/\(0"`6'RA,_B9`(/X?8#"`1A!2_F9""OX?8"*`AQ``?+]A -MU*T"``&$1@@`F@9@`*8I8*#**"@"?D%``80&"#@`)P@"?@!```Z@&4,$!P@` -MID9`('0R*/S_;4#\@0T(`!H`0``.H!E`"`<(@'K@9P$*`"``?!]@Z*\"``$$ -M(`@"_D!```0@")SZX%?\A0T0`0,`(`"^#V``?%]@7,@"`*#@+2@E?BI`@/__ -M)Z"[*"@`IB9`_($-"``:`$``#J`90`@'"`)ZX&@I"@H`*8F0/R!#0@`&@!```Z@&4`(!P@(>N!G`0H`(`!\'V`0L`(` -M`00@"`+^0$``!"`(W?K@5_R%#1`!`P`@`+X/8`!\7V!@ -M@R@H`*8F0/R!#0@`&@!```Z@&4`(!P@@>N!G`0H`(`!\'V!"`P`@.``'"`"F)D`@!S(H_/]-0/R! -M#0@`&@!```Z@&2*(!P@`&@!`(H"'$*!6`2@*_A]@.*4($```"`B@B!,H`?X_ -M8!&$!PB??@!@`7K@5X$%`"``?#]@[)<"``"```@!?@!``(``$'3^'V"@$R@H -M@'XJ0#R!"`@*>N!7CAT`(`!\/V`HE@(``(``"`%^`$"@^S(H`(``$``!X&>" -M!0`@`'P_8/"7`@``@``(`7X`0`"``!!Q_A]@(`HH*(U^*D`@/`$H"?X?8``4 -M`"`\@0@("WK@5P$#`"``O@]@`'Q?8%S(`@`@<2THDWXJ0(#__R" -M`P`@```,"`%^`$`@?``H```,$''^'V`@/@`@.WXK0`!\7V)@L0(`/`$)"`-Z -MX%N!7-"<)$($$`"!P_A]@()4G*'-^*T``@`L(`7X`0`"`"Q`\`0D(!7K@ -M5P[O\B>`?3(H``'@9P(#`"````P(`7X`0```#!!Q_A]@H`0`((!^*T`\`0D( -M!WK@5P$%`"````P(AGXK0`%^`$````P0!G@@8`(/B! -M+0@+_A]@#(!`$`3^'V`.@(`0]($-"#R!)@@``@`0^($-"/R!+0B@-`,H#'X` -M0``#`"``O@]@("LM*/G^/T```0`@()4`*`G^'V`\@08("7K@5X$!`""@D@`H -M````4#R!!@@)>N!7`@$`(`"\_B\\@08(#'K@5P$.`"`@C@`H````4``,`"`# -M_(`!$&T```!\AD%$&P`````&.+>W`K&Q`@```'R_86"Q`@`\@08(#'K@5X(# -M`"!#!`<(``'@9P(!`"``VR`H/@0G"`+ZX%`"@)_A]@`(`&"""9$B@!_C]@$00'")]^`&`!>N!7`04`(`!\ -M/V`PE@(``(``"`%^`$``@``0`'P_8,$%``"@(R"`P`@`'Q?8%S(`@``?#]@ -M.P$``*"'+"@`O@]@@/__)P`415&@`P`@`03`"0"$H`@`C*)H`(I`$``.01`! -M!,`)`7Y%00`=Y5<*:/(G`'R_85BM`@``BJ)0(`$`(&B$9@D!_J)``)?B5XKZ -M_R<`%,!``@3C"`/^XJ=D@,8(?_XC80)R`P$`D>17@OK_)X#ZXV>!]?\G`'*C -M0`*$P@@!A*((`OKB5P'^_V`!\/\G`(2A"`",HF@`BD$0(/#_)P`.0A``@^!G -M@@4`(`W^/V`8`D`0!@0@"*`"`"#^_R!@"OX_8!@"0!`&!"`(`?X@:""`#S@& -M`D`0`?K@5P+]X%<"`````?O_)P"^#V`@Q"P@Q?X_8``$05`3!$`0"@1`$`0$ -M0!`#_C]@%@)`$!($0!`&_C]@'```"""`#S@L`D`0!#X.$*`K\B\`DB11`!S' -M40":IE$`$`11`)9E40`!X&<`CN-0H@,`(``415$`O@]@`'Q?8%S(`@"@6RPH -M]/X_8(#__R<`BJ)0`'R?8%BM`@"@!``@`03@"0",96@`CF$9`"'H9P*,9&@" -MCB$9`GS?80$````!_J)``)_B5XH/`"!H!&(*(`$`(``,PU`!?L-``"?C5XK[ -M_R<`"F!``H0A"@-^XZ=D``(*?_Y(8@)R:```!^E7@OK_)P&,?X``AF-H`)#A -M&`!R:$`"A,$(`81A"`+ZX5>`_@AB@>__)P`,96@`CD$9`"'H9P(,9&@"?+]A -M`0```*#O_R<"C@$90P0""`)ZX%=G`7P_80H````">N!7`9OF9P%\'V$/ -M``````7A9X$"`"!L#H(0'!!"$!L20A`>%$(0'19"$`"#X&>!)O(G(";R)P". -M@!`$/@X0`//Q+PUZX%<``*!A!0,`(`"^#V``?%]@7,@"`"`U+"C>_C]@@/__ -M)X"[\B\`&A\0G+`"`("\\B^`%_(G!#X.$`#K\2\->N!7``"@804#`"``O@]@ -M`'Q?8%S(`@`@+2PHS_X_8(#__R>`L_(O`'Q?8&"Q`@`\`2$(`(/F5X4``"`\ -M&P$0@++R+X`-\B<$/@X0(.3Q+R#^GV$`@L!A`((@4/^#31#^@TT0_8--$/R# -M31#[@TT0``'@9P":IE&B`P`@^H--$`"^#V``?%]@7,@"`*`>+"BR_C]`@/__ -M)___+4#]_TU`_O]M0*"/_R_\_XU``!WG9P$#`"``'`=@__\M0/O_34#^_VU` -MH(O_+_K_C4``?#]@6*T"`$.$0`@">N%7@@,`(/V%#0@``>!G`@(`(/N%#0@` -M`>!G(0$`(`K^?V#_A6T(`GKA5X(#`"#\A0T(``'@9P("`"#ZA0T(``'@9R$! -M`"`/_E]@_H5-"`"'X6>!`@`@&X0`"`"!X5%G@0(` -M(!R$``@``>%7`0$`(!R$0!`!_K]A`)H&8"#]\2<@_I]A`#X.$""^\2\<_I]A -MH_[?@0``H&$0@`T0M_X?8*"2)BA&?B=`M_X?8""1)B@`FB9@`)H&8/__+4`@ -M0S`H_O]-0/^%#0@``>!G`GW@5P$````"?>!7`@```($%`"``O@]@`'Q?8'#( -M`@"@]2LH2WXG0(#__R<2A`T(!GK@5P($`"`@!``@_H4-"``!X&>!_/\G`7K@ -M5P)]X%<"`````?S_)P```%"@G?,G'/Z?80`^#A"@J/$O'/Z?8:/^WX$``*!A -MM_X?8*!])BAJ?B=`M_X?8"!\)B@`FB9@`)H&8/__+4`@+C`H_O]-0/^%#0@` -M`>!G`GW@5P$````"?>!7`@````$#`"``O@]@`'Q?8'#(`@"@X"LH;GXG0(#_ -M_RN!7`GW@5P(```!![_\G_H4-""#N_R<```!0`'P?8"#Z`@``@`\X!#X. -M$*"C\2]$_I]A]/Y?0@`!H&$`?']B8JT"`*(#`"``@L!A`+X/8`!\7V!XR`(` -M(-0K*.#^/V"`__\G#(`&"J!9!2@`).A!('L%*`P`2!`7!"@(``'@9_[_`&`" -M_`!H`0```!<`2!`:"`@(```(0!P$(`@#_@!@`WK@5Z(B`"`"FJ91,/K@9P$# -M`"``O@]@`'Q?8'C(`@`@QRLH_OX_8(#__R?`^N!G`0,`(`"^#V``?%]@>,@" -M`"##*RC__C]@@/__)P``'PC(WP(`'00`"$!ZX&N=7"@"($(("`"``IBE@H*T; -M*"Q^"$```>!G@0,`(%!ZYU>"`P`@^O\I0""J&R@@?@A```'@9P(!`""@*P`@ -M%9I'$`'^'V#X@0T0_)L-$`">!V#X_RU`H,4N*`">1V``@`@(\/\M0/"!#1`$ -M@`@(]($-$`">!V"@P2XH^/]-0````&+X@2T(H#$F*##^'V`!>NA7`?X?8@(@ -M"%(U?PE`H"XF*)_^/T#P@2T(("TF*#5_"4#T@2T(H"LF*#5_"4"`>N=7#J!' -M$`(:`"``1!\(#-\"```!X&!G`18`(``$'PABK`(` -M``'@9_;_R4&"%``@`"'H9P()`"`(B`@("7X@@/B!#0@``^!7C@8`(`!\/V!H -MM`(`?($`"`%^`$!\@0`0@($`"`%^`$"`@0`0`?X?8!6`1Q`@=BTH`*((8(`` -M`"`5FD<0\($-"`!\/V"LL@(``(``$/2!#0@$@``0`7X(>`9^H($P_A]@H!,F -M*+7^/T!6""<(7@A'"/C_#4``AF%0(/Z&0"`G_2\`BJ)0H'+Q)T3^GV%6""<( -M7@A'"/C_#4`#_G]@``B"4*`B_2\`BJ)0`,__)P!\7V!DEP(``'Q_8$27`@`! -M^N!G`'R?8#27`@`"@`\X``0_")NM`@`!^N!7`@T`(!1ZX%>!`P`@"0D`(`IZ -MX%<"@`\X```""`%^`$`@@`\X```"$`0``@@!?@!`((`/.`0``A`(``((`7X` -M0""`#S@(``(0#``""`%^`$`@@`\X#``"$#=ZX%N!7`A@`(!0``0@!?@!`((`/.!0``1````$(`7X`0""`#S@` -M``$0!``!"`%^`$`@@`\X!``!$`@``0@!?@!`((`/.`@``1`,``$(`7X`0""` -M#S@,``$0$``!"`%^`$`@@`\X$``!$!@``0@!?@!`((`/.!@``1`<``$(`7X` -M0""`#S@<``$0(``!"`%^`$`@@`\X(``!$"0``0@!?@!`((`/."0``1`H``$( -M`7X`0""`#S@H``$0+``!"`%^`$`@@`\X+``!$#=ZX%-$0`@`(WQ+P```&(@ -MGAXH`)H&8`":!F``@B!0H.\+*/C_34`!>N!7@?C_)Q3^YJ<`\MQA`'S_8?#@ -M`@#X@0T(!```"``!X&>"WPTH`)P'0`3^/V"@=#`H`?Y?8`":!F``@B!0H.8+ -M*/C_34`!>N!7`OG_)Z"!\2\`(`A@`'P?8`L!``"@B"4H`)HF8`#M_R>`>_$O -M(*TE*```H&$`?!]@`/```(`6'B@@>_$O`)H&8"#H\"9G'_?_ -M!P'(\"<`?!]@]*L"``":)F`@RA(H``1!4`#%\"<$/@X0H)WP+P`$05```.!A -M`(+`80'^'V`@>PTH`?X_8``!X&=!PO`G"/X?8`0`!Q`,`*`)')P&$"#&`B@` -MF@9@'(`F"!"$``CX?P!@$(!`$!R`)@@0A``(`!X`:!"`0!`!_@=0``H@&!:` -M1A#_^^!7````4`*X\">@M_`G%H!&$`0^#A"@E?`O+/Z?80``P&$`@@!B`*(H -M4J!3\2_\HPT0``"@8:!^`"@`(`A@`'S_852]`@```>!G!($'$$$2`"``(@<0 -M`'Q?8E2[`@``)"!`_X8@"*"Q"RC\_TU`_($M"`"#X&>"`@`@"*%'$`"^#V"@ -M&RLH7OX_8/R!+0@$@``(``'@9P("`""@WO\O!($'"/R!#0@$```(```'$/R! -M#0@F(H`0```'"``!X&<"`@`@($/Q+P":!F"@`P`@`?X_8@2!!PC__S]@`"0` -M0/\"0!`@/_$O`)H&8`"B"&"@JO`G+/Z?800^#A`@;_`O(/Z?80``P&$`@J!A -M````4"`#`"#\@0T0__^F0?S_#4`$_C]@("8P*`'^7V``F^9G`0H`(/R!+0@` -M'`=@()<+*/C_34#X@0T(!```"``!X&!G`GW@5P0` -M```"?>!7`P```(+T_R?\@2T(`'P'0%2[`@#_`D`0````4*"9\"<@_I]A!#X. -M$`!9\"\`?+]AK.$"`!B$!@@``>!G`8+P)QR`!@@`""`(`(/@9X(!`""`7`8H -M```@8!R`!@@<`$`(``(?$,SA`@`0!`$(?W\`8*![\"<0`$$0!#X.$(!.\"^@ -M8@4H`(*@80!\7V#HOP(```DA"``#X%<`?/]@7-4"``$0`"```8$0H`(`(`"* -MHE``?0,0D@D```'^(D``CJ`8!/KB5XH+`"`,_N*G`/R<`%S>`@`"_B*```GB -M9P".P$"!^?\G@OY?0(+^?T`@!``@``<#$`-^((``A."G$/X\D`")X%<%!&%@ -M%'XA0`"00!@`?>%7D@D```S[_R<@\_\G``<#$`+^!H``#@!```$`"*!C\"<` -M$``8!#X.$(`V\"^@`_$O``"@81B$1@@!>N%G@0(`(`!\?V"HX0(``(@A"`'^ -M($``@H$0`GKA9P!\7V"LX0(``0(`(`@`(0@``@$0#``A"`0"`1`8`"$($`(! -M$!P`(0@4`@$0`((@4*#Z\"\8`D$0`%7P)P0^#A"@-?`O,/Z?82#U\"\``,!A -M```@8@'^'V`<`$<(^(%-$"0$`0@`?/]AK.$"`/J!31`6!@<($(0G"``.`!KY -M@4T0`(/@9_B!#0B!`0`@&(`'$*`!`"`-!``@&(0G"`"#X&!`0`@`(`!$*`"`"!_?P)@`(`A"`"``$`` -M@`$0@'X":!``01``(`A@(!(`*``<)V"@U_`O`*((8*!#\"!!0`@__OG5P$$`"``F@9``'Q?8*SA`@`$!"```)X'0`0$````@>!7 -MB0``(`":YF$`"J<9!/KF5POT_R>@)/`G`?X'0`0^#A``!_`O``#`80!\OV&L -MX0(``(`&"!R`(`@(@`80!(`&""V$8`HNA(`)#(`&$`A^AH$`'$="#'[GIP!\ -M'V)N!7`)AI:DD!`"`JA(`0*H:` -M$`#O*"@`)B!@!(@("``:B4$`@`!```"&$*`$`"``HBA2(.LH*`:(@0H`*`!@ -M`"8`0``:B4$``(80`?X(0``.(!H$^NA7BA+P)P`CYUB4!HH`J((8/^%#0@!>N!7 -M@@L`(/C_#4`@0O\O`?X_8/B!#0@,`"`('(``"``AX%>"!@`@`H@`"`B(0`@` -M`>%7"0$`(``%X6>"`P`@$(0`"`%ZX%!B@`'`=@@`,`(*`! -M`"`"_A]@`%@>*`'^'V``@`80H!G_+P&>'X"@^^\G+/Z?80P```@6!@`(`7X` -M0``.`!B@%?\G`8`?@`0^#A`@V.\O5/Z?80'^'V#X@0T0`'Q_8A2W`@``(`A2 -M`'S_85B?`@``?%]B!=@"``!\/V(`V`(``O[?80!\OV'IL0(``'P?8T2\`@`` -M?#]C6*T"``!\GV+TJP(`(`,`(`/^_V(`&Q#```@`*!'$!/ZX(<# -M`P`@`(0'"`1ZX% -M^N!G@14`("`#`"`!_K]BH%'P+P`L"V"@4/`O`"P+8`'^JD($^NI7#1$`(/R! -M#0@!JC^``('@9X'\_R>`2?`O``#`8@"J"F``@B!0(*T**/#_34`!>N!7@??_ -M)_"!#0@$```(``'@9PP`(`@!]?\G$H0@"`+ZX%<"_>!7`0````+]X%<%```` -M@O'_)X":#"@@1@LH`*H*8`"J"F``@B!0H*(**/#_34`!>N!7@O7_)X#K_R>` -M.O`O``"@8O3_#4`@XOXO`((@4`%ZX%<`@B!0@0$`(/2!#0@``>!G@@``(`'^ -M/V``C^`?`@<`("#!!2CT@0T(]($-"""1!RCX_RU`H#/P+P"J"F#T@0T(``'@ -M9P$#`"#X@0T(``'@9X'R_R<``0`@("_P+P"J"F#\@2T(&/K@CX&Q_R<'^N"' -M@P(`(``$#`@``>!G`0$`((`&!2C\@2T(!OK@AP.M_R<`JO\G!#X.$`!<[R\` -M`.!A`(+`80$$``@`FJ910'K@9P(N!G`0(`(`*(!P@,`*<)$'X`0``` -MAQ``F^9G`;X/8$'P*2CW_C]@`((@4`*"1A`#_A]@`(!&$`&"1A`#@D80#/X& -M0`">)V`@_/`O!/Y?8`&$!PB`>N!G`7;O)R`!`"@`'`=@@'3O)P0^#A``1N\O -M``&@88$&`"``$O`O`'Q?8+B\`@```2$(`(/@9X(!`"`$&P$0(`(`(``;`1`$ -M`2$(!!L!$`2:`!"`#O`O`(L**`!I[R<$/@X0@#SO+X`)\"^@8_\O``"@8:`* -M\"\`F@9@`&7O)P0^#A``-N\O#``@"`#\8$#H`0``'/Y`0!2$(0@`A&!``H0@ -M``"#X&<""@`@`80A"`3ZX%<.!0`@`+X/8"#2*2CN_C]`@`8`(``H`2B`!0`@ -M!'Y?$%2?`@``[/DO@`,`(`/\@`&LAP```'R&0>LA``````8X]0("`O<````@ -M5.\G`?X?8`0^#A``+>\O``'`81K^_YD"`P`@`+X/8`!\7V!N!7!@$`("!-[R!G`0,`(`"^#V``?%]@7,@"`*!:*2@/_B=`@/__)R!![R<` -M``!0!#X.$(`>[R\``>!AO?Y?F@(#`"``O@]@`'Q?8%S(`@`@5"DH'WXI0(#_ -M_R<,@`<(`'S?86"Q`@``?$!`Z`$``!Q^($`4!`$(``(@0@`$'PB5K0(`#WZ@ -M83P!!P@``>!G`?X?8H$X`"`&>N!7AC<`(`*(*`@@W2,HN!7#0@`(`2("`@``>!G`_X?8`)\'V`$ -M`````!#]+R`'$BA(?P=```'@9X$L`"``O@]@`'Q?8%S(`@"@/2DH/7XI0(#_ -M_RN!7`A4`(`+ZX%>-)``@-!\' -M$''^'V"@R2,H27XI0`2("`@``>!G`"`(4@(#`"!Q_A]@(,8C*$Q^*4`@`/TO -M`_X?8``(`"``N.\O``"@87'^'V`@PB,H57XI0`2(*`B@P",H!V"@8@\H"_X_8*"S[R\`F@9@(.X1*$A_!T```>!G@1,`(`"^ -M#V``?%]@7,@"`*`D*2AA?BE`@/__)P1ZX%!!@`@`+X/8`!\7V!97`@````*^#V#";BDH?WXI0*#][B<`(`A@!#X.$"#6[B\H_I]A``#@82#] -M\"\`@@!B(/[P+P``P&$">N!77/X_FH(!`""@3PXH``0("``I`"``!!\(*-X" -M``%ZX%<")P`@`'R_85RM`@`&A08(``'@9X(D`"`%>N=7A2,`(`!\WV%8K0(` -M$'X(0"`$&2@*?B=```'@9P$@`"````!0_X%-$*'^'V"@DR,H(/XH0(#L\"\` -M`"!@H)$C**'^'V!H@08(``'@9P$#`"``O@]@`'Q?8,3'`@`@^B@H)?XH0(#_ -M_R<8?@A`#(`G"&R!!A``_&!`Z`$``!J(0`@4A"$(:)\&$``"(5``?']@M-," -M`'"'!A``D"`8H!<:*&X(1PC_A0T(('K@5XH&`"!P@28(%(``""#'_"\H@"`( -M``#@87"!!@@@%0`H_X4M"``>`&@`#^`?`AP'8"*U`B@"@B!0`'P_8`CX`@`` -M@``(`7X`0`"``!"@K!$H3/\&0``!X&!G`08`(``$'PCTM`(```'@9P$$`"``?#]@7*T" -M`'R!``@!?@!`?($`$`!\'V`````!`.O]+R!-_R\`G@=@````4"#0[B!`@`@`@0` -M"`)ZX&>"!``@H`0`('__`6`&?@&``'P`0-BU`@`F"``(`'W@9]@/``""`@`@ -M@/X!:"``0A`@`0`@``Y@&`"*8F``A^)7`GP_8`$```"@H>XG`((`8`0^#A"` -M?^XO``#@80!\OV%@L0(`/($F""!,(RAX_A]@`)_G9P`N!7A0H`(``Y[R\```!B```` -M4#R!!A!X_A]@($(C*%7^*$`%?E\0D:T"`#R!1@@`G@=@(.0.*`O^/V`$_A]@ -M/($&$`!\'V````(`@+W]+Z`R[R\`(`A@``(`('C^'V"@.2,H8_XH0`'^WV&@ -MCNXG`!P'8`0^#A``8.XO``"@80`$(`@@-2,H(_X?8`"$)@@!_@!0('K@5^+^ -MWX$.(@`@H#$C*+K^'V``O@]@H/XGN/X? -M8*`L(R@E?B=``'P_8'BS`@"6Q0`(`7K@5P$#`"``O@]@`'Q?8'#(`@`@E"@H -M)GXG0(#__R<```!0EH%`%`!R_2\``>!G@G?N)Z!M`"@$_A]@`';N)[C^'V"@ -M(2,H,7XG0`!\/V!XLP(`EL4`"`%ZX%XG`+X/8*"Y*"@"A"8(`7Y?%`S?`@"@7/DO`)H&8`!E[B<@XQ\H -M`)H&8`#]_R<#?(`!8(\```!\AD'8(P`````&.`GP]?7U\[?UM]:]M\`)M_6W -MM[?XM[>WM_7U]?7UM_6W]0````!<[B<$/@X0H#;N+R3^GV$```!0_X%-$`C^ -M'V(`?/]A```@``!\WV%XLP(`"*`'%""V#"C__PU```&@80$"`"`@R?\O#(`& -M"""@#"@`F@9@ED4'"``!X&<"^O\G_X4-"``!X&>"^/\GH&#N)R3^GV$$/@X0 -M@"CN+P``X&$`?+]A8+$"`#R!)@B@]R(H>/X?8`"?YV<`',=1H@,`(!K^'YH` -MO@]@`'Q?8%S(`@"@7R@H(7XH0(#__R<\@08(#'K@5P((`"`@(_PO"?X?8'C^ -M'V"@[B(H*GXH0`5^7Q"1K0(``'P?8````@``;?TO/(%&"`">!V`@CPXH"OX_ -M8`#O"RB`!@`@>/X?8*#G(B@V?BA`/($&"`EZX%<.`P`@`+X/8`!\7V!&2@$?B=``'P?8-R8`@`@7!DH -M"GXG0`($*@C_A6T(`!P'8*!<""@`HDA@`!,`(`!\_V&`X`(`&/X'0`"<*4`@ -MH.\O`_Y?8`!\WV%ANP(``"!'$"`&`"#_A0T*&/[FIP">'$`>?@!``*0H0*": -M[R\`IDE@`?X&0``.H!D``$<0`*0)0``.0!H`)>A7#`8`(`"D"$`!!``(`GX` -M0`/ZYE<`#F`:B_;_)P"^#V``?%]@R,@"`*`E*"C/_C]`@/__)Z"9!R@`F@9@ -MH!GN)S3^GV$$/@X0@-[M+R!J%R@``*!A#/H&8$3^WX$"`P`@`+X/8`!\7V!P -MR`(`(!TH*`U^)T"`__\G"'K@5P)]X%<$`````0,`(`"^#V``?%]@<,@"`"`8 -M*"@1?B=`@/__)P!\/V```"```,0`"`3ZYE`@``@`<(`?X_8`!^`!0`?!]C0-X"````#`@``@`40X0F"*"$^R\`)`E@ -M(`$`(``HBE(`*D<4`.+O+PMZX%<",P`@`'S?843>`@``1`<(`8`_@```'PA( -MW@(``$``"``#X&`@`#?@""`*#F0@!\/V!!G`@4`(`"N"V`@`ADH -M7/XH0`*@!@`!>N!G(04`(`4$"0A_?P!@H`4`(`4`21``O@]@`'Q?8,3'`@`@ -MVB`?@!H!0!)$`;^'V`@`$D0```+"*#8#2@!_C]@$80H")_^ -M`&`!>N!7`@D`(`!$!P@`@"<(`8!?@`#```@`!`!H`(``%`"`!P@`0"`(H&(B -M*(;^'T``1`<(`(`I"`&`7X``P``(``0`:`"``!0@!P`@`?Z?8@/^`&`#>N!7 -M@@,`(`!$!P@`@"D(`8!?@`#```@`!`!H`(``%(`!`"!Z_A]@(%@B*#W^+$`` -M1`<(`7X`0```1Q0`1`<(('K@5P+,_R<`R_\G`7KJ5P'!)"A[_A]@(%(B*$[^ -M+$````P(`"H`%("N[2<$/@X0`'OM+P!\_V%@O0(`H*SO+Q"!IPD&>N"'@Z#M -M)X#S"2@``>!G`I_M)P";YFN!7`0<`(*#I#B@`'`=@ -M'``'"*!/(R@P?@!`(/$?*`":!F"`_A]@$@!'$`Z%!P@!?@!```_@'Z$!`"`. -M@4<0H/7_)P2`I@D`?%]@#,D"``!\/V#?`0``H*DG*`"^#V"`__\G!#X.$"!B -M[2\N_A]@`'R_8732`@`"_C]@7/]&0""6(2@`AF%0````4`3^/V!@_T9`H),A -M*`"&85`<_A]@!/X_8&3_1D`@D2$H`(9A4"#^'V`$_C]@9/]&0*".(2@`AF%0 -M)/X?8`3^/V!D_T9`((PA*`"&85`H_A]@!/X_8&3_1D"@B2$H`(9A4`!][2<$ -M/@X0H%#M+PC^'V``?+]A=,X"``""(%#X_T9`@/Y_8`+^GV"@,ADH`(JB4`C^ -M'V#*_C]@>/Y&0`+^?V`"_I]@("\9*`"*HE`0_A]@`((@4'S^1D`2_G]@`OZ? -M8*`K&2@`BJ)0``0?")3A`@``?%]@=-("``5ZX%<"?>!7!````(($`"``"!\( -M++T"``!]X%<@0@```@(`("#^'V`R_C]@(`(`(&I_04`@_A]@,OX_8&A_04`" -M_G]@`_Z?8*`?&2@`BJ)0!?X?8"+^/V"0_D9`D/Y_8"`!+2@`"()0`'Q?8)3/ -M`@`'_A]@`((@4&+^?V"@_2PH``B"4(!=[2<$/@X0H#/M+P+^/V``?-]A5I`` -M``!\OV%TR@(`&GX'0(#_1D`@9"$H`(9A4!]^!T`"_C]@@O]&0*!A(2@`AF%0 -M'GX'0`+^/V"$_T9`(%\A*`"&85`B?@=``OX_8(;_1D"@7"$H`(9A4"%^!T`" -M_C]@B/]&0"!:(2@`AF%0`GX'0`+^/V"*_T9`H%TO'/Z?80!\WV$-A0```'R_8730 -M`@`)?@=``OX_8);_1D`@/2$H`(9A4``*'P@8L0(`J(DF"`"``%#^@8T0#GX' -M0`+^/V#^_TU`(#@A*`"&85``'`=@`OX_8)K_1D"@-2$H`(9A4`5^!T`"_C]@ -MG/]&0"`S(2@`AF%0"WX'0`+^/V">_T9`H#`A*`"&85`,?@=``OX_8*#_1D`@ -M+B$H`(9A4`U^!T`"_C]@HO]&0*`K(2@`AF%0&'X'0`+^/V"D_T9`("DA*`"& -M85``?!]@!I<```+^/V"F_T9`("8A*`"&85``?!]@!($```+^/V"J_T9`(",A -M*`"&85``?!]@!8$```+^/V"L_T9`("`A*`"&85``?!]@`9$``!K^/V"P_T9` -M(!TA*`"&85``?!]@`*$``(#^/V`<_D9`(#$A*`"&85``?!]@0*$``(#^/V"< -M_D9`("XA*`"&85`6?@=``OX_8)C_1D"@%"$H`(9A4`!\7V`6R@(``'P?8`"4 -M```"_C]@(!$A*`"&85`@&.TG'/Z?800^#A`@VNPO`OX_8`!\WV$`E````'Q? -M8!3*`@``'`=@(`LA*`"&85``?+]A=,X"``%^!T`0_C]@Z/]&0*`>(2@`AF%0 -M#'X'0`+^/V"F_T9`(`4A*`"&85"`^>PG!#X.$*#)["\"_A]@@.,>*(!&`"@` -M!``H(.(>*`'^'V``\/\O@+S_+X!>'2B@`_4O````4(#P["<$/@X0`,KL+P!\ -M_V$/D```H)'_+VG^WX$`?+]A=-`"`"[^!T`"_C]@BO]&0"#W("@`AF%0*7X' -M0`+^/V#T_T9`H/0@*`"&85`B?@=``OX_8/K_1D`@\B`H`(9A4#;^!T`"_C]@ -M%OY&0*#O("@`AF%0-_X'0`+^/V`8_D9`(.T@*`"&85!?_@=``OX_8!K^1D"@ -MZB`H`(9A4`U^!T`"_C]@C/]&0"#H("@`AF%0#WX'0`+^/V"._T9`H.4@*`"& -M85`A?@=``OX_8.C_1D`@XR`H`(9A4"=^!T`"_C]@ZO]&0*#@("@`AF%0*'X' -M0`+^/V#L_T9`(-X@*`"&85`7?@=``OX_8/;_1D"@VR`H`(9A4"5^!T`"_C]@ -M^/]&0"#9("@`AF%0$7X'0`+^/V#\_T9`H-8@*`"&85!"?@=``OX_8/[_1D`@ -MU"`H`(9A4$-^!T`"_C]@`)I&8*#1("@`AF%0('X'0`+^/V`&_D9`(,\@*`"& -M85`S?@=``OX_8.;_1D"@S"`H`(9A4#I^!T`"_C]@"/Y&0"#*("@`AF%0`)X' -M8`;^/V`,_D9`H,<@*`"&85`D_@=`!OX_8`S^1D`@Q2`H`(9A4&U^!T`"_C]@ -M%/Y&0*#"("@`AF%0`'Q?8)#1`@``?!]@`-L``$#^/V`@UB`H`(9A4`!\7V`2 -MR@(`3'X'0`+^/V`@O"`H`(9A4("Q["<$/@X0((OL+XC^GV$`?/]A@*4``&G^ -M'X(`?+]A=,H"`$Q^"$`"_C]@G/]&0""U("@`AF%0H`,`(`""(%``@@!``(`- -M0)A]@!``?P```?X`0``.(!@T^N!7"_S_)P!\'V``H@``:/X_8)C_34`@Q"`H -M`(9A4*`%`"``',=1!GX'@`!\`$``I````!``&(#^/V`@_D9`(+\@*`"&85`! -M?@=```[`&01ZYU<+^O\G@/\'0(#^/V"@_D9`H+H@*`"&85``?+]A=,P"`,#_ -M!T"`_C]@(/]&0""W("@`AF%0`)X'8(#^/V"@_T9`H+0@*`"&85!`_@=`@/X_ -M8"#^1D`@LB`H`(9A4(#^!T"`_C]@H/Y&0*"O("@`AF%0`'R_873.`@#`_@=` -MA/X_8"#_1D`@K"`H`(9A4!A^"$`"_C]@I/]&0*"2("@`AF%037X(0$#^/V"H -M_T9`(*<@*`"&85``?%]@X-$"`#Y^"$`"_C]@((T@*`"&85`@D^PGB/Z?800^ -M#A`@5NPOI/X?8""[("@`@B!0`'R_873*`@"D_P9`+OX_8*#)("@`!$%0``@? -M""R]`@``?-]A```@``!]X%)9>PG`'Q_8#"^`@``@B!0!_K@ -M5XGY_R<#_@:```(`:(!^0&@`@@!```8`0`0%0!`!_@!`(/O_)P`.(!@`!!\( -MS+P"``"`#SB`_G]`0OK@5P'^/V`!@B!0"/X@@`"&0$`-_B&``'K@5PS```@! -M`@`@"(0`%````6@,@``4@`$`(``$`'`,@``4"(0`%`"`#S@`?)]@``(```!\ -M7V!XLP(```'@9PQ^(H`!$``@`?X?8(X!01`,P&`("(``%`'^`6@,@``4`$`? -M"!3?`@```>!G@0(`(`S`8`@"_A]@"(``%`+^`6@,@``4C`4!"`%ZX%<"`P`@ -M#,!@"(#^'T`(@``4`/P!:``!```,@``4C04!"`%ZX%>"!@`@#,``"`B(`!0` -M"`!H#(``%``$`"````!0C@%!$`S```@`?`!@_/[__PR``!0(_``4`P$```"` -M#S@``!\(,+T"``"`#S@$/@X0@`OL+X#-_R^`N/\O@#__+P"I_B\`T_`O```? -M"#"]`@```T>POH(<**```H&&@TNPO`)H&8``M["<$/@X0@`#L+X#-["\` -M?%]@K-\"````H0D`@B!0``(?$+#?`@"@S.PO`'X!$`";YF>!`0`@(,PGH"3L)P```%`$/@X0@/?K+X#$["\`?%]@M-\"````H0D`@B!0``(? -M$+C?`@"@P^PO`'X!$`";YF>!`0`@(+XD*`":!F``'.PGH!OL)P```%`$/@X0 -M@`?L+P``H&$`@D!BH+KL+P">YU$``"!B`$0?")R\`@`!>N!7V_[_0H(!`"`! -M_O]AH(H-*`'^'V`@M>PO!O[?8@```&(@<_`O./X?8`!\WV%XLP(`D`F'"@!\ -MOV(`B`(``"IJ0@`JBD$`+$80`)H&8`"F*6`@!R$H./Y?8``JJD(`K$H0&(0& -M"`-ZX%N!7,0%'$((!`"`!?E\0']\"```"`"`#>N!7`@$`(`)^7Q`> -MWP(```0?")NM`@`">N!7@@$`("`1`2@@A`8(((0I"(\#1Q24!0<(./X_8`&` -M21``A`D(`?Y?8*#S)"@`)&E@((3L+P`@"&`!^N=7H50-*`$``%"@@>PO`*(( -M8`#FZR<$/@X0@*_K+P!\OV&LWP(``(`&"``!X&>"V.LG```?"+3?`@```>!G -M@M;K)P!\'V#$LP(`H)$.*/__/V```>!G@?G_)P!\7V!XR`(``'P_8%X'```@ -MZR4H`+X/8(#__R<$/@X0@++K+P``8&(`@L!A``2A80"&06(`"")B(&[L+P"> -MYU$```!B`$0?")R\`@`!>N!7@@$`(`'^_V&@/@TH`?X?8``<'Q00WP(``!H? -M%!3?`@`!>NE7`?Y_8`*&85``I@E@`!PG8`":1F`0_I]@((;W+P"BJ&`!^N=7 -MH38-*`$``%"@8^PO`"`(8`#$ZR<$/@X0`)3K+P``H&$`@L!A8_X?8*!H("@` -MFB9@``0?",R\`@``@>97`0,`(``:7Q!YK0(``)H&8*#I$"@`'"=@@+;K)P!S -M]"^`M>LG!#X.$*"%ZR\&?D"``'P_8-BU`@``A`!!-@0D"#@"1!`W!"0((`\` -M*#8"1!"@K>LG-P!$$`9^0(``?#]@;+8"`&S_`$``!(!`-@3B""@$P@@!CA^` -M`!!`&+")H`@`C@-@``W@5PH&`"``!"%``)!`&``(/PC$K0(``7X`0`"$8&`F -M""((`((B8`"'X&<`#@`8`H`/.`#Y_R<@@`\X`(X#8`9^((``?%]@;+8"`&Q_ -M`4```H!`-@3B""D$P@@!CA^``!`@&+`)H0@`C@-@``W@5XP%`"``A"`8``A? -M",2M`@#_?P!```)A8"8(0@@`A$)@``?A9P`.`!@"@`\X@/G_)R"`#S@`C@-@ -M!#X.$*!DZR\&?D"``'P_8-BU`@``A`!!-@0D"#<"1!`X!"0(H.#_+S8"1!"@ -MC.LG.`!$$````%``?)]@;+8"`"`$`"!@!4((`GX@@`"&85``B"!`,(<`$`"' -M`!`!?@!```X`&``%X%>+^_\G`(`/.`9^((``?!]@V+4"```"0$````!0/`!! -M$#T`01`Z`$$0H`(`(`""(%#__G]@``(!0"H&0!`!_B!`#/K@5PO]_R<`@`\X -M'`!@"`!\GV!LM@(`"(0A"%``H@@&_D"`;'\B0`"$0$`V!"$(`H(B`"2"01`V -M!"$('`!@"!<"0!`2A"$(_O\@8!*"01`V!"$(5`!B"`*"00`<`"`($H0`"``` -M`6@@@`\X$H!`$`0^#A`@6.LO!GX@@```X&$`?#]B;+8"`&S_"$```F!"/81) -M"CR$J0D`&@E```Z`&J#V""@`G@=@KH4("`"!YE<`(`A2B0$`(*V%"`@``>E7 -M#&[K)S>$J0HVA*D).(3)"0```%`\@$D0/8!)$`=^"8"@+NTO`"@J8&"`B`@` -M`&!A`AH"``":24(`%N"G0/X<0`=^`(@`#B`9*@!)$`"J"4`J!"`(`)P)0"H$ -M``C_^N!7`?Y_8`*&85#_>N!7`?Y?8`($05``D^1G`@$`(`"KYE>"$0`@`)WF -M5X($`"``A^%G`0(`(`(J`@``@>17B@X`((`-`"``@^17"@T`(``,`"``J^97 -M`08`(`"'X617BOC_)X`#`"``@>17"@<`(``"`"`` -M@^17#`(`(``%X6>!_/\G(`0`(`'^'V(`@^17B@(`(``%X6<"`0`@`('D5XSX -M_R<"_A]B`"'H9X$/`"`!>NA7@@T`(""N_R\`G@=@``T`(`!\WV%8K0(`0P0G -M"`+ZX%<"_>!7`0````(%`""OA0@(`('E5X8#`"``"!\(!-\"``"!YE>,`0`@ -MH(3_+P">!V!#!"<(`(/@9X(#`""OA0@(`('E5R6!_R\%G@=@``$`(`)ZZ%!7BP$`(""J_R\`G@=@*A))$%"` -M"`@VA"D(`@(`````'Q`$]P(`@#/K)P;^@(``?']@;+8"`&S_(4``B(!`/`0B -M"`)^08``@"!`/`)"$``&@4`P`2((`(`@0#`#`A!D@2$(`(`@0&2#`1!H@2$( -M`(`@0&B#`1!P@&$(`(0A``"``$``A$%`((`/.````1`&?@"``'Q?8&RV`@`` -M!&!`J84!"`%^`$"I@4$0`OX`@``$($``@0`(`7X`0`"!`!!D`0$(`7X`0""` -M#SAD`0$0!GX`@`!\7V!LM@(```0`0*(%``@``"!`7``!"""`#S@$`@``!#X. -M$"#PZB\`"()0``#`80P`H`D`@B!B$81F"!R`Y@F@_D%@H'KA5P>$)@@A`@`@ -M"(0'"@'^`$``#B`8!X!&$)_^`6`!>N!7`GWA5Z`````"?)]@`0```!&$!P@( -M>N!G0@$`(`:$1@@%A$8(`(0`0`>`1A``"`%```X`&!>$1@B@UO\O`"`H8!&$ -M!@B??@!@`7K@5P$0`"``!%\(.+,"``>$!@@`!>!7`?X_8`H"`"``@D@0!/X? -M8"`E`"`2@$80`/Y($!*"1A``?#]@Y/<"``"```@!?@!``(``$""(!@@``#\( -MV+8"``%^`$``$&`8%X0&"`)^0(``A`````8`0`"$0$````$0^OX?8"">'R@` -M'"=@@!D`(`+^'V`2@$80`/Y($$"$!P@@B"8(`7H`8`'^($``D&`8%X0F"*$$ -M`"`"_D"``'R?8'SW`@```"((`(8@0``"`A```)\(U+8"`(`#`"``?)]@&/<" -M````(@@`AB!```("$```GPC0M@(```0B``"&($``!$)```(!$`>$)@@`?%]@ -MX/<"``'^8%```"$(`(8@0``"`1``?%]@`/@"````(0@"B&8(`(8@0``"`1`1 -MA"<(@/K@9P(!`"```>!G@@$`(!>$)@B@M_\O`"`(8"!E_R\`(`A@@-CJ)P"` -M#S@``#\(6-X"``"((`@`@^!G`H`/.(!ZX&<`?#]@;+8"``$"`""GD1\8L(&` -M$"`"`"`(_@!`L/V`$.3`P"!X%<4@P80"P@`(!B%Q@D9A08(&H4F"*"+["\!?@!``!WG9P". -M`!@"`@`@`?X?8!B!1A`@!@`@&8-&$``!X&<9@T80`@(`((`#`"````!0&(%& -M$!F!1A"@]?`O````4!MZX%<,`0`@``(`*("UZB<@M^PO````4`"TZB<$/@X0 -M((3J+P```%``"#\(++T"``#]X%!G@:SJ)X"T["\% -M>N!7!:OJ)Z"N["\!_A]@`'P?8```!`"`V/DO`*CJ)P0^#A"`?.HO`+3L+P!\ -MOV$0M`(`*84F"`'^($`/>N"'*8-&$`2DZB>`C`0H`GK@5X&BZB<`BP0H`WK@ -M5P&AZB&"``@H$T0*/S_#4``?+]A.+T"``"!!@C\@2T( -M`(`@4`2!!@@`@>!7C@,`(`!\'V`````!`+'Y+P'^'V`0@480_($-"`"!!A"@ -MD^HG&/Z?800^#A"`4NHO`'_L+P%ZX%>!R?\O@(/L+P5ZX%<`?+]A.+T"`(4& -M`"`.B08(`7X`0``0(!@.@880"(D&"`"!X%<"!@`@`*O_+R`[$"@`_P9````` -M4*`#`"`.@880$(4&"``!X&>!`0`@````4""F_R\0@480`,?_+X!OZB<`!#\( -MFZT"``"#X&!G`'R?8`C?`@"""P`@"/X_8&`#01#,?R%`4`(! -M$-1_(4!4`@$0W'\A0%@"`1"\?R%`7`(!$&1\`1`L]P(`:'P!$)#W`@!L?`$0 -M1)8"`'!\`1"PE@(`%?Z_8;1_(4!@`@$0H!@`(`3^/V`!>N!7@@L`(`3^/V!@ -M`T$0\'\A0%`"`1#T?R%`5`(!$/A_(4!8`@$0Z'\A0%P"`1!D?`$0'/<"`&A\ -M`1"`]P(`;'P!$#26`@!P?`$0H)8"``/^OV'D?R%`8`(!$"`,`"`#_C]@#/X_ -M8&`#01`L?B%`4`(!$#A^(4!4`@$01'XA0%@"`1`4?B%`7`(!$&1\`1!,]P(` -M:'P!$+#W`@!L?`$09)8"`'!\`1#0E@(``'R_86\!``#\?R%`8`(!$`C^/V`` -M@H$0H/DC*``*@A`@!``@`!S'40":!F"@*P`H`!PG8*"R_B\`'`=@`7X'0``. -MP!D`>N=7C/O_)P"H_B\"?E\0%K,"`(`TZB<<```)`'S_8&RV`@`(!"0(!OY` -M@&S_(T``A(!`-@1"""D$P@@!A#^``)!@&"`"`"!4@*,(`(1A&/]_(4``CD`8 -M``WA5PP#`"`F""((`(?@9P'\_R<"A"(``?K@5X+Z_R=0@",(`H0@`"0"1!`< -M`"`(%P1`$!*$``@!?@!H((`/.!*`0!`<`"`(`'Q_8&RV`@`(A"`(!OX@@`"& -M($"BA2`(`()`0%R`(0@$A"```_Y`@`(((`@`A."G$/Y`@``"``(``'@9P(``&$FD(40(#@9*`"2!&`VA$4(`80? -M@``1X&<"!P`@*80E"``#X5=+`@`@-H)%$"!,_B\`D@1@-H0E"%"`!@@"`@`` -M```?$`3W`@"@=_XO`)($8``/`"``!!\(FZT"```$/P@AL`(``('@5P$,`"`! -M^N!7`7W@5P(```""`P`@=(`&"`%^`$`#>N%7=(`&$(('`""@!``@!?X?8`+Z -MX%!7`0````(#`"!X@`8(`7X`0'B`!A`#_A]@(`(`(#:`11!\@`8(`7X` -M0'R`!A`@3/XO`)($8#>`11`@/?XO`)($8"#JZ2@!0!'P`0`,````"?@"0("8`(`Y^`$``>N!7#"@`(`YZX%<) -M)P`@(",`(`%^`%`(>N!7"P0`(!!ZX%<)`P`@"'H`4`1\`$`#`````GX`D"`> -M`"`2?@!`(GK@5PL$`"`P>N!7"0,`(")^(%`?_@"(``(`0``"`!@@&0`@%7X` -M0#1ZX%<+!``@0'K@5PD#`"`T>@!0!'P`0`,````"?@"0(!0`(!U^`$!D>N!7 -M"P0`((QZX%<)`P`@9'H`4`1\`$`#`````GX`D"`/`"`A?@!`D7K@5PL$`""9 -M>N!7"0,`()%Z`%`$?`!``P````)^`)`@"@`@+'X`0)MZX%<+!``@G7K@5PD# -M`"";?B!0'_X`B``"`$```@`8(`4`("]^`$"A>N!7"P<`(*5ZX%<)!@`@H7H` -M4`1\`$`#`````GX`D#%^`$```$$0((`/.````%`!^N!7`OW@5P(````!U_\G -M((`/.`'^'V`$/@X0($KI+XS^'V``?#]@B`0``"`A'B@%_K]A`'P_8%RM`@!U -MA0`(`7K@5X(!`"````!0=8%`$`;^OV&@;NDG`(X&&`0^#A"`2^DO1/X_@@!\ -MOV$(W@(`H(D%*``@"%(`?>!7__\``"$$`"``GN=1@'L%*```P&$@E"8H`)HF -M8`)ZX%=!`0`@`?X?8@":QF&,_A]@(!$>*#+^*$`0@`8(``'@9X(!`"`4@`8( -M``'@9X$$`"",_A]@H`P>*#;^*$``'`=@H"4E*``@*&`">N!7`G[@406>YU$@ -M7^DG`)X'8`0^#A``+NDO`/OI+P!^7Q!BK`(`(%4F*```H&$``>!G@0(`(`!\ -M/V!-!```(`(>*(S^'V"`)A4HH/?I+P":!F``4NDG!#X.$"`KZ2\D_I]A//[_ -MF8S^'V"@_!TH'_XG0(!7ZR\!>N!7@00`(`!4ZR\(>N!7`0,`(``T`R@">N!7 -M@0$`((`R`R@#>N!7`@\`((S^'V`@]1TH+/XG0`!\OV$(W@(`$(`&"``!X&>" -M`0`@%(`&"``!X&>!"0`@@.3I+P``P&$!?E\08:P"`!#^!D``FB9@('LF*/C_ -M34`">N!7`@(`(`"`!@@0@`80!(`&"!2`!A"`#A4HH-_I+P`G`)X<0`!\`$#0 -MR`(`"?KG5P`%0`JB!@`@`*9I4@IZYU<"?>=7"`````($`"!4_A]@H-8=*!/^ -M*D"`L?\O``!`8E/^'V`@U!TH`"0I8`%^"5`)>N!7#0D`(``>`"`!_A]B`?Y_ -M8@!^7Q!CK`(``'PJ:`````$`#@D8H`8`(``"`&@`?"I@_____@`."1@`@`!H -M`'P`:````0*``P`@`?X?8@!\*F#____^``X)&`"``&@`?`!H`````@"!!A`@ -MO.DO`*((8`%ZZ%<"!0`@`($&"`!\`&``_P``"'X`B`%ZX%<"?>!7`P````%\ -M'V````$``4#X+P"GZ6>!`@`@``,7*`![%RB@/?@O@/X?0`!K^R]1_A]@(+H= -M*``<)V!2_A]@H+@=*`">)V!3_A]@(+<=*``D*6`,>NE7`A#I)P"^#V`@?",H -M_?X_0``.Z2<#?(`!1+H```!\AD&1+@`````&.,_(R,B_P]#(R,@```0^#A"@ -MVN@OG/X_0```X&$@K1TH6/X?8("@Z2\`?']@\*T"``"!00@`?"%@`/\```C^ -MP(D&?N>G`)X\0`"&($`$A:`)`'Q!8/\`__\(_B:``(0@:*";Z2\`@P$05?X? -M8""C'2@`'"=@5OX?8*"A'2@`GB=@5_X?8""@'2@`FB9@!/KF5P+SZ"<`?#]@ -M9P$``*!D(R@`O@]@@/#H)P/^/V`8`D`0`OY?8!D$0!`/_G]@'`9`$'_^/V`; -M`D`0(@9`$",&0!`H!$`0+01`$#($0!`W!$`0`((@4"0"@!``@H!A*1A`$`A^ -MAHDJ&$`0+@*`$#,"0!`(_B"(-`)`$`!\/V#_`P``)@*`$`""@&$K&$`0"'Z& -MB2P80!`P`H`0-0)`$`C^((@@@`\X-@)`$`0^#A"`K>@O`'R?8`RN`@"@Z_\O -M3'\"0`?^/V"(`T(0`?X?8``"'Q"DF`(`H-7H)X\!0A`$/@X0H*GH+P```%`` -MG/\O`'R_80RN`@"(A08((!3]+X^%)@A,_P9`H+7\+P""(%``&!`@"@"0`@`((@4`""@$``B`%`&`C` -M"`S^X*<`BIQ!``P&$`@(``@`BEQ`"`"!$`2(`0`&`($0`(*!0!`$`@@$`($0 -M%`0""`H`01`!_@!```X@&`3ZX%<+]O\G`(`""`!\/V`,K@(`<(&`$`B(`@AR -M@8`0!(@""'2!0!`,@`((=8%`$`A^`(AV@4`0%(@""'>!0!`(?@"(>(%`$!"( -M`@AY@4`0&(`""'J!@!`@B`((?(&`$!R(`@A^@4`0)(`""'^!0!`(?@"(@(%` -M$"R(`@B!@4`0"'X`B(*!0!`HB`((((`/.(.!0!`$/@X0@(+H+P'ZX%=#_K^! -M`0,`(`"^#V``?%]@5,@"`*#$(B@1_B9`@/__)P!\'V`HL`(``(@+*``!X&_X? -M8"!)'2@U_B9`@)KH)P`$/PB;K0(```A?"!*Q`@"`7`@@!#X.$(!ZZ"\`!!\( -MU:T"```!X&!G`'P_8!BQ`@""`0`@`*"`$"`!`"````!0`(H`"("#$"@`GO4O``#@83P! -M!P@,>N!7`@D`(```'PCTUP(`$'X`0*"M$R@*_B9`(`K^+P'^/V)LB`8(H&'^ -M+P""(%`9A`8(,'X`:!F`1A!#A`8(``'@9P'^7V*!JA8H``H`(``!X&!G@00`(&[^'V"@!ATH=/XI -M0#@!!P@*_C]@H*D(*`">1V`@`0`@."$'$`!7]"\`"`8H`'(?*``W%BB@^Q8H -M````4``-`"```>!G`@,`(`"^#V``?%]@7,@"`"!I(BB&_BE`@/__)PSZYU`@``?+]A^-<"`""`0!`@_A]@!8!`$`"`!@A`_C]@ -M``)`$*`$$R@0?@!``(`&""`#$R@$?@!``#GH)P0^#A"`#.@O``0?"`/8`@`` -M?+]A6*T"`""`1A``!!\(!-@"`!F`1A`@20`H`?X?8``$/PCIO`(``(/@9SR$ -M!@@B`0`@`H(@4$.$)@@`*````%`@U?LO`?X?8``HZ"<$/@X0(/[G+X'^'V"B_M^! -M(-,<*#5^)T``!!\(_MX"```!X&<"!@`@@`L"*`)ZX%>!!``@``H"*`-ZX%!`0`@`#`$*`!ZX%>,!0`@@?X?8*#)'"A#?B=```2_"?BP -M`@```'NHO`7K@5X("`"``'^HO`7K@ -M5P(!`""`Y`N!7`A/H)P`;ZB\!>N!7@A'H)X'^'V`@O1PH -M87XG0("\_B\!>N!7@@[H)X'^'V`@NAPH9WXG0``*!R@!?E\0U[`"```+Z"<$ -M/@X0@-WG+P`2ZB\``>!G@0?H)P!\/V`"`P``H+,<*('^'V``?+]AV+$"`"#D -M"B@$_P9`)($&"`%^7Q#]W@(``7X`0"2!!A``?!]@```!`(`N]R\`_^!HH`)X'8(#^'V`2@$80(.WG)P!^!Q``?%]@#+`"`-@%(0@``^!7`8`/ -M.-@!01```>!G`@``4`%\'V`!`````!;_)P0^#A``P.!G`GW@5PD````"?>!7#`````$#`"`` -MO@]@`'Q?8%S(`@`@]2$H"GXH0(#__R<,>N!7`H0G"`(%`"``@^!G`OW@5P$` -M```"`P`@`+X/8`!\7V!"#0`@(`0'"%Y_`&!`?@!H(`!'$"2$)P@?!`<(`(/@9P)\ -M`&@$`````7P`8/O___\@"P`@'P!'$"`$!P@_?@!@H`0`("%^`&@@!`<(7WX@ -M8%((!P@5>N"'I`$`($'^`&B__@!@`7X`:"`$`"`@`$<0`7K@5P'X_R<">N!7 -M`?G_)P"^#V`@*2(H9GXH0(`)`"@X``<(;'XG0*!H]2\!_E]@,($&"``!X&<" -M`P`@`+X/8`!\7V!!G`@L`(`!\'V#XK0(`.(`& -M$&3\!A`,K0(`(`<`(`C^/V``?!]@"*X"`#B`!A!D_`80)*T"`*`#`"`$_C]@ -M`'P?8!BN`@`X@`809/P&$#"M`@`,_C]@(`4`(&B"1A`!>N!7@??_)P)ZX% -M`@``D^`@`@`P`@`(9A4/#^(&```B%H -M.@)"$`'^(4``CF`8``8@0`.$(`@`@^!G`(I!0`$&`"`$`D$0`(0A&`"*@$`! -M^N%G.@0B""+X_R<`!$`(#_X@8`1^08```B%HH/;_)P".(!@`@B!0!`)!$``$ -M(`@"!(`)`()`0`$$(`@(?H:!`)@@:``*`4`@@`\X5@*`$`!\/V"N!7@G/G)R`@^R\```!0(/0=*`'^'V`@`@`@$APHI/X?8(`"`""@$!PH9/X_@"`J_B\$_A]@`(D7 -M*`!M""@!?E\08JP"`(``^R\`!#\(FZT"`(`L#2@`7>,!``@#H4'"``!X&<" -M`P`@`+X/8`!\7V`,R0(`H&TA*`%^*4"`__\G#`"G"6+^'V`<@`8*(/X;*``< -M)V`P!`@(#'H@8($!`"#\?@!@2'K@5P(=`"`.A0<(``'@9P(#`"``O@]@`'Q? -M8`S)`@"@8R$H#WXI0(#__R?_?P!`#H%'$`'^'V``@`@0$80&"*!^`&"@>N!7 -M`0D`(*")""@`'`=@#(`&"``!X&B!@@0$`(/Q^`&!(>N!7`@\`(`X%!P@``>!G`@,`(`"^#V``?%]@#,D"`*`F -M(2@-_BA`@/__)_]_`$`.`4<0`_X?8!*`1A"@3@@H`)X'8`R`!@@``>!G`0\` -M((#F"2@``>!G`0,`(`"^#V``?%]@#,D"`*`=(2@=_BA`@/__)P```%"@"0`@ -M#(`&$`CZX%N!7@@0`("_^'V"@FQLH''XG0`'^'V`(@480`'P?8```(```&O8O -M@.OF)R_^'V`@EQLH)'XG0(`T'"@`Z>8G!#X.$`"YYB\`[N@O"GK@5P)]X%<) -M`````GW@5P0````"?>!7`P```((#`"`#>N!7`GW@5PD```#!J/TO"/X?8*#9 -M%R@```!0@"H<*`#=YB<$/@X0(+?F+R#^GV&@X^@OI?[_00AZX%>!!``@@.'H -M+P)ZX%OHO````4(![_2\``:!A`@,`(`"^#V``?%]@F,@"`*#D("@3_B=`@/__)R!* -M'2@!_A]@`/86*`";YF!7__\` -M``$"`"#\@0T(`('@5X8``"#\@PT0@(L;*/R!+0@)^N!7!0$`(``!X&<"`P`@ -M```<*`!\'V!8K0(`(*'Z+P""(%``!P`@``0'"`'^/V`$>N!7"X(@4`5ZX%N!7@00`(`"WZ"\$>N!7`0,`(`"^#V``?%]@F,@" -M`*#&("@!_BA`@/__)]7^'V`@6!LH`_XH0*"C%R@!_A]@(+#H+P'^'V(*>N!7 -M`B`(4@!\'V!8K0(`H(KZ+P""(%"@!P`@`)JF413^YJ<`?/]AM+("``*>'``` -M`>!G`/+<88$"`"``G`=`(*,8*`""(%``'N=!`/Y'$`'^!D``#J`9!/KF5POX -M_R<`(>AG@08`((`\YR^@/_TO``"@82!A_2\)_A]@H#SG+P":!F`@&!TH```` -M4"!"^B\!_A]@@"0#*``!`"`@7/TO"?X?8-7^'V`@0!LHZ/X_0("5YB<`>N!7 -M`(!?4,L!`"``A``0`(``$```0&!`?D%`!WY!D`!ZX%<`A``0"@$`(`"$'U`` -M@``0`(`/.`0^#A"@8.8O``1!4`""H&$`?#]@`(````_^GV```*!@``1A0`"" -M84``B&&`_W^"0`"+X5<.A$!`#H:B4`"%(!B"^_\G!W[!@0`$X:<`!G -M`7KF)___'V`@TAN!7H1S]+P":IE$`?!]@8+P"``0;`!`( -M&T`0`!M`$``:7Q!CK`(`("4#*`$;0!``&A\0E.`"`(!PYB<$/@X0($?F+R#^ -MGV$``&!@`'Q?8.C)`@```0$(`((@4/B!#1`$`0$((%0`*/R!#1```>!G@A$` -M("`<`2@!_A]@`'R_88#@`@```0`@`?X`0``.(!@8_N"G`)I<0"$$`0@``>!G -M`0$`(`"#X5>)^_\G`'S?86"\`@```T<0#_X?8!\`01`>_@9``'(`0`9^`$`@ -MBR,H^/\M0``!X&<"`0`@`#\'*(`#`"``!0<(`'P_8%Y"```8?N"G)/X&0""Q -M!B@`<@!`(&OF)R#^GV$$/@X0("OF+RS^GV'H_PU``((@4*#SYR\8_E]@T/X? -M8.B!31````!0Z8%-$`!\OV%BK0(``)H&8*"+$2CL_RU``'P?8-R8`@"@B1$H -M\O\M0`":!F`@B!$H^/\M0`!\7V">X`(`Z/\-0`""(%`@B``H$?Y_8"!!GM/_-00(#`"``O@]@`'Q?8,C(`@`@42`H -MX?X_8(#__R<`HBA2`'S_88#@`@`@!P`@`!RG81C^Z*<`GEQ"'P0)"`)^0$`` -MF@9@H+;G+QY^*4`?!`D(`GX`0``:H$$!_@A```X@&@`$"`@`@>A7B_C_)QJ$ -M)P@`G`90``Y@&.C_#4"@:``H`!Q'8"`ZYB=T_I]AH,4`(````%`$/@X0H/WE -M+R#^GV$`"!\(KJT"``!\OV&`X`(`"G[`@12`!@@``>!G@08`(`":!F`(_B9` -MH%LC*/C_34`!>N!7H@8`(`(``%#\@0T(``'@9X(!`"#X@2T(``/G5P8"`"`` -M``!0$(`&$*#!_R?__Q]@$(`&"`"``$"@O_\G$(`&$```'PADNP(``(`/.`0^ -M#A`@Z>4O````4*!X`"@`@B!0@/O_+P-ZX%<"`P`@``0?")2M`@`@2``H`((@ -M4("6`B@`M/PO`'R_86"\`@``A08(&'[@IP#\'$"`X`(`+@0`"`AZX&<$_A]@ -MH+P`*`$``%"@>_LO`?X?8`#`_R\`)1TH````4"`&YB<`@480`'P_8)"[`@#D -M_P!`(*P((``$05`$/@X0(.OE+TS^GV$``,!A`(*@80!\/V#HR0(`"($`"``$ -M`6+H@0T0#($`"`">YU'L@0T0`*(H4@!^01"@!@`@`"1)4@7^"D``G"=`(-SG -M+P`>05`#_A]@`8!*$`"$!@@+?@!0`(!&$`O^!U``#N`9`"A($"`*`"``A`8( -M`!X'0`$$``@`A$8(`GX`0``.8!H`G@E```[@&0"%YU>*`P`@`*H*8`"<)T"@ -MT.*'P`@`)RG0B?^ -M'V``G(=!``!&$`.$"@@``>!G`O+_)P2$"@@``>!G`?Z?8H(-`"`@-Q8H\/\- -M0`;^"D#X_RU`H-<:*`C^7V#X_PU`H`PC*.C_+4```>!G@0(`(/C_#4`@"B,H -M\/\M0`%ZX%<"!``@`,3_+P`!X&>"`0`@`Z)*$"`$`"``)"E@H`(`(`3^/V`# -MJ$H0H`$`(``H*F`"_C]@`X)*$``>!T`!!``(`GX`0``>`$``@^!G`(1&""+7 -M_R<`#N`9`?YG0@"<"4``G"=`(++G+P`>05`/_A]@`8!*$!#^'V``'N=!`(!' -M$`"$!@@!?@!``(!&$"#5_R<`CND9````4*#8Y2=,_I]A!#X.$(";Y2^@"/HO -M`(*@80!\'V!8K0(``)OF9T#^/V`"?#]@"0```"`"0!`@I_DO`((@4`#!Y2<$ -M/@X0`*;E+P``@&(`@B!B``0!8@"&P6$```!0`?X_8"!V`B@`!$%0``&@88(# -M`"``?%]@R,@"``!\/V`%`0``H-(?*`"^#V"`__\G#(!&"@""(%``)`E@(%7G -M+X#^7V`H?@E`'``)$`Q^X$&@9/,O`"0)8!P`:0H`*"I@,/X)0*`VYR\8_E]@ -M'``I"!&$``@@?@!H$8!`$!P`*0@2A``(\W\`8!*`0!`#?@=`(@")$`;^'V!4 -M`$D0!_X?8%4`21`(?@"(((,>*%8`21`'?@!@4@")$*#^'V`Y`$D0`)X'8"!, -M\R\`@B!0````4#@`21`(`(D02(!)$`'^'V!)@$D02J))$$O^"4``("A@("7G -M+P`<1V``F@9@(+H%*`""(%"`H^4G```?")3@`@`````X!#X.$"!TY2\D_I]A -M``#@80""H&$@WQ4H"OX?8`!\WV%@O`(`%'\'0"!2""A]_C^8`)_G9X$#`"`` -M!0<(&'[@IP#\/$"`X`(`+H0`"`A^`&@N@$`0`)OF9P$1`"``!0<(`'R_88#@ -M`@`8?N"G)_X?8`":/$`>@$`0#_X?8!^`0!````!0H"OY+R*`0!``!2<(&/[@ -MIP":/$`C@$`0(-L5*/C_#4#X_PU`#'\G0*#`(B@``$!@``4'""3^)D`8?N"G -M^/\-0`#R($`@>!HH"/Y?8``%!PC(_C]@&'[@IP":'$`L`H`0()'E)R3^GV$$ -M/@X0@$[E+P!\/V!@O`(`"(4`"`%^`%`#>N!7#A,`(`!\/V`O`0``H`D`(`"^ -M#V`@*@`H!/X?8`'^'V"@VO\O`?X_8(`=_R\`<^4G`(4`"!A^X*<`_#Q`@.`" -M`"Z$``@(?@!HH#<&*"Z`0!"`;N4G`+X/8)'^/T``XQ\H@&SE)P!6_R\%>N!7 -MC?S_)P-\@`$4UP```'R&0<4U``````8XY.OKZPX.``"`4O\O@&;E)X`;`"B` -M9>4G`WR``4#7````?(9!T#4`````!CCM]_D!`#O_+X!AY2<`8>4G!#X.$*`X -MY2\D_I]A``#`8?S_#4#X_RU`H$WT+_3_34#\@2T(%/X?8`"`@!#X@:T)`!WG -M9Q7^'V`!?!]@%@````R`1A``B``($'X`4`Z`AA"@_A]@#8!&$!#^!D``@B!0 -M(/7F+P3^7V``!!\(8+L"`/R!+0@8?N"G`/P<0(#@`@`C!``($(!&$/B!#0B@ -MS/4O#'X`0*!BY24O`(/@9P!\OV&`X`(`@3KE)P8((`@` -M^N!7`'Q_8&"\`@`,`P`@`(4A"!C^X*<`FEQ`+@0A"`'^(&@N`D$0"`@@"`(( -M0`@``^%7@0,`(`"%(0@8_N"G`)I<0"X$(0@"_B!H+@)!$`((0`@."``(``7@ -M5P$#`"``A0$(&'[@IP":/$`NA``(!'X`:"Z`0!"@"@@H%/\!0(`IY2<`?!]@ -M=+L"```(""`$/@X0H/GD+Q3^GV$`"!\(`-("`/R!C1"@$1`?](,-$*0#`"#X@PT0`'P_8/2U`@!( -M@0`(`7X`0"`2`"!(@0`0`'P`8/]___\`$*`9_/\-0/C_+4`@]_,O]/]-0``! -MX&<"!0`@^($M"!G^'V`,@$`0!/X?8`Z`@!"@@@\H`)H&8/2!+0@@`@`@`(`` -M$`"^#V"@=1\HL?X_8`!\/V#TM0(`]($-"$R;@!`````(4($`$$2!``@!?@!` -M1($`$/B!#0C\@2T(H';U+PQ^`$`@#>4G(/Z?800^#A`@S^0O'/Z?80""@&`` -M!,%A%'[@IP!\OV#PX`(``(J\00"*/``$@$8(``/A5P#R?&"!!``@``GB9P(" -M`"`,@$8(!_X`@"`(`"``!`!```D`*``!XE<%`0`@H`8`(`'^'V``B@$`$(`F -M"/R!#1#\_PU`('TD*``(0F#\@0T(#(`F"`=^`(```@!````'$````%`@^>0G -M'/Z?811^X*<`?!]@\.`"``"`/$``@!P`!(!`"``!X5IV$`HLAA`!WG9X$2 -M`"`,`(<*``C'"OS_#4``@B!0($L.*`"F26`(`"<*`*/H9X(+`"``!`D(`WK@ -M5P'^OV*"!@`@"OX?8/R!31`,``<(#00`""!ZX&<"`@`@(`(`(````%`,_A]@ -M_(%-$`'^'V"@Z_\G_8%-$`EZX%@Z?\G`)KF80`(!P@` -M&N!!!/X?8*#F_R?\@4T0!'X(0"#^/V`@0R0H`?Y?8`0`"`@`@"L(`('@5X+8 -M_R>`U_\GH%#E+P"R#&`@N>0G2/Z?800^#A"@?N0O&/Z?80``H&$`F@9@(*P9 -M*/S_+4#\@2T(`(/@9P$"`"`@NP4H`)H&8`%ZX%<"^_\G(+?D)QC^GV$$/@X0 -M('[D+RC^GV$@!``@`"`(4J"K&2@`G@=@````8J#=$2@(_A^`H/+_+P">!V`` -M``!0_/\M0"#$#2C[_TU`^X4-"``!X&T)`'S?8?#@`@`4_N>G`)P< -M0`0`H`D$?@=`_H5-"`!R`$`@(B0H!/X_8/Z%+0B@G!DH`)X'8`"?YV<```!B -M@@@`(``@"%+^A2T(``/H5P;I_R<`H`9`!WX@@`P`!P@``B!`!/X`0*!('"@( -M_B!``!P'8`3^/V"@%R0H`?Y?8*#X_R-]O\G`WR` -M`5#?````?(9!U#<`````!CCHTNCHZ.@#Z`,```#)_A]@(`T9*,?^/V"`7QDH -M`'P?8%CA`@`@_C]@(/`C*`'^7V```*!AH)H1*`+^'V#]A0T(``'@9P'K_R<` -MZ/\G`)H&8*!KY"<<_I]A!#X.$*`RY"\D_I]A``#`80`@"%+\H0T0%'[@IP#\ -M'$#PX`(`!/X_8"#E(R@!_E]@`!P'8"!<&2@!_C]@``#@80!\/V`4]P(``(`` -M"`!\OV&HO`(``7X`0`"``!`$@08(`7X`0`2!!A`!?@=0```_@``0```(@08( -M``(`:`B!!A`&_A]@(!$3*/S_+4`,@08(_($M"`"!X%<.?#]@$"<``,X9$R@& -M_A]@`($&"`2!)@@`@>!7!0(`(`2A!A"@?A$H"($&"`BA!A`@D_\O`!P'8`"> -M!V"@3N0G)/Z?800^#A"@$>0O__\?8*"2%2A"_C]@`!S'40!\OV'LO0(`H.D` -M*"R=!A``G480````4*`O`"@!_C]@`#7D)P0^#A"@#^0O*/Z?80``X&$`@L!A -M^/\M0"`G&2@(_E]@`!WG9P!\OV'LO0(`@7\`*`-^)X``F@!""@4("`%ZX%>, -M!P`@(!<`*``+]_\G`!P'8"`WY""!@`@^X4-"``!X&?_?P=`(?O_ -M)P$.P!D$_T9``OX'0``"(4"@%!DH!OY?8/N%+0B@`P`@!`-($`3_1D`"_@=` -M``(A0*`0&2@&_E]@!`4H"`)^!X``&D!`_HD-"!P#@1`>`8$0`?X?8`H!2!`@ -M`0`H`!P'8(#N_R<"?@"``'P_8.R]`@```D!```@?"*ZM`@`<"6$(``;@IQX) -M`0@`<@!``!``&!1ZX%<4?@!0"1!`&#")``@,!$%0``'A5PJ`#S@PA8`0`!`! -M&`I^`(`T@0`0````4#B!`!``?!]@B.`"`#3_($"@+"$@`()`8`0^#A"`V^,O -M``&@8:$!`"``@L!A`!WG9P$#`"``4P`H``(`(````%`*@4`0`?X&0``.H!D# -M^N97"O_C)P/^!H``?"!`[+T"``J%``@!>N!7#/K_)P`=YV<"^?\G!'K@5ROE -M_R\+F@9@`/C_)P``8&"@`@`@````4`""85``D&$8`7X`0``0`!@`@^%7"OW_ -M)R"`#S@`!H$0``B!"``)X%>*`@`@`'R?8.R]`@`L!P(0*`-"$```@1``@`\X -M``0?".R\`@``@`\X!#X.$*#`XR\<_I]AH#X4*/C_#4``?+]A[+T"`/C_#4`@ -M%2$H-/\F0`%ZX%>!`0`@`)/N+P%ZX%<"`@`@^($-"#2!!A#\@0T(.($&$#3_ -M!D`@]N,G'/Z?80`('P@``!X`0!X)``@`?']@ -M0$(````<)V"@X_\O_O]-0`%^!T``#L`9`WKG5PHC`"`#?@>``'S_8>R]`@`` -M'D!`"@4!"`1ZX%<.&0`@`+X/8*`=`"`9_BA``)OF9P$5`"`"?@>``!X@0!R) -M``C_?P!``!'@'R(2`"`<@8`0`OX?8`H!01``A0<(`'Q_8$!"```!?@!``(%' -M$"`,`"`>B0`(`GX'@``>`$(`F^9G'`D("($&`"```>!G`@0`()3^'T"@;A@H -M`?XH0"S]!Q#V00``(#X`*"B=1Q`<"0@(_W\@0`"0`!@<`X@0``'@9P(#`"`> -M"0@(`'Q_8/9!````'"=@_O]-0`#&_R\@I/\O`!P'8(#A_R<#?(`!O.0```!\ -MAD$O.0`````&.+[,M-X"`````?KF5P+=_R<`O@]@VOX_0``F'B@`V_\G_HD- -M"`I^`(`@P>,G*/Z?8?^1'Q@`?#]@[+T"`#"!@!#__Q]@-($`$""`#S@X@0`0 -M``0?"!R[`@``@`\X"'Z.4P0^#A`@A.,O)/Z?81"`#1`4@@T0`WX!@`!\?V#L -MO0(```8`0A2(#0@&"2@(`('@5P("`"`6B`T("`DH"`"!X%=G@1`` -M(`H%"`@#>N!7!06H"8(-`"`("0@(!@DH"``"`$``$``8``@_"*ZM`@`@G/\O -M_O]-0*`(`"``@`90@#\8*`@)"`@&"2@(``(`0``0`!@`"#\(KJT"`*"6_R_^ -M_TU`'(DG"``"`%``'>=G`!"@&8$!`"`%!0@(`!H`4``0H!D`G>97`@,`(`'^ -M'V``A^4O!(#M"R00;@L@@`\X"'Z.0QR))PB@,A@HE/X?0)3^'T`@,1@H`)HF -M8)3^'T"@+Q@H`!PG8`#A_R<`?#]@[+T"`"B%``@L@2`(`(``.`0^#A``4N,O -M`'R_81R\`@``A08(``'@9P(!`""`HA,H`(4&"`%^`$`@>>,G`(%&$`0^#A"` -M2>,O`'Q?8!R\`@``!0$(`'K@5XP!`"#_?R!``(X`&``#01```>!G@G'C)R"A -M\B^`_A]`@,[U+X!OXR<$/@X0($?C+S3^GV&@PA,H^/\-0`!\WV&(X`(`^/\- -M0``<)V`@IR`H\/]-0/"!#0@`"#\(KJT"``I^`(@`$``8('#_+^;_34```*!A -M````4.R!#1#FB0T(Z/\M0.B!#1#P_PU`()\@*/#_34``'`=@\/\M0""(("@` -M'$=@(`T`(`""(%`#_@"``'R_8.R]`@``"H!`"@5""`!ZX5<,"``@!'KA5PH' -M`"`"_@"```I@0!R)`0@`&@!0'(&!$``1X!\!?>%7`0```(("`"`"_A]@"@%" -M$`"%`@@!?@!``(%"$`'^`$``#B`8`_K@5XOR_R<@XR^`_A]``'Y?$!R[`@"` -M>?(O@*?U+X!(XR<@@`\X`P0`"`1^`(``?`!`,*@"``"`#S@$/@X0("3C+PQ^ -MX*<`@L!A``0!8@#R_&$`?#]B"*@"`"#DXR\`\JA!!)ZH``*()@@`G$)```/A -M5XX!`"``(>AG`HK`40$=G@0H`(``(@E`$@`8*`((@4*`"`"``($A@ -M"`!A"`'^($``!(%@`(9!8`"=X%<%_?\G"(@F"`">Z$$`G"!0"(*&$``*)T`` -M@H<0`((@4`@"`A`@`0`@!(0&$``@"%*`U>,OH#3C)P`@"&`,`"`(`'Z`$`#\ -M(&``_O__((`/.`P"`!`$/@X0(/[B+P``8&``@H!@(`0`(`!^`1"@^?\O`(8! -M8````0@!?@!````!$``&`A`(@&$(`(?A9X$DXR<`^_\GH```(````%`$/@X0 -M@/?B+Z#$XR\``*!A````80!\?V#\IP(`,(`!"``!X&<"`0`@,/P!$``$`@`` -M^N97`?[_8`*.XU``"()0``S#4*`%`"``AD%@%`@!"`":H$$``@!`%`"!$`"` -M`0@!?H)```(`0`"``1`$?L-`#'Y!0`-ZXE<*$``@`(X#0``,`$``?*!`3*<" -M``X(`0@`B2((``(`0`X`@1``CB89`(X`&``:`$``@>17AO/_)P3^)(``AD!! -M-Q)%$#8(11`P@`$("?YD@0"`!4!```40-/X!0``"8$&@V/\O`)8%8!```0@0 -M%@$0/``%$`'^!$``#B`9(/7_)P")(@B@J.,O`!`$8``#XR<$/@X0(.'B+RS^ -MGV$``"!B````4`*$R`GX@0T0#'[GIP#R'&(`?+]A"*@"``#RYD$`H@A@^/\M -M0*#._R_\_TU`@)SC+_B!+0@$@$<("(0`$`B()PC\@4T(`(0@0`B"AQ`$H"8` -M!*('$`"$(%``H`9"()GC+P`"B!``'>=G`@$`(("_]B^````@@(CS+R`#XR!G -M@?/_)_R!#0CU_RU`H#\A*/3_34#TA>T)$?X?8*")%R@`GB=@]84M"`/ZX%>" -M`0`@((<7*!+^'V"`\?\G_($-""`"!S@`FB9@````8A'^'V`@@Q"`P`@($(,*/R!#0B`_C]@#`!`"""F^R\1`D$0]84-"``!X&>" -MW/\G($$,*/R!#0@``>!G@=K_)P)^`(``?$``>+("```%X6>!`0`@`'WA5P`$ -M`@`%U?\G`+X/8`!\7V!4T@(`H-4<*$K^*$"`__\G$?X?8"!G%RA3_BA`H,KB -M)S#^GV$$/@X0H(GB+Q3^GV$`"#\(!-("`/R#C1``"#\(++T"``#]X%N!7@@4`(`!\/V#(Q@(``($`"`%^`$``@0`0"GK@ -M5P4$`"``?!]@````!`"I^R\``@`@````4`!\/V#(Q@(``($`$`2`[0L@@`\X -M$!!N"P0^#A``-@X0`#AN8R!^CE,0&@X0%!P.$!@>#A`<(`X0``#@80""`&(` -M!,%A`)JF40!ZYU>,!@`@@`\`*`%ZX%>"`@`@`'P_8,C&`@`$@0`(`7X`0`2! -M`!``G@=@@-X?*`'^ID$`&^=7B?G_)P!\/V#(Q@(`!($`"``!Z%>-`@`@`'P? -M8`````2`D_LO`?X?8``!`"````!0!($`$!``K@D4`,X)&`#N"1P`#@H$@.T+ -M((`/."`0;@L$/@X0`#8.$``X;F,4?HY3`'P?8`P`(`B`*.,O`'P_8``1,`#\ -M@PT4`'Q`8````0`#?B!@_,$-"`````@`?`!@`````0!ZX5<"`@`@`/K@5P(! -M`"``>N!7`0,`(`%ZX5<"`P`@`?K@5P("`"``>N!7`@$`(`'^'V"````@```` -M4`2`[0L@@`\X%!!N"P0^#A`@3^(O2/Z?80`!X&<`(`A2`B,`(`9^`(``?+]A -M;+8"```:P$$`?/]A6*T"`$.$!PBB!2<(`GK@5Y2"!A""```@C(`&"@%ZX%>" -M```@D(`&"@`!X&>"```@B(`&"@`#Z%<`(!\0>.`"``4#`""`@`8(``'@9X(! -M`"``W@8HE(`F"("`!A```^A7!@(`(````%"`@`80(`$`()R`!A"`@`8(``'@ -M9X$0`"``V`8H@(`F"``"(%"$@`8(`('@5XX-`"`@U08H`"`(4H"`!A`"_A]@ -MV($-$-RA#1"$@`8([*$-$/2!#1"B!0<(Z*$-$/"!#1!#A`<(Y*$-$/R!#1"< -M@`8(X*$-$`%^`$"<@`80^($-$*".`BC8_PU`F(`&"``@'Q`LM`(``7X`0)B` -M!A"@7^(G2/Z?800^#A`@(.(O````4`!\OV%HM`(`*(`&$"R`!A`P@`80-(`& -M$#B`!A"@P08H/(`&$*#`!BA,@`80H+\&*%"`!A!4@`80R/\&0`""(%`@XN,O -M(/Y?8.C_!D``@B!0(.#C+R#^7V`(_@9``((@4"#>XR\@_E]@`?X?8*"W!BAD -M@`80;(`&$`'^'V`@.^(G:(!&$`0^#A`@$>(O0/Z?80!\OV%HM`(`9(`F"``` -MP&$!^N!7-(`&"`()`"``AF%09(8&$"`$`"``AD%@`!P`0`)^(8``FB!`R)T` -M$.B=`!`(G``0`7Y!0`AZX5>%^_\G/(`&$#B`!A!(G`80(`$`($2."0`@.(`&"$"`9@@L@$8(`("!0`)^ -M`8``&B!`Z($`".B'`!````)0.(`&$`%^`4`'?@!@()<&*"R`!A!0@`80.(`& -M"`-^`(@@`0`@1(`&$$2`!@@``>=7C@<`(``(@E`#?F=0``A"8"`#`"``"`)@ -M`(`!0`)^(8``FB!`Z(<`$`%^04`(>N%7A?S_)SB`!A!$A@80+(@&$("*!BA4 -M@"8(``(@4+2!!@@`@>!7C@D`(#R`!@A$@"8(,(!F"`"`@$`"_@&``!I`0`@` -M`0@(`@$0```"4#R`!A`!_@%`!WX`8*"!!B@P@`805(`&$#R`!@@#?@"((`$` -M($B`!A!(@`8(0(!F"``'X%>&"@`@<(`&"``(@E`%?@!``('A5SR(!A".```@ -MQ(D&$#R`!@@@`P`@``A"8`"``4`"?B&``)H@0`B&`!`!?D%`"'KA5X7\_R<\ -M@`802(8&$#"(!A``A@%@@"8`*$"`)@@``D!`:(0&"``!X&=8A`80@00`(`!N -M!BAL@"8(``(`4`!]X%?)7#@T` -M(&B$!@@``>!G@@L`(`""(%#8@PT00(!F"-R=#1!$@`8(X(<-$.2!#1#HB0T0 -M[(4-$/2##1#P@PT0^(,-$/R##1!PA@80(","*-C_#4!<@`8(`7X`0*"6_R]< -M@`80@%P&*"`!`"#$@080Q($&"``!X&2!#1!(@`8(])T- -M$.B!#1!8@`8(\)T-$.R!#1#XG0T08(`&"/R=#1`!?@!`8(`&$*`0`BC8_PU` -MQ)T&$*#DX2=`_I]A!#X.$`"DX2\`?+]A:+0"`+B!)@@``B!0P($&"``"X*<` -M\AQ@H`/C+V3^/V"\@28((,KA)P"``$`$/@X0H)WA+R#^GV$!_A]@H+8**/S_ -M+4#\@0T(``'@9P":IE$!$0`@`_X?8/C_+4"@``LH]/]-0`!\/V#DOP(``($` -M"``!X&<"`P`@`+X/8`!\7V!@T@(`(-@;**+^/V"`__\G](&M"?]_`$``F^9G -M`($`$`$'`"````!0!(`&$`B`!A#X@0T(`'W@5P`"```.`P`@`+X/8`!\7V!@ -MT@(`(,\;**S^/V"`__\G`("&$`":!F"@QN$G(/Z?800^#A`@@^$O```@8``` -M`%``_H`0!(``$*`E"B@,@``(`'P_8.2_`@``@0`(`7X`0`"!`!"@R`TH`?X? -M8`"IX2<``!\(Y+X"``9ZX%<&@`\X````(`0^#A`@>^$O````4```/PCDO@(` -M#((_4*!=_B\!_E]@@`(`(`@`H`D`@B!0H.__+P@"`!``F@9@``'@9X&?X2<` -M_/\G!#X.$("+X2\`?-]BL-\"```!X&'T_O]"H@,`(%W^OYH`O@]@`'Q?8'C( -M`@`@LQLHC_\J0(#__R<`_D<0`'R_8<3?`@``B`8(``'@9P`N!7`GW@5PX````"?!]@ -M`0```,([`"``@$<0#GK@5P(3`"``?#]@:+0"`'B!``@"'$@0`7X`0'B!`!`` -M"`@(``'@9PP`B1`"`P`@`+X/8`!\7V!XR`(`()\;**[_*D"`__\G`'W@5P`" -M```,`P`@`+X/8`!\7V!XR`(`H)H;**__*D"`__\G`(@&"``@'Q"\WP(```'@ -M9P`@'Q#`WP(``1``(`"^#V``?%]@>,@"`""4&RBR_RI`@/__)QH("0@=?@!` -M(!GU+P`08!H,`$D0`"`?$,#?`@``"`@(`"`?$+S?`@``@>E7`(!("@P&`"`` -M@"E0`)``&"`%`"``@H80`(0`4`"`AA`@`P`@`!``&`!\/V+(WP(`(`$`(`"` -M2`H`B`8(``'@9P$)`"``!`D(#GK@5P$4`""`G_\O``'@9X$5`"``?%]@P-\" -M````(0@```$0"(``$``(0`@`B"8(`(7@5P"`2`J)\O\G``*`$`"N!G`@$`(*`6`"````@( -M`'P_8*"8`@``@``(`'R_86BT`@`!?@!``(``$!R%!@@!>N!7`@8`(`"%!@@` -M`>!G@00`(`0$"@@!>N!7`@,`("">#2@$?@I```'@9Z(!`"````@(``L`(``` -M"`@`?%]@K-\"````(0@`@^!G`BQ+8$(Q`"```"L(```!$"`;!"A<_P9```'@ -M9P$#`"``O@]@`'Q?8'C(`@"@41LH3?XJ0(#__R<`+$M@H"H`(```"`B`,?XO -M@"D`(`!\7V"TWP(````A"`"#X&>!`@`@`'Q?8+C?`@```"$((`@`(`2``!`` -M``$0`'P?8,2S`@``#00H``'@9P$#`"``O@]@`'Q?8'C(`@`@1!LH;?XJ0(#_ -M_R<```@(`'Q?8+C?`@````$0`(`("*!^#2@`+@!`@/KF5P+]YE=0`````AD` -M(```"`@@8N\O`*8I8``7`"``@`@('`0@"*#-%2@Q_A]@Y/KF5P+]YE?T```` -M@@(`(```'PC,WP(```'@9P("`#@`S_\G`+X/8`!\7V!XR`(`(#,;**?^*D"` -M__\G!'K@5X'U_R<(>N!7`<7_)X#Z_R!G@0D`(```*P@$@``(``'@9P`L2V`!`P`@`+X/8`!\7V!XR`(`("<; -M*+;^*D"`__\G```("`2``!````$0(&#_+P`<"!`!_A]@(+;_)P"`1Q````@( -M`(``$`!\'V#$LP(`@.4#*``!X&%G`A$`("(%!P@!?@!`(@%'$`;^`9`A`4<0/_\!8``.0!@C -M`4<0`?X`0``.(!B@"P`@(`%'$"`%!P@`*,IB`!X`0`0$(`@@E!4HA_X?8"`% -M!P@A!2<(`!X`0`"`2@@$!``(`!!A&*`I`"@`FD9@(`4'"`%^`$``#B`8(`%' -M$",%!PC_?P!```Y`&",!1Q``!>%G`0X`(`!\OV(`WP(``'S_8O[>`@``A``8 -M`!X`0`'ZX&!G`@,`(``MZE<-`@`@`(`*"`1^`$```>I7C>;_)R,% -M1P@`!>%G`=G_)QDB2!`@)D@0'R1($*#A^"\!_A]@/`0("*`,]2]#!"@(``H? -M"!BQ`@``U@@H`"`(8*"L]"\$_C]@@%@"*",%!P@``>!G`0(`(``$'PC^W@(` -M``'@9P$&`""@P/`@``FD<0H,GV -M+P":!F`">N=7`GWG5P,```"A0@`H`0X'&`1ZYU<"`@`@H$``*`+^'V"@/P`H -M`_X?8`'^'V``?+]A_-X"``"`1A``?!]@W+`"`"!F`R@`("A@`/Y&$"`3]B\` -MA`<(`*K@)P```%``?#]@V+$"`""!0!`B@4`0(X%`$`/^'V`@@`\X(8%`$`0^ -M#A"`>.`O`'R_8=BQ`@`@A28(`(0`&`!\`$"`@``!"<(`(/@9P&:X"<``>!G`IG@)P!\/V"G`@`` -M($05*(;^'V"@=0,H!/\&0*"5X"<`?D<0!#X.$*!JX"\D_I]A``#`80":IE'\ -MFPT0_/\-0/C_+4"@?N\O]/]-0``!X&<"!``@^($M"`W^'V`,@$`0!/X?8`Z` -M@!#T@0T(H`(`(`$<0!``?#]@)P$``*#]&B@`O@]@`'P_8/[>`@``A``(``'@ -M9P(/`"``;OHO`GK@5X$%`""`;/HO`WK@5P$$`"``+^LO`7K@5X$"`""`DOPO -M`'K@5_2!+0B,!``@@```(/2!+0@`?%]@_/<"`````0@!?@!````!$*`#`"`# -M_A]@`'Q?8/3W`@````$(`7X`0````1`!_A]@H`0`(`*`0!``FD`0`'P_8/CW -M`@``@``(`7X`0`"``!#T@0T(`GY`$(7^'V`@'Q4HH_X_0/B!#0C\@2T((.SP -M+PQ^`$`@@N`G)/Z?800^#A"@4^`O-/Z?80``(&(`(`A2("_T+_^A31``#D`: -M`'S_833>`@``@`<(#`#`"2`9[B\`'`=@```?"/C7`@`"^NA7&'Z@08(%`"`` -M?#]BU*T"``&$2`@`H@A@`)HF8"!8%2@"?D%``80("`)^`$`@`P`@``Y@&@`` -M`%``FB9@(%05*`+^7V`"_G]B`"7I9P!\/V*8W@(``0H`(`!\GV(HK@(``OX? -M8``H*F``FDE`H/L>*/__;4#_A0T(`"8`0``.0!H`*`I@`!HI0"#I'BC__TU` -M_X4-"``D`$``#D`:`(`(""`&`"`!_C]@`'P_8#BN`@````!0`)I)0"#R'BC_ -M_VU`_X4-"`""(%``)@!```Y`&@"`"`@`\NTO`'P_8ABP`@`!A$@(``7A9P$$ -M`"``H@A@`!HI0"`]%2@"?D%``80("`)^`$``)`!```Y`&AP`!P@B)(<0+"!` -M$`"`!P@@7@`H`?X_8!$$!PB??@!@`7K@5X("`"``?#]@")8"``"```@!?@!` -M`(``$*!,X"N!7`@(`((!.#B@@!0D(`"``0`0$(`@@"``@/_\` -M8`]^H&$`(`%`!`0@""#!%"B'_A]@(`4)""$%*0@`(`!`!`0`"`":1D``($%` -M5@AA""!6_R\`FD9@__\*0``.H!H`J^IG`(1H"`$'`"`@!0D(`7X@0`"'X6<@ -M`TD0H@0`(`".0!@`!`$8`"``0`'ZX&)V"@@.`O`!S'40```&(` -M)$E2$J1&$"`6`2@`G@=@`*/H9T/^GX*!!``@`'P?8'B\`@`,@`80,(0)"$!Z -MX%<4_M]A`GS?860```"````@#*0&$``R\B\`H^AGH1``(``@"&``=^`O`'R_ -M86"]`@`8_P9`((T"*``<)V```>!G`=;?)UW^'V"@>Q0H`GXJ0`"%!@@``>!G -M`?0/*%W^'V"@>!0H"'XJ0!C_!D`@A@(H__\_8``!X&!G`0,`(`"^#V``?%]@Q,<" -M`"#5&2CD_C]@@/__)_R!#0@X_C]@``*`$/B!K0DH_C]@#()&$``(``@0?@!0 -M#H"&$*#^'V"@5N`O#8!&$```P&$0_@9``)XG8"`XX2\H_E]@H%7@+P`"E]\G,$4'"`!\OV$``"````'@9P'^_V&"!P`@N/X?8"`]%"@)_C]@@`4` -M(*`[%"B]_A]@0/X?8`B`!A0,P`8(OW\`8`R`!A0P12<(H#<4*+W^'V`P'T<4 -M,$4'"``!X&<"`@`@",`F"$#ZX&NA7H@(`(+_^'V"@)Q0H+OXH0"`"`"",_A]@H"44 -M*#/^*$"$_A]@`(`&%`!ZWR<`>N%7#`,`(``"`%``@>%7"P(!4`H``%`@@`\X -M```"$""`#S@`!`(0!#X.$*!.WR\!_C]@````8@```%"@)_PO``1!4``!H&&" -M`P`@`'Q?8,C(`@``?#]@G0(``""$&2@`O@]@@/__)PR`Q@D`@B!0`!P'8*`& -MX2^`_E]@*'X'0!P`!Q`,?N!!(!;M+P`!G@0L`(`8)`@@`"#\( -MKJT"`*!,^R_^_TU`!04B"`"`0%`"_@:```H@0`@)`@@!G`@,`(`+^'V`*`4(0`(4""`%^`$"@`@`@`(%"$"`!`"`!_A]@````4`H! -M0A"@3=\G&/Z?800^#A"@"M\O&/Z?80!\/V"XR0(`"($`"/B!#1`,@0`(_($- -M$`!\/V`M`@``H.`3*(K^'V#X_PU`((K_+P""(%#__Q]@((D0*!S^/V"@X/DO -M!/X?8`!\'V```(```%SN+R!!WR<8_I]A!#X.$*`"WR\<_I]ABO[?00``H&$5 -M?@=`(-83*`%^)T``J?LO`_X&@`/^/V``?)]@[+T"```(`$`*`T`0!@D@"`@) -M``@``@!``!``&``(/PBNK0(`("G[+_[_34`"_B:``(@@0!R!@!#^B0T('H&` -M$"`QWR<<_I]A!#X.$*#SWB\H_I]A`'P_8+C)`@``@0`(\($-$`2!``CT@0T0 -M``0?"&"[`@`8?N"G`/R\09[@`@"@:0\H^/\-0*#]^"___M]!`7K@5X$!`""` -M^_@O``'@9P(=`"``!!\(E*T"``6$)@@`@>!7`OX?8`)\'V`#````@,#Y+XK^ -M'V`@NA,H!WXG0`>$A@D&A"8("'Z&@0"8(&@(A(8)"H0&"!!^AH$`F"!H"82& -M"1A^AH$`F"!H"X2&"0"#X&<(?H:!`!@`:`R$A@D0?H:!`!@`:`V$A@D8?H:! -M`!@`:`$!X&+P!\'V"(X`(``$4/ -M*(#)^"\@21`H'/X_8*`!`"`!_A]@`&W[+P```%``#?LO``'@9X']_R>@1!`H -M0OX_8`"HZ2\`Z=XG!#X.$"#-WB\X_I]A```@8@""8&(`)$E2]*4-$!1^X*<` -M?/]A\.`"``">O$$(@`8(`/(<8OR!#1`0@"8(_/\-0"!U'B@!_E]@_($M"``> -M"```@>!7C@``(!"`!@@``L!1`!WG9Z(!`"``H@A@`%4,*``%`"``CPPH`)WI -M5PZFR6$(@`8($(`F"`"``%```>=7#0#`80`=YV<"`0`@(`\`(`'^'V#XI4T0 -M^:--$/J=31``H@A@H.L3*/3_+4`(@`8(#(!F"@=^0(+X_PU`H%<(*`""(%#T -M@2T(!WYG@/B!K0@```!0`"9)0"`F!R@!_I]@(.D**````%`(_@=`$(`F"``@ -M`$"@7!XH`!Q'8`"B"&"@VQ,H`!PG8*#7WB!G`@,` -M(`"^#V``?%]@#,D"`"#<&"CN_C]@@/__)P!\7V!@O0(`$`$A"`"#X&>!`0`@ -M%`$A""`!`"`$@``0$`$!$!0!`1``@B!0(+K>)P0"`!`$/@X0@(O>+P!\7V!@ -MO0(`$`$A"``#X%)P0&`!`$!"`(@/K@9QP`0`B"!0`@@/X@ -M:`0"0!`0!`$(!WX`8````$``?"!`8+T"``2)``@0?@!`!(&`$$8`@1``@`\X -M!#X.$"!^WB\!_A]@`'S?8?S7`@`@+O!G`:3>)P!\OV'< -ML@(`8/\&0`!\/V``Q@`!`?Y?8%S_9D`@=@`H__^?8%R!)@@6^N"'`P(`(``$ -M'P@!V`(```'V+UR!)@@5^N"'@P,`(``$'P@`V`(``7X`8`%^`'B@*?XO`GX` -M0%R!)@@'^N"'@P@`((2!!@@!?@!`A($&$``$'PCTM`(```'@9P$%`""@V`XH -M`OX?8`!\'V`` -M4O8O````4`!^1Q`@B]XG#(%&$`0^#A"`6MXO``'@9P!\'V"XO@(`@0$`(*!" -M`2C__S]@@```((!D`2@``>!G@8+>)P"^#V``?%]@5-("`*";&"A-_C]@@/__ -M)P0^#A"`6]XO````8@""X&$`!*%A((7@+P"&P6$)>N!7`@,`(`"^#V``?%]@ -M5-("`""4&"A9_C]@@/__)P"`X"\#>N!7`@,`(`"^#V``?%]@5-("`*"/&"A: -M_C]@@/__)P`@"&``GB=@`)I&8*#^!B@`'&=@((\**````%"`<]XG!#X.$(!! -MWB^`QOLOH&W>)P```%`$/@X0(#_>+\C^/V``?!]@*+`"`(`G`2@``>!G`6G> -M)P!\7V!4R`(``'P_8"$"``"@@1@H`+X/8(#__R<```!0=``-$""`#SAX``T0 -M````4'P`#1`@@`\X@``-$`0^#A``.]XO>`#@"0``H&$`H!\(``$`2``!`$@` -M`0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W]T@"8(`(/@9P*? -MYV"!0`@ -M!_X_8)""!A`H`"T(`?X@0"@"#1```*`?(.\!*`":!F```>!G`K_?+X```"`` -M`*`?<(`&"``!X&>!`0`@(.0"*%C^!D"````@6)P&$`"@'P@``0!(``$`2``! -M`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?P``H!^`/]XG!#X. -M$``1WB\``*!A!`(`$````%`(@`80$(`&$!2`!A`,@`80`*`?"``!`$@``0!( -M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_;``M"`"#X&<` -M_`803D161`$#`"`<@$`(')H`$!@:`1`)P```%`$/@X0``G>+P``H&$`@@!B``0A -M8@"&06(`".)A`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!( -M!'X@8`"`H!____]_`OKH9PB`)@@A`@`@`*!`8``%Z%>"`@`@``$`(``%X6!Q`! -M_B!`*`(-$```H!__^^=70H8"*%A^!T"@_`$H`!P'8*`!`""0`,<)!_[?80`` -MH!^@`]XG`!P'8````%!L``T0((`/.'``#1`$/@X0`.'=+P``@&(`@J!A``3! -M80"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`? -M____?P@`*@@">N=G`IH@8$(;`"`(`@H0$`#J"0":P&D`G^=G%``*"B%?`"`( -M'`H0`7KH5X(7`"",@"<(A(!'"`+ZX&"`@`@``$`(`"# -MX&!`0`@H'D"*%C^!T"````@6)H'$)":!Q"@?0$H`)X'8``!X&YU$`'^%7@`!A -M"`&"X&&`A@`0?``A"'R"`1`4`"H(__\@0!0""A``I^EGD"(!$*("`"!T(@$0 -M?"(!$``$06(@`@`@``1A8GP$"1!\(@$0``1!8O]["$*"VO\G$!X*$```H!^` -M"@`@($@"*%C^"4``H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``! -M`$@$?B!@`("@'____W\H`"T(`?X@0"@"#1```*`?H$4!*`"F"6``FF9B`*?I -M9P$#`"!P@`D(``'@9WR`J0F"\O\G(//_)UBB"1``H!\(``$`2``!`$@``0!( -M``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W\H`"T(__\@0"@"#1`` -M`*`?$``-"`P`+0@`@>!7@0$`(```#0@``>!G`;G_)R"7W2<```!0`"'H9P&X -M_R<,`"H(`?X@0*"V_R<,`@H0!#X.$(!=W2^`N@`H`#X"*`!H`"@`"P`H`(O_ -M+P`B_R^`(_\O@(;=)P0^#A``6]TO```-"`!\OV'P\/#P`'W@5_'P\/"!`0`@ -M(-?=+P`:#1"`]?\O`!H-$*"Y'2@$``T(````4"#YW2\```T0@'[=)P```%!D -M``T0((`/.&@`#1`$/@X0`%7=+W@`X`D``*!A`*`?"``!`$@``0!(``$`2``! -M`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_=(`F"`"#X&<"G^=G`1H` -M(`"`)P@`_>!704U%4P(8`"!\@"8(`!S'40"#YE=TG`8000,`(`R!G@0$`("#^`2A8_@9`@```(%B)P&$`P` -M)P@`@^!G@00`('R"!A"`@"`(@((&$`P`)PB`@"`(?)H`$`P`)P@@`@`@@)H` -M$`P:!Q!\F@80@)H&$!``)P@!_B!`$`('$`;^/V`\@@80`?X_8$2"!A`H`"T( -M6)X&$`'^($`H`@T0``"@'__[YU="J@$H6/X&0*`@`2@`F@9@H`$`()"`I@D- -M_K]A``"@'Z`DW2<`F@9@````4%P`#1`@@`\X8``-$`0^#A"`^-PO``#`80"@ -M'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____ -M?PP`IPD`F^9G`)[G40$/`"!\@"8(`(/F5T$#`"`,'@<0#`('$("`1@B`A``0 -M?(`F"'P"`1`0`"<(__\@0!`"!Q`H`"T(=)X&$`'^($`H`@T0``"@'W"`!@@` -M`>!G@0$`(""J`2A8_@9`@```(%B>!A"0G@80(*X`*`":!F```>!G`G[>+P`" -M`"`(`"<(`?X@0`@"!Q```*`?(`?=)P```%`$/@X0`-C<+P``H&$T`@`04`0` -M$%0&`!``@B!0"`(`$`P(`!`4"@`0`?X"4``(`$`0@`80'WY#8!_^`V!(@`80 -M$(`-"#B$!A`8@`80'(`&$`2"!A`#_A]@/(`&$$""!A!$@@808/P&$&%)``!D -MF@80<((&$%R"!A!T@@80>((&$'R"!A"`@@80`80?@$R`!A`H@@80+((&$#"" -M!A``?#]@/T@``"!*WB\`F@9@`*`?"``!`$@``0!(``$`2``!`$@``0!(``$` -M2``!`$@``0!(!'X@8`"`H!____]_%``M"`"#X&<`_`801%)(5`$#`""8@$`( -MF)H`$)0:`1"8A`80(`(`()2"!A`4&@T0E)H&$)B:!A`8`"T(`?X@0!@"#1`H -M`"T(`?X@0"@"#1```*`?%(`-"``!X&>!`@`@(($`*`":!F```>!G`E'>+P`( -M`"``H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@ -M'____W\H`"T(__\@0"@"#1```*`?(-+<)P```%`@@`\X#``-"``(@E`,"`T0 -M$`@-$!P(#1`@"`T0(/X?8"0`#1``?!]@6-4"``!^0!`!?F!`(`(`(`'^7V`` -M@D$0`?YA0`%^04``?>%7``$```8$`"``@B!0``0!8`%ZX&<"^_\G``0`&`'^ -M($"@_?\G`(X@&`!\/V!8U@(`(`(`(````%``B``0!/X@0`%^`$`@>N!7A?W_ -M)Q0(#1`8"`T0((`/."@(#1`$/@X0`)7<+P``X&$`@J!A``3!80"@'P@``0!( -M``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?SB`)P@` -M@^97#18`(`"#YE>"!``@`OX@@`#\(`!8U@(``(/G5P("`"!,@"<((`!-"``" -M(7`@`@T02(`G"``"!Q`0`"T(`(/G5TB:!Q""#``@.(`G""0`30@`A>!7#87F -M5PX*`"`"?B&``/P@`%C6`@`0`@T0``"@'R@`#0@``>!G@1G>+P"@'P@``0!( -M``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?R`!`"`` -MFJ91&/Z_80``H!\@G=PG`)H&8`0^#A``<]PO``#@80""P&$@^N!7``2A8<8Z -M`"`/_K]A`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@ -M8`"`H!____]_.(!'"`"$!A`\@"<(`(/@9X$#`"`XG`<02)P'$`&!&0`@0`!'"``%X6<`@B!0`0(`($`"!Q`#_C]@ -M(!8`(#P"!Q`X`$<(/`('$`)^88``?)]@6-8"``"((0``@^!G`0,`("2`0`@@ -M'`$0))P`$"0$!Q`@#P`@(`('$`"(@4``'`(03``G"!P`;0@`AB!H$`!M""`< -M!Q``A^%G'`(-$"("`"`D'`<0$!P-$"`(`"`D!`T0)``M"``#X5<&!@`@2("! -M"``)X5".P`@`)J!00`$!A`@`$T(``7A9X$!`"!,@"<( -M``(A<"`"#1`0`"T(`(/G5P(V`"`D`"T(`OX@@`":(``@-``@$`(-$```#0@` -M`>!G`NO;)P`D`"``FH%!3(`G"!P`;0C_@S]P(`"-"`""86``">)G'`8-$*$! -M`"``"@80`(B`8"`(#1``CR$8`B#(8<(*`"`"H&``"/XAB`"/(!@!`@`@`"#( -M80*@(``@!P`@"/Y@0!#^(8@`CR`8`0(`(``@R&$"H"``H`,`(!#^8$`8_B&( -M`(\@&($1`"`"H"```"#(81C^8$`D!@T0$``M"`"#YU>"'0`@`OXA@`":(``` -M">)G$`(-$`$;`"`!?B%`*`(-$```H!\`H!\(``$`2``!`$@``0!(``$`2``! -M`$@``0!(``$`2``!`$@$?B!@`("@'____W\H`"T((`!-"/__($`H`@T0``\A -M&`$$`"`@"P`@`IP@`"#^/V`D`@T0$`H-$```H!\`.=TO@,7;)PA^(8@`CR`8 -M@0$`(`*<(``@!0`@"/X@0!!^(8@`CR`8@0$`(`*<(``@`@`@$/X@0!A^(8@" -MG"``&/X@0`+^((``FF``)``M"$B`@0@`B>!7!0(`($R`(0@0!@T0``(A<"`" -M#1```*`?$``-"`P`+0@``^!7@;;;)X#)_R<$/@X0`(G;+PP`K0D`',=1`*`? +M____?____W____]_____?____W____]_____?____W____]_J'Z.4Q`^#A"` +M9``HH*8Z*!!^CE,0?HY#`'T`(/___W____]_____?____W____]_____?___ +M_W____]_____?____W____]_____?____W____]_____?____W____]_____ +M?____W____]_J'Z.4Q`^#A``5P`H($8Z*!!^CE,0?HY#@&\`(`@X#1#\_Q]@ +M`'P_8&`%```$D$`(`'KA5P208`B!`0`@!`0`$2#]_R<$!@`1`'P_8(3J`@`$ +M_B!`2`(-$`!\7V```@``3`0-$`#^GV!0"`T0`(0@0`3^($#\_R!@!`(-$`"` +M#S@``!\X:P$`````'SAO`0`````?.',!`````!\X=P$`````'SA[`0`````? +M.'\!`````!\X@P$`````'SB'`0`````````````!@+\?____?____W____]_ +M`8"_'____W____]_____?P&`OQ____]_____?____W\!@+\?____?____W__ +M__]_`8"_'____W____]_____?P&`OQ____]_____?____W\!@+\?____?___ +M_W____]_`8"_'____W____]_____?P:`OQ\0``T(`'K@5X'^_R<$@+\?____ +M?PP`#1`$`&`(&`"`"`'^84`$!@`0"`"`"S`(#1```"X(`/K@5P()`"`$`.X+ +M"`!N"PP`3@L0`"X+%``."Q@`[@H<`,X*(`"N"B0`C@HH`&X*+`!."C``+@HT +M``X*.`#N"3P`S@E``*X)(($/.$1^CD,$``X(`H`?$@@`+@@#@A\2#`".#Q`` +M[@L4`*X+&`!N"QP`3@L@`"X+)``."R@`[@HL`,X*,`"N"C0`C@HX`&X*/`!. +M"D``+@I$``X*2`#N"4P`S@E0`*X)5`"."5@`;@F(``X(`7[@KUP`3@E@`"X) +M9``."6@`[@AL`,X(<`"N"'0`C@AX`&X(?`!."(``+@B,``X($H`?$H0`#@@@ +M@0XXJ'Z.0P#\[V/____[`($/.`#\[VL````$`($/.`#\#V`````$`/SO8___ +M__L`@0\X`(#O:P"!#S@`_`]@````!`"!#S@@@`\X`"``"""`#S@`@``2@`(. +M$(0`#A````T(>`8.$`!ZX%=\!`X0(0H`(`%^`$````T05!@.$%@6#A!<%`X0 +M8!(.$&00#A!H#@X0;`P.$'`*#A!T"`X0`J!?"0.@/PD,>`X0!!0.$`@2#A"( +M<@X0C'8.$""`#S@4.@X0```-$`P`+0A4&`X0`/K@5U@6#A`!"0`@7!0.$&`2 +M#A!D$`X0:`X.$&P,#A!P"@X0=`@.$`*@7PD#H#\)#'@.$`04#A`($@X0B'(. +M$(QV#A`4.@X0"+@`$""`#S@(`(T+((`/.*A^CD,$@+\?____?P``#0@!>@!0 +M```-$`$-`"`$``X(`H`?$@@`+@@#@A\2#`".#Q``[@L4`*X+5`"."5@`;@F( +M``X(`7[@KUP`3@E@`"X)9``."6@`[@AL`,X(<`"N"'0`C@AX`&X(?`!."(`` +M+@B,``X($H`?$H0`#@@@@0XXJ'Z.0PP`#0@`>N!7*`!-"*$<`"``>N%7$`"- +M""(!`"``">!7@@T`(`@`@`L$``X(`H`?$@@`+@@#@A\2#`".#Q``[@L4`*X+ +M5`"."5@`;@F(``X(`7[@KUP`3@E@`"X)9``."6@`[@AL`,X(<`"N"'0`C@AX +M`&X(?`!."(``+@B,``X($H`?$H0`#@@@@0XXJ'Z.0P@`X`@!_M]@`(P#$!BV +M`Q``Q!,G`,04)H#$#``30@`>N%7`/[_8`$!`"`8!``0,`X-$`P.#1``A_\G +MD&4``("ZC`$(!`X0+``-"#``30@!?@!``'KA5RP`#1`,``X0$`(.$!0$#A`8 +M!@X0'`@.$"`*#A`D#`X0*`X.$"P0#A`P$@X0-!0.$#@6#A`\&`X00'@.$`*@ +M7PD#H#\)`*`?"404#A!($@X03!`.$%!R#A!4=@X06#X.$!!^CE.`>CHH$'Z. +M0U``#@@!?N"O1`!."4@`+@E,``X)`I0?$@.2'Q(9?N2(`("C'Q``+@@4`$X( +M&`!N"%0`#@@2@!\2'`".""``K@@D`,X(*`#N""P`#@DP`"X)-`!."3@`;@D\ +M`(X)0`".#PP`#@A8`.X+(0,`(`#^/V`!>D%0,`0-$`(!`"`!_C]@-`(-$$`` +M#0@``$`(`'KA5X$!`"`!_C]@(`0`($0"#1`\`$T(!'X`0``%X%=```T0`@$` +M(#@`30A`!`T0`/K@5P$/`"````X(!``N"`@`3@@0/@X0@(K_+T0`30@`>N%7 +M*`"-"($#`"`!?H)`*`@-$`!\'V"XUP(`(&(B*!!^CE,0?HY#-`!-"`!ZX5@`0`@`/X?80'^'V$`A$!0`!`$206!`%`! +M_M]@(/Z?9X`"`#```0!``((@2`"%X%<&#`!`!H0@4`#^_V`#>N17`H`#4`%Z +MY&<"@B-0`($/./^%'Q@@@0\X`/X_8!``8`C\_V%@N/YA4`#\`1`!`````/Z_ +M8`2*`1`(B@$0#(H!$!"*`1``_,!H````#!2,`1`8B@$0'+0!$""*`1`DB@$0 +M*(H!$"R*`1`PB@$0-(H!$#B*`1`\B@$00(H!$$2*`1!(B@$03(H!$%"*`1!4 +MB@$06(H!$%R*`1!@B@$09(H!$&B*`1!LB@$0<(H!$'2*`1!XB@$0?(H!$("* +M`1"$B@$0B(H!$(R*`1"0B@$0E(H!$)B*`1"H%G!)"`"*#X_R<$B`$1`?X@4`%^ +M8%```0`P`92`"`&(01$`@0\X((`/.!#^'Q(@@`\X1_X?$B!ZX5<``(!@!0\` +M(`-ZX&<``(!@`0,`(``"0A`!?H)``WKB9_]_04!"_O\G``)"$`3^GV<`@F!@ +M``$`,`"&84``AF%``()A:`C^GV<`AB%@``$`,`""($``@B!``(8@:``$@1D` +M!(8?`WY!8``!`#```@(0!'Z"0*`!`"``>N%7``"`8`!ZX5?_?T%``8`/.``" +M0A``>N%7_W]!0"&`#S@!?H)`H/W_)P`"0A`@%0`@$/Z?8:`3`"`4_I]A(!(` +M(!C^GV&@$``@'/Z?82`/`"`@_I]AH`T`("3^GV$@#``@*/Z?8:`*`"`L_I]A +M(`D`(##^GV&@!P`@-/Z?82`&`"`X_I]AH`0`(#S^GV$@`P`@0/Z?8:`!`"!$ +M_I]A2/Z?840`3@M``"X+/``."S@`[@HT`,X*,`"N"BP`C@HH`&X*)`!."B`` +M+@H<``X*&`#N"10`S@D0`*X)!(#M"P@8;@,@@`\X!'Z.0P"#0&``_C]@@1,` +M("0(`"```>!'`?[?8(4%`"`&%*`8`?ZB0""*GE<`"@"`@@(`,``!`$``@B!( +M`(7@5P8,`$`&A"!0`($/.*`!`"``_A]A`?X?80"$0%``$`1)!8$`4/__OV`& +M%*`8`?ZB0""*GE<`"@"``?[?8(("`#```0!``((@2`"%X%<&#`!`!H0@4`#^ +MWV`#>N17`@`#4`%ZY&<"`B-0`($/.```(&`@@0\X__\?8``#X%?_?V%`#@(` +M(`"$@$``">!7____?X4&`"``!>%G____?P&`#S@``(!@`(1`"``$0A`!?H)` +M`/KA5___84`A@`\X`?X@0*#\_R<`A$`(``7A9____W\!@`\X`H9````&@$$` +M^N%7__]A0"&`#S@`!$80(/W_)P*&0`!$-`X00#(.$#PP#A`X+@X0-"P.$#`J +M#A`L*`X0*"8.$"0D#A`@(@X0'"`.$!@>#A`4'`X0(($/.!`:#A!$`$X+0``N +M"SP`#@LX`.X*-`#."C``K@HL`(X**`!N"B0`3@H@`"X*'``."A@`[@D4`,X) +M(($/.!``K@D``!\(N+4"``"`#S@`?%]@L+8"``@!(0@"_B"``(``0``$`$`0 +M!0`(((`/.`@!`1```!\(\*P"`""`#S@`#@`8```?"/"L`@``?`!@`/\``""` +M#S@(?@"(```?"/"L`@``@`\X!#X.$`##_2\`"!\(PKP"``)ZX%<,[OTG`+X/ +M8`!\7V!LR0(`(.\W*';^/V"`__\G%OZ?8`"(0!`@`0`@`(JB4`'^HD`E^N)7 +M"@0`(`"*@D``?,)`8,4"`!0%@P@`">!7@OO_)Q4%@P@`B$`0#GK@5P%^`%`) +M``!0`(!!$""`#S@``$$0!#X.$("W_2\``>!G@0$`(`"&0A"@W_TG``A#$`", +MH1D`?-]A8,4"`&0'AQ``#&(99@F'$``0!%%D"T<)9@LG"6H+!PAL"X<(H`0` +M(``0Y&``$(1@`!`$8``:0D$`#*49`!8@00",9!D!_N-``(SC&!GZXU>*"@`@ +M"O[CIP"<'$!P!8`(``GA5XOX_R=Q!8`(``GA5PGW_R=R!8`(`(G@5XOU_R=S +M!8`(`(G@5PGT_R=T!8`(``GB9P*)X5<"\O\G=@N`""#R_R=X"P`(;`F'$&H! +MAQ!H#X<09A.'$&05AQ``FD(0H,7])P`60Q```$!@````4`!\7V%@Q0(```S# +M4`!\?V!@P0(`$X4A"22!`0D@#0`@`(JB4`#\@D!@PP(`5`1B"``'X5<+"0`@ +M501B"``'X5>)!P`@5@1B"`"'X%<+!@`@5P1B"`"'X%>)!``@6`IB"``,Y!@` +MC^%7B0(`(%H*8@@`A^-7"0$`(%P`8@@`@`%``7[#0`S^HD``$^-7B_+_)R"` +M#SA@`040``(`4``"`!@@@`\X``!!$`0^#A`@D?TO-/Z?80```&(`@N!A``2A +M80"B*%(@K3LH_*,-$``!X&<`',=1H@<`()W^?YH`2?XOH+4@*```P&$`@B!0 +M(,D@*/S_34```>!G`0,`(`"^#V``?%]@T,@"`*"C-R@C_BE`@/__)P```%"@ +M;"8H^/\M0`CZYE>!`0`@^($-"``!X&>!#@`@`'Q?8J2S`@"510D(``'@9P$# +M`"``O@]@`'Q?8-#(`@`@FC!G@@0` +M(*#3'2@`F@9@`$4/*``@"&"@M1HH`)XG8""7#R@`F@9@@`$`(``@"&"@LAHH +M`)XG8)4C212`D#LH``'@9X(+`""@,/XO`!P'8`":("C\@2T((*X@*/S_34`` +M`>!G`0,`(`"^#V``?%]@T,@"`*"(-RA&_BE`@/__)_R!#0@``>!G`0,`(`"^ +M#V``?%]@T,@"`""$-RA(_BE`@/__)Z"1_2!G`8`/.`%^7Q`3L@(``'P?8`"````@6`P@`/Y`$`!\'V``$````%H,(`0^ +M#A``^_PO`#+_+P`!X&>!)OTG`#45*(`E_2<$/@X0H/?\+P``(&``?!]@8-@" +M`*"I_B\!_E]@``0?"!BR`@``>N!7`'P?8``$```!`0`@@$L,*``>_2>`3@PH +M`!W])P"-'2`$/@X0@.[\+R""!2@!!@`(`(LX*`-ZX%<"&?TG`";_+P]ZX(>$ +M%_TG@-H%*(`6_2<$/@X0`.O\+P!\/V!P!@(8`/.`"``!``?>!7``$```:`#SB`_A]`((`/.`"``!`$ +M/@X0`+W\+P`E%"@`6C@H@.C\)P!\/V`8L`(`(,0Q(`G^7V`$/@X0@+C\+P$$ +M@`D`!"`("'Z&@0"8(&@"!(`)$'Z&@0"8(&@#!(`)&'Z&@0"8(&B@IAN!7`?X?8*`2%"@"``!0@-?^+P5Z +MX%<%SOPG`-O^+P]ZX(>$S/PG`'P?8%BM`@"@OQ`H`((@4`#*_"<`?#]@W*\" +M``$$0`@@I3$@`GY!0`!\/V!PK@(``01`"*"B,2`"?D%`!#X.$`"<_"\``*!A +M`00`"`!\WV%8K0(`(P!'$`"$!@@@R?XO(@!'$`5ZX%>%`@`@`,S^+P]ZX(<# +M'`=@H[$0*`."(%`@]1(H`80&"`"]_"<``"`(``(?$$2T`@`$`"`(``(?$$BT +M`@`(`"`(``(?$$RT`@`,`"`(``(?$%"T`@`0`"`(``(?$%2T`@`4`"`(``(? +M$%2W`@`8`"`(``(?$%RW`@`<`"`((```"``"'Q!8MP(````?$%"W`@"`3AH@ +M``@`"```'Q`,]P(`@.$2(`0^#A``@OPO``"@80`$``@!?B!0'_X`B``"`$`` +M`@`8``Y`&`'Z`&"A`@`@`82&"`1^(H``CH`8(`$`(##^?V`#_G]@`'S?89RN +M`@``'$%`!`0A"`"&H'`$"D$0`X0F"`'ZX&" +M`0`@((D3*````%``_D80H`$5*``N!7`G?\)P!\ +M/V`\L0(``(@`"`&`'W``@(`0`'P?8````0``H@LH@'+\)P0^#A"`1_PO``"@ +M80'^'V``?-]A%;("````1Q``!!\(%+("```!X&>"`0`@('H3*````%``?D<0 +M(`45*`":!F``@`8(`7X`8```GQ`\L0(`@&[^+P%ZX%!G`'S? +M85"H`@"!!``@!_X?8`!\/V!(L0(``H"`$!7^'V`$@(`0G`$'"`%^`$"<`0<0 +M($@`8<0!#X.$``H_"\` +M`*!A``0`"`A^((`"A`8(``(`:`!]X%<``0``(04`(``N!7`?G_)P!\/V!>`@``H)LV*`"^#V``GN=1 +M`((@4"`!`"`!A&8(`?X@0`"'X%>*`P`@`((&0`0$0`@``@=``@0`"``!X5>! +M^_\G`?[_80$&1Q`!A$8(!/X&0"`1,2@"?B=`@#O^+P5ZX%<%-?PG`)T4*`"? +MYV<"V!$H`'R_85BM`@!LB`8(H#`2*`""(%``._XO#WK@AX0O_"<`F@9@("`0 +M*`""(%"`+?PG`'W@5P$!``"!Y_\G`'W@5P`"``"!Y/\G`'W@5P$"``"!Y/\G +M@.;_)P0^#A"`_/LO"00@"`+ZX%<`?+]A6*T"`*("`"```,!A````4!^`1A`@ +M`0`@`((@4!^"1A`)!`<(``!?$%BQ`@!@A`8(``'@9X$!`"`$_@!H'X!&$``. +M(!@`!`<(`GK@9P$"`"`(_@!H'X!&$``.(!@`!`<(!'K@9P$"`"`0_@!H'X!& +M$``.(!@`!`<("'K@9P$!`"`@_@!H'X!&$`,$)P@9A`8(`(/@9P)\`&@!```` +M0@(`(!F`1A#^?P!@&8!&$``.`!@$!"<(`(/@9P)\`&@"`````7P`8/W___\9 +M@$80``X@&`,$!P@``>!G`?X`:`'\`&#^____&8!&$``.0!@1!"<(&H0&"`"# +MX&<"?`!H&````$("`"`:@$80YW\`8!J`1A``#@`8$`0G"`"#X&?"`@`@"'X` +M:!$$)P@`@^!G@@$`(/=_`&`:@$80``X`&`4$)P@`@^!G!'XA:`%\(6#[____ +M&8)&$`".0!@&!"<(`(/@9PA^(6@!?"%@]____QF"1A``CD`8!P0G"`"#X&<" +M?`!H`0````%\`&#^____&H!&$``.(!@(!`<(``'@9P+^`&@!_`!@_?___QJ` +M1A`*!"<(((0&"`"#X&<"?`!H!````$("`"`@@$80^W\`8""`1A``#@`8"P0G +M"`"#X&<"?`!H"`````%\`&#W____((!&$`($!PAR@$80``0?"%S8`@```>!G +M`04`(-]_`6`9@$800X0&"`%ZX%<"?>!7`@````G^'V`"?!]@0````""`1A`" +M!`<(H.3]+W*`1A`%>N!7A0(`((#G_2\/>N"'`YH&8"/-#R@#@B!0``0'"`X$ +M)P@``%\03*<"``!\7V!-IP(```)!$`1ZX&<"@^!G`0,`(`'^'V!+_C]@`?Y_ +M8`+^GV"@;"@Z2TH`H0&"("R^R<$/@X0@(/[+X"X_2\% +M>N!7!J_[)P"]"B@`KOLG!#X.$""`^R\``"!@``0`"`&$0`@@7`0H`OX@0``; +M-R@#>N!7`JG[)P"V_2\/>N"'A*?[)X!J!"B`IOLG(+\M(`""(%``?#]@!+`" +M``$$0`B@@#`@`GY!0`!\'V``(```@-(*(```0`@$`(`(``1"4!=^X:<(`&`( +M`/*\8`"(05`/?N&G#```"`#R7&``!@!0"W[@IP`*`4``<@!``(``$""`#S@` +M``!0!#X.$*!M^R_\?X!@`'Q?8*2S`@"2"2$(`'R_80`$`````@)`!'Y@0`"0 +M`1@`&^!7D@>!$*L#`""0`X$0````4)`!@1``@B!0!'YB0`"0`1B2!X$0`)O@ +M5PL#`"``O@]@`'Q?8-#(`@"@CC4HO?X_0(#__R<`&^!7BXK[)P!\7V#0R`(` +M`'P_8'L!```@BC4H`+X/8(#__R<$/@X0H%C[+Q3^GV&`>N!7"P,`(`"^#V`` +M?%]@C-("`*"$-2B,_C]@@/__)P```$``#@`8`7X`:/Z!C1!I_A^``OX_8/[_ +M34"@;B\H`(9A4````%"@D/LG%/Z?800^#A`@5_LO+/Z?80``H&$`@N!A```@ +M"`0```@``B!`"(`&"``"($`,@`8(``(@0!"`!@@`@"!0%(`&"`"`(%`8@`8( +M`(`@4!R`!@@`@`!0`'P_8,JT!G`?X?8""`#S@"``!0!#X.$"`S^R\'_A]@('$@*`'^/V``!!\( +MO+4"``%ZX%<`?+]A(/8"``("`"``@`8(*WX`:*!8^R<`@`80@%8#**#?`B@! +M_A]@``@?"(R]`@``?>!7(T(``(("`"`D_A]@H&8@*`""(%"@V@(H````4`"A +M`RB`]O\G!#X.$*`S^R]L_I]A]OY_0@``X&&`_C]B`'R_84S``@`%HT80!*-& +M$`>C1A`&HT80":-&$`BC1A`@`0`@`!S'40%^QT$$>N=7"@\`(``:!T`4!0`( +M`GX'@@J!1A#`_TU`!/\&0`""(%`@K@`H`"!!0``!X&?@_TU"`@8`(`3_!D`! +M_C]@H*H`*``@24```>!G@?7_)P"^#V``?%]@Y-("`"`^-2@%_BE`@/__)P"^ +M#V``?%]@Y-("`"`[-2@!_BE`@/__)Y[^'V`%@480!(%&$`>!1A`&@480":-& +M$`BC1A`@`0`@!/[?80%^QT$(>N=7"@\`(``:!T`0!0`(`GX'@@J!1A#`_TU` +M!/\&0`""(%`@F0`H`"!!0``!X&?@_RU"`@8`(`3_!D`!_C]@H)4`*`"@2$`` +M`>!G@?7_)P"^#V``?%]@Y-("`"`I-2@5_BE`@/__)P"^#V``?%]@Y-("`"`F +M-2@1_BE`@/__)\#_#4``GB=@(#<`*"#_1D```>!G`0,`(`"^#V``?%]@Y-(" +M`"`@-2@9_BE`@/__)P```%`@+?LG;/Z?800^#A`@_/HO:/Z?84/^7X(``,!A +M@/X?8`!\_V%,P`(`"8%'$`B!1Q`@`0`@`)JF40'^ID$$^N97"@\`(`">!D`8 +M!0`(`OX&@@J!1Q#`_TU`!/\'0`""(%`@>P`H`"!!0``!X&?@_RU"`@8`(`3_ +M!T`!_C]@H'<`*`"@2$```>!G@?7_)P"^#V``?%]@Y-("`"`+-2@*?BE`@/__ +M)P"^#V``?%]@Y-("`"`(-2@&?BE`@/__)Y[^'V`)@4<0"(%'$"`!`"`$_K]A +M`?ZF00CZYE<*#P`@`)X&0!0%``@"_@:""H%'$,#_34`$_P=``((@4"!H`"@` +M($%```'@9^#_+4("!@`@!/\'0`'^/V"@9``H`*!(0``!X&>!]?\G`+X/8`!\ +M7V#DT@(`(/@T*!I^*4"`__\G`+X/8`!\7V#DT@(`(/4T*!9^*4"`__\GP/\- +M0``<)V`@!@`H*/]'0``!X&!G@0,`(`!\7V#DT@(``'P_8),!```@Y30H`+X/8(#__R<@_@=`_/\M0"!E +M_R\$_D9```'@9P$#`"``O@]@`'Q?8.32`@`@WS0HS/X_0(#__R?X@2T(``)' +M$/R!+0@!`D<0H.SZ)R3^GV$$/@X0H+3Z+R3^GV$`?!]B``(````!P&$`?!]@ +M(/8"``)]YUN!G@B@`(!]_"$`@82\H='XH0*"?+"@"_A]@($\`*``!G`0,`(`"^ +M#V``?%]@Y-("`*#*-"AZ?BA`@/__)P!\_V%,P`(`#/V'$``$````?!]@&9`` +M``+^/V`,_T=`(+0N*`"&85"@`1A`F +M@$80(`0`(`""(%``_!Q`DN`"``("0```G@!`!`5`$`'^`$``#B`8!/K@5XO[ +M_R<,H8<0`'P?8!F0```"_C]@#/]'0*"A+B@`AF%0()3_+_[_#4```>!G`0,` +M(`"^#V``?%]@Y-("`""N-"B:?BA`@/__)_Z%#0@H@$80_X4-""F`1A`@`P`H +M`!P'8)#^'T`@.B\HHGXH0*"X^B!G`0``4`)\'V`"`````H%&$`!\7V#4T@(``OX?8`/^/V`"_V9`(/@N*``( +M@E`7?@=``OX_8!+_1D`@C"XH`(9A4*3^'V`@O"XH`((@4`!\7V!RR@(`3'X' +M0`+^/V"@ARXH`(9A4(#F*B@`EOHG`#X.$"!J^B\D_I]A$(*-$```8&``!*%A +M`'S?8!G +M`'R_84S``@"B`@`@:?[_@87^'V`<@480(`(`(!3^/V`E_A]@'(%&$!;^/V`` +M@T80H)YU$"_>A7`0````$#`"``O@]@`'Q?8/S2`@`@3#0HXOX_8(#__R<` +M```(`GK@9P)2`"`9?@E`H-DN*.G^/V`@&"PH`OX?8"!?`B@`H@A@H+S^+PG^ +M'V```>!G`'S?8?#3`@"!`@`@`+X/8//^/V"@030H#']'0(#__R>@[0$H]/\- +M0``!X&>!`@`@`+X/8/?^/V`@/30H#']'0(#__R?XB4T(``X!&!!^((#TB0T( +M``(`0`A^`(@`#"`8"'X!D!!^0(#VB0T(`(+@IP`$`$`(?@"(``P`&`#R/&`` +M`."G`((<0*"Z$RCL_RU```'@9X$"`"``O@]@`7XI0"`P-"@,?T=`@/__)^R! +M#0@`?!]B?,`"``-^X*<`\AQ@(&+[+P7^/V#L@0T0"_X?8/*!C1`#_@E``OX_ +M8/+_34`@%RXH`(9A4"`$`"``FJ91Z($-".R!+0@`@>!7A@``(``%Z`D!_@9` +M``Z@&0;ZYE>*&P`@!9H?4`&`'X``'@!``0%($``!2!`"_A]@`_X_8`!_1T`` +M?VA`H'4N*``(@E`@D_XO"?X?8``!X&<"#P`@H,!G@@\`(/B) +M30@`#@$8$'X@@/2)#0@``@!`"'X`B``,(!@(?@&0$'Y`@/:)#0@`@N"G``0` +M0`A^`(@`#``8`/(\8```X*<`@AQ`()<3*.C_+4```>!G@>?_)P"^#V`G?BE` +MH`PT*`Q_1T"`__\G`+X/8!-^*4`@"C0H#']'0(#__R<`O@]@%WXI0*`'-"@, +M?T=`@/__)P$?2!``'T@0`*((0`!\`$!NX`(`,1Y`$#`>0!``H^AG`0``4`)\ +M'V`"````"`%($`7^'V`#_C]@!']'0`A_:$"@5BXH``B"4`!\7V!RR@(`3/X) +M0`+^/V`@ZBTH`(9A4`!)*B@@#0(H````4)#^'T`@B2XHH?X_0"`&^B=$_I]A +M!#X.$(#/^2\`?/]A\-,"```!X&<"?>!7`0````$#`"``O@]@`'P_8$\!``"@ +M\#,H#/]'0(#__R<``*!!`'P?8F[@`@`P?LA!`OX?8`/^/V``_T=``!IG0*!# +M+B@`"()0`OX?8`/^/V`"_T=``!IG0*!`+B@`"()0`*`&0#`$``@``!\0;)@" +M``#F^2<$/@X0(+?Y+RS^GV$`@J!AH%G^+P`.`!@``>!G`0,`(`"^#V``?%]@ +M$-,"`"#?,RBZ_C]@@/__)R"+`2CT_PU```'@9P$#`"``O@]@`'Q?8!#3`@`@ +MVC,HOOX_8(#__R?XB4T(``X!&!!^((#TB0T(``(`0`AZX(<$?`!H````_P5^ +M`)``#"`8``/@5P$#`"``O@]@`'Q?8!#3`@`@T3,HR_X_8(#__R<(?@&0``X` +M&!!^0(#VB0T(``0`0`AZX(<$?`!H````_P5^0)``#`$8``'A5P$#`"``O@]@ +M`'Q?8!#3`@`@R#,HU_X_8(#__R<`@N"G`/(\8```X*<`@AQ`($P3*`":)F`` +M`>!G`0,`(`"^#V``?%]@$-,"`"#!,RC@_C]@@/__)Z#1^2!G``HA"$$!`"`""@$(!`H!"`"!X%<)@`!0#`(`4""`#S@`$``8!#X. +M$("*^2\`?!]@(/8"``````@$>N!GUOZ_00*S^2=S_P9`($4N*(W^)D"@@RLH +M`OX?8``$'PBQM0(``WK@5P$!`"`1>N!7"P@`(*`&`"``BJ)0`/P"0)S``@`` +M!0`(`OY"@`!\?V"`X`(`_O\A0`"$($"@!``H`(1!0`'^`D``#J`8!?KB5POY +M_R>0_A]`H#``(`-0.P# +M`!`!?L=!`)X?4``*X!D">N=7"A,`("J+!@@"_C]@`!X`0/Z!C1``?!]@!M(` +M`/[_34`@8RTH`(9A4`!\'V`^D````OX_8.;_34`@8"TH`(9A4`'^'V"@BO\O +M^/\M0``!X&<"!@`@`OX?8""(_R_T_RU```$`8@'N_R<`?%]@$-,"``!\/V`) +M`0``(&DS*`"^#V"`__\G`+X/8`!\7V`0TP(`(&8S*(/^/T"`__\G\($M".R! +M30@`A`!```,A4`=^`(!!!``@`?X?8H`K^R\@X1(HZ/\M0"J+!@CH@2T(``(` +M4"J!AA``(`A@H&WY)SS^GV$$/@X0(#;Y+SS^GV$`GN=1`'R_89S``@`LBP8( +M`?[?8>:!C1``?!]@!M(```+^/V#F_TU`H$0M*`"&85`@!0`@`"`(4O2!#0CX +M@2T(`(`@4`)^"(``@`U`[`,`$`%^"$(`G!]0``S`&0)ZZ%<*$``@+HD&"`+^ +M/V``'`!`_H&-$`!\'V`^D```_O]-0*`Y+2@`AF%0`_X?8"!D_R_X_RU```'@ +M9P(&`"`$_A]@H&'_+_3_+4```>!A`?'_)P!\7V`0TP(``'P_8$4!``"@0C,H +M`+X/8(#__R<`O@]@`'Q?8!#3`@"@/S,HH?X_0(#__R?P@2T([(%-"`"$`$`` +M`R%0!WX`@$$'`"`!_O]A``7[+Z"Z$BCH_RU`Z($-""Z))@@`@`!0+H&&$`!\ +M'V`^D````OX_8"[_1D`@)"TH`(9A4*#6_R<`G@=@!#X.$``*^2^/_O]!``'` +M80!\'V`@]@(``GWG5P$````!`P`@`+X/8`!\7V`0TP(`("TS*,G^)T"`__\G +M````"`1ZX&>"*ODG`?X'0*"Z+2CW_C]`(/DJ*`+^'V``"!\(C+T"``'^/V`` +M?>!7(T(```&"(%!]_A]@`_X@0*`D`"@`'$=@H`$`(`":IE$!_@9```Z@&0/Z +MYE<*"0`@@)O_+P`!X&>"!``@@,'_+P`!X&` +M`'Q?8)S``@`J"P$(`/P@0&[@`@`(@(`0+@D!"`J`@!"0_A]`H*$M*(+^/X"` +M#_DG!#X.$(#>^"\`?']@G,`"```!X&!7(T(```(#`"`` +M?%]@\,@"``'^'V`"_C]@H,\L*`"&85`!_@A`#/X_8!#_1D`@S2PH`(9A4!?^ +M"$`$_C]@)/]&0*#*+"@`AF%0//X(0`3^/V`<_T9`(,@L*`"&85`*_@A``OX_ +M8"#_1D"@Q2PH`(9A4"/^"$`"_C]@(O]&0"##+"@`AF%0`'P?8!F0```"_C]@ +M*/]&0"#`+"@`AF%0`-+X)P0^#A``I/@O``'@9P)]X%!7(T(```3^'V`" +M?!]@`P````/^/V``_T9`"/]F0*`++2@`"()0`'P?8!?2```"_C]@%/]&0""? +M+"@`AF%0:?X?@`+^/V`6_T9`H)PL*`"&85"`^R@H`*KX)P0^#A"`@O@O`'R_ +M88R]`@``B"8(:?[_@0#]X%=G(/X?8`)\'V`B````!(%&$`#]X%!7(T(``*)`_R\"F@9@`+K^+X!P^"<$ +M/@X0`$[X+P``X&$`?+]AL+8"``B!!@@!>N!7`!S'42)P^"?]_C]"DOX?0*#] +M+"@!_BA``''Z+P5ZX%>%`P`@@`H/*`MZX%>&`0`@*_\(0*`4`"`0_BA``?[? +M88!G+R@(@08(`GX`@``:`$`2!0`(`7KG5PB!!A#!QRXH`?X?8`!\'V*0O0(` +MH"W_+P``"`@@D/\O```("`!\/V!NX`(``(H`"`*`@!```!\02)@"``B!!@@" +M?@"``!H`0!,%``@(@080(!P<*`+^'V`!^N=7`7P?8%BM`@"A2`PH`8(@4`%Z +MYU!G`00`(`"^#V``?%]@C-("`"!',BAA_C]@@/__)Z!#^"!G@37X)P"^#V``?%]@C-("`*`V,BC>_C]@@/__)P0^#A"`!/@O +M`(/@9P!\OV#`OP(`@0$`(!R!(@@`@^!G`@,`(`"^#V``?%]@C-("`"`O,BAW +M_C]@@/__)P($0`@"?D%0``Y!&*#[(2@%?@!`H.D:*`#_`D```>!G@2;X)P"^ +M#V``?%]@C-("`*`G,BA\_C]@@/__)P0^#A"@^/"`P`@`'Q? +M8*#2`@``?#]@%P$``*`A,B@`O@]@@/__)P($(`@"_B!0`(Y`&`5^`$"@[2$H +M]/\M0/R)+0B`^N!G`OP`:`#_``!"`@`@_(&-$`".`!C\@8T0`(X`&!!^((#Z +MB0T(`'R_86[@`@```@!```P@&`"`AA```A\01)@"`"!5_B\!_A]@`WK@5XP! +M`""`T@`H`(H&"`2`AA"3_A]`(*$L*)[^/T`@(?@G(/Z?800^#A"`Y_!7(T(```("`"``@B!0"(*!$"`"`""`_A]@#OX_8`B"@1"'_A]@"H"! +M$`R"@1`.@($0H`0`(````%`"?B"```B"4`"&0$`0"($0@/X_8!("@1`!?@!` +M``X`&`5ZX%<+^_\G(/X?8#"`01`Q@$$0,H!!$""`#S@S@$$0``'@9P)\7V#H +MR`(``7Q?8.S(`@``?!]@%](```3^/V`@URL@`(9A4`0^#A"@OO_T9`(+HK*`"&85`@V_!7(T(```(#`"#X@0T(@/X_8`@: +M@!`*`H`0#!J`$`X"@!"1_A]`H#`L*"E^)T#\@0T(]($M""`;""@,?@!`(*[W +M)R3^GV$```!```!?$(J[`@``@`\X!#X.$`""]R\```!B`()@8@"B*%(@%@`@ +M`)[G40+^OV$#?@=``GX`D``*(!@`>N=7"H(@4/G[X%<+?#]@^?___P?^`$`` +M#@`8!7Y`@`/^!H``!`!``WX`0`"HIT$`J(="``!*$`+^`(````=0`H`_4`"* +M`!@1>N!7"0-)$`L#`"``?#]@:0$``*`9+"@+_A]@$/X?8`D!21``>N!7B@(` +M(`O^'V`@%BPHM_X_0````%`)`4D0`"H`0!`%``@!_BA"`8!&$`+^YT$%^NA7 +M"A@`(`!\GV*`NP(``R+(`0!\7V+@P`(``GKG5P!\OV(^=7B@$`(+7_WV$`(HA!`!Q&$-A[YU>)W_\GR'OG5PP) +M`"``_`E`S-4"```'(`@0!P`(`GX`0`"``%``"L`:$'X'0``L`$``"L`9!?X? +M8"``+"@`HBA@!?X?8*#^*R@`+"M@H-;_)P/^OV'">^=7"9JF4:D!`"`>?@=` +M`?Z_82Q^!T"@TO\G``K`&8```"@`;O)V`@K@TH__]-0``!X&<`?#]B@+P"`('U_R<`O@]@`'Q? +M8#C)`@"@03$HH?X_8(#__R>@3_!7($(```$^`2``!!\(L;4"`!)ZX%`Q?\G!#X. +M$``(]R\`?!]@(/8"``````@0>N!G`'P_8BS6`@`"*O!G`'S?86#!`@`"(@`@`)?E9T$! +M`"!JA`8(:X0&"````$``'`!`/`4`"'"`!A!T@`80;(0&"``<`$"H!0`(>(`& +M$#@%!PA*>N!71'YG0`)\9T`(`````(8!"`P'!Q!\@`80$`4'"`+ZY5<"_>57 +M`0````($`"`,AB$($89!"(2$!A`2AD$(@((&$(B$!A"@$``@$X9!"%!ZX%>, +M"P`@:H0F"`[^0%``#B$8!_K@5Y"$1A"+`@`@'_K@5XH!`"`!_D!```XA&)"$ +M1A``HB!`((<@"`""0!@2!R<(``/A5PD#`"``@B!0C((&$(B"!A"$@@80(`8` +M((""!A`DAB$(*89!"(2$!A`JAD$(@((&$(B$!A`KAD$(H`$`((R$!A"`@"8( +M$`4'"```?PBTM0(`BX1!"`A^@8"*A$$(``AA:`",01@`!I\0M.$"```*GPAN +MX`(`%`4'$!@)!Q`E?N&G"/Y^%7BP$`(-Q[X5=,+0`@`?Y_8-U[X5>+`0`@X7OA +M5\PJ`"`"_G]@XGOA5XL!`"#F>^%73"@`(`/^?V#G>^%7BP$`(.M[X5?,)0`@ +M!/Y_8.Q[X5>+`0`@\'OA5TPC`"`%_G]@\7OA5XL!`"#U>^%7S"``(`;^?V#V +M>^%7BP$`(/I[X5=,'@`@!_Y_8/M[X5>+`0`@!7KA5\P;`"`(_G]@!GKA5XL! +M`"`*>N%73!D`(`G^?V`+>N%7BP$`(`]ZX5?,%@`@"OY_8!!ZX5>+`0`@%'KA +M5TP4`"`+_G]@%7KA5XL!`"`9>N%7S!$`(`S^?V`:>N%7BP$`(!YZX5=,#P`@ +M#?Y_8!]ZX5>+`0`@(WKA5\P,`"`._G]@)'KA5XL!`"`H>N%73`H`(`_^?V`I +M>N%7BP$`("UZX5?,!P`@$/Y_8"YZX5>+`0`@,GKA5TP%`"`1_G]@,WKA5XL! +M`"`W>N%7S`(`(!+^?V`X>N%7*@$`(!/^?V``AF%0`)?E9R@'!Q`""0`@:H1& +M"`YZX5<+`0`@('KA5PP$`"`A>N%7BP$`("MZX5?,`P`@`?Y?8"MZX557`@````'Z_R=0>N!7C"L` +M(`"7Y6<`!$%0@@<`(&J$9@@._@%0``X`&`=ZX%<`HHA@"P(`(!]ZX%<+?`!` +M`0````L.`!@`"`!`(`<`")"&1A`!?@!0D8!&$`'ZY5<"`P`@;(1F"`"B`4`` +M!P`(D(9&$`%^`%"1@$80`OKE5P($`"!KA&8(`*(!0!`'``@!?H!0``H"&)&( +M1A"@`0`@D(9&$)"$9@B1A@8(``2_".2O`@`#_($`C+L"``'ZXE<"`@`@``9_ +M"(J[`@``!^)7"H:!8)*(1A``">!7"P!@8`H(8F``">!7E(0&$*$"`""3AD80 +M``?B5P(!`"``"$!0E(0&$"#O%BB8_H9`D88&"(2`)@B4@$8(DX9F""#L%BB< +M_H9`D88&"(B`)@B4@$8(DX9F""#I%BB@_H9`D88&"(R`)@B4@$8(DX9F""#F +M%BBD_H9`D88&"'R`)@B4@$8(DX9F""#C%BBH_H9`@(`F"'"`!@IT@"8)>(`& +M"7R`9@B$@.8(B(#&"(R`1@DP`:<(`'S_86##`@``E^5GN/]'0"(%`"`T`8<( +M:H0&""%ZX%>+`0`@*WK@5RP!`"`<_P=`@'X'0"`!`"`$`0<0!`4'$`"@`$`` +M"B!`F(`&"`@%!Q```D!``)(#0``*($"<@`8(K(0&$``"X$``$@-```H@0*"` +M!@BPC@80``+`0``2!4``"B!`I(`&"+2,!A```J!``)`!0``(($"H@`8(``(` +M0`"7Y6>\@`80H@X`(+B*!A!JA"8(H)CX+P`$`6"L@"8(``(`0*R`!A"P@`8( +MH)7X+VJ$)@BP@"8(``(`0+"`!A"T@`8(H)+X+VJ$)@BT@"8(``(`0+2`!A"X +M@`8(H(_X+VJ$)@BX@"8(K(!&"``"H$"XB@80L(#F"+2`Q@B\@`8($`4G"%#Z +MX%<,*0`@@(`&"4UZX5>8@&8(20(`($W^/V``>N%7"@$`(`""(%"L@@803?KC +M5TD"`"!-_C]@`/KC5PH!`"``@B!0L((&$$UZXU=)`@`@3?X_8`!ZXU<*`0`@ +M`((@4+2"!A!-^N)720(`($W^/V``^N)7"@$`(`""(%"X@@8037K@5TD"`"!- +M_A]@`'K@5PH!`"````!0O(`&$)&&!@@`?)]@2.$"``"0(4`@B?@O``A"8)&& +M!@B<@"8(A(!&"`"$($`@AO@O`7Y"0)&&!@B@@"8(B(!&"`"$($`@@_@O`GY" +M0)&&!@BD@"8(C(!&"`"$($`@@/@O`WY"0)&&!@BH@"8(?(!&"`"$($`@??@O +M!'Y"0*`#`"``@B!0`XA@``+^0(``?`%`_)@"```&`!`!_B!`!?K@5PO\_R>L +M@$8(L(#F"+2`Q@BX@*8(O(`&"`0!)PD`!(%``HAD``!\_V&`NP(``(9'$`"( +MA$`!!((("`$'"0&(1Q``CD-!`I3D`&J$)@@"CD<0`)3D0`&$XP@`C@4:`XY' +M$``,XT`"CL0`!(Q'$`".Q$`!!,,(!8Q'$`"*PD`"C*0`!HI'$`",I$`!A*(( +M!XI'$```H$`""@0`"(!'$``*!$`!!``(`'^G0`F`1Q``(`A@(##X+P%_QT`` +M!0<(:H0F"`"`1Q`!!0<(L(!&"`&`1Q`"A&<(`X2'"``@"&``?Z=`("KX+P%_ +MQT``!0<(:H0F"`*`1Q`!!0<(M(!&"`.`1Q`$A&<(!82'"``@"&``?Z=`("3X +M+P%_QT``!0<(:H0F"`2`1Q`!!0<(N(!&"`6`1Q`&A&<(!X2'"``@"&``?Z=` +M(![X+P%_QT``!0<(!H!'$`$%!P@'@$<0P(`&"`%^`$"@EOXOP(`&$(#^]2<$ +M/@X0H-CU+RC^GV$`?!]BS-4"``!\'V`@]@(`````"`!\OV'@P`(`$'K@9RC_ +MYD&B8@`@R_X_0@"C"2@``N!7`GW@5P(```"!"@`@`WK@5X('`"``($)`(`)7"@"@8``$'PBP +MM0(```'@9P!\7V!(X0(``@P`(`"&85"@!0`@!X?&"``*@!@`A(%!`(X`0#`' +M``@`"$80``'B5PP(`F``A(%!``!&$`'^84`%^N%7"A4`(`#\`4`)7`"#H8(GV_R>@]O\G`(J"8````%``?!]A'-0"``>'Y@B@!``@ +M`*#`0`"*81@`!(!!``9&$`")X5<,AH%@``2`00`(1A`!?@!``!!@0`B%80@$ +M>N!7`(9C4(H"`"``A^)70`>#"`GX_R<@^/\G`(IB8`"'XE<)BJ$8``2`05`' +M8P@`"D80`(?B5PR*8F``!(!!``9&$``*'PANX`(``(IG"`"`(5$0BP8($HL& +M"0`2X*<4B^8(`)`+^O\G(/K]+P#_!D`@H_4G*/Z?800^#A"`8?4O +M`'P?8"#V`@`````($'K@9P*,]2>`/`DH`'K@5PD#`"``O@]@`'Q?8#C)`@"@ +MBR\H@/X_8(#__R>`6@DH@%'^+P"&]2<$/@X0@%KU+P!\OV%$O@(``X4&"`%Z +MX%>"`0`@`(4&"`%ZX%>!'1(H````4`"!1A`#@480((#U)P2!1A`$/@X0H%/U +M+QS^GV'X_RU`(%DJ*`7^7V``?!]@*P$``"`.*BA=_C]@_(5-"``%X6<`?+]A +M1+X"`(("`"`$A08(`7K@5P$``%!!#``@!(%&$`"%!@CZA2T(`('@5X$#`"`! +M^N!7`@$`((`'$BB````@@`P2*/R%30CZA2T(^X4-"`*%1A`!@480`(-&$`'^ +M'V``!>%G`X%&$($&`"@```!0!(%&$```7Q!8GP(`H'WU)QS^GV$,`"`(`/P` +M0.@!```4!``(``(`0*#F_R<>?@!`!#X.$*`^]2\@_I]AEOX?0"#V*2BU_C]@ +M`'R_842^`@`!A08(`((@4"#*"RC__TU```'@9X(*`"```/8O``#@80&%!@@% +M@480(*@/*`""(%`!A08(``!?$)2M`@``"!\(C+T"``!]X%N!7@CGU)P*%!@C_?P!```_@'Z(W]2<"@480`-'_+P'^'V"@-?4G +M!(%&$`0^#A"@"_4O'/Z?80``P&$```!0__K@5_R!#1`L!``@`(*@80!\7V"T +MT@(``'P_8.,!```@,"\H`+X/8(#__R<`CD88_/\-0"`.+R@"_C]@_/\-0""2 +M'BB`_C]@`'P?8#2_`@#\@4T(!/X_8``<9V"@%1XH`)J&8(`@`"`$/@X0(/ST +M+QS^GV$``,!A`(*@80"`!@C^_RU`('\S*/W_34#^A2T(`OK@5P*$!@@!`@`@ +M%7K@5P(9`"`5>N=7`1@`(``!X&<"`0`@`OK@5P(3`"#]A2T(H-,=*````%`` +M``!0`)HF8*`A'BC__TU`_X4-"``!X&`A!`H``'@9P*^#V#";B\HFOX_8````%``FB9@(!D>*/__34#_A0T(``'@ +M9X$(`"``@`8(H&X>*(#^/V`!>N!7`>C_)P"^#V``?%]@M-("`"`++RBC_C]@ +M@/__)P"^#V``?%]@M-("`"`(+RB%_C]@@/__)R`8]2<<_I]A!#X.$"#8]"\@ +M_I]A``"@80`$(`@@E"DH%OX?8````%"@S!TH]/\M0````%`@X!TH`((@4`%Z +MX%>""0`@````4`""(%`@^QTH_/]-0/R!#0B@6QXH@/X_8``!X&<""``@`&D0 +M*``!X&<"O@]@0E,O*-K^/V#T@0T(_WL`0"+U_R?T@0T0@`,`(`"^#V``?%]@ +MM-("`"#S+BC0_C]@@/__)_2!#0@``>!G`@,`(`"^#V``?%]@M-("`*#N+BC> +M_C]@@/__)_R!+0B@?2DH%OX?8`"$!@B@P_\O_/\M0*!&'BC\@0T(``'@9P$. +M`"`,>N!7!0,`(`"^#V``?%]@M-("`*#E+BCK_C]@@/__)P)^`(``?$``I+(" +M``"$!@@!_C]@`GK@5P&"(%``!>%G@0$`(`!]X5<`!`(`!0,`(`"^#V``?%]@ +MM-("`*#<+BCQ_C]@@/__)R`"`3@`F@9@_($-"/O_+4"@-#,H^O]-0/J%+0@@ +MCQTH````4````%#\_RU`(-T=*/G_34#YA0T(``'@9X$%`"#\@0T(H#(>*(#^ +M/V```>!G`@,`(`!`$"@``>!G`GP_8`D!``"B*2\H`KX/8*#?]"<@_I]A!#X. +M$""I]"\X_I]A``"@80`$(`@@6RDH&/X?8*!L]2^4_C]"``'@9X$&`"``R#(H +M``'@9S#^/X""`0`@&(``"``!X&'2@`@B!0`7K@5X()`"````!0`((@4*"Y +M'2C\_TU`_($-""`:'BB`_C]@``'@9P((`""`)Q`H``'@9P*^#V#"$2\H"_XH +M0.R!#0C_>P!`(O7_)^R!#1"``P`@`+X/8`!\7V"TT@(`H+$N*`'^*$"`__\G +M[($-"``!X&<"`P`@`+X/8`!\7V"TT@(`(*TN*`_^*$"`__\G`(0&"*"#_R_\ +M_RU``80&"/V%#0H``>A7#GXH0`D!`"```^!7"P,`(`"^#V``?%]@M-("`""E +M+B@=_BA`@/__)_R!#0C[_RU`(/XR*/K_34#[A0T(`7K@5P$#`"``O@]@`'Q? +M8+32`@"@GBXHI/X_0(#__R<@]ATH_($-"``!P&$"`P`@`+X/8`!\7V"TT@(` +MH)DN**;^/T"`__\G#`#G"0"?YV<"`P`@`+X/8`!\7V"TT@(`()4N**?^/T"` +M__\G`X0&"`:`1Q`"A`8(!8!'$`&$!@@`("!0$X0'"``"`$`3@$<0"X0&"!&` +M1Q`+A`8(OW]`8`%ZX5>??B!@`0<`((+ZX%<+`0`@AOK@5PP%`""@>N!7`GW@ +M5^`````!`P`@`+X/8`!\7V"TT@(`((8N*+C^/T"`__\G`?K@5X(3`"`9_A]@ +M(!0I*+O^/T`@B`<($X0G"`"!X%!+@`@_($-""#5'2B`_C]@``'@9P(L`""`X@\H``'@ +M9X$J`"``O@]@H!T`(&7^*$"`:0,H``'@9R("`"`!_A]@H*L4*`3^'V`"_A]@ +M$(!'$/J%30C\_PU`H$LN*`/^/V#\@2T(('T=*````%"`=/8O````8@`"'0`@`"'H9P$!`"`">NA7CA@`(`"^ +M#V``?%]@M-("`"!@+BBC_BA`@/__)PN$)@@@[R@H&OX?8/J%+0@@%!TH```` +M4````%#\_RU`(&(=*//_34#SA0T(``'@9P$1`"#\@0T(H+<=*(#^/V```>!G +M@@X`(`#%#R@``>!G`0T`(`"^#V"-_BA``*XN*``+`"``(>AG`0$`(`)ZZ%<. +M`P`@`+X/8`!\7V"TT@(`H$XN*-[^/T"`__\G^H4M""`$'2@```!0`'P?8`@= +M```@;!$H`((@4``"`"#\@2T(^H5-"*#],B@`G@=@(%?T)SC^GV$!>N!7@>;_ +M)P)ZX%"`P`@!(`)"#@!"A``@`D(-`$* +M$([^'T`@"0`@#7XL0`+ZZE>"`P`@-'\*0`"F*6"@2S$H``!`8([^'T"@!``@ +M%'XL0`/ZZE>"!@`@-'\*0`"F*6`@7#$H``!`8([^'T`;?BQ`@+4H*`"`*0B@ +MM"@HCOX?0`2`*0@@LR@HCOX?0##^!V`#_BI@`(``:`*`1A``$"<8(`(R*`"F +M"6``@"D(!((&$`2`*0@0^N=7"((&$`(+`"`*?B>``(``4``EZ6<`@B!0(00` +M(``$05``)"=0`OX@@`^$1A`0@D80"/X@B"`"`"`1@D80$81&$!""1A`/@D80 +M#(1&$`)^)X`-@D80!GXGB*`"`"`.@D800/KG9P$!`"#_@1]P`7X`0`!\`&#_ +M_P\`_($-$/R%#0@8_C]@%8!&$/V%#0@!_E]@%H!&$/Z%#0@7@$80E`4*"`&` +M1A`"(@@`(/\L*``L:V`@J/0O`*X+8"`1]"=$_I]A!#X.$"#6\R\@_I]A_/\- +M0/C_+4`@[P(H]/]-0!3^/V#\@0T(()_T+P`"@!```*!A_($-"```7PBN!7`0,`(`"^#V`` +M?%]@O,@"`"#?+2@N_BI`@/__)P!\GV)@L0(`0'\*0*#V'BA,_B=`(/X?8#"` +M1Q!2_N=!"OX?8"*`B1``?#]BU*T"``&$2`@`H@A@`)XG8""P*"@"?D%``80( +M"#B`)@@"?@!```X@&D.$!@@`GDA`('`R*/S_;4#\@0T(`"(`0``.(!I`B`8( +M@'K@9P$*`"``?!]@Z*\"``$$(`@"_D!```0@")SZX%?\A0T0`0,`(`"^#V`` +M?%]@O,@"`*#(+2A,_BI`@/__)R"A*"@`GBA`_($-"``B`$``#B`:0(@&"`)Z +MX&N!G`0H`(`!\'V`0L`(``00@"`+^0$``!"`(W?K@5_R%#1`!`P`@`+X/ +M8`!\7V"\R`(`H*8M*&O^*D"`__\G('\H*`">*$#\@0T(`"(`0``.(!I`B`8( +M0'K@9P$*`"``?!]@V*X"``$$(`@"_D!```0@"(7ZX%?\A0T0`0,`(`"^#V`` +M?%]@O,@"`*";+2AV_BI`@/__)R!T*"@`GBA`_($-"``B`$``#B`:0(@&"!!Z +MX&N!G +M`0H`(`!\'V!*$#\@0T(`"(`0``.(!I`B`8(!'K@9X$) +M`"``?!]@W*\"``$$(`@"_D!```0@"-WZX%?\A0T0`0,`(`"^#V``?%]@O,@" +M`*!Z+2B1_BI`@/__)R!3*"@`GBA`_($-"``B`$``#B`:0X0&"`)ZX%>"`P`@ +M.(`&"`">*$`@`S(H_/]-0/R!#0@`(@!```X@&B*("0@`(@!`(H")$*!9`2@* +M_A]@.!T*$```"`@@:1,H`?X_8!&$"0B??@!@`7K@5X$%`"``?#]@[)<"``"` +M``@!?@!``(``$'3^'V`@^2N!7#B(`(`!\/V`HE@(``(`` +M"`%^`$"@^3(H`(``$``!X&>"!``@```+"`%^`$````L0.)/,G +M`+$R*``!X&>"`P`@```,"`%^`$`@@@`H```,$''^'V`@/@`@-'XK0`!\7V)@ +ML0(`/`$)"`-ZX%N!7-"<)$($$`"!P_A]@('8G*&Q^*T``@`L(`7X`0`"` +M"Q`\`0D(!7K@5X[J\B<`=S(H``'@9P(#`"````P(`7X`0```#!!Q_A]@H`0` +M('E^*T`\`0D(!WK@5P$%`"````P(?WXK0`%^`$````P0.)0`@`+X/8`!\ +M7V"\R`(`H,LL*&7^)T"`__\GH+,`*````%``?+]A8+$"`#R!)@@)^N!7!AL` +M(``('PB,O0(``'W@5R-"``""`@`@(,7T+P'^'V"@4/HO`?X?8#R!)@@`@^!G +M`0,`(`"^#V``?%]@O,@"`""_+"@;_B=`@/__)ST$!P@/?@!@`WK@5PH,`""` +M>/\O_/\-0/C_+4`@J`$H]/]-0``!X&>"!@`@^($M"`O^'V`,@$`0!/X?8`Z` +M@!#T@0T(/($F"``"`!#X@0T(_($M"*`P`R@,?@!```,`(`"^#V`@#"TH__X_ +M0``!`"`@F0`H"?X?8#R!)@@)^N!7@0$`(*"6`"@```!0/($F"`GZX%<"`0`@ +M`+'^+SR!)@@,^N!7HI(`*`(``%``#``@`_R``41M````?(9!41L`````!CBX +MM@*PL`(```!\OV%@L0(`/($&"`QZX%>"`P`@0P0'"``!X&<"`0`@@+<@*#X$ +M)P@"^N!7`1L`**"'`"@```!0@',.*``R#"@`$_TO`'X?$#BU`@!U_A]@("LG +M*&G^)T`\@28(H"DG*'7^'V`\@08((*CR)RC^GV$$/@X0@&KR+P!\OV'LW@(` +M`(`&"`P`P`F@30`H`!P'8!P`)PC`_A]@,(!`$````%`Q@$`0'`!'"!$$`0@@ +M?@!H$0!!$!P`1P@2!`$(\W\`8!(`01`"_A]@(@"'$`'^'V"@S>`@``@`8(`'Y?$-*L`@`,`,`) +M(#@`*``57"EWR)P!\OV%8K0(``(JB4"`! +M`"!HA&8)`?ZB0`"7XE>*^O\G`!3`0`($XP@#_N*G9(#&"'_^(V$"<@,!`)'D +M5X+Z_R>`^N-G@?7_)P!RHT`"A,((`82B"`+ZXE!7`@````'[_R<`O@]@(*$L(,S^ +M/V``!$%0$P1`$`H$0!`$!$`0`_X_8!8"0!`2!$`0!OX_8!P```@@@`\X+`)` +M$`0^#A"@(/(O`)(D40`!G`([C4*(#`"``%$51 +M`+X/8`!\7V"\R`(`H#@L*/O^/V"`__\G`(JB4`!\GV!8K0(`H`0`(`$$X`D` +MC&5H`(YA&0`AZ&<"C&1H`HXA&0)\WV$!`````?ZB0`"?XE>*#P`@:`1B"B`! +M`"``#,-0`7[#0``GXU>*^_\G``I@0`*$(0H#?N.G9``""G_^2&("N!7`1WG9P%\/V$* +M`````GK@5P&;YF!`@`@;`Z"$!P00A`;$D(0'A1"$!T6 +M0A``@^!G@1OR)R`;\B<`CH`0!#X.$`#H\2\->N!7``"@804#`"``O@]@`'Q? +M8+S(`@`@$BPHY?X_8(#__R>`L/(O`!H?$)RP`@"`L?(O@`SR)P0^#A``X/$O +M#7K@5P``H&$%`P`@`+X/8`!\7V"\R`(`(`HL*-;^/V"`__\G@*CR+P!\7V!@ +ML0(`/`$A"`"#YE>%```@/!L!$("G\B^``O(G!#X.$"#9\2\@_I]A`(+`80"" +M(%#_@TT0_H--$/V#31#\@TT0^X--$``!X&<`FJ91(@0`(/J#31``?%]@O,@" +M``!\/V!K`0``(/LK*`"^#V"`__\G__\M0/W_34#^_VU`H(__+_S_C4``'>=G +M`0,`(``" +M`P`@_84-"``!X&<"`@`@^X4-"``!X&N%7@@,`(/R% +M#0@``>!G`@(`(/J%#0@``>!G(0$`(`_^7V#^A4T(`(?A9X$"`"`;A``(`('A +M5P$!`"`;AD`0`?Z_80`%X6>!`@`@'(0`"``!X5!7`0````)] +MX%<"````@04`(`"^#V``?%]@T,@"`"#2*RA7?B=`@/__)Q*$#0@&>N!7`@0` +M("`$`"#^A0T(``'@9X'\_RN!7`GW@5P(````!_/\G````4""2\R<<_I]A +M`#X.$""=\2\<_I]AH_[?@0``H&&W_A]@H%,"C^_TU`_X4-"``!X&<"?>!7`0````)]X%<"`````0,`(`"^ +M#V``?%]@T,@"`""]*RAZ?B=`@/__)P%ZX%<"?>!7`@```$'O_R?^A0T((.[_ +M)P```%``?!]@(/H"``"`#S@$/@X0H)KQ+TC^GV'T_G]"``%`8@!\GV)BK0(` +MH@,`(`""H&$`O@]@`'Q?8-C(`@"@L"LHXOX_8(#__R<,``D*H%P%*``FR$$@ +M?@4H#`!($!<$*`@``>!G_O\`8`+\`&@!````%P!($!H("`@```A`'`0@"!T$ +M"`A`>N!G(A@`(`">YU$#_@!@`WK@5P']X&!V`( +M`(@0$'X`B(#ZYE<*`(@0@@(`(``H*F`@C1LH+'X(0``!X&>!`P`@4/KF5X(# +M`"#Z?RI`H(D;*"!^"$```>!G`@$`(*`K`"`5'D<0`?X?8/B!#1#\GPT0`!P' +M8/C_+4"@P"XH`!Q'8`"`"`CP_RU`\($-$`2`"`CT@0T0`!P'8*"\+BCX_TU` +M````8OB!+0@@%B8H,/X?8`%ZZ%!G]G^J08(4`"``(>AG`@D` +M(`B("`@)?B"`^($-"``#X%>.!@`@`'P_8)2T`@!\@0`(`7X`0'R!`!"`@0`( +M`7X`0("!`!`!_A]@%0!'$*!I+2@`H@A@@```(!4>1Q#P@0T(`'P_8-BR`@`` +M@``0]($-"`2``!`!?@AX!G[`@3#^'V`@^"4HN/X_0%:()@A>B$8(^/\-0`"& +M85`@?H=`("+]+P"*HE`@B$8(^/\-0`/^?V``"()0H!W] +M+P"*HE``S_\G`'Q?8&27`@``?']@1)<"``'ZX&<`?)]@-)<"``*`#S@`!#\( +MFZT"``'ZX%<"#0`@%'K@5X$#`"`)"0`@"GK@5P*`#S@```((`7X`0""`#S@` +M``(0!``""`%^`$`@@`\X!``"$`@``@@!?@!`((`/.`@``A`,``((`7X`0""` +M#S@,``(0-WK@5P'[_R=N>N!7`H`/.(#[_R<"^N!7@B``(&YZX%<"&``@%``! +M"`%^`$`@@`\X%``!$````0@!?@!`((`/.````1`$``$(`7X`0""`#S@$``$0 +M"``!"`%^`$`@@`\X"``!$`P``0@!?@!`((`/.`P``1`0``$(`7X`0""`#S@0 +M``$0&``!"`%^`$`@@`\X&``!$!P``0@!?@!`((`/.!P``1`@``$(`7X`0""` +M#S@@``$0)``!"`%^`$`@@`\X)``!$"@``0@!?@!`((`/."@``1`L``$(`7X` +M0""`#S@L``$0-WK@5P'M_R,^(SYLKJ,]8SVC,S,S/.`(/@9P*`#S@!?@!0#GK@5PV`#S@# +M?(`!3'D```!\AD%3'@`````&.!PD("0,)!`D%"08)`0D"```@`$(`7X`0""` +M#S@`@`$0!(`!"`%^`$`@@`\X!(`!$`B``0@!?@!`((`/.`B``1`,@`$(`7X` +M0""`#S@,@`$0$(`!"`%^`$`@@`\X$(`!$!2``0@!?@!`((`/.!2``1`8@`$( +M`7X`0""`#S@8@`$0'(`!"`%^`$`@@`\X'(`!$`"`#S@$/@X0@.CP+P``X&$` +M@J!A``3!80```%`!_C]@H-D-*``$05```>!G`(`'$($$`"`,`"`(`((&$*#^ +M'V`-@$`0`(`&"!!^`$````<0(`CQ)P```%`@!_$G"/X?8`!$'P@YLP(``(`/ +M.`0^#A"@U/`O%/Z?84#^'V#__RU`_O]-0*`3\R_]_VU`_X4-"`!\'V%@P0(` +M````0``0`$`\!>`(9/X?8/__+4#^_TU`(`[S+_W_;4#_A0T(````0``0`$`\ +M!0`(`('C5PL.`%`*@`-0!'K@5Q#^'V`,?!]@#0```!,!1!"@!_$G%/Z?800^ +M#A`@SO`O*/Z?80```%"@[!PH_/\M0/R!#0@``>!G`?W_)R`"`"`!_K]A()'Q +M+P`@"&`!_J9!!/KF5XT1`"``C/$O````8B"`'B@`F@9@`)H&8`""(%"@`@PH +M^/]-0`%ZX%>!^/\G%/[FIP#RW&$`?/]A4.$"`/B!#0@$```(``'@9X+R#2@` +MG`=`!/X_8*!Q,"@!_E]@`)H&8`""(%"@^0LH^/]-0`%ZX%<"^?\GH(#Q+P`@ +M"&``?!]@"P$``"!M)2@`FB9@`.W_)X!Z\2^@D24H``"@80!\'V``\```@/@= +M*"!Z\2\`F@9@(.?P)RC^GV$`?>!G`,8``2&`#S@``"!@`'P?8&BR`@`@M1(@ +M``1!4`0^#A"`H_`O(-OR+P``H&$/>N"'@P0`(`!\/V"LM@(``($`"`#\1F#_ +M_\?_``0`:`"!`!``_*9A```X``#]YF_C]@_($M"`2```@``>!G +M`@(`(*#>_R\$@0<(_($-"`0```@```<0_($-""8B@!````<(``'@9P("`"`@ +M0O$O`)H&8*`#`"`!_C]B!($'"/__/V``)`!`_P)`$"`^\2\`F@9@`*((8*"I +M\"!7!`````)]X%<#````@O3_)_R!+0@` +M?`=`M+L"`/\"0!````!0H)CP)R#^GV$$/@X0`%CP+P!\OV$,X@(`&(0&"``! +MX&)G`([`0('Y_R>"_E]`@OY_0"`$ +M`"``!P,0`WX@@`"$X*<0_CR0`(G@5P4$86`4?B%``)!`&`!]X5>2"0``#/O_ +M)R#S_R<`!P,0`OX&@``.`$```0`(H&+P)P`0`!@$/@X0@#7P+Z`"\2\``*!A +M&(1&"`%ZX6>!`@`@`'Q_8`CB`@``B"$(`?X@0`""@1`">N%G`'Q?8`SB`@`! +M`@`@"``A"``"`1`,`"$(!`(!$!@`(0@0`@$0'``A"!0"`1``@B!0H/GP+Q@" +M01``5/`G!#X.$*`T\"\P_I]A(/3P+P``P&$``"!B`?X?8!P`1PCX@4T0)`0! +M"`!\_V$,X@(`^H%-$!8&!P@0A"<(``X`&OF!31``@^!G^($-"($!`"`8@`<0 +MH`$`(!R!G&82G"2("`"`1A$<*(#`&*``)```@`)KF80`*IQD$^N97"_3_ +M)Z`C\"G`'P?8KS>`@``H#Q"!(AH"`0:Z0$` +MAD=0``P!&`!ZX%<`F&EJ20$`("J$@!`JAH`0@-4H*``F(&`$B`@(`!J)00"` +M`$```(80H`0`(`"B*%*@T2@H!HB!"@`H`&``)@!``!J)00``AA`!_@A```X@ +M&@3ZZ%>*$?`G`"/G5P']_R<,_NBG`*!\0`2(80H`I@=0``P@&`#ZX%>,^?\G +M`*)(0@0:20``)@%0`('@5PGT_R>@]?\G``(!4"`R_R""P`@^/\-0"!"_R\!_C]@^($- +M"`P`(`@<@``(`"'@5X(&`"`"B``("(A`"``!X5<)`0`@``7A9X(#`"`0A``( +M`7K@5P$"`"``_@80H"T&*``$`0`@`(0)"``!X&N!7`?X?8*!$\B\!``!0_($M"!'ZX(>#`@`@ +M``0)"``!X&N!G`AP'8"`N#R@! +MK@M@_($M"`_ZX(<#!``@`(0&"``!X&>!`0`@H,<&*````%``H$80@*<'*/R! +M+0@.^N"'`P$`(``N!RC\@2T(#?K@AX,!`"`@0_!_/\G@$KP+P``P&(`J@I@`((@4"#""BCP +M_TU``7K@5X'W_R?P@0T(!```"``!X&<,`"`(`?7_)Q*$(`@"^N!7`OW@5P$` +M```"_>!7!0```(+Q_R>`KPPH(%L+*`"J"F``J@I@`((@4*"W"BCP_TU``7K@ +M5X+U_R>`Z_\G@#OP+P``H&+T_PU`(.3^+P""(%`!>N!7`((@4($!`"#T@0T( +M``'@9X(``"`!_C]@`(_@'P('`""@T@4H]($-"/2!#0@@J@!\O\G``$`("`P\"\`J@I@_($M"!CZ +MX(^!L?\G!_K@AX,"`"``!`P(``'@9P$!`""`%`4H_($M"`;ZX(<#`P`@`*<6 +M*`"\%B@`L@Q@H'8#*`""(%#\@2T(`_K@AP.I_R<`J/\G!#X.$`!9[R\``.!A +M`(+`80$$``@`FJ910'K@9P(N!G`0(`(`*(!P@,`*<)$'X`0```AQ`` +MF^9G`;X/8$'5*2CW_C]@`((@4`*"1A`#_A]@`(!&$`&"1A`#@D80#/X&0`"> +M)V`@^?`O!/Y?8`&$!PB`>N!G`7/O)R`!`"@`'`=@@''O)P0^#A``0^\O``&@ +M88$&`"``#_`O`'Q?8!B]`@```2$(`(/@9X(!`"`$&P$0(`(`(``;`1`$`2$( +M!!L!$`2:`!"`"_`O`)P**`!F[R<$/@X0@#GO+X`&\"^@8?\O``"@8:`'\"\` +MF@9@`&+O)P0^#A``,^\O#``@"`#\8$#H`0``'/Y`0!2$(0@`A&!``H0@``"# +MX&<""@`@`80A"`3ZX%<.!0`@`+X/8""W*2CN_C]`@`8`((`S`2B`!0`@!'Y? +M$%2?`@"`[?DO@`,`(`/\@`'$AP```'R&0?$A``````8X]0("`O<````@4>\G +M`?X?8`0^#A``*N\O&O[_F0``P&%W_A]@H.$C*#_^)T``?+]A8+$"`#R!)@@@ +MWR,H=_X?8``=YV<"`P`@`+X/8`!\7V"\R`(`H$HI*$+^)T"`__\G/($&"`MZ +MX%<&`0`@"GK@5P8!`""@1N\G`?X?8"`W_2\+_A]@.($&"``!X&@.N\G````4`0^#A``&.\O``'@863^7X(" +M`P`@`+X/8`!\7V"\R`(`H#4I*`-^*4"`__\G#(`'"`!\WV%@L0(``'Q`0.@! +M```97`@```(()`"`\`0<( +M`GK@5PT(`"`$B`@(``'@9P/^'V`"?!]@!````(`4_2\@X1$H2'\'0``!X&>! +M+``@`+X/8`!\7V"\R`(`(!\I*"%^*4"`__\G`?KF5P(E`"`\`2<(!OK@5XTC +M`"`"B`@(`GK@5P(5`"`"^N!7C20`(#0?!Q!Q_A]@H*@C*"U^*4`$B`@(``'@ +M9P`@"%("`P`@\O`)H&8"#($2A(?P=```'@9X$3`"``O@]@`'Q?8+S(`@`@!BDH17XI0(#_ +M_R<$>N!7`0,`(`"^#V``?%]@O,@"`"`"*2A*?BE`@/__)R#R_"\&_A]@!(@( +M"``!X&<'_A]@`GP?8`@```"`[OPO(+L1*$A_!T```>!G@08`(`"^#V``?%]@ +MO,@"`"#Y*"A8?BE`@/__)P'ZYE<"F^9G`OWF5P(````"O@]@0E`I*&-^*4`@ +M]^XG`"`(8`0^#A"@S^XO*/Z?80``X&&@]O`O`((`8J#W\"\``,!A`GK@5[W^ +M/YJ"`0`@("@.*``$"`@`*0`@``0?"(C>`@`!>N!7`B<`(`!\OV%")``@!7KG5X4C`"``?-]A6*T"`!!^"$`@WA@H"GXG0``!X&*!@`@<($F"!2```B@R_PO*(`@"```X&%P@08((!4`*/^%+0@`'@!H +M``_@'P(!G`0P`(`"^#V``?%]@),@"`*#$*"A)_BA`@/__)P`$'PAXG*/Z?800^#A`@B.XO`()`8"!ZX5<`@B!0 +MBP,`(`!\7V`DR`(``'P_8&P%``"@LR@H`+X/8(#__R<``>!G`1,`(`!\GV!8 +MK0(`0P1B"`+ZX5<@!*((`@X`(`P`8`@`B&$(%?KAAT#^8FA$`@`@(`9"$+__ +M8F`@!D(0`(YA&"0```@``>!G@0(`(`($``@">N!G@@0`(*`$`"!__P%@!GX! +M@`!\`$`XM@(`)@@`"`!]X&?8#P``@@(`((#^`6@@`$(0(`$`(``.8!@`BF)@ +M`(?B5P)\/V`!````()ON)P""`&`$/@X0`'GN+]W^/YH``.!A>/X?8*`K(R@> +M_BA``'R_86"Q`@`\@28(("DC*'C^'V``G^=G`!S'40(#`"``O@]@`'Q?8+S( +M`@`@E"@H(/XH0(#__R<\@08("7K@5X4*`"``,>\O````8@```%`\@080>/X? +M8*`?(R@M_BA`!7Y?$)&M`@`\@48(`)X'8*"\#B@+_C]@!/X?8#R!!A``?!]@ +M```"`("V_2^@*N\O`"`(8``"`"!X_A]@(!X_A]@(`@C*"E^)T``?#]@I+,"`);%``@!>N!7`0,`(`"^#V``?%]@ +MT,@"`"!R*"@J?B=`@/__)P```%"6@4`4`&G]+P`!X&>";>XG('(`*`3^'V`` +M;.XGN/X?8"#](B@U?B=``'P_8*2S`@"6Q0`(`7K@5P$#`"``O@]@`'Q?8-#( +M`@`@9R@H-GXG0(#__R<`7_TO`7K@5P$#`"``O@]@`'Q?8-#(`@"@8B@H//X_ +MF(#__R<```!0EH%`%`!?[B<"A"8((/`B*+K^'V`#A"8(H.XB*+K^'V``O@]@ +MH)0H*`*$)@@!?E\4;-\"`"!4^2\`F@9@`%CN)Z"['R@`F@9@`/W_)P-\@`'( +MCP```'R&0?(C``````8X">KU]?7SL/6PT+>PN@FP];"PL/BPL+"P]?7U]?6P +M];#U`````$_N)P0^#A"@*>XO)/Z?80```%#_@4T0"/X?8@!\_V$``"```'S? +M8:2S`@`(H`<4H(,,*/__#4```:!A`0(`("#$_R\,@`8(H&T,*`":!F"610<( +M``'@9P+Z_R?_A0T(``'@9X+X_R>@4^XG)/Z?800^#A"`&^XO&OX?F@``X&%X +M_A]@H-`B*%Y^*$``?+]A8+$"`#R!)@@@SB(H>/X?8`"?YV<`',=1`@,`(`"^ +M#V``?%]@O,@"`"`Y*"A@?BA`@/__)SR!!@@,>N!7`@@`(*`?_"\)_A]@>/X? +M8*#%(BAI?BA`!7Y?$)&M`@``?!]@```"`(!?_2\\@48(`)X'8"!A#B@*_C]@ +M@,T+*(`&`"!X_A]@H+XB*'5^*$`\@08("7K@5PX#`"``O@]@`'Q?8+S(`@"@ +M*2@H=GXH0(#__R!G +M@@@`(/Z%#0@!>N!7`AH`(!V@1Q`*?@=`(#`9*`1^)T``?!]@W)@"`"`N&2@* +M?B=``@0J"/^%;0@`'`=@(&((*`"B2&``$P`@`'S_8>#@`@`8_@=``)PI0*"1 +M[R\#_E]@`'S?8<&[`@``($<0(`8`(/^%#0H8_N:G`)X<0!Y^`$``I"A`((SO +M+P"F26`!_@9```Z@&0``1Q``I`E```Y`&@`EZ%<,!@`@`*0(0`$$``@"?@!` +M`_KF5P`.8!J+]O\G`+X/8`!\7V`HR0(`(/\G*,_^/T"`__\G()\'*`":!F`@ +M"^XG-/Z?800^#A``T.TO(#P7*```H&$,^@9@1/[?@0(#`"``O@]@`'Q?8-#( +M`@"@]BN!7`GW@5P0````!`P`@`+X/8`!\7V#0R`(`H/$G +M*!A^)T"`__\G`'P_8```(```Q``(!/KF5P$:`'`"?`!@\____P"`0!2@\!DH +M````4`#J[2<`@B!0!@)`$`4"0!`2`D`0"`*`$`H"0!`+`D`0!`)`$!,"0!`, +M`@`0!P)`$!$"0!`0`D`0&`)`$!P`(`@`?H`0#H@@"`("@!`@@`\X````4`0^ +M#A"`T.TO`'S?8I3>`@````L(&OX_FPP`(`H`?+]A6*T"`!R`"`@`JJI2#'Y` +M0I#^'V!8@$@0"OX&0*#S&"AH_BA``'Q_8IC>`@``@`D((JJ($`!^`!0`?/]A +MG-X"``"`!P@!_C]@`'X`%`!\'V.@W@(````,"``"`!1#A"8((('[+P`D"6`@ +M`0`@`"B*4@`J1Q2`T^\O"WK@5P(S`"``?-]AI-X"``!$!P@!@#^````?"*C> +M`@``0``(``/@9P$K`"``1`<(`8`_@`"`"0@`0``(``/@9P(H`"``1`<(`8`_ +M@`"`!P@`0``(``/@9P(E`"``1"<(H%(B*'K^'V`@>_LO`*((8`!$!P@``+\) +MK-X"``-^`((`H.9"`'P_8%RL`@`@M1" +M`P`@`$0'"`"`*0@!@%^``,``"``$`&@`@``4@`$`('K^'V`@+R(H4/XL0`!$ +M!P@!?@!```!'%`!$!P@@>N!7`LS_)P#+_RNI7`9HD*'O^'V`@*2(H8?XL +M0```#`@`*@`4`*#M)P0^#A"`;.TO`'S_8<"]`@`@GN\O$(&G"09ZX(<#DNTG +M`/D)*``!X&>"D.TG`)OF9X&/[2<,@,8)$@0'"(!ZX%TO`OX_8`!\WV%6D``` +M`'R_8=3*`@`:?@=`@/]&0"`[(2@`AF%0'WX'0`+^/V""_T9`H#@A*`"&85`> +M?@=``OX_8(3_1D`@-B$H`(9A4")^!T`"_C]@AO]&0*`S(2@`AF%0(7X'0`+^ +M/V"(_T9`(#$A*`"&85`"?@=``OX_8(K_1D"@+B$H`(9A4`-^!T`"_C]@C/]& +M0"`L(2@`AF%0`!P'8`+^/V"._T9`H"DA*`"&85`!?@=``OX_8)#_1D`@)R$H +M`(9A4`Q^!T`"_C]@DO]&0*`D(2@`AF%0#7X'0`+^/V"4_T9`("(A*`"&85`. +M?@=``OX_8);_1D"@'R$H`(9A4`]^!T`"_C]@F/]&0"`=(2@`AF%0$'X'0`+^ +M/V":_T9`H!HA*`"&85"`*>TG!#X.$"#_["\<_I]A`'S?80V%````?+]AU-`" +M``E^!T`"_C]@EO]&0"`4(2@`AF%0``H?"$2Q`@"HB28(`(``4/Z!C1`.?@=` +M`OX_8/[_34`@#R$H`(9A4````'P`0`"D````$``8@/X_8"#^1D`@EB`H`(9A4`%^ +M!T``#L`9!'KG5POZ_R>`_P=`@/X_8*#^1D"@D2`H`(9A4`!\OV'4S`(`P/\' +M0(#^/V`@_T9`((X@*`"&85``G@=@@/X_8*#_1D"@BR`H`(9A4$#^!T"`_C]@ +M(/Y&0"")("@`AF%0@/X'0(#^/V"@_D9`H(8@*`"&85``?+]AU,X"`,#^!T"$ +M_C]@(/]&0""#("@`AF%0&'X(0`+^/V"D_T9`H&D@*`"&85!-?@A`0/X_8*C_ +M1D`@?B`H`(9A4`!\7V!`T@(`/GX(0`+^/V`@9"`H`(9A4*"$[">(_I]A!#X. +M$*!'["^D_A]@()(@*`""(%``?+]AU,H"`*3_!D`N_C]@H*`@*``$05``"!\( +MC+T"``!\WV$``"```'W@5R-"``""`P`@Z/\&0!;^/V`@FR`H``1!4!A\!Q0B +M,@```&;L)]3_!D`4_C]@H)<@*``$05`8?`<4`!`````$'PBPM0(```'@9QS^ +M!D`"_`9`&`````+^/V`@DB`H``1!4`!>["<$/@X0@##L+Z`#`"``FJ91!/\! +M0!#^/V"@C2`H``1!4`'^!D``#J`9#_KF5PE7["<`?']@D+X"``""(%`'^N!7 +MB?G_)P/^!H```@!H@'Y`:`""`$``!@!`!`5`$`'^`$`@^_\G``X@&``$'P@L +MO0(``(`/.(#^?T!"^N!7`?X_8`&"(%`(_B"``(9`0`W^(8``>N!7#,``"`$" +M`"`(A``4```!:`R``!2``0`@``0`<`R``!0(A``4`(`/.`!\GV```@```'Q? +M8*2S`@```>!G#'XB@`$0`"`!_A]@C@%!$`S`8`@(@``4`?X!:`R``!0`0!\( +M=-\"```!X&>!`@`@#,!@"`+^'V`(@``4`OX!:`R``!2,!0$(`7K@5P(#`"`, +MP&`(@/X?0`B``!0`_`%H``$```R``!2-!0$(`7K@5X(&`"`,P``("(@`%``( +M`&@,@``4``0`(````%".`4$0#,``"`!\`&#\_O__#(``%`C\`!0#`0```(`/ +M.```'PB0O0(``(`/.`0^#A``_>LO@,W_+X"X_R^`/_\O`*G^+P#)\"\``!\( +MD+T"``!G]"\`^?\OH!GT+P""(%``=APH@"/L)P0^#A``^.LO```?"$2_`@`, +M>N!7AB'L)P##["^@4PHH``"@82#$["\`F@9@@![L)P0^#A``\NLO`+_L+P!\ +M7V`,X`(```"A"0""(%```A\0$.`"`""^["\`?@$0`)OF9X$!`"`@H"0H`)H& +M8(`6["<@%NPG````4`0^#A``Z>LO`+;L+P!\7V`4X`(```"A"0""(%```A\0 +M&.`"`""U["\`?@$0`)OF9X$!`"`@ER0H`)H&8(`-["<@#>PG````4`0^#A`` +M^>LO``"@80""0&(@K.PO`)[G40``(&(`1!\(_+P"``%ZX%?A_O]"@@$`(`'^ +M_V&@7`TH`?X?8*"F["\&_M]B````8B!I\"\X_A]@`'S?8:2S`@"0"8<*`'R_ +M8@"(`@``*FI"`"J*00`L1A``F@9@`*8I8"#>("@X_E]@`"JJ0@"L2A`8A`8( +M`WK@5P$#`"``O@]@`'Q?8-#(`@`@^B4HW?X_0(#__R<@A"D(`OK@9P$#`"`` +MO@]@`'Q?8-#(`@"@]24H`?XK0(#__R<$^N!G`0,`(`"^#V``?%]@T,@"`*#Q +M)2CB_C]`@/__)P'ZX&"`0`@H`\!*""$!@@@A"D(CP-'%)0%!P@X_C]@`8!) +M$`"$"0@!_E]@H,PD*``D:6"@=>PO`"`(8`'ZYU>A)@TH`0``4"!S["\`H@A@ +M@-?K)P0^#A``H>LO`'R_80S@`@``@`8(``'@9P+*ZR<``!\(%.`"```!X&<" +MR.LG`'P?8/"S`@"@8PXH__\_8``!X&>!^?\G`'Q?8-C(`@``?#]@8@<``*#$ +M)2@`O@]@@/__)P0^#A``I.LO``!@8@""P&$`!*%A`(9!8@`((F*@7^PO`)[G +M40```&(`1!\(_+P"``%ZX%>"`0`@`?[_8:`0#2@!_A]@`!P?%'#?`@``&A\4 +M=-\"``%ZZ5A +M"`TH`0``4"!5["\`(`A@@+7K)P0^#A"`A>LO``"@80""P&%C_A]@H#\@*`": +M)F``!!\(++T"``"!YE!7"@8`(``$(4``D$`8``@_",2M`@`!?@!``(1@8"8( +M(@@`@B)@`(?@9P`.`!@"@`\X`/G_)R"`#S@`C@-@!GX@@`!\7V#,M@(`;'\! +M0``"@$`V!.((*03""`&.'X``$"`8L`FA"`".`V``#>!7C`4`(`"$(!@`"%\( +MQ*T"`/]_`$```F%@)@A""`"$0F``!^%G``X`&`*`#SB`^?\G((`/.`".`V`$ +M/@X0(%;K+P9^0(``?#]@.+8"``"$`$$V!"0(-P)$$#@$)`B@X/\O-@)$$"!^ +MZR%7C%_K)S>$QPDV +MA&<*.(1'"@```%`\@$<0/8!'$*`A[2\'?@&`8("&"```8&$")@(``*:'0@`6 +MX*=`_AQ`!WX`B``.(!DJ`$H0`)P'0"H$(`@`I`=`*@0`"/_ZX%E7@@0`(`"'X6*#@`@@`T`(`"#Y%<*#0`@``P`(`"=Z5%G`@4`(`"!Y%>*^/\G@`,`(`"!Y%<*!P`@``(`(`"#Y%<,`@`@``7A9X'\ +M_R<@!``@`?X_8@"#Y%>*`@`@``7A9P(!`"``@>17C/C_)P+^/V(`H^AG@0\` +M(`'ZZ%>"#0`@H*__+P`@"&``#0`@`'S?85BM`@!#!"<(`OK@5P+]X%57A@,`(``('PADWP(``('I5XP!`"`@AO\O`"`(8$,$)P@` +M@^!G@@,`(*^%!@@`@>57I8+_+P4@"&```0`@`OKH5P'S_R+`0`@H*O_+P`@"&`J$DH04(`&"#:$)P@"`@`````? +M$`3W`@"`)>LG!OZ`@`!\?V#,M@(`;/\A0`"(@$`\!"((`GY!@`"`($`\`D(0 +M``:!0#`!(@@`@"!`,`,"$&2!(0@`@"!`9(,!$&B!(0@`@"!`:(,!$'"`80@` +MA"$``(``0`"$04`@@`\X```!$`9^`(``?%]@S+8"```$8$"IA0$(`7X`0*F! +M01`"_@"```0@0`"!``@!?@!``($`$&0!`0@!?@!`((`/.&0!`1`&?@"``'Q? +M8,RV`@``!`!`H@4`"```($!<``$(((`/.`0"```$/@X0(./J+P`(@E```,!A +M#`"@"0""(&(1A&8('(#F":#^06"@>N%7!X0F""$"`"`(A`<*`?X`0``.(!@' +M@$80G_X!8`%ZX%<"?>%7H`````)\GV`!````$80'"`AZX&="`0`@!H1&"`6$ +M1@@`A`!`!X!&$``(`4``#@`8%X1&"*#6_R\`("A@$80&")]^`&`!>N!7`1`` +M(``$7PADLP(`!X0&"``%X%@!@`?X@0`"08!@7A"8(H00`(`+^0(``?)]@?/<" +M````(@@`AB!```("$```GP@TMP(`@`,`(`!\GV`8]P(````B"`"&($```@(0 +M``"?"#"W`@``!"(``(8@0``$0D```@$0!X0F"`!\7V#@]P(``?Y@4```(0@` +MAB!```(!$`!\7V``^`(````A"`*(9@@`AB!```(!$!&$)PB`^N!G`@$`(``! +MX&>"`0`@%X0F"*"W_R\`(`A@H&;_+P`@"&"`R^HG`(`/.```/PBXW@(``(@@ +M"`"#X&<"@`\X@'K@9P!\/V#,M@(``0(`(+#]@!"G#P``(`(`(`C^`$"P_8`0 +MYP\``/S_`$`@@`\X8(``$`0^#A``E.HO`(_^+Z"O\B\!_C]@`'R_89B]`@`` +M"A\(;N`"``C]AA!8`@``)7[@IPC^')"4?B!`&X4&"`3]!A``AY,#`('@5Q2# +M!A`+"``@&(7&"1F%!@@:A28(H'[L+P%^`$``'>=G`(X`&`("`"`!_A]@&(%& +M$"`&`"`9@T80``'@9QF#1A`"`@`@@`,`(````%`8@480&8%&$"#M\"\```!0 +M&WK@5PP!`"```@`H@*CJ)R"J["\```!0`*?J)P0^#A`@=^HO````4``(/PB, +MO0(``/W@5R-"``!!/^\O!/X?8``!X&>!G^HG@*?L+P5ZX%<%GNHGH*'L+P'^ +M'V``?!]@```$`(#,^2\`F^HG!#X.$(!OZB\`I^PO`'R_83RT`@`IA28(`?X@ +M0`]ZX(N!7@97J)P"2!"@#>N!7`93J)RF%!@@`@/Y7 +MAI+J)R"\&B@"_A]@``0?"%2U`@```>!G`00`(`S_!D"@*PTH??X_F`!\/V"( +ML@(``(``"`%^`$``@``0````4```'Q`TM@(````?$#"V`@"@B.HG*8%&$`0^ +M#A`@6>HO`OX?8`"P&B@`?!]@2+,"`*`A#2A]_C^8`'P_8'R_`@`(@0`(`($@ +M""`!^R\,?@!`H'_J)P```%```%\0I+P"``"`#S@$/@X0H%+J+QC^GV$`A.PO +M!7K@5X8(`"`@(1`H_/\-0`!\OV&8O0(``($&"/R!+0@`@"!0!($&"`"!X%>. +M`P`@`'P?8`````$`I?DO`?X?8!"!1A#\@0T(`($&$*"&ZB<8_I]A!#X.$(!% +MZB\`""P`@!/X_8&"#1A#P_R9`4((&$/3_ +M)D!4@@80^/\F0%B"!A#H_R9`7((&$&3\!A`<]P(`:/P&$(#W`@!L_`80-)8" +M`'#\!A"@E@(``_[_8>3_)D!@@@80(`P`(`/^/V`,_C]@8(-&$"S^)D!0@@80 +M./XF0%2"!A!$_B9`6((&$!3^)D!<@@809/P&$$SW`@!H_`80L/<"`&S\!A!D +ME@(`%7#`,`("8((@@`A^!G`?S_)P*$(@`!^N!7@OK_)U"`(P@"A"``)`)$$!P` +M(`@7!$`0$H0`"`%^`&@@@`\X$H!`$!P`(`@`?']@S+8"``B$(`@&_B"``(8@ +M0**%(`@`@D!`7(`A"`2$(``#_D"``@@@"`"$X*<0_ER0`!`A&``$@!`@@`\X +M`((`8!P`8`@`?)]@S+8"``B$(0A0`*((!OY`@&Q_(D``A$!`-@0A"`*"(@`D +M@D$0-@0A"!P`8`@7`D`0$H0A"/[_(&`2@D$0-@0A"%0`8@@"@D$`'``@"!*$ +M``@```%H((`/.!*`0!`$/@X0H-+I+P```&$`@J!A!OX@@`!\?V',M@(`;/\% +M0``"($$``!\(N-X"```(``@``>!G`@``82:0A!"@#!DH`)H&8#:$1`@!A!^` +M`!'@9P()`"`IA"0(``/A5XL!`"`HA"0(``/A5PP!`"`@`@`@-H)$$"!*_B\` +MF@9@-H0D"%"`!0@"`@`````?$`3W`@"@=?XO`)H&8``/`"``!!\(FZT"```$ +M/P@AL`(``('@5P$,`"`!^N!7`7W@5P(```""`P`@=(`%"`%^`$`#>N%7=(`% +M$(('`""@!``@!?X?8`+ZX%!7`0````(#`"!X@`4(`7X`0'B`!1`#_A]@ +M(`(`(#:`1!!\@`4(`7X`0'R`!1`@2OXO`)H&8#>`1!`@._XO`)H&8*#9Z2@!0!'P`0`,````"?@"0("8`(`Y^ +M`$``>N!7#"@`(`YZX%<))P`@(",`(`%^`%`(>N!7"P0`(!!ZX%<)`P`@"'H` +M4`1\`$`#`````GX`D"`>`"`2?@!`(GK@5PL$`"`P>N!7"0,`(")^(%`?_@"( +M``(`0``"`!@@&0`@%7X`0#1ZX%<+!``@0'K@5PD#`"`T>@!0!'P`0`,````" +M?@"0(!0`(!U^`$!D>N!7"P0`((QZX%<)`P`@9'H`4`1\`$`#`````GX`D"`/ +M`"`A?@!`D7K@5PL$`""9>N!7"0,`()%Z`%`$?`!``P````)^`)`@"@`@+'X` +M0)MZX%<+!``@G7K@5PD#`"";?B!0'_X`B``"`$```@`8(`4`("]^`$"A>N!7 +M"P<`(*5ZX%<)!@`@H7H`4`1\`$`#`````GX`D#%^`$```$$0((`/.````%`! +M^N!7`OW@5P(````!U_\G((`/.`'^'V`$/@X0H#GI+XS^'V``?#]@FP0``"#V +M'2@%_K]A`'P_8%RM`@!UA0`(`7K@5X(!`"````!0=8%`$`;^OV$@7NDG`(X& +M&`0^#A``.^DO1/X_@@!\OV%HW@(`((T%*``@"%(`?>!7__\``"$$`"``GN=1 +M`'\%*```P&&@?R8H`)HF8`)ZX%=!`0`@`?X?8@":QF&,_A]@(.8=*$7^*$`0 +M@`8(``'@9X(!`"`4@`8(``'@9X$$`"",_A]@H.$=*$G^*$``'`=@(/TD*``@ +M*&`">N!7`G[@406>YU&@3NDG`)X'8`0^#A"`'>DO@.KI+P!^7Q!BK`(`H$`F +M*```H&$``>!G@0(`(`!\/V!@!```(-<=*(S^'V"`]A0H(.?I+P":!F"`0>DG +M!#X.$*`:Z2\D_I]A??[_F8S^'V"@T1TH"OXG0`!'ZR\!>N!7@00`((!#ZR\( +M>N!7`0,`((`W`R@">N!7@0$`(``V`R@#>N!7`@\`((S^'V`@RATH%_XG0`!\ +MOV%HW@(`$(`&"``!X&>"`0`@%(`&"``!X&>!"0`@`-3I+P``P&$!?E\08:P" +M`!#^!D``FB9@H&8F*/C_34`">N!7`@(`(`"`!@@0@`80!(`&"!2`!A"`WA0H +M(,_I+P`^PL_'Q\<```0^#A``RN@O``#@80!\/V`]`0``H($=*%C^'V"`C^DO`'Q_ +M8/"M`@``@4$(`'PA8`#_```(_L")!G[GIP">/$``AB!`!(6@"0!\06#_`/__ +M"/XF@`"$(&B@BNDO`(,!$%7^'V"@=QTH`!PG8%;^'V`@=ATH`)XG8%?^'V"@ +M=!TH`)HF8`3ZYE<"XN@G`+X/8"`\(RBV_C]``.#H)P/^/V`8`D`0`OY?8!D$ +M0!`/_G]@'`9`$'_^/V`;`D`0(@9`$",&0!`H!$`0+01`$#($0!`W!$`0`((@ +M4"0"@!``@H!A*1A`$`A^AHDJ&$`0+@*`$#,"0!`(_B"(-`)`$`!\/V#_`P`` +M)@*`$`""@&$K&$`0"'Z&B2P80!`P`H`0-0)`$`C^((@@@`\X-@)`$`0^#A`` +MG>@O`'R?8`RN`@"@Z_\O3'\"0`?^/V"(`T(0`?X?8``"'Q"DF`(`(,7H)X\! +M0A`$/@X0()GH+P```%``G/\O`'R_80RN`@"(A08((!+]+X^%)@A,_P9`H+/\ +M+P""(%"`ZA8H@+[H)P`!X&<"``!0!7X`@`!\8$!0IP(``'R_8+S>`@"@"0`@ +M`((@4`""@$``B`%`&`C`"`S^X*<`BIQ!``P&$`@(``@`BEQ`"`"!$`2(`0`& +M`($0`(*!0!`$`@@$`($0%`0""`H`01`!_@!```X@&`3ZX%<+]O\G`(`""`!\ +M/V`,K@(`<(&`$`B(`@AR@8`0!(@""'2!0!`,@`((=8%`$`A^`(AV@4`0%(@" +M"'>!0!`(?@"(>(%`$!"(`@AY@4`0&(`""'J!@!`@B`((?(&`$!R(`@A^@4`0 +M)(`""'^!0!`(?@"(@(%`$"R(`@B!@4`0"'X`B(*!0!`HB`((((`/.(.!0!`$ +M/@X0`'+H+P'ZX%=#_K^!`0,`(`"^#V``?%]@M,@"`""<(B@1_B9`@/__)P!\ +M'V`HL`(``%@+*``!X&>!EN@G`+X/8`!\7V"TR`(`H)8B*!3^)D"`__\G!#X. +M$`!GZ"^@F>HO&OZ_F0MZX%_X?8"`>'2@(_B9``(KH)P`$/PB;K0(```A?"#ZQ`@`` +M*P@@!#X.$`!JZ"\`!!\(U:T"```!X&@*/PO````4"!^&"@`GN=1/(0&"""\ +M_"]#A"8(`)H&8*!=_"\`@B!0`&P?*$.$!@@``>!G`'P_8$2Q`@""`0`@`)Z` +M$"`!`"````!0`(H`"`!2$"B`D/4O````8CP!!P@,>N!7@@L`(```'PA4V`(` +M$'X`0"!\$R@*_B9`(`7^+P'^/V)LB`8((%[^+P""(%`9A`8(,'X`:!F`1A!# +MA`8(``'@9P'^7V*!>Q8HD`4'"``!X&>""P`@`?X?8*`*`""0`4<0``'@9P$# +M`"``O@]@`'Q?8+S(`@`@52(H!!``@;OX?8*#7'"B- +M_BE`.`$'"`K^/V"@=0@H`"!(8"`!`"`X'P<0@#[T+X#@!2@`11\H@`46*"#* +M%B@```!0``T`(``!X&<"`P`@`+X/8`!\7V"\R`(`H#PB*)_^*4"`__\G#'KH +M5P$#`"``O@]@`'Q?8+S(`@"@."(HH/XI0(#__R<\`2<(``/H5P("`"`*_C]@ +M(&8(*``@2&"`T@4H.!\'$*!I_2\```!09!]'$``>'Q`(^`(``!X?$`SX`@!N +M_A]@(,`<*`?^/X`\`2<(H+X<*&[^'V"`,.@G!#X.$"#^YR\```!0```_"/C> +M`@``?+]A6-@"`""`0!`@_A]@!8!`$`"`!@A`_C]@``)`$"#-$B@0?@!``(`& +M"*#+$B@$?@!``"'H)P0^#A"`].*``` +M`%"@R_LO`?X?8``0Z"<$/@X0(.;G+X'^'V"B_M^!H*`<*#5^)T``!!\(7M\" +M```!X&<"!@`@@`<"*`)ZX%>!!``@``8"*`-ZX%!`0`@ +M`"P$*`!ZX%>,!0`@@?X?8""7'"A#?B=```2_"22Q`@``.@`!NHO`7K@5X("`"``!^HO`7K@5P(!`""`JPN!7`OOG)P`#ZB\!>N!7@OGG)X'^'V"@BAPH87XG0`"U_B\!>N!7@O;G +M)X'^'V"@AQPH9WXG0`#1!B@!?E\0`[$"``#SYR<$/@X0@,7G+P#ZZ2\``>!G +M@>_G)P!\/V`"`P``(($<*('^'V``?+]A!+("`*"L"B@$_P9`)($&"`%^7Q!= +MWP(``7X`0"2!!A``?!]@```!`(`7]R\`Y^!G`@``4`%\ +M'V`!````@`[_)P0^#A"`I>"`@`@ +M("D>*`'^'V````!0D`%'$&H%)P@!_A]@`'R_8538`@`!^N!7`(!&"*(#`"!D +M`4<0<'\'0*#8$B@$?B%`A'\'0*`!`"!`?R=`A'\'0`1^(4``U1(H`(`F"'!_ +M!T"@TQ(H$/X@0`!\OV%8K0(`0X0&"#S^)D```%\0(;`"`&A_!T"@CAPH*/Y? +M8$.$!@@``>!G@@T`(""$!@B,!2<(7G\`8$!^`&@@@$80'X0&"`"#X&<"?`!H +M!`````%\`&#[____(`L`(!^`1A`@A`8(/WX`8*`$`"`A?@!H4H@&"""$)@@5 +M>N"'7_Y`8*0!`"!!?@%H'_X`8`%^`&@@!``@((!&$`%ZX%!G`@,` +M(`"^#V``?%]@O,@"`*";(2B%_B=`@/__)Z!*]2]#A"8(`'P?8````@``QO8O +M@)?G)P0^#A``:>N!7`?K_ +M)P!\/V"?`P``H.`A*`"^#V`X@`8(;/XF0*!#]2\!_E]@;(@&"```GQ#TW@(` +M`'_G)P0^#A``4..`P`@`'Q?8/C(`@``?#]@,P$``"!\(2@` +MO@]@@/__)P``'Q!LMP(`@';G)P!\OV#\W@(`(`,`(`"&85#P_B!@``(A:#H" +M0A`!_B%``(Y@&``&($`#A"`(`(/@9P"*04`!!@`@!`)!$`"$(1@`BH!``?KA +M9SH$(@@B^/\G``1`"`_^(&`$?D&```(A:*#V_R<`CB`8`((@4`0"01``!"`( +M`@2`"0""0$`!!"`("'Z&@0"8(&@`"@%`((`/.%8"@!``?#]@_-X"`*`_'"!@ +M_E]@!#X.$``TYR\`(/XO`7K@5X)?YR>@&OLO````4*#%'2@!_A]@H&S^+P'^ +M'V"@BO\O````4`!\/V!8K0(`&80`"-]_`&`9@$`0``0?"&;8`@"`SOXO`%?G +M)P0^#A"@*^N!7(@0`((S^'V"@Y1LH +M#?XF0```/PAXW@(`H.,;**3^'V"``@`@(.(;*!/^)D"@)OXO!/X?8`!8%RB` +M.0@H`7Y?$&*L`@``^_HO``0_")NM`@``^0PH`$GG)P0^#A``*>N!7C`0`(`Z%!P@``>!G`@,` +M(`"^#V``?%]@;,D"`*!!(2@!?BE`@/__)PP`IPEB_A]@'(`&"J#/&R@`'"=@ +M,`0("`QZ(&"!`0`@_'X`8$AZX%<"'0`@#H4'"``!X&<"`P`@`+X/8`!\7V!L +MR0(`H#!G`0T`(`"B*%*@[0DH`*-'$``!X&N!7`B3G)WW^'V`@L1LHH/X_0"`N!"@`'`=@`"'G)PCZX%!`P`@`)H& +M8""R]B\`@B!0`HD'"/]_`$`@%^N!7`0,`(`"^#V``?%]@ +M;,D"`"`0(2BS_C]`@/__)X#^'V`@$>8O``#@80!\WV'` +MO0(``@D'"``!X&>[_C]"`0$`(`)ZX%>,!``@#@4'"``!X&<"`P`@`+X/8`!\ +M7V!LR0(`H`0A*`'^*$"`__\G#("G"6+^'V`<@`8*H)(;*`">)V`P!`@(#'H@ +M8($!`"#\?@!@2'K@5P(/`"`.!0<(``'@9P(#`"``O@]@`'Q?8&S)`@"@^B`H +M#?XH0(#__R?_?P!`#@%'$`/^'V`2@$80(!L(*`">!V`,@`8(``'@9P$/`"`` +MLPDH``'@9P$#`"``O@]@`'Q?8&S)`@"@\2`H'?XH0(#__R<```!0H`D`(`R` +M!A`(^N!7`0,`(`"^#V``?%]@;,D"`"#L("@Q_BA`@/__)P":!F`@AO8O`?X_ +M8`()!PC_?P!``@&'$`/^'V`2@$80H/SV+P">!V"`3_DO`.?F)P0^#A``N>8O +M`'R_86RX`@`@[>@O!($&$`]ZX(>B_M^!A`,`(`2!!@@`?>!7`````@(&`"`` +M3"(H`WK@5X($`"`O_A]@(&T;*"!^)T`!_A]@"(%&$`!\'V```"````?V+X#7 +MYB8O`-KH+PIZX%<"?>!7"0`` +M``)]X%<$`````GW@5P,```""`P`@`WK@5P)]X%<)````0:7]+PC^'V`@JQ8G!#X.$""CYB\@_I]AH,_H+Z?^_T$(>N!7@00`((#-Z"\" +M>N!7`0,`(`"^#V``?%]@^,@"`"#%("@!_B=`@/__)]3^'V`@5!LH`_XG0`!\ +MWV'J<1PH`?Z_88#$Z"\(>N!7`IJF40";YF>!!@`@('7Z +M+P```%``>/TO``&@80(#`"``O@]@`'Q?8/C(`@"@N"`H$_XG0(#__R>@&QTH +M`?X?8`#%%B@`F^9G`0P`(/S_#4`@\B0H`?X_8(#C`B@`$"`8`/W@5___```! +M`@`@_($-"`"!X%>&```@_(,-$`!=&RC\@2T("?K@5P4!`"```>!G`@,`((#1 +M&R@`?!]@6*T"`*";^B\`@B!0``<`(``$!P@!_C]@!'K@5PN"(%`%>N!7`?X? +M8`L``%"@(A"R`@`"GAP```'@ +M9P#RW&&!`@`@`)P'0*!T&"@`@B!0`![G00#^1Q`!_@9```Z@&03ZYE<+^/\G +M`"'H9X$&`""`*.8G`'K@5P"` +M7U#+`0`@`(0`$`"``!```$!@0'Y!0`=^09``>N!7`(0`$`H!`"``A!]0`(`` +M$`"`#S@$/@X0H$SF+P`$05``@J!A`'P_8`"````/_I]@``"@8``$84``@F%` +M`(AA@/]_@D``B^%7#H1`0`Z&HE``A2`8@OO_)P=^P8$`!.&G`',`4`(%X6<' +M?@"`(J/G+P($(4`"',!!`)P&$"!JYB<```!0!#X.$``\YB\`9``H``'@9P%F +MYB?__Q]@H*,7*!S^/V``80`H`WK@5R$9_2\`FJ91`'P?8,"\`@`$&P`0"!M` +M$``;0!``&E\08ZP"`"`E`R@!&T`0`!H?$/3@`@"`7.8G!#X.$"`SYB\@_I]A +M``!@8`!\7V!(R@(```$!"`""(%#X@0T0!`$!""!4`"C\@0T0``'@9X(1`"`@ +M'`$H`?X?8`!\OV'@X`(```$`(`'^`$``#B`8&/[@IP":7$`A!`$(``'@9P$! +M`"``@^%7B?O_)P!\WV'`O`(```-'$`_^'V`?`$$0'OX&0`!R`$`&?@!`(',C +M*/C_+4```>!G`@$`((`+!RB``P`@``4'"`!\/V`?0@``&'[@IR3^!D"@?08H +M`'(`0"!7YB<@_I]A!#X.$"`7YB\L_I]AZ/\-0`""(%"@W^C_#4``@B!0(-#G+QC^7V#0_A]@Z(%-$````%#I@4T0 +M`'R_86*M`@``F@9@H$@1*.S_+4``?!]@W)@"`*!&$2CR_RU``)H&8"!%$2CX +M_RU``'P?8L&[`@``!`@(``'@9[3_S4$"`P`@`+X/8`!\7V`HR0(`("4@*.'^ +M/V"`__\G`*(H4@!\_V'@X`(`(`<`(``?BE`'P0)"`)^`$``&J!!`?X(0``.(!H`!`@(`('H5XOX_R<:A"<( +M`)P&4``.8!CH_PU`H&@`*``<1V`@)N8G=/Z?8:#%`"````!0!#X.$*#IY2\@ +M_I]A``@?"*ZM`@``?+]AX.`"``I^P($4@`8(``'@9X$&`"``F@9@"/XF0*!# +M(RCX_TU``7K@5Z(&`"`"``!0_($-"``!X&>"`0`@^($M"``#YU<&`@`@```` +M4!"`!A"@P?\G__\?8!"`!@@`@`!`H+__)Q"`!A```!\(Q+L"``"`#S@$/@X0 +M(-7E+P```%"@>``H`((@4(#[_R\#>N!7`@,`(``$'PB4K0(`($@`*`""(%"` +ME@(H@+#\+P!\OV'`O`(``(4&"!A^X*<`_!Q`X.`"`"X$``@(>N!G!/X?8*"\ +M`"@!``!0H'3[+P'^'V``P/\O@/@<*````%`@\N4G`(%&$`!\/V#PNP(`Y/\` +M0*!X""``!$%0!#X.$"#7Y2],_I]A``#`80""H&$`?#]@2,H"``B!``@`!`%B +MZ($-$`R!``@`GN=1[($-$`"B*%(`?D$0H`8`(``D25(%_@I``)PG0"#(YR\` +M'D%0`_X?8`&`2A``A`8("WX`4`"`1A`+_@=0``[@&0`H2!`@"@`@`(0&"``> +M!T`!!``(`(1&"`)^`$``#F`:`)X)0``.X!D`A>=7B@,`(`"J"F``G"=`H+SG +M+P`>05``I@=0`(1&"``.X!D`)@%0`(!&$``.`!@`@>=7BA\`(`"N!7`@0`(`#$_R\``>!G@@$`(`.B2A`@!``@`"0I8*`"`"`$_C]@`ZA* +M$*`!`"``*"I@`OX_8`."2A``'@=``00`"`)^`$``'@!``(/@9P"$1@@BU_\G +M``[@&0'^9T(`G`E``)PG0"">YR\`'D%0#_X?8`&`2A`0_A]@`![G00"`1Q`` +MA`8(`7X`0`"`1A`@U?\G`([I&0```%"@Q.4G3/Z?800^#A"`A^4O(`/Z+P"" +MH&$`?!]@6*T"``";YF=`_C]@`GP_8`D````@`D`0H*'Y+P""(%``K>4G!#X. +M$`"2Y2\``(!B`((@8@`$`6(`AL%A````4`'^/V`@=@(H``1!4``!H&&"`P`@ +M`'Q?8"C)`@``?#]@!0$``*"F'R@`O@]@@/__)PR`1@H`@B!0`"0)8"!!YR^` +M_E]@*'X)0!P`"1`,?N!!H%OS+P`D"6`<`&D*`"@J8##^"4"@(N!V`@0_,O +M`((@4````%`X`$D0"`")$$B`21`!_A]@28!)$$JB21!+_@E``"`H8"`1YR\` +M'$=@`)H&8*"&!2@`@B!0@(_E)P``'PCTX`(`````.`0^#A`@8.4O)/Z?80`` +MX&$`@J!A(*X5*`K^'V``?-]AP+P"`!1_!T"@'@@H??X_F`"?YV>!`P`@``4' +M"!A^X*<`_#Q`X.`"`"Z$``@(?@!H+H!`$`";YF`&P`H@%'E +M)P-\@`'@UP```'R&0?@U``````8X[??Y`0`[_R^`3>4G`$WE)P0^#A"@).4O +M)/Z?80``P&'\_PU`^/\M0*`Z]"_T_TU`_($M"!3^'V``@(`0^(&M"0`=YV<5 +M_A]@`7P?8!8````,@$80`(@`"!!^`%`.@(80H/X?8`V`1A`0_@9``((@4"#A +MYB\$_E]@``0?","[`@#\@2T(&'[@IP#\'$#@X`(`(P0`"!"`1A#X@0T(H+OU +M+PQ^`$"@3N4G)/Z?80``7Q#(NP(``(`/.```'Q#$NP(``(`/.`0^#A"`#>4O +M`'S?8<"\`@``!0<(&'[@IP#\O$'^X`(``$']+Z"R^B\```!0@#0<*"!;%2@+ +M_A]@%'\'0*#,!RA]_C^8@"O_+P-ZX%>"`@`@@.O[+P#"`2@%A`8(H'?_+P"" +M(%"@W/\O`?X?8(`JY2<$/@X0`/WD+P"#X&<`?+]AX.`"`($FY2<&""`(`/K@ +M5P!\?V#`O`(`#`,`(`"%(0@8_N"G`)I<0"X$(0@!_B!H+@)!$`@((`@""$`( +M``/A5X$#`"``A2$(&/[@IP":7$`N!"$(`OX@:"X"01`""$`(#@@`"``%X%4G`'P?8-2[ +M`@"`U`<@!#X.$*#EY"\4_I]A``@?"`@#\@8T0(.,6*`'^'V``?%]@H-`" +M``!\'V`!D0``&OX_8"#^&"@`AF%0_/\-0`+^/V`@/QDH``1!4/V%#0@``!\0 +M;)@"`"#;%B@"_A]@(!SE)Q3^GV$`@."G____?____W____]_____?____W__ +M__]_____?____W____]_____?____W____]_____?____W\@@`\X`/8=8`0^ +M#A"@TN0O(/Z?80""(%#\@PT0``W@'_2##1"D`P`@^(,-$`!\/V!4M@(`2($` +M"`%^`$`@$@`@2($`$`!\`&#_?___`!"@&?S_#4#X_RU`(.3S+_3_34```>!G +M`@4`(/B!+0@9_A]@#(!`$`3^'V`.@(`0($\/*`":!F#T@2T((`(`(`"``!`` +MO@]@H$D?*+'^/V``?#]@5+8"`/2!#0A,FX`0````"%"!`!!$@0`(`7X`0$2! +M`!#X@0T(_($M"*!E]2\,?@!`(/GD)R#^GV$$/@X0(+OD+QS^GV$`@H!@``3! +M811^X*<`?+]@4.$"``"*O$$`BCP`!(!&"``#X5<`\GQ@@00`(``)XF<"`@`@ +M#(!&"`?^`(`@"``@``0`0``)`"@``>)7!0$`(*`&`"`!_A]@`(H!`!"`)@C\ +M@0T0_/\-0"!G)"@`"$)@_($-"`R`)@@'?@"```(`0```!Q````!0(.7D)QS^ +MGV$4?N"G`'P?8%#A`@``@#Q``(`<``2`0`@``>%7)H`/.`8``5`0@"`(`(0@ +M0""`#S@`@`!0!#X.$*"\Y"](_I]A@&KE+P``(&,`?/]BH/\"``!\'V*XX0(` +M!``("`"`*P@`@>!7`'P?8QB]`@""`@`@T/X?8"!5&2A"_C]@@```(`!.$B@` +M`6P*`*?I9X$F`"`$``@(`(`K"`"!X%>!)``@`GX@@`@`"`@`JJI2``*@`02` +M"0@,@$D*``$,$*`(`"``ILEA!?X?8/R!31``FN9A"``G"@-^:T#\@:T(!/X? +M8``H*F``FD9@_/]A8"#M#"@`JHI@H+(0*`+^'V``GJ=A`*+(80`=YV>!$@`@ +M#`"'"@`(QPK\_PU``((@4*`7#B@`IDE@"``G"@"CZ&>""P`@``0)"`-ZX%N!G`@(`("`"`"````!0#/X?8/R! +M31`!_A]@H.O_)_V!31`)>N!7`>G_)PYZX%>!^_\GH.G_)P":YF$`"`<(`!K@ +M003^'V"@YO\G_(%-$`1^"$`@_C]@("TD*`'^7V`$``@(`(`K"`"!X%>"V/\G +M@-?_)Z`\Y2\`L@Q@(*7D)TC^GV$$/@X0H&KD+QC^GV$``*!A`)H&8*!]&2C\ +M_RU`_($M"`"#X&N!7`OO_)R"CY"<8_I]A!#X.$"!J +MY"\H_I]A(`0`(``@"%(@?1DH`)X'8````&*@K!$H"/X?@*#R_R\`G@=@```` +M4/S_+4"@D`TH^_]-0/N%#0@``>!G`1P`(/R!#0@@Y@TH`((@4``!X&>!&0`@ +M````4"`[#2@!_C]@_(4-"``!X&<"]_\G_87M"0!\WV%0X0(`%/[GIP"<'$`$ +M`*`)!'X'0/Z%30@`<@!`(`PD*`3^/V#^A2T((&X9*`">!V``G^=G````8H(( +M`"``(`A2_H4M"``#Z%<&Z?\G`*`&0`=^((`,``<(``(@0`3^`$`@'!PH"/X@ +M0``!G`1(`(/R!#0B@MPTH +M`((@4``!X&>!#P`@`OX?8*`,#2@!_C]@_(4-"`1^`%`(>N!7C?;_)P-\@`'P +MWP```'R&0?PW``````8XZ-+HZ.CH`^@#````R?X?8*#>&"C'_C]@`#$9*`!\ +M'V"XX0(`(/X_8"#:(R@!_E]@``"@8:!I$2@"_A]@_84-"``!X&!7#GP_8!`G``#.Z!(H!OX? +M8`"!!@@$@28(`('@5P4"`"`$H080H$T1*`B!!@@(H080()/_+P```)H`0@H%"`@!>N!7C`<` +M("`7`"@`'`=@^($-"/R!+0@@@``H`!Q'8`%ZX%N=7 +MB_?_)P`!G@@8`(/N%#0@``>!G_W\'0"'[_R``!I`0/Z)#0@<`X$0'@&!$`'^'V`*`4@0(`$` +M*``"0$( +M`'(`0``0`!@4>N!7%'X`4`D00!@PB0`(#`1!4``!X5<*@`\X,(6`$``0`1@* +M?@"`-($`$````%`X@0`0`'P?8.C@`@`T_R!`H!0A(`""0&`$/@X0@,?C+P`! +MH&&A`0`@`(+`80`=YV=G`OG_)P1ZX%!7B@(`(`!\GV!,O@(`+`<"$"@#0A```($0`(`/.``$ +M'PA,O0(``(`/.`0^#A"@K.,O'/Z?8:`-%"CX_PU``'R_84R^`@#X_PU`(/T@ +M*#3_)D`!>N!7@0$`(("#[B\!>N!7`@(`(/B!#0@T@080_($-"#B!!A`T_P9` +M(.+C)QS^GV$`"!\(?+T"``"`#S@$/@X0(*KC+RC^GV'0_C]"``"@80`('PBN +MK0(`H"T`*/Z!C1"@!@`@`!S'42#&_R\`'`=@`GX'@``>`$`>"0`(`'Q_8`%" +M````'"=@H./_+_[_34`!?@=```[`&0-ZYU<*(P`@`WX'@`!\_V%,O@(``!Y` +M0`H%`0@$>N!7#AD`(`"^#V"@'0`@&?XH0`";YF($``@````'ZYE<"W?\G`+X/8-K^/T``^ATH`-O_)_Z)#0@* +M?@"`(*WC)RC^GV'_D1\8`'P_8$R^`@`P@8`0__\?8#2!`!`@@`\X.($`$``$ +M'PA\NP(``(`/.`A^CE,$/@X0('#C+R3^GV$0@`T0%((-$`-^`8``?']@3+X" +M```&`$(4B`T(!@DH"`"!X%<"`@`@%H@-"`@)*`@`@>!7`0$`("`7`"````!0 +M`GX!@``&X$$,`0`@_W\@0`".`!@``T$0``'@9X)=XR<@CO(O +M@/X?0`#)]2^`6^,G!#X.$"`SXR\T_I]AH)$3*/C_#4``?-]AZ.`"`/C_#4`` +M'"=@((\@*/#_34#P@0T(``@_"*ZM`@`*?@"(`!``&"!P_R_F_TU```"@80`` +M`%#L@0T0YHD-".C_+4#H@0T0\/\-0""'("CP_TU``!P'8/#_+4`@<"`H`!Q' +M8"`-`"``@B!0`_X`@`!\OV!,O@(```J`0`H%0@@`>N%7#`@`(`1ZX5<*!P`@ +M`OX`@``*8$``?`7WA5P$```""`@`@`OX?8`H!0A`` +MA0((`7X`0`"!0A`!_@!```X@&`/ZX%>+\O\G('+_+P```%```>!G`@$`(`#/ +M_R\`_?\GH'D4*$+^/V"@3>,G-/Z?800^#A"@"N,O@/X?0`!^7Q!\NP(`@&;R +M+P"B]2^`-.,G((`/.`,$``@$?@"``'P`0#"H`@``@`\X!#X.$"`0XR\,?N"G +M`(+`80`$`6(`\OQA`'P_8@BH`@`@T.,O`/*H002>J``"B"8(`)Q"0``#X5>. +M`0`@`"'H9P**P%$!',=1`!WG9X$*`"``"()0!(`&"@""(%"@`@`@`"!(8`@` +M80@!_B!```2!8`"&06``G>!7!?W_)PB()@@`GNA!`)P@4`B"AA``"B=``(*' +M$`""(%`(`@(0(`$`(`2$!A``(`A2@,'C+Z`@XR<`(`A@#``@"`!^@!``_"!@ +M`/[__R"`#S@,`@`0!#X.$"#JXB\``&!@`(*`8"`$`"``?@$0H/G_+P"&`6`` +M``$(`7X`0````1``!@(0"(!A"`"'X6>!$.,G`/O_)Z```"````!0!#X.$(#C +MXB^@L.,O``"@80```&$`?']@_*<"`#"``0@``>!G`@$`(##\`1``!`(``/KF +M5P'^_V`"CN-0``B"4``,PU"@!0`@`(9!8!0(`0@`FJ!!``(`0!0`@1``@`$( +M`7Z"0``"`$``@`$0!'[#0`Q^04`#>N)7"A``(`".`T``#`!``'R@0$RG`@`. +M"`$(`(DB"``"`$`.`($0`(XF&0".`!@`&@!``('D5X;S_R<$_B2``(9`03<2 +M11`V"$40,(`!"`G^9($`@`5`0``%$#3^`4```F!!H-C_+P"6!6`0``$($!8! +M$#P`!1`!_@1```X@&2#U_R<`B2((H)3C+P`0!&``[^(G!#X.$"#-XB\L_I]A +M```@8@```%`"A,@)^($-$`Q^YZ<`\AQB`'R_80BH`@``\N9!`*((8/C_+4"@ +MSO\O_/]-0("(XR_X@2T(!(!'"`B$`!`(B"<(_(%-"`"$($`(@H<0!*`F``2B +M!Q``A"!0`*`&0B"%XR\``H@0`!WG9P(!`"``NO8O@```((!W\R\@[^(G+/Z? +M800^#A"@NN(O,/Z?823^/X(``,!A`(*@80```%"@`0`@]H&-$*#`#RCV_PU` +M````4""C"RCX_RU`(`0`(/:)+0@```!0(`(!.`""(%#VB0T(`(`'0/:!C1`` +M$"`8^($-"`"!X%<&*0`@````4*#."RC\_TU`_($-""`O#"B`_C]@``'@9X'S +M_R?\@0T(]?\M0*`G(2CT_TU`](7M"1'^'V`@6QS_)P`!X&>!!``@((CM+P`@*&"`!@`@`+X/8`!\7V"T +MT@(`(+P<*"O^*$"`__\G````4*!Q"R@`("A@`)[G40```%`@@PLH^/\M0/6% +M#0@!>N!7@@,`(*`.#"C\@0T(@/X_8`P`0`@@IOLO$0)!$/6%#0@``>!G@MS_ +M)Z`-#"C\@0T(``'@9X':_R<"?@"``'Q``*2R`@``!>%G@0$`(`!]X5<`!`(` +M!=7_)P"^#V``?%]@M-("`*"I'"A._BA`@/__)Q'^'V"@.!!7(T(``((` +M`"#]@4T0('`4*`'^'V``?%]@A-`"``!\'V`!D0``&OX_8""+%B@`AF%0_/\- +M0`+^/V`@S!8H``1!4/V%#0@``!\0;)@"`"!H%"@"_A]@@(S])P0^#A``-@X0 +M`#AN8Q!^CE,`(0`H`7K@5X(%`"``?#]@*,<"``"!``@!?@!``($`$`IZX%<% +M!``@`'P?8`````0`J?LO``(`(````%``?#]@*,<"``"!`!`$@.T+((`/.!`0 +M;@L$/@X0`#8.$``X;F,@?HY3$!H.$!0<#A`8'@X0'"`.$```X&$`@@!B``3! +M80":IE$`>N=7C`8`((`/`"@!>N!7@@(`(`!\/V`HQP(`!($`"`%^`$`$@0`0 +M`)X'8(#&'R@!_J9!`!OG5XGY_R<`?#]@*,<"``2!``@``>A7C0(`(`!\'V`` +M```$@)/[+P'^'V```0`@````4`2!`!`0`*X)%`#."1@`[@D<``X*!(#M"R"` +M#S@@$&X+!#X.$``V#A``.&YC%'Z.4P!\'V`,`"`(@!3C+P!\/V``$3``_(,- +M%`!\0&````$``WX@8/S!#0@````(`'P`8`````$`>N%7`@(`(`#ZX%<"`0`@ +M`'K@5P$#`"`!>N%7`@,`(`'ZX%<"`@`@`'K@5P(!`"`!_A]@@```(````%`$ +M@.T+((`/.!00;@L$/@X0(#/B+P```%``?+]AE+0"`&R`!A!P@`80=(`&$""V +M!BAX@`80(+4&*(2`!A"(@`80S/\&0`""(%`@]^,O4/Y?8!S^!D``@B!0(/7C +M+U#^7V`!_A]@(*\&*)B`!A"@@`80`?X?8)R`1A"=@$80(%'B)YZ`1A`$/@X0 +MH"GB+T3^GV$`?-]AE+0"`)@`)P@``*!A`?K@5W0`!PB"!P`@`(9A4)@&!Q"@ +M`P`@`(9!8``:`$`"?B&``)P@0,R;`!```'$"`! +M`""`&@<0;`!G"``:0$`"_@&``!P@0,R!``C,FP`0``#A470>!Q`!_@%`('?C +M+Q3^/V!L`@<0`)X'8"!UXR\4_C]@()<&*'P`!Q"(`"<(``(@4+0!!P@`@>!7 +MC@H`('@`!PA\`&<(<`!'"`"`@4`"?@&``!P@0!R```@97C@<`(``(@E`#_F90``A"8"`#`"``"`)@`(`!0`)^(8``G"!`'(8` +M$`%^04`4>N%7A?S_)W@`!Q"`!@<0<`@'$'P`!P@``!\0$/@"`+P!!PB,``<0 +MG`0'"``!X&!!``@I``G"`7^`%```>%7!0$` +M(`"#X&>"`0`@````4)X`1Q``AF%0``GA5\0!!PB&#P`@G`0G"`"#X&!G +M@@T`(`"'X6>!`0`@G00G"`"#X&<""P`@`((@4-B##1#!#0`@`%@&*,0!)P@``@!0`'W@ +M5X@3``"."@`@`?X?8-B!#1!\``<(W)L-$."!#1"```<(`)JF4>2!#1",``<( +MZ)L-$.R!#1#TFPT0\)L-$/B;#1"4``<(_)L-$`%^`$"4``<0H`\"*-C_#4#$ +M&P<0H`+B)T3^GV$$/@X0(,/A+R#^GV$!_A]@H+P**/S_+4#\@0T(``'@9P": +MIE$!$0`@`_X?8/C_+4"@!@LH]/]-0`!\/V!$P`(``($`"``!X&<"`P`@`+X/ +M8`!\7V#`T@(`H.4;**+^/V"`__\G](&M"?]_`$``F^9G`($`$`$'`"````!0 +M!(`&$`B`!A#X@0T(`'W@5P`"```.`P`@`+X/8`!\7V#`T@(`H-P;**S^/V"` +M__\G`("&$`":!F`@[.$G(/Z?800^#A"@J.$O```@8````%``_H`0!(``$*`K +M"B@,@``(`'P_8$3``@``@0`(`7X`0`"!`!`@T0TH`?X?8(#.X2<``!\(1+\" +M``9ZX%<&@`\X````(`0^#A"@H.$O````4```/PA$OP(`#((_4""7_B\!_E]@ +M@`(`(`@`H`D`@B!0H.__+P@"`!``F@9@``'@9P'%X2<`_/\G!#X.$`"QX2\` +M?-]B$.`"```!X&'T_O]"H@,`(%W^OYH`O@]@`'Q?8-C(`@"@P!LHE?\J0(#_ +M_R<`_D<0`'R_823@`@``B`8(``'@9P`N!7`GW@5PX````"?!]@`0```$(]`"``@$<0 +M#GK@5P(3`"``?#]@E+0"`'B!``@"'$@0`7X`0'B!`!``"`@(``'@9PP`B1`" +M`P`@`+X/8`!\7V#8R`(`H*P;*+3_*D"`__\G`'W@5P`"```,`P`@`+X/8`!\ +M7V#8R`(`(*@;*+7_*D"`__\G`(@&"``@'Q`E7`(!("@P&`"``@"E0`)``&"`%`"`` +M@H80`(0`4`"`AA`@`P`@`!``&`!\/V(HX`(`(`$`(`"`2`H`B`8(``'@9P$) +M`"``!`D(#GK@5X$5`""`G_\O``'@9P$7`"``?%]@(.`"````(0@```$0"(`` +M$``(0`@`B"8(`(7@5P"`2`J)\O\G``*`$`"R`@#\_JEA``'@9P(D"6"B@PLH`B@J8`SZ"6"" +M1@`@,?X?8*`1%BAE_BI``(`("!P$(`B@#Q8H,?X?8```"`@`""`(`*_@5XPC +M`"``(@`@`+X/8`!\7V#8R`(`H'D;*.__*D"`__\G`!P'8J!_X2<`(`A@,OX? +M8"`'%B@K_BI``(`("!P$(`@@!18H,OX?8$CZYE<"`P`@``0?"'&M`@`!>N!G +M`@$`(*`6`"````@(`'P_8*"8`@``@``(`'R_892T`@`!?@!``(``$!R%!@@! +M>N!7`@8`(`"%!@@``>!G@00`(`0$"@@!>N!7`@,`(*"C#2@$?@I```'@9Z(! +M`"````@(``L`(```"`@`?%]@#.`"````(0@`@^!G`BQ+8,(R`"```"L(```! +M$"`>!"A<_P9```'@9P$#`"``O@]@`'Q?8-C(`@`@7!LH5_XJ0(#__R<`+$M@ +M("P`(```"`@`:/XO`"L`(`!\7V`4X`(````A"`"#X&>!`@`@`'Q?8!C@`@`` +M`"$((`@`(`2``!````$0`'P?8/"S`@``$`0H``'@9P$#`"``O@]@`'Q?8-C( +M`@"@3ALH&_X_F(#__R<```@(`'Q?8!C@`@````$0`(`("""$#2@`+@!`@/KF +M5P+]YE=0````@AH`(```"`@@D.\O`*8I8(`8`"`Q_A]@(-85*(O^*D``@`@( +M'`0@""#4%2@Q_A]@Y/KF5P+]YE?T````@@(`(```'P@LX`(```'@9P("`#B` +MS?\G`+X/8`!\7V#8R`(`(#P;*+3^*D"`__\G!'K@5P'T_R<(>N!7`<+_)X#Z +M_R!G@0D`(```*P@$@``(``'@ +M9P`L2V`!`P`@`+X/8`!\7V#8R`(`(#`;*,/^*D"`__\G```("`2``!````$0 +MH%O_+P`<"!`!_A]@(+/_)P"`1Q````@(`(``$`!\'V#PLP(``.<#*``!X&>! +MS/\G`+X/8`!\7V#8R`(`H"4;*,O^*D"`__\G!#X.$"`/X2\```!0(-OT+___ +MWV(`]?@OH(47*`'^'V``?!]B6*T"`"`$:`H?!$@*&00H"@```%`9`$@0("GX +M+P'^'V`@1_DO````4`!\/V`E`@``H*H5*(+^'V``?-]A!+("`"`%)P@V^N!7 +MBB4`(`!\_V'\W@(``)X`0`0$8`@`A^%G@2(`(",%1P@`!>%G`A$`("(%!P@! +M?@!`(@%'$`;^`9`A`4<0/_\!8``.0!@C`4<0`?X`0``.(!B@"P`@(`%'$"`% +M!P@`*,IB`!X`0`0$(`B@FA4HA_X?8"`%!P@A!2<(`!X`0`"`2@@$!``(`!!A +M&*`I`"@`FD9@(`4'"`%^`$``#B`8(`%'$",%!PC_?P!```Y`&",!1Q``!>%G +M`0X`(`!\OV)@WP(``'S_8E[?`@``A``8`!X`0`'ZX&!G`@,`(``M +MZE<-`@`@`(`*"`1^`$```>I7C>;_)R,%1P@`!>%G`=G_)QDB2!`@)D@0'R1( +M$*`:^2\!_A]@/`0(""`\]2]#!"@(``H?"$2Q`@"`UP@H`"`(8"#<]"\$_C]@ +M`%H"*",%!P@``>!G`0(`(``$'PA>WP(```'@9P$&`"`@\O`O``"@80`$P6$`"%\(/+$" +M`"!Z`"@`A@%B`'S_85W?`@``FD<0(/OV+P":!F`">N=7`GWG5P,```"A0@`H +M`0X'&`1ZYU<"`@`@H$``*`+^'V"@/P`H`_X?8`'^'V``?+]A7-\"``"`1A`` +M?!]@"+$"`*!G`R@`("A@`/Y&$"!!]B\`A`<(`,O@)P```%``?#]@!+("`""! +M0!`B@4`0(X%`$`/^'V`@@`\X(8%`$`0^#A"`F>`O`'R_802R`@`@A28(`(0` +M&`!\`$#\W@(``?K@9SH$``C"`0`@#WX`8/!^`&`$?@"0`'S?85S?`@``!"<( +M`(/@9P&[X"<``>!G`KK@)P!\/V"G`@``H$H5*(;^'V`@=P,H!/\&0*"VX"<` +M?D<0!#X.$*"+X"\D_I]A``#`80":IE'\FPT0_/\-0/C_+4"@H.\O]/]-0``! +MX&<"!``@^($M"`W^'V`,@$`0!/X?8`Z`@!#T@0T(H`(`(`$<0!``?#]@)P$` +M`*`&&R@`O@]@`'P_8%[?`@``A``(``'@9P(/`"``H_HO`GK@5X$%`""`H?HO +M`WK@5P$$`""`5.LO`7K@5X$"`""`Q_PO`'K@5_2!+0B,!``@@```(/2!+0@` +M?%]@_/<"`````0@!?@!````!$*`#`"`#_A]@`'Q?8/3W`@````$(`7X`0``` +M`1`!_A]@H`0`(`*`0!``FD`0`'P_8/CW`@``@``(`7X`0`"``!#T@0T(`GY` +M$(7^'V"@)14HH_X_0/B!#0C\@2T((!#Q+PQ^`$`@H^`G)/Z?800^#A"@=.`O +M-/Z?80``(&(`(`A2H%[T+_^A31``#D`:`'S_893>`@``@`<(#`#`"2!%[B\` +M'`=@```?"%C8`@`"^NA7&'Z@08(%`"``?#]BU*T"``&$2`@`H@A@`)HF8*!> +M%2@"?D%``80("`)^`$`@`P`@``Y@&@```%``FB9@H%H5*`+^7V`"_G]B`"7I +M9P!\/V+XW@(``0H`(`!\GV(HK@(``OX?8``H*F``FDE`H!@?*/__;4#_A0T( +M`"8`0``.0!H`*`I@`!HI0"`&'RC__TU`_X4-"``D`$``#D`:`(`(""`&`"`! +M_C]@`'P_8#BN`@````!0`)I)0"`/'RC__VU`_X4-"`""(%``)@!```Y`&@"` +M"`@`'NXO`'P_8ABP`@`!A$@(``7A9P$$`"``H@A@`!HI0*!#%2@"?D%``80( +M"`)^`$``)`!```Y`&AP`!P@B)(<0+"!`$`"`!PB@7P`H`?X_8!$$!PB??@!@ +M`7K@5X("`"``?#]@")8"``"```@!?@!``(``$*!MX"`G!#X. +M$"`XX"\!_A]@(%WW+P`_@O````4`!\GV)8K0(`(`1J"@!\/V"S`0`` +M(-T4*(+^'V````!0`'Q?8@2R`@``?!]B_-X"``!\_V'VW@(`H`(`("`!21`@ +M!0D(`7X@0`".`!@@`TD0-GK@5PH=`"``(`!`!`0@"`"#X&WP(`H@$`("$!21``7@XH``(`(`"$!P@!>N!7`@(` +M((!2#B@@!0D(`"``0`0$(`@@"``@/_\`8`]^H&$`(`%`!`0@"*#'%"B'_A]@ +M(`4)""$%*0@`(`!`!`0`"`":1D``($%`5@AA""!6_R\`FD9@__\*0``.H!H` +MJ^IG`(1H"`$'`"`@!0D(`7X@0`"'X6<@`TD0H@0`(`".0!@`!`$8`"``0`'Z +MX&`G`#(.*``@X"<$ +M/@X0H.[?+R3^GV$``,!A_/\-0/C_+4"@!.\O]/]-0``!X&>!`P`@`'Q?8"3( +M`@``?#]@!0$``*`2&B@`O@]@@/__)_R!#0@8_C]@``*`$/B!K0D1_C]@#()& +M$``(``@0?@!0#H"&$*#^'V`@K.`O#8!&$```)P@0@@80!`0G"!2"1A`%!"<( +M(*O@+Q6"1A#X@0T(_($M"""$\"\,?@!`(!?@)R3^GV$$/@X0`.C?+P``X&$, +M`*`)`((@8AR`9@I@_A]@()(4*`">)V`@H.`O`!S'40```&(`)$E2$J1&$"`6 +M`2@`G@=@`*/H9T/^GX*!!``@`'P?8-B\`@`,@`80,(0)"$!ZX%<4_M]A`GS? +M860```"````@#*0&$`!@\B\`H^AGH1``(``@"&"`EN`O`'R_8<"]`@`8_P9` +M((T"*``<)V```>!G@?7?)UW^'V"@@!0H`GXJ0`"%!@@``>!G@?8/*%W^'V"@ +M?10H"'XJ0!C_!D`@A@(H__\_8``!X&!G`0,`(`"^#V``?%]@),@"`*#<&2CE_C]@ +M@/__)_R!#0@X_C]@``*`$/B!K0DH_C]@#()&$``(``@0?@!0#H"&$*#^'V`@ +M=N`O#8!&$```P&$0_@9``)XG8*!7X2\H_E]@('7@+P`WR\```!B#'H`8`!\/V(` +M!````@,`(`"^#V``?%]@T,@"`""]&2@`HBA@@/__)PAZX%<"?>!7!`````$# +M`"``O@]@`'Q?8-#(`@`@N!DH!/XH0(#__R<`?-]AI+,"`)9%!P@``>!G@K;? +M)S!%!P@``>!G`?[_82((`"`+_JB!N/X?8"!"%"@)_C]@@`4`(*!`%"B]_A]@ +M0/X?8`B`!A0,P`8(OW\`8`R`!A0P12<(H#P4*+W^'V`P'T<4,$4'"``!X&<" +M`@`@",`F"$#ZX&NA7H@(`(+_^'V"@+!0H+?XH0"`"`"",_A]@H"H4*#+^*$"$_A]@ +M`(`&%("9WR<`>N%7#`,`(``"`%``@>%7"P(!4`H``%`@@`\X```"$""`#S@` +M!`(0!#X.$"!NWR\!_C]@````8@```%`@6_PO``1!4``!H&&"`P`@`'Q?8"C) +M`@``?#]@G0(``*"+&2@`O@]@@/__)PR`Q@D`@B!0`!P'8"`FX2^`_E]@*'X' +M0!P`!Q`,?N!!H$#M+P`!G@0L`(`8)`@@`"#\(KJT"`""`^R_^ +M_TU`!04B"`"`0%`"_@:```H@0`@)`@@!G`@,`(`+^ +M'V`*`4(0`(4""`%^`$"@`@`@`(%"$"`!`"`!_A]@````4`H!0A`@;=\G&/Z? +M800^#A`@*M\O&/Z?80!\/V`8R@(`"($`"/B!#1`,@0`(_($-$`!\/V`M`@`` +MH.43*(K^'V#X_PU`((K_+P""(%#__Q]@((X0*!S^/V`@%/HO!/X?8`!\'V`` +M`(``@'SN+Z!@WR<8_I]A!#X.$"`BWR\<_I]ABO[?00``H&$5?@=`(-L3*`%^ +M)T"`W/LO`_X&@`/^/V``?)]@3+X"```(`$`*`T`0!@D@"`@)``@``@!``!`` +M&``(/PBNK0(`H%S[+_[_34`"_B:``(@@0!R!@!#^B0T('H&`$*!0WR<<_I]A +M!#X.$"`3WR\H_I]A`'P_8!C*`@``@0`(\($-$`2!``CT@0T0``0?","[`@`8 +M?N"G`/R\0?[@`@`@;`\H^/\-0"`Q^2___M]!`7K@5X$!`"``+_DO``'@9P(= +M`"``!!\(E*T"``6$)@@`@>!7`OX?8`)\'V`#`````/3Y+XK^'V`@OQ,H!WXG +M0`>$A@D&A"8("'Z&@0"8(&@(A(8)"H0&"!!^AH$`F"!H"82&"1A^AH$`F"!H +M"X2&"0"#X&<(?H:!`!@`:`R$A@D0?H:!`!@`:`V$A@D8?H:!`!@`:`$!X&+P!\'V#HX`(`@$@21`H0OX_8`#,Z2^` +M"-\G!#X.$*#LWB\X_I]A```@8@""8&(`)$E2]*4-$!1^X*<`?/]A4.$"``"> +MO$$(@`8(`/(<8OR!#1`0@"8(_/\-0*"2'B@!_E]@_($M"``>"```@>!7C@`` +M(!"`!@@``L!1`!WG9Z(!`"``H@A@@%<,*``%`""`D0PH`)WI5PZFR6$(@`8( +M$(`F"`"``%```>=7#0#`80`=YV<"`0`@(`\`(`'^'V#XI4T0^:--$/J=31`` +MH@A@H/`3*/3_+4`(@`8(#(!F"@=^0(+X_PU`H%<(*`""(%#T@2T(!WYG@/B! +MK0@```!0`"9)0"`F!R@!_I]@H.L**````%`(_@=`$(`F"``@`$`@>AXH`!Q' +M8`"B"&"@X!,H`!PG8"#WWB!G`@,`(`"^#V``?%]@ +M;,D"`*#C&"CN_C]@@/__)P!\7V#`O0(`$`$A"`"#X&>!`0`@%`$A""`!`"`$ +M@``0$`$!$!0!`1``@B!0H-G>)P0"`!`$/@X0`*O>+P!\7V#`O0(`$`$A"``# +MX%)P0&`!`$!"`(@/K@9QP`0`B"!0`@@/X@:`0"0!`0!`$( +M!WX`8````$``?"!`P+T"``2)``@0?@!`!(&`$$8`@1``@`\X!#X.$*"=WB\! +M_A]@`'S?85S8`@"@8?!G@)P!\OV$(LP(`8/\&0`!\ +M/V``Q@`!`?Y?8%S_9D`@=@`H__^?8%R!)@@6^N"'`P(`(``$'PAAV`(``#'V +M+UR!)@@5^N"'@P,`(``$'PA@V`(``7X`8`%^`'@@*/XO`GX`0%R!)@@'^N"' +M@P@`((2!!@@!?@!`A($&$``$'PA4M0(```'@9P$%`"`@VPXH`OX?8`!\'V!( +MLP(`($P!*'W^/YB`@08(7($F"`%^`$"`@080`(W@'X/G_R<`BO8O````4`!^ +M1Q"@JMXG#(%&$`0^#A``>MXO``'@9P!\'V`8OP(`@0$`(*!"`2C__S]@@``` +M((!D`2@``>!G`:+>)P"^#V``?%]@M-("`""C&"A-_C]@@/__)P0^#A``>]XO +M````8@""X&$`!*%AH*3@+P"&P6$)>N!7`@,`(`"^#V``?%]@M-("`*";&"A9 +M_C]@@/__)X"?X"\#>N!7`@,`(`"^#V``?%]@M-("`""7&"A:_C]@@/__)P`@ +M"&``GB=@`)I&8*#^!B@`'&=@H)$**````%``D]XG!#X.$`!AWB\`^OLO((W> +M)P```%`$/@X0H%[>+\C^/V``?!]@*+`"`(`G`2@``>!G@8C>)P!\7V"TR`(` +M`'P_8"$"```@B1@H`+X/8(#__R<```!0=``-$""`#SAX``T0````4'P`#1`@ +M@`\X@``-$`0^#A"`6MXO>`#@"0``H&$`H!\(``$`2``!`$@``0!(``$`2``! +M`$@``0!(``$`2``!`$@$?B!@`("@'____W]T@"8(`(/@9P*?YV"!0`@!_X_8)""!A`H +M`"T(`?X@0"@"#1```*`?(.\!*`":!F```>!G@M[?+X```"```*`?<(`&"``! +MX&>!`0`@(.0"*%C^!D"````@6)P&$`"@'P@``0!(``$`2``!`$@``0!(``$` +M2``!`$@``0!(``$`2`1^(&``@*`?____?P``H!\`7]XG!#X.$(`PWB\``*!A +M!`(`$````%`(@`80$(`&$!2`!A`,@`80`*`?"``!`$@``0!(``$`2``!`$@` +M`0!(``$`2``!`$@``0!(!'X@8`"`H!____]_;``M"`"#X&<`_`803D161`$# +M`"`<@$`(')H`$!@:`1`)P```%`$/@X0@"C>+P``H&$`@@!B``0A8@"&06(`".)A +M`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!__ +M__]_`OKH9PB`)@@A`@`@`*!`8``%Z%>"`@`@``$`(``%X6!Q`!_B!`*`(-$``` +MH!__^^=70H8"*%A^!T"@_`$H`!P'8*`!`""0`,<)!_[?80``H!\@(]XG`!P' +M8````%!L``T0((`/.'``#1`$/@X0@`#>+P``@&(`@J!A``3!80"@'P@``0!( +M``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?P@`*@@" +M>N=G`IH@8$(;`"`(`@H0$`#J"0":P&D`G^=G%``*"B%?`"`('`H0`7KH5X(7 +M`"",@"<(A(!'"`+ZX&"`@`@``$`(`"#X&! +M`0`@H'D"*%C^!T"````@6)H'$)":!Q"@?0$H`)X'8``!X&YU$`'^%7@`!A"`&"X&&`A@`0 +M?``A"'R"`1`4`"H(__\@0!0""A``I^EGD"(!$*("`"!T(@$0?"(!$``$06(@ +M`@`@``1A8GP$"1!\(@$0``1!8O]["$*"VO\G$!X*$```H!^`"@`@($@"*%C^ +M"4``H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@ +M'____W\H`"T(`?X@0"@"#1```*`?H$4!*`"F"6``FF9B`*?I9P$#`"!P@`D( +M``'@9WR`J0F"\O\G(//_)UBB"1``H!\(``$`2``!`$@``0!(``$`2``!`$@` +M`0!(``$`2``!`$@$?B!@`("@'____W\H`"T(__\@0"@"#1```*`?$``-"`P` +M+0@`@>!7@0$`(```#0@``>!G`;G_)Z"VW2<```!0`"'H9P&X_R<,`"H(`?X@ +M0*"V_R<,`@H0!#X.$`!]W2^`N@`H`#X"*`!H`"@`"P`H`(O_+P`B_R^`(_\O +M`*;=)P0^#A"`>MTO```-"`!\OV'P\/#P`'W@5_'P\/"!`0`@H/;=+P`:#1"` +M]?\O`!H-$"#9'2@$``T(````4*`8WB\```T0`)[=)P```%!D``T0((`/.&@` +M#1`$/@X0@'3=+W@`X`D``*!A`*`?"``!`$@``0!(``$`2``!`$@``0!(``$` +M2``!`$@``0!(!'X@8`"`H!____]_=(`F"`"#X&<"G^=G`1H`(`"`)P@`_>!7 +M04U%4P(8`"!\@"8(`!S'40"#YE=TG`8000,`(`R!G@0$` +M("#^`2A8_@9`@```(%B)P&$`P`)P@`@^!G@00` +M('R"!A"`@"`(@((&$`P`)PB`@"`(?)H`$`P`)P@@`@`@@)H`$`P:!Q!\F@80 +M@)H&$!``)P@!_B!`$`('$`;^/V`\@@80`?X_8$2"!A`H`"T(6)X&$`'^($`H +M`@T0``"@'__[YU="J@$H6/X&0*`@`2@`F@9@H`$`()"`I@D-_K]A``"@'R!$ +MW2<`F@9@````4%P`#1`@@`\X8``-$`0^#A``&-TO``#`80"@'P@``0!(``$` +M2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?PP`IPD`F^9G +M`)[G40$/`"!\@"8(`(/F5T$#`"`,'@<0#`('$("`1@B`A``0?(`F"'P"`1`0 +M`"<(__\@0!`"!Q`H`"T(=)X&$`'^($`H`@T0``"@'W"`!@@``>!G@0$`(""J +M`2A8_@9`@```(%B>!A"0G@80(*X`*`":!F```>!G@IW>+P`"`"`(`"<(`?X@ +M0`@"!Q```*`?H";=)P```%`$/@X0@/?<+P``H&$T`@`04`0`$%0&`!``@B!0 +M"`(`$`P(`!`4"@`0`?X"4``(`$`0@`80'WY#8!_^`V!(@`80$(`-"#B$!A`8 +M@`80'(`&$`2"!A`#_A]@/(`&$$""!A!$@@808/P&$"))``!DF@80<((&$%R" +M!A!T@@80>((&$'R"!A"`@@80`80?@$R`!A`H@@80+((&$#""!A``?#]@`$@` +M`*!IWB\`F@9@`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!( +M!'X@8`"`H!____]_%``M"`"#X&<`_`801%)(5`$#`""8@$`(F)H`$)0:`1"8 +MA`80(`(`()2"!A`4&@T0E)H&$)B:!A`8`"T(`?X@0!@"#1`H`"T(`?X@0"@" +M#1```*`?%(`-"``!X&>!`@`@(($`*`":!F```>!G@G#>+P`(`"``H!\(``$` +M2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W\H`"T( +M__\@0"@"#1```*`?H/'<)P```%`@@`\X#``-"``(@E`,"`T0$`@-$!P(#1`@ +M"`T0(/X?8"0`#1``?!]@N-4"``!^0!`!?F!`(`(`(`'^7V``@D$0`?YA0`%^ +M04``?>%7``$```8$`"``@B!0``0!8`%ZX&<"^_\G``0`&`'^($"@_?\G`(X@ +M&`!\/V"XU@(`(`(`(````%``B``0!/X@0`%^`$`@>N!7A?W_)Q0(#1`8"`T0 +M((`/."@(#1`$/@X0@+3<+P``X&$`@J!A``3!80"@'P@``0!(``$`2``!`$@` +M`0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?SB`)P@`@^97#18`(`"# +MYE>"!``@`OX@@`#\(`"XU@(``(/G5P("`"!,@"<((`!-"``"(7`@`@T02(`G +M"``"!Q`0`"T(`(/G5TB:!Q""#``@.(`G""0`30@`A>!7#87F5PX*`"`"?B&` +M`/P@`+C6`@`0`@T0``"@'R@`#0@``>!G`3G>+P"@'P@``0!(``$`2``!`$@` +M`0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?R`!`"``FJ91&/Z_80`` +MH!^@O-PG`)H&8`0^#A"`DMPO``#@80""P&$@^N!7``2A8<8Z`"`/_K]A`*`? M"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_ -M/(`F"`"#X&>"#``@'(`F"!B"!A`H`"T(`(/@9P)\/V`!````0@D`(!B"!A`@ -M@&8(`(?F5P$'`"!(@"8(.(!&"``#X5<"!0`@`GXA@`!\7V!8U@(``(2`020` -M+0@`!@80`OX@@`"$(``!_M]A$`(-$```H!\@G=LG`!P'8`0^#A"`<=LO``"@ -M83P```@$>N!7@@D`(`"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!( -M``$`2`1^(&``@*`?____?R@`+0@!_B!`*`(-$```H!^@-/\O`)H&8`"0VR<` -MH!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'___ -M_W]T@,8)``"@'P`=YV"#@`@('KA5Q_^/V`.?"%0`0````+^0(!``"T(`(1`0#P`+0@``^%7!0(` -M(``"(5#\_T!@.``M"`"$0$```"$(`(/@9P$$`"`0@@80%(`@"!2"!A`0F@`0 -M```A"!2:`!"@`@`@&(0&$!":!A`4F@80&(0&$``:`1```*`?H&+;)P```%`$ -M/@X0@#7;+P``H&$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``! -M`$@$?B!@`("@'____W\8@"8(`(/@9X$$`"`0@$8(`(7F5X($`"``@&`(`(?F -M5P`$05""```@`(0`$!B$!A```*`?H%/;)P```%`4@"8(%`(!$!"`9@@0A@`0 -M&(`F"`"`0`@`A>97@@$`(!B"`1`0@$8(`(0`$"#X_R<`!$%0!#X.$"`@VR\` -M@B!0"'Z.4P":IE$L&@T0,!H-$#0:#1!$&@T0`'Q?8-C6`@`@`@`@``0!8``: -M`!`$?@!``?X@0"#ZX%>%_?\G.`0-$$`$#1"`?@%`/``-$`!\'V!8UP(``'P_ -M8#BG`@``?%]@*$H``$@`C0A,`*T(4`#-"!`:#A`4&@X0`'Q_8$U)5$$@-OXO -M``SC8%0:#1!8&@T0"'Z.0P`XVR<$/@X0H!W;+SC^GV$`?>!734E40:$!`"`` -MGN=1H$3;)SC^GV$`FJ91^)L-$/S_34+X_\U!`_X_8B`%`"`!_A]B#``M"#RB -M`!!$H``0*``M"`'^($`H`@T0``"@'R`G_R\,``T(`*`?"``!`$@``0!(``$` -M2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_0`!-"```(0@`@^!G -M_(,-$($``"`8I``0`!H!$$``+0@$_D!`/``M"``#X5=`!`T0`@$`(#@`+0A` -M`@T0(!@`($0:#1`0@"D(`(/I5T$$`"#\FPT0%(!)"!2$`!`0@"D($`(!$!BD -M`!`0@"D(_(,-$`"`*0@@^N!7#@(`("#^(%``@@D0H`,`(``HBE($@"D("(") -M"@"#X&<`@@D0(0(`(`R`Z0D8G`D0(`$`(!"F"1`8F@D0``"@'P`IZF!G`?W_)]``"0@`&^!7`B?@5P(AX%!A""!0`@`)_G9P(# -M`"``O@]@`'Q?8'#(`@`@[10H%WXJ0(#__R<`_`=H````$`"`!A``H@D0(-X& -M*````%`@<]LO`!P'8"#>VB"!P`@`'P?8"#)`@`"_C]@ -MH`$/*``$05`%!"<(`_K@5P!\'V```"``B0$`(!A\`!0B,@````$`(!A\`!0" -M,@```)OF9P%\'V`DR0(``01!4,'Y#B@"_C]@`)X'8*!X`"@`FB9@(!_\+P'^ -M'V``?%]BG+T"``!%"0@``>!G`0,`(`"^#V``?%]@;,D"`*"]%"@J?BI`@/__ -M)P'^'V```4D4!P0G""`(&2@`F@9@`P0'"``(*`B`?@!H#P%)$`$$!P@)`4D0 -M``0'"``"``#8]R\`"`@(`"?@5P(&`"`%!`<("7K@5X$$`"``?%]@&,D" -M``-^@(`)V!C_A]@H!X/*``<)V"@@-HG -M-/Z?800^#A``3=HO``"@80""(&(`!.%A`(;!8:!UW"\`"`)B`GK@5P$0`"`` -M!`@(``'@9P"()PB!!0`@```'"````$`$@`@``(``4``:($``D``8`(*'$"`Q -MW"\*_C]@(`(`(``0X!D`F@!``("'$`":YF$```<(````0`"`"$``&H`0```' -M"`%^`$`@EMLO"OX_8`"#X&<``@<0`@$`(`'^'V```$@0`)ZG82!>VB<`F@9@ -M!#X.$``V#A``.&YC&'Z.4Q`:#A`4'`X0``"@80#\`&#_/P```!#`&0#\!F#_ -M/P```!"@&1#^!H``?#]@(@`@"`#YVB\`_`9``(```!!^`(``?#]@(@`@"`#V -MVB\`?`=``$```!!^`(``?#]@(@`@"`#SVB\`?`=``,```!!^`(``?#]@(@`@ -M"`#PVB\```!0`'P_8"(`(`@`[MHO$`"N"10`S@D$@.T+((`/.!@0;@L`?%]@ -MQ,8"```!(0@`@`!`((`/.``!`1```!\(Q,4"``"`#S@$/@X0H!#:+Q3^GV&@ -M`@`H_/\-0/R!#0@*?@"(H$_:)Q3^GV$$/@X0H!/:+R#^GV&@VMHO``#@82#W -M_R\``*!A``#`80'^'V"@``DH_/\M0/R!#0C_@1]0`!P`0`"`!Q`@U]HO`)H& -M8*!$VB<@_I]A!#X.$``V#A``.&YC)'Z.4Q`:#A`4'`X0&!X.$!P@#A`@(@X0 -M``#@80!\OV$`$3```/KG5PP"`"`.^N=7"0$`(`#ZX%>"```@`)[G48`NW"\! -M>N!7`@(`(``OW"\`>N!7@@``(`">YU$`?#]B3*@"``"%2`@!?@%@`'K@5X$V -M`"`"A0@(`('G5P$U`"`"GT@0`(`F"`#\`&@```@(`'P`:`````0`?`!@___[ -M_P"`!A`0?@%@`'K@5P$(`"``N]HO``#`80#ZYU>!`@`@`(`F"`#\`&@`"``` -M`(`&$``"`"``@"8(`/P`8/_W__\`@`80`!P'8("VVB\`)P`@`+/:+P``P&$# -MGT@0`'P?8`D`(`B`M=HO``#@80#\)V@```"``'P?8`D`(`B`L]HO<_X_8@"` -M)@@$_@!@`'K@5P$!`"`!_A]B@```(('^'V(`@"8(`/P`:``(````@`80!?X? -M8`!3%R@??@A@`'K@5P$4`"``^NA7`1,`((!^"&``>N!7@0,`(`"`)@@$_@!@ -M`'K@5P$,`"!_?@AB$/X_8H`+`"``@"8(!/X`8`!ZX%>""``@`'P_8DRH`@`# -MA0@(`"``8`!ZX%N!7`0$`(`#ZZ%<"[?\G`(`F -M"`#\`&#_]___`(`&$`!\'V`)`"`(`)XG8`"3VB^`U_\G$`"N"10`S@D8`.X) -M'``."B``+@H$@.T+((`/."00;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$` -M$3``@"#H+P"$VB\`@"8(`/P@:```"`@`_"!@__?__P""!A``@]HO````4`/^ -M/V``K/\O$`"N"02`[0L@@`\X%!!N"P0^#A`@N]DO)'[@0`":IE$`!$%0"`@` -M"0">YU$`>N17``B"4"P"`"`<`*`(`@@@"``#Y%<+`P`@`+X/8`!\7V`8TP(` -M(.P3*)S^/V"`__\G6(#"""`$`"``AF%0`(8A0`""(D!TB"`(`(@@0`"0@!@! -M_B%``(Y@&`"-X5>%^_\G`!'D9R$,`"`!"`)A`'WD5RH)``")`0`@`'WD5P`! -M```*`P`@`+X/8`!\7V`8TP(`H-X3**[^/V"`__\G`7KD9P$#`"``O@]@`'Q? -M8!C3`@"@VA,HK_X_8(#__R<+!"`(``(D4`"0`!D&>N-7#0$`(``-XV<"`P`@ -M`+X/8`!\7V`8TP(`(-03*+7^/V"`__\G`)9E45R`P@ETB$()`!!D8``((F$. -M^N97B@@`(`YZX5>*"@`@`_XF@`""@T$`!$80`((C0@&>2!`$G`@0``?E5P`@ -M"%(L"0`@`"1)4@'^7V(`!L=!``8E4"`-`"``D$`9`+X/8`!\7V`8TP(`(,43 -M*+W^/V"`__\G`+X/8`!\7V`8TP(`(,(3*+[^/V"`__\G``?E5X(!`"`!_E]B -MH`0`(`'^'V(!_A]B`I2($`"4(5``D&`8`!0B4`"0@!@!_B=``([@&0%ZZ5<" -M!@`@`H:($`&$*`A`_B!H`8)($``&(E``D8`8`GPA0`$````"CD`8`I[G40(0 -M9&`""")A`7KH5P(%`"`!_B5``(Y@&0"-Y5<&`P`@`OXE@`""(D!<@,`)`)8E -M0`""(D!TB$`)`?XF0``)XF<`CJ`9`MO_)P/^)H``@F-`^84A",#^(&CY@T$0 -M"7KA5R`$@!`+`P`@`+X/8`!\7V`8TP(`H*43*/S^/V"`__\G"P0@"`"2($`` -M>N%7(@*`$`D#`"``O@]@`'Q?8!C3`@`@H!,H__X_8(#__R<#?N&G`_X\0`": -M@$``?&!`(`(``,*%(0@`@^!GP8E!$"$"`"``#J(8``0B0,``CJ`8"P0` -M"!IZX%<"@MDG`(0"0""!V2?!@4$0!#X.$"!/V2\D?J!``'R_80`"```("$`( -M`(9A4``%X6<+!``)(04`(!P`(`D"""`(``/A5PH#`"``O@]@`'Q?8!C3`@"@ -MC!,H4_X_8(#__R=8@$0)!GKE5PT!`"``%>5G`@,`(`"^#V``?%]@&-,"`""' -M$RA5_C]@@/__)P".XU"@`0`@``S#4`'^(T``CN`8`)7C5P82`"``CB-``((D -M0'2(0`@"_B.``((D0%R`@`@`!"1`H`(`(`"0`!D"A(`0``1!4`'^(4``CF`8 -M`'KA5XSV_R<.^N%7B@8`(`/^(8``@H)!``Q&$`""(D`$B``0`!OA5P&,0!`, -M^/\G`IJ`$``:(5``D$`8(/?_)P`:@D``O@]@`'Q?8!C3`@"@<1,H8_X_8(#_ -M_R<#_B&``()"0/D%(0C`_B!H^0-!$"`,@!`B$(`0`?XA0`!\`$`@`@``P0-` -M$*!0V2?``T`0!#X.$``FV2\``*!A'``@"`O^'V`,@$`0`'Q?8`+'`@`!!0$( -M#8!`$`Y^`$`!`4$0``X`&'%ZX%<,_L!!#`$`(!#^'V`!`4$0``0?""#?`@`! -M>N!7`GW@5P(```"!`P`@`'Q?8!C3`@``?#]@70$``*!;$R@`O@]@@/__)QD` -M1Q"@!!,H`!P'8``$'PAXK0(`@'K@9P$#`"`7A`8(`8`?@`!]X&?8#P``(@?O -M+P*:!F`@B`8($X0F"`"!X%<"`@`@````4!P`AQ`@!``@(H@&"`%^`%``@>!7 -M00$`("*(!@@(B`8('`"'$`B(!@@@,]DG`@"'$`0^#A"`!]DO``#`81P`(`@+ -M_A]@#(!`$`!\7V`"QP(``04!"`V`0!`.?@!``0%!$``.`!AQ>N!7#/Z@00P! -M`"`0_A]@`0%!$``$'P@@WP(``7K@5P)]X%<"`````0,`(`"^#V``?%]@&-," -M`*`]$RC)_C]`@/__)QF`1A"@YA(H`)H&8``$'PAXK0(`@'K@9P$%`"`7!`<( -M`8`?@`!]X&?8#P``@0(`(`6$!@@`!#\($+,"```"`&@%@$80(`@'"!,$)P@` -M@>!7`@(`(````%`<@(80(`0`("((!P@!?@!0`('@5T$!`"`B"`<("`@'"!R` -MAA`("`<((!/9)P*`AA`$/@X0H.78+R3^GV$``>!G@@,`(`!\7V#$QP(``'P_ -M8!\!``"@)A,H`+X/8(#__R<$`"`(](,-$```(`CP@PT0`((@4/R##1`(""`( -M(/$6*/#_#4```*!A^($-$`!\7V"LTP(`\/\-0*`_%BCX_RU``)H&8*`6V2O`(`'H&&$`1^ -M`(`@@880H`,`*("#AA`@VP`H"(L&"!Z+!@@@RO\O`!``&`#+V"<$/@X0(*'8 -M+P""(%``',=1`'R_81"R`@"N!7 -M000`($()`0@#>N!71`DA"$&`#S@$`X$00@D!"``#X%<,@@!@((`/.`0!@1`$ -M/@X0@'G8+P!K["\!>N!7`@$`((`!`"@`I-@G@#@`*`"CV"<$/@X0`'K8+P!\ -MOV$0L@(`=HDF"```7PCPLP(``((`0``:`$!H!8`0`?X`0``0(!@'^N!7`!S' -M42(!`"!V@880=IV&$`"&85``!$%0H`,`(``N!7`@(`($J)!@A. -M@880(`,`($R)!@@">N!7@@(`($:)!@A.@8802(D&""`"`"!0@880`+X/8"`! -M$RC9_C]`"(L&"#J+)@@``@!`"(&&$``,(!@\A08(``'@9SJ=AA`!"P`@3HD& -M"`2)1@@`!>!7BP4`(/__`$``#"`8"(&&$%*)!@@&B48(``'A5XL-`"!6B08( -M`7X`0"`,`"!6@8804(D&"``%X%<)"@`@`?X`0``,(!B@"``@"(&&$%*)!@@& -MB48(``'A5ZH#`"`!_@!`9(4&"``$7PC2K`(```'A5XP!`"#__P!```P@&`B! -MAA!8B08(`7X`0%B!AA`BBP8(`('@5\L#`"`(@8805(E&"`"%X%<)#`$820$` -M(`B%AA``@@!@)HDF"``#X%>!;M@G(*<`*":!AA``;=@G``A?")Z\`@``?#]@ -M$+("`)R+``@&?F%``('A5XP6`"`$B0`("GK@5PH5`""`B6`(,OKA5PH2`"`! -M^N%7!'X!@"$!`"`!#(`8((N`"`'^`4"`@8`0!7X!4`!ZX%<)$&`8#(9A4(J' -M@!`%?@%``!#`&(:!@!">BZ`(EHE`")"+``@`A>)7"0@`0`P``E``#``8!'Y# -M@``%X%<*#`$8!/Y!@``%X%<+#`$8((&`$`A^`$`$?D"0``P!&!Z%@!`!?D!` -M(!T`((2%@!"$BP`(H!L`(!Z!@!``"A\("M\"`(QZX%>+`0`@I7K@5\P'`"`1 -M_E]@@'K@5XL!`""$>N!73`4`(!+^7V`H>N!7"P$`("QZX%<,`0`@:'K@5P(! -M`"`@`0`@%OY?8!7^7V",A8`0B(D`"```?PCLLP(```8`0``0H!B&@8`0E(E@ -M")*)@`@`!^)7((L`""P"`""*A8`0CHM@""`#`"``@`%`!(E@"`;ZX5>*`0`@ -MCHM@"``&`%``#``8!/YB@``'X%<*C`$8!'Y!@``%X%<+#`$8((&`$`A^`$`$ -M?D"0``P!&!Z%@!""BT`(``7@5P&`#SB"@8`0H#__)P`0`!@$/@X0``S8+P`` -MP&$8"``(``@_"/[7`@``?+]A$+("```#X%<`GN=1K`4`(`:!AA`!_A]@(-H, -M*`""(%`!_A]@R(%&$"!=#2@&B28(`?X?8*`&`"!D_C]@R(4&"`%ZX%<"!0`@ -M`?X?8*#3#"AE_C]@R)]&$`:))@B@5@TH`OX?8`'^'V#(_C]@@,\,*!8()P@` -MC>`?@P$`(!X(1P@`#>$?!`0`("F%!@@\GT80`7X`0``.(!@$^N!7*8%&$(I7 -M_R^`$``@`?X?8#R!1A`IGT80`'P!8/]___\`$$`81(&&$``$'PB;K0(``/P@ -M8/]___\">N!70H.&$"(#`"``D&`86H4&"``!X&<"`0`@1(.&$`"&06`TBP8( -M`(1@4"J%1@@`!H!```0!0``:($`LBP`(+(>`$````E`T@880`7X!0`-^`&`J -M@480!`A'")B%!@B2A880``!_".RS`@```>!G``R!&*('`"``C*$8`?Z?8"`# -M`"````!0`GX@@`":($"@AX`0HH6`$`%^`$`(>N!7B_S_)YR'AA">A880H`'8 -M)YB)1A"9A<8(`((@4`)^`X``&@!`H`>`$*(%@!`@!0`@````4``:8$"@BT$( -M`(7B5PD$H6"BBT$(``7B5PD$@6`!_B!`!'X`0`CZX%>+^O\GGHF&$)R+AA`! -M?@-`!WX`8"#UUR>9@480!#X.$*#+UR\D_I]AC_[_02"TZR\``*!A``#`872: -M'U#^@8T0;/X?8`%ZYU?Z@8T0H0,`(!/^!D``"!\(GKP"```:`$``>N!7"1`` -M&`P``%#\@8T0`?X'0*"4#"B8_C]``(C8+P%ZYU<``*!A@@D`("#1"2@!_A]@ -M`'P?8!N%```"_C]@_O]-0*#L"R@`AF%0_HD-"&QZX%<"`0`@:_X?8/J!C1`` -M?!]@'(4```+^/V#Z_TU`(.<+*`"&85"@QPDH`OX?8`!\'V`FT@```OX_8/S_ -M34`@XPLH`(9A4/R)#0@`?%]@$+("`````$`$?"``=,D"``!\'V!8K0(`4?K@ -M5QH$8`@,!0`@P`4A"`"#X&>"`P`@'`4A"`+ZX%<"`@`@`?X_8%H#01`@`@`@ -M(/XA:`""(%!:`T$0W_\A8!H"0!`@K^LO`((@4*!MV"\`F@9@D/X?0"!U#"A/ -M_B=`H-G7)R3^GV$$/@X0@)G7+Z"(ZR\``*!A=)H_4`%ZX%=L_I]@(A$`(`"0 -MH!@3_@9``!`@&&SZXE<`?+]A6*T"``*$!@@!?)]@:P````-^`&@"@$80`((` -M0`1\``!TR0(``'Q?8!"R`@!1>N!7&H1F"`P%`"#`!0$(``'@9X(#`"`N!7"1`@&`!\OV%8K0(``H0&"`R"(%`!?@!H`H!&$`." -M1A`6BD80%XA&$`":!F`@CNLO`((@4`*$!@C\?P!@(*?7)P*`1A``/@X0()#7 -M+RA^X*<`BB)B``#`8@""H&(`!(%B`(9A8@#\'$#(Q@(`)```"``(0F(8?N"G -M`/+<80!\OV'0J@(`($#8+P#RYD$```!B"(`'"`%^($`4B`<(`('@5X4"`""@ -M/M@O`"`(8`"^#V"@#1(H9OX_8`")G`(P<0$(!`"``C!P`!```"``&`&@``F!X`(1A>`R& -M`A`(A`(0!(("$""`#S@`@`(0``!?"$3'`@`(@``0`'QA:``"```$@$`(``9! -M>```07@,A``0((`/.`"&`!`$/@X0H`O7+RC^X:<``.!A``2A80#\'$#(Q@(` -M!```"*!&`R@``L!I"(`&$``>)W@`@`!X#(`&$`2>!A`@+=`$(!&"`"F"6``)"E@``9!0*"S_R\" -M_G]@#(`&"`+^)X```B!``)P`$`%^"$(!_@=``*'H5PWX_R<@AMN!7`(!($`("`"`,@`8(`OXG@``"``````D0H'#7+P`@"&``T-8G`#X.$*"@ -MUB\8?N"G`/R\0="J`@`@:M@$$!>NA7 -M`"(&$`("`""`O0(H$(`F"`">($`$@``0`7['01#^YT$4B`8(``'G5POY_R<@ -M1]T(``(!```"84``?,!@____[P`"(4`$@`$( -M`(P`$``,('@(@`$(`7Z"0``"`'@,@`$0`?X"0``.H!@`#^)7$`!'"*7W_R<$ -M_B*```(!```"@4$`?`!@____[P``!A`0`$<(``(!```"(4``@``0H"O7+P": -M!F"@F=8G'/Z?80`^#A``5M8O$(`-$!.$#0B@.O,O?WX`8``WV"<$?HY3`#8. -M$``X;F,0@`T0$X0-""`%`"!_?@!@!'Z.4P`V#A``.&YC$(`-$!.$#0B`?@!@ -M`('@5P'^'V`"``!0`!!N"R"`#S@$?HY#`P1`"']_06```B%H((`/.`,"0!`$ -M/@X0H$G6+P`$86"@^_\O``"@80.$!@B`?P!@`X!&$"`H\R\`A@%@`X0F"``" -M`&B@;]8G`X!&$`0^#A`@0-8O``!@8*#T_R\`!(%@`X0!"(!_`&``"`!HH&G6 -M)P.`01``?#]@,```":`0UR<```!0`'P_8#````F@#M"``(`7KA5X$#`"``_4!@`(````$#`"``#>`?`P(`(`"! -MX%<+`P`@H`(`(`""`&``!>%G`O[_)P`-X!\#_?\G`(`/.`0^#A"@&M8O1/Z? -M80``H&$`@N!A``0!8@"&P6'L_PU``((@4*#9UR\0_E]@H`4`(`""(%`!_@!@ -M`WY`@`*"!P``!&"`_O\`8`"`34#L"0$(`?X@0``&`&CL`8$0$/K@5P7Z_R<` -M!`<("'Y(@`A^((`!!`<(``(`0`($)P@`$``8`(0@:`"08!@@"P`@``1!4``$ -M(4``@HU`[`DB"`%^04``@`!X`!"@&``.`!@```!``'P`0!BX`@`$"2`("/X" -MD````$``?`!`&+H"``0)``@``B!X`()A>`"0`1C%]/\G -M[(D-""`&`"`'_C]@``!`0`]^`)``!`!H`!!@&`""`$``@$U`W`D!"/__($`` -M@&%``)`!&-P'@1``@^!G@OG_)P`$!P@`@$80`00'"`&`1A`"!`<(`H!&$"`% -M`"`#_C]@`?X`8`-^0(#^_P!@`(`-0-P)``@`@H9!``0`D```1A`!_B!`$/K@ -M5X7Z_R<@(M8G1/Z?82`#`"``"()0`@A@``"(@$$`!D80`7YB0`".@1@`">%7 -M#(`/.`#\_R<$/@X0`.75+P```&(`@J!AH*G6+P`$X6$``,!AH&?:+Q/^'V`` -M?)]@>+,"`)`)(@@`?%]@`(@"``"$8$`=_A]@`(1`0``AZ&<``$$0@0,`(`!\ -M7V!PR`(``'P_8%4'``"@%Q`H`+X/8(#__R<"H$$0(`,`(````%``A$8(`(`A -M0`.$0!`!_J9!`7X`0`-ZX%>%_/\GE`4""!/^/V`!@$$0'?X?8`'^7V"@!P\H -M`)YG8""8UB\`'`=@@/75)P0^#A"`R-4O()/6+P``P&$``*!A(%':+P+^'V`` -M?)]@>+,"`)`)`@@`?#]@`(@"``7^7V```H!!``1&$)0%0@@``F!``81!$`(" -M```"_C]@`?Y?8*#Z#B@`'&=@((O6+P":!F"`YM4G!`A`"`2(8`@`A>%7@@0` -M(`((0`@"B&`(`(7A5X("`"``"``(`(@@"`"!X%N=7C`$`(`5ZYUNI7#`$`(`5ZZE>"!0`@ -M`"GJ9X$#`"``C^-G@@(`(``EZ6>!`@`@0H0*"`1ZX%NQ7`?X_8@L'`"`$!`@(`7K@5P$%`"`!!`@(`7K@9P)] -MX&<"````0@$`(!X("`@8"`@(8'X`8"!ZX%>"```@`*(H4@":!F"@)0(H`"@J -M8```@&``+`M@`!PG8"`R`B@`CD-@``@@0`!\GV#!`0`@H$\"*``NE7#`$`(`5ZZ5>" -M!``@`"7I9X$"`"``G^=G@@$`($*$"0@$>N!7`0$`("`!`"`!_E]@``1!4``. -M*1@@_0$H`*((8```@&``(`A@`!PG8*`)`B@`GD=@``@@0`!\'V+)V```2@( -M``(`0``!"!"`%=@O```?$/B8`@``A]4G!#X.$`!!G`"`(4H$(`"``/^DO``@_"!*Q`@`!>N!7`((@0((! -M`"`%_```)+$"```%`"`%_```*+$"```00!@`"!\(GKP"```$`$`@`@`@`!#@ -M&0`*'P@8L0(``!!`&`!\OV%8K0(`0X0F"`"#X&>""P`@`)X'0`1\```4F0(` -M``XG&``.`!@@'``H``1!4``&`"`"?B>0(`,`('2$'U``!`%``'P`0'3)`@`F -M"``(`GXGD``.`!@`CB`8H`<`*``$05````!BH`(`($.$)@@!^N!7@??_)P+Z -MX%,@"``!\/V#'`P``(&P/*`"^#V"` -M__\GH$_5)P`&`%`??F!@`(*!&``&HD!`?F!@!OYAD`&&GU``!G\("KX"`"!^ -M`&``@F$8#_YA0`"(X:<`\F)0!7X`D!1^X*<`"A\("N`"``"&G$```F`8``H? -M"`S@`@```@`8``8`0``(`$``!>%G``Q@&($``"```($0``0?"!"T`@```@!` -M((`/.``&`%`$/@X0(!/5+P+^'V``?+]A)-\"``"`1@@`@B!0@/Y_0"#:%"@` -M"()0!(!&"`/^'V``@B!0@/Y_0"#7%"@`"()0`#?5)_^1/Q@``H`0`@*`$""` -M#S@$`H`0`'Q_8!``(`"@`@`@``1!4``$(4`$`B```7Y!0`""@10`?>%7``$` -M``:`#S@`_/\G!#X.$``'U2\``,!A`'S_81``(`"@"P`@`)JF40":)D``R`<( -M``(G0`"`@!#___]_____?____W____]_____?____W____]_____?____W__ -M__]_____?____W____]_____?____W____]_____?P'^ID$`_>97``$``(8@ -MU2<`\_\G!#X.$"#OU"\`"()0``,`(`)^`H``?`!`)-\"`*#E_R\(```(`7Z" -M0"!ZXE<&%]4G@/O_)P0^#A"`\M0O0_[_@0!\'V(DWP(```#`8:`#`"`"_K]A -M`OXF@`"$0$"@X_\O```!$`@`QPD!_J9!`!WG9P$&`"`B^N97!@4`(`P`!P@` -M`>!G`"!(8`+Y_R<`O@]@`'Q?8!S2`@"@)`\H%/XG0(#__R<``-\)H.$"```# -M`"`"_B:``(1`0"#8_R\```$0"`#'"0'^ID$`'>=G`08`("+ZYE<&!0`@#``' -M"``!X&<`($A@`OG_)P"^#V``?%]@'-("`"`9#R@A_B=`@/__)P#D`2B@`P`@ -M``#`80+^)H``A$!`H,S_+P```1`(`,<)`?ZF02+ZYE<&"0`@`!WG9P`@2&"! -M!``@#``'"``!X&<"^?\G`+X/8`!\7V`!G`MG4)P"^#V``?%]@'-(" -M`"#O#B@5_B=`@/__)P0^#A``JM0O``#`80"#X&N!7BP,`(`!\7V`E7#!L`(`*D"``&>N!7@0D`((D1`"`%>N!7C?G_ -M)P-\@`$P70$``'R&04Q7``````8X[`+N!>X(````(@E`(/7_)Q2`!A``(@E` -MH//_)QB`!A``(@E`(/+_)R"`!A``(@E`H/#_)QR`!A``(@E`(.__)R2`!A`` -M(@E`H.W_)RB`!A`#^N=7"NS_)P`B"4`@9O`O`)XG8`%^`$"@Z?\G``[@&25^ -M`%`->N!7C>?_)P-\@`'`70$``'R&07!7``````8X!,K*\,KJRLK*RLK*RNT` -M`*`-WR\`(@E`@.'_)P/ZYU<+G@=@JXGP+PN"(%`@@$8(``7A9P$0`"`#?@B0 -M`!!@&`0$`0C^?P!@`(`A4`"!X5<`D"`8"P8`(`$$`0@#?@!0`!``&`"!X%>) -M`P`@``(!0`4$(`@'?@A@`8`?@``"@&(@`0`@+*A&$"R<1A``*>IG@0(`(`!\ -M/V#@EP(``(``"`%^`$``@``0!`0!"`%^`&"@A-0G+8!&$"R<1A`@@]0G+9Q& -M$`"`#S@$/@X0(%G4+RC^GV$`?#]B``(```S^J($(P"8(#,`&"`!\WV%XLP(` -M``+@82#^'V`@(@DH`)XG8)9%!P@``>!G`0,`(`"^#V``?%]@<,@"`*"*#B@Y -M_BA`@/__)Y5%!P@``>!G`0,`(`"^#V``?%]@<,@"`""&#B@Z_BA`@/__)P'Z -MYV'`P4`(+3^'V"@#@DH3OXH0`#?\"^`_A]` -M"(`&%*!^\"\```!0H+8%*$+^/V`6^N>'`P0`(+3^'V"@"`DH6/XH0("][B\( -MH@84`#+N+Z"Q!2@<_C]@0/KG9X$&`""]_A]@H`,)*`">)V!`_A]@"(`&%`S` -M!@B_?P!@#(`&%#!%)PB@_P@HO?X?8`'^'V`P`4<4"/KG9P$)`"````!0_X%- -M$`C^'V((H`84(*[R+___#4```>!A`0(`("#!Y2\,@`<(()CR+P">!V"610<( -M``'@9P+Z_R?_A0T(``'@9X+X_R<@6-0G*/Z?800^#A"`*M0O``"`8@""8&(` -M!*%A`(;A80`(0F(`BB)B"/X!0*#BU"\`#L`9````8J"@V"\`'`=@`'R?8'BS -M`@"0"2((`'Q?8`"(`@``A&!`(?X?8`"$0$```$$0````4`*`@1`$GD$0!:1! -M$`:H01`'ID$0"/XA0"`#`"``!$%0`(0&"`%^04``@$`0`?X@0`'^ID$`A>=7 -MB?S_)Y0%`@@`'"=@`8!!$`"$`0@!_E]@($(-*`"B:&"@TM0O`"`(8``TU"<$ -M/@X0@`#4+X#-U"\``*!A`?X_8`!\'V!YU$'_A]B -MB_X?8"U^*4``R`@H3/\&0"#6]B\`("A@``$@8H$"`"`-^NA7`@P`("`$!P@! -M>N!7@@H`((S^'V`@P@@H"7XI0(O^'V"@P`@H`"`H8"`$!P@``>!G`1T`('2% -M!@H`(>AG@@<`((S^'V`@O`@H$GXI0"#V$"CX_PU``(XH&*#D$"CX_PU```4` -M(`"^#V``?%]@Q,<"`"`C#B@'?BE`@/__)W2?1A",_A]@(+0(*!M^*4",_A]@ -MH+((*!]^*4"`"]8O```@8*"P""B+_A]@@`G6+P=ZX%<"?>!7!@```('C_R=U -MA28(`?K@5P$AZ&>!X?\G"'K@5X("`"````<(^($-$`0`!PB@`0`@_($-$*#B -M$"CX_PU`^/\-0*#`#R@`@B!0````8HO^'V`@I`@H`"`H8`)ZZ%<-?`A2`@`` -M`(#9_R?__Q]B=)]&$(O^'V`@U_\G2'XI0`1^`(``?"!`E,<"``R```@`?$!H -M``P```2```@`!``4`(`/.`1^`(``?`!`E,<"``@```@````(((`/.`"``!`` -M?!]@!``@``"`#S@`?!]@!``@``"`#S@$?@"``'P`0)3'`@`$```(`$``"`%^ -M`&`@@`\X`(``$`1^`(``?$!`E,<"``0`(0@`P``(`GK@9P*`#S@,``$(`'P` -M:``"````@``4`(`/.`0^#A`@L],O'/Z?8:!\U"\``,!A``"@80```'P@ -M0)3'`@`,@``(`'Q`:``0```$@``(``0`%`#%TR<$/@X0`)73+X``XB\%!"`( -M!`0`"`C^((```@!H`'P_8"R^`@``?>!7)$(``"*]TR<`@8`0`/V`$"-"```` -MN],G!#X.$`"-TR^`^.$OY`0@".4$``@``E\0E>$"``]^`&```%\0E.$"`("U -MTR<$/@X0`(_3+P``H&$`@N!A(/+A+P`$P6$``>!G@@,`(`!\7V#DT0(``'P_ -M8$$*```@R@TH`+X/8(#__R<"&B```!H`0`$$8`@`?%]@,+X"``"*`1C0`X$0 -MT@=!$`"#X&!G`8(@4`$``%``@H<0(*K3)P``1Q`$/@X0`'O3+R!G^2\` -M`*!A(*73)PB`!A`$/@X0@'_3+P``P&$`(`A2`'S_86BT`@`@`0`@`)JF40'^ -MID$`A0<(`('F5XH'`"`&_N:G!/\'0`!R`$`@M_TO`!PG8`%ZX%>"^O\G`?X? -M8@!\/V"0!P``H$8(*#+^'V`R_A]@($4(*`":)F"@F=,G`"`(8```8&``?`!` -MW+("`%`%0`@">N%7`8)`8`'^'V"@"@`@`(8A8`0^#A"@8M,O``!@8`""P&`` -M!*%@`?KA9P```%`A`@`@``B"4``%`"B@`0`@``"`8`+ZX6"```@`?Y?8`"#X&<`#F$8`0\`(``+ -M`!@$#``@`'P@0-RR`@``A^%G1(5`"($#`"`">N!7#`$`(`5ZX%>"`0`@``0_ -M"'2M`@``!``@`(?A9P($`"`">N!7#`,`(`5ZX%!G -M@@<`(*#S_R?_?P!``(?A9P$%`"`@!0`@`OX?8`"'X6,```@"/X?8`"`#S@$/@X0H!S3+P`$05`">N!7`'R_8=RR -M`@`,`0`@!7K@5X(``"`!_E]@`(/@9P`.01@"$0`@``H`&`!ZX%<+#0`@``7A -M9P$%`"`">N!7#`$`(`5ZX%<"`P`@`!H@0$2%8`@`!#\(=*T"``"'X&<".],G -M``7A9P(%`"`">N!7#`0`(`5ZX%%G(C/3)P+^'V`@,M,G"/X?8`5ZX%=)`0`@!?X?8``* -M`!@`>N!7"P8`(``:($!$A4`(``0_"'2M`@``A>!G`0(`(`)ZX%>,*M,G!7K@ -M5X$ITR<@^?\G_W\`0`!\/V!)`@``()P-*`"^#V`@)M,G````4``!X&<"`P`@ -M`'P?8`C@`@``@`\X`'P?8`G@`@``@`\X`7K@5X']_R<@@`\X__\?8``!X&<" -M`P`@`'P?8`#@`@``@`\X`'P?8`3@`@``@`\X`7K@5X']_R<@@`\X__\?8`0^ -M#A"@]](O*/Z?823^/X(`GN=1`"`(4@!\OV'DO@(`(`(`(``"!``@"(``"``!X&>!]O\G`+X/8`!\7V`!G@>W_)P"^#V``?%]@'-("`*`9#2@N_BA`@/__)P"^#V``?%]@'-(" -M`*`6#2@M_BA`@/__)P">!V"@#-,G*/Z?800^#A``T-(O``@@"`"#X&<``*!A -MH@D`(*+^WX&@]_LO````4``!X&! -M\M(G`+X/8*!E#2@=?B=`@/#2)P"(!@@!?@!`(._2)P"`AA`2_A]@()H'*"=^ -M)T``_/\G!#X.$``V#A``.&YC$'Z.4P``(&#__Q]@``<`*`2`[0L@@`\X$!!N -M"P0^#A``-@X0`#AN8Q!^CE,``"!@`'P?8````!"``0`H!(#M"R"`#S@0$&X+ -M!#X.$``V#A``.&YC&'Z.4Q`:#A`4'`X0``"@80""P&$`F@9@`*X`*```!Q`` -M>N!7`0(`(`":!F``?#]@```@"("`TR\0`*X)%`#."02`[0L@@`\X&!!N"P0^ -M#A``-@X0`#AN8Q!^CE,``"!@`88?&(#Q_R\$@.T+((`/.!`0;@L$/@X0`#8. -M$``X;F,0?HY3```@8(#^'T"`[/\O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC -M$'Z.4P``(&``?!]@````(`#G_R\$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,0 -M?HY3`GY`@`!\`4#XR0(```$`"`#A_R\$@.T+((`/.!`0;@L$/@X0`#8.$``X -M;F,0?HY3`'P_8`(`(`@`9=,O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC&'Z. -M4Q`:#A`4'`X0``#`80!\OV$$`#``@%C3+P"`)@C[_R!@`)P@<`""!A"`6-,O -M$`"N"10`S@D$@.T+((`/.!@0;@L`?#]@!``P``"`(`@`@`!@`(`/.`0^#A`` -M-@X0`#AN8Q1^CE,0&@X0`'R_800`,```3=,O`(`F"/O_(&`!_B!H`((&$`!- -MTR\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC%'Z.4Q`:#A``?+]A!``P -M`(!$TR\`P"8(^O\@8`""!A0`1=,O$`"N"02`[0L@@`\X%!!N"P0^#A``-@X0 -M`#AN8QA^CE,0&@X0%!P.$```P&$`?+]A!``P`(`[TR\`@"8(^_\@8`"<(&@` -M@@80@#O3+Q``K@D4`,X)!(#M"R"`#S@8$&X+!#X.$``V#A``.&YC%'Z.4Q`: -M#A```*!A`'P?8`$`(`@`-],O`!H`<`!\/V`!`"`(`#;3+Q``K@D$@.T+((`/ -M.!00;@L$/@X0`#8.$``X;F,0?HY3`'P?8````"``]/\O!(#M"R"`#S@0$&X+ -M!#X.$``V#A``.&YC$'Z.4P5ZX%>&`@`@`GX@@`#\`$#XR0(```$`"`#M_R\$ -M@.T+((`/.!`0;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$8`#```![3+P"` -M)@@`_"!@_W___P""!A``'M,O$`"N"02`[0L@@`\X%!!N"P0^#A``-@X0`#AN -M8Q1^CE,0&@X0`'R_81@`,`"`%=,O`(`F"`+^(&@`@@80`!;3+Q``K@D$@.T+ -M((`/.!00;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$8`#``@`W3+P"`)@@! -M_B!H`((&$``.TR\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC$'Z.4P!\ -M'V`````0@`$`*`2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q1^CE,0&@X0``"@ -M80!\'V`!`"`(``73+P`:`&@`?#]@`0`@"``$TR\0`*X)!(#M"R"`#S@4$&X+ -M!#X.$``V#A``.&YC$'Z.4P&&'QB`]/\O!(#M"R"`#S@0$&X+!#X.$``V#A`` -M.&YC$'Z.4X#^'T``\/\O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC$'Z.4P!\ -M'V`````@`.O_+P2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,%>N!7A@(` -M(`)^((``_`!`^,D"```!``@`Y/\O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC -M%'Z.4Q`:#A``?+]A&``P``#CTB\`@"8(`/P@:`"`````@@80`./2+Q``K@D$ -M@.T+((`/.!00;@L`?!]@$``P``!\7V`8`#``````"`!\(&`/SP`````!"``" -M(&``@A]0``(`:!]^`(@`@`\X`'P?8!``,``````(`GX@8`""'U```@!H'WX` -MB`"`#S@`?!]@$``P``````@$?B!@`((?4``"`&@??@"(`(`/.`0^#A``-@X0 -M`#AN8Q1^CE,0&@X0``"@80!\'V`0`#``````"`%^(&``@A]0``(`:!]^`(@` -M>N!7@0,`(`!\'V```"`(`,S2+P`:(&``@A]0``(`:!]^`(@0`*X)!(#M"R"` -M#S@4$&X+`'P?8!``,``````(`'P@8`"`````@A]0``(`:!]^`(@`@`\X!#X. -M$``V#A``.&YC$'Z.4P!\'V`4O0(```4`"`1ZX%>-`P`@``4`("#^'V``6_\O -M``@`(!#^'V"`6?\O@`8`(`"^#V"E_C]``(@,*(`$`"`"?H"!`'R&`=QQ`0`` -M``8X;%P``&E<``!L7```:5P``'Q<```$@.T+((`/.!`0;@L$/@X0`#8.$``X -M;F,8?HY3$!H.$/S_#4"`SO!7`*`/ -M`(4Y`"``?!]@H)@"````0`@`?!]@&/<"``````@`!$!``'P?8'SW`@`````( -M``2@002!``@`@`90`'W@5P`"```%`P`@`'P_8`"0`0``?!]@A.$"```"`!`` -M+``@`'W@5P`!```%`P`@`'P_8``@`P``?!]@A.$"```"`!"`)P`@0'K@5P4# -M`"``?#]@`+`$``!\'V"$X0(```(`$(`C`"`0>N!7!0,`(`!\/V``0`8``'P? -M8(3A`@```@`0@!\`(`!ZX%>!`@`@,OX_F`!\'V"$X0(```(`$``<`"``?%]@ -M`$`?``!\'V"$X0(```0`$`"%``@#>N!7@A$`(`1ZX%>-`P`@@`4`("#^'V`` -M1?\O@`@`(!#^'V"`0_\O``<`(`"^#V``?#]@(P$``(!4#"B`!``@`GZ`@0!\ -MA@%XN!7`0,`($#^'V"`"/\O`((@4`!\'V"6W@(```)` -M$`2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,`?!]@%+T"```%``@!>N!7 -M`0,`($#^'V"`'/\O`?X_8`!\'V"6W@(```)`$`2`[0L@@`\X$!!N"P0^#A`` -M-@X0`#AN8Q!^CE,`\]\O2@0`"`!\/V`4O0(``(%`$`1ZX%>!$@`@!'K@5XT# -M`"``!0`@(/X?8`#T_B\`"``@$/X?8(#R_B^`!@`@`+X/8*7^/T``(0PH@`0` -M(`)^@($`?(8!%'4!````!C@Z70``-UT``#I=```W70``2ET``"#^'V"`ZOXO -M`'P_8!2]`@``A0`(`7K@5P$#`"!`_A]@`.?^+P""(%``?!]@EMX"```"0!`` -M``!0`$@`*`!\/V``D`$``'P?8(CA`@```@`0`'P_8`!`'P``?!]@A.$"```" -M`!``?#]@`#`J``!\'V"0X0(```(`$`!\/V``L`0``'P?8(SA`@```@`0!(#M -M"R"`#S@0$&X+!#X.$``V#A``.&YC''Z.4Q`:#A`4'`X0`'S?883A`@````<( -M`'W@5P!`'P"""P`@`'R_812]`@``A08(`WK@5X(Q`"#\_PU``%#W+_R!+0@0 -M@P80`'P?8(#A`@``!``(`'K@5P(!`"````<(@`$`(`!\'V"(X0(`````"`!\ -MOV$4O0(`%($&$(`H`"#\_PU``$?W+_R!+0@`?+]A%+T"`!"!!@@`@`!0#($& -M$!2!)@@`@>!7"2``(`!\'V"`X0(```0`"`%ZX%<"#@`@```'"!2!!A``A08( -M!'K@5XT#`"``!0`@(/X?8`"[_B\`"``@$/X?8("Y_B^`!@`@`+X/8*7^/T`` -MZ`LH@`0`(`)^@($`?(8!W'8!````!CBL70``J5T``*Q=``"I70``O%T````` -M`%"`%0`H@!``(`!\'V"(X0(`````"!2!!A``A08(!'K@5XT#`""`!0`@(/X? -M8`#)_B^`"``@$/X?8(#'_B\`!P`@`+X/8`!\/V`C`0``@-@+*(`$`"`"?H"! -M`'R&`5AW`0````8XRET``,==``#*70``QUT``-M=```!_A]@``8`*``!`"`` -M@`!0%($&$/R!+0@`?+]A%+T"`!"#!A`0`*X)%`#."02`[0L@@`\X'!!N"P!\ -M/V"`X0(``(!`$`"`#S@`?#]@$``P``!\'V!8IP(`#`$`"`"``!``@`\X!#X. -M$``V#A``.&YC$'Z.4P!\'V#`:P"``'P_8$,```F`]=$O!(#M"R"`#S@0$&X+ -M!#X.$``V#A``.&YC%'Z.4Q`:#A```*!A!?KF5X$%`""`Z=$O!?Y&@`!\/V!8 -MIP(```)!0`0!(0@,`6$(`,!`"``&07``A``4`.?1+Q``K@D$@.T+((`/.!00 -M;@L$/@X0`#8.$``X;F,4?HY3$!H.$```H&$%^N97@04`(`#>T2\%_D:``'P_ -M8%BG`@```D%`!`$A"`P!80@`P$`(``9!:`"$`!2`V]$O$`"N"02`[0L@@`\X -M%!!N"P5^8(``_$%`6*<"```!00@`0$$(`WK@5P("`"``?$%@____?P"$`!`` -M!@`@!'K@5X($`"``?$%@____?P5^`8``!`!0`GX`@``$`$`"?@"(`(``$(`` -M`"``A``0`(`/.`0^#A``-@X0`#AN8QA^CE,0&@X0%!P.$```P&$`@J!A!7XG -M@`#\`$!8IP(`"`$`"`"$_B\#>N=7@@$`(`#\IFD```"`@`,`(`1ZYU>"`@`@ -M`OX&@'W^/V"`5=(O`'R@:0```(`%?B>``/P`0%BG`@```0`(`!H`%`1ZYU>" -M`P`@!7XG@`#\`$!8IP(```$`"`!```@`@>97@OS_)P5ZYUN!7`@<`(``(PF`%?J"``'Q_8%BG`@``AJ)` -M`(%B"`#`@0@!?F-0``?B5P$"`"``?*)@____?P#ZXE<"^?\G!7Z@@`!\?V!8 -MIP(``(:B0!"!P@@`@6((`(P!%`-ZX%>"`0`@`'SB8/___W\`"@`@!'K@5X(( -M`"``?*)@____?P7^8H``BF%0`OYA@`"*84`"_N&(!7Z@@`!\?V!8IP(``(:B -M0`"!8@@`P($($('""``-XE>"^_\G@```(``(XF``CB!0``(!$`#ZX%>"!``@ -M!7Z@@`!\?V!8IP(``(:B0!R!8@@`A&$8`((A0``"`1"``P`@!7Z@@`!\?V!8 -MIP(``(:B0!R!8@@`@B%```(!$("=_R\$@.T+((`/.!`0;@L`?)]@$``P``5Z -MX%>!!P`@!7Y`@`!\'V!8IP(```!A0`R!`0@``$((``!!8`"$'U``!`!H'WX` -MB`"``!``>N!7`0$`(`R!`0@```(0`(`/.`!\'V`(`#``````"`"`#SB@`0`@ -M``1!4`%^(4``CD`8`WKA5XH#`"`"A']0`@8@``'^($``C^`?``9@0"'[_R<` -M@D$0`(`/.```(&"@`0`@````4`%^`$``#@`8`WK@5PJ`#S@``&!`!(9```%^ -M04``$>$?`(9@0"*`#S@`A($0`/K_)P`(@E``!$%0`'S_8&RV`@`@!P`@8(7# -M"`9^((``CF!`DHDA"`&$OX``B^!G@0(`(``)XF<"`0`@E85!$`'^GV"4A4$0 -M`7XA0`".0!@`#>%7"H`/.`#X_R<$/@X0(*/0+S#^GV$`?/]A]-,"`!2!!P@` -M?#]B5+4"`/B!#1`8A0<(`'S?80SB`@#\@4T0`'P?8`#]`@`<'``0`'P'$`[@ -M`@``?+]A`,$"`#S_!D`$``<0%'P'$""[`@`!_A]@`?X_8*`.YR___TU`_X4- -M"`!\'V*4F0(``WX`@```"$`#>N!G"``'$"$#`""8_E]"`+X/8-)^*4"@R`HH -M`/]'0(#__RN%7 -M"_W_)TZ$``A0^N)7.(%&$(Q'`"!@A@`(`/Q`0``"`````*!```8$!`@!?L-`#WX`8````$``@`)0$(%#$`&%!`@!?N5`!'X`D````$````)0 -M`(;C0`"!0Q#F!`0(!'X`D````$``@`)0$(%#$`=ZXU>+\?\G````4/R'K0CX -MART)^8<-"?J'[0C[A\T(H`,`(``(@E``EF51``9%0"`701`!?@!``GZ"0`'^ -M($`3>N!7"B``(.V$0`@/?D%@`'KB5P`$04"+`0`@!GKB5ZP*`"`,A$11"'KB -M5XL!`"`/>N)7+`@`(`P$1%$0>N)7BP$`(!-ZXE>L!0`@#(1#411ZXE>+`0`@ -M'GKB5RP#`"`,!$-1'WKB5XL"`"`D>N)7B0$`(`"$0E$`!D)`(!5!$`%^0D$' -M>N57@>O_)R5ZY5>!#@`@[89`"`1^09``>N57``1!0(L!`"`&>N57K.?_)PR$ -M9%$(>N57BP$`(`]ZY5+`0`@$WKE5ZSB_R<,A&-1%'KE -M5XL!`"`>>N57+.#_)PP$8U$?>N57B]__)R1ZY5>)WO\G(-W_)P"$8E$@AT$( -M(`,`(````%`@AR$(``/A5PN"0&`!?@!``?YA0"5ZX%>+_/\G$85&$``"`1@# -M?@!0$H%&$(!)WR^@7M`G,/Z?800^#A"@+-`O`([C4```7PA4M0(``'Q?8@`" -M``"0!F$)D09!"6`&`0B2!B$)````00`(@E`%_A]@`'S?8(#``@`4`8,0`'P_ -M8-3A`@``?!]@`/T"`!P"`!``?+]@;-4"``#_`D``@``0$/\"0`2``!`@_P)` -M"(``$!3\`!`.X`(`&'\#0!B``!!0_P)`#(``$$#_`D`<_``0<)@"`"#\`!!T -MF`(```1_"%&U`@`D_``0D)@"``/ZX5N!7C`,`(&`&`0@```!```K@&`-\`0```0``````0``*@!@`FJ91(`<` -M(`""(%`"_@=``(`#4$`!1Q``)`%``!H`0`$%``@$?@"0````0`)^`$````)0 -M4`%'$`'^ID$"_B!`!_KF5XHM`"``&N%!H83'"0!\'V*5X0(`#WX'8`AZYV<" -M?`!H\`````(*`!@`$L!!`(H@02"=1!":A"<*#_X(8`CZZ&<"?`!H\`````(* -M`!@`%$!!`)5$$).$)PH/_@A@"/KH9P)\`&CP`````@H`&``$"`H`%F!!`7KH -M5Q"71!`,#``@YH0'"`]^`&`#^N%7```@0@((`"``!!\(4+4"``!ZX%<,!@`@ -M`OX(0`"``U!`@400`"0!0``:`$`!!0`(#WX`8````$`"?@!````"4"`#`"!0 -M@400`OX(0"`!`"````10(/X?8#"!1!"AA@<(`?X@0@1^`)``'`!```H@&0"* -MR$$@`4<0FH8'"`1^`)``%`!```I`&0`!1Q"3A@<(!'X`D``6`$`!>NA7$`%' -M$*P&`"``"F`9YH0'"`1^`)`#^N%7``#@00("`"``!!\(4+4"``!ZX%<)SO\G -M`OX'0"`!`"````10(/X?8"#1_R, -M!0`@H`,`(`""(%``)`%```(`0`@'8`@`C`!`&`=`$`'^($`.^N!7BO3/)X#[ -M_R>@`@`@`((@4*@&80@`C`!`&`=`$`'^($`.^N!7"O#/)X#\_R<$/@X0H+O/ -M+P``P&`@@?PO`((`8```H&"@>?PO`((`8```0&`@QOPO`((`8```8&"@OOPO -M`((`8```@&#_^^)7`OWA5_____\"?>%7_____P)]XE?_____@@,`(`!\7V!X -MR`(``'P_8&\$``"@]@DH`+X/8(#__R<`#`-@(&OU+P"*(F"`V,\G`'P?8!29 -M`@``@`\X!#X.$""ISR^W_A]@`'P_8$T%``"`@@0H`'P?8/$<````@B!0("72 -M+P3^7V``T<\G!#X.$""CSR^W_A]@`'P_8%0%``"`?`0H`'P?8,8<````@B!0 -M(!_2+PC^7V``R\\G!#X.$*"=SR\4_I]A`'P?8"#V`@`````(@'K@9P(.`""` -MB^,O``!@8`!\GV"N!7"1``&`P``%`"`8(0(,[/)Q3^GV$$/@X0`(_/+Z!9T"\``,!A -M``"@8:`7U"\"_A]@`'R?8'BS`@"0"0((`'P_8`"(`@`4_E]@``*`00`$1A"4 -M!4((``)@0`&$01`"`@```OX_8`'^7V`@P0@H`!QG8*!1T"\`F@9@`*W/)P0^ -M#A``C,\OC?X_0@``X&$`?+]A>+,"``!\'V(``"``,$`H"#2!Q@DT@P80H%,$ -M*`'^"$`P0"@(-(,&$*!1!"@!_@A`-($F"``#YU?P_U^"#@,`(``"!U``)>!7 -MA0D`(#B!!@@@`P`@`7X`0`"<`%``)>!7A08`(#B!!@C_?P!`.($&$`'^"$`@ -M2`0H`!PG8#2!)@B@1@0H`?X(0#B!)@@@100H`?X(0#2!)@@`@@<0.($&""": -MSR<$@`<0!#X.$*!JSR\"_A]@H'\!*&G^WX$`?+]A=-`"`#Q^!T`"_C]@A/]& -M0*":`R@`AF%0/7X'0`+^/V""_T9`()@#*`"&85"@>`$H`?X?8`!\'V`+@@`` -M`OX_8(C_1D`@E`,H`(9A4`!\'V`,@@```OX_8(;_1D`@D0,H`(9A4("%SR<$ -M/@X0@&G/+P``@&(`!!\((=\"``%ZX%<`@F!B@8?/)R`BT"\?_A]B``!`8B#@ -MTR\\_A]@`'P_8GBS`@"0B>@)`'R_80"(`@``FL=!`)J'00`@1A``*`I@`!PG -M8"!T!"@\_E]@`)J'092%"`@`($80`0!'$`*:!P`\_C]@`?Y?8""'""@`IFE@ -MH!?0+P`D"6``><\G!#X.$*!-SR\D_I]A````8@""X&$@$=`O``2A80``P&'\ -M_PU``((@4"!G"2@!_E]@`(Y&&/S_#4"@^_@O@/X_8/R!30@`(`A@`)XG8*#G -M\"\!_G]@H`O0+P`AG`@<`(*!:^2\#_A]@`'P? -M8"B^`@"@!_(O#_X_8``!(&`!!0`@H/8#*"[^'V``O@]@H+P)*+#^/V```@`@ -MH%/Y+P```%"@DPPH"7X)@`!$'P@,WP(```'@9P$#`"``?!]@5-0"``"5_R\` -M?!]@1+X"```%]2\```!0(.7T+PI^*8`!_A]@H./T+PI^*8`$_A]@(.+T+P"" -M(%`%_A]@H.#T+\#^/V`!>N=7@@L`(*!&^R\!_A]@`/X&%$#^'V``@`84```_ -M".2^`@````!0%H(_4"#MZR\`!$%0``'@9P``'Q"@X0(``@,`(`"^#V``?%]@ -M'-("`"!)"2C7_C]@@/__)R`6^B\`G@=@@.<&*`7^'V`@TO0O`((@4````%"@ -MT/0O`((@4`'^'V`@S_0O`((@4`%ZYU<"`0`@`+X&*(```""`=OPO````4*#S -M]"\#_C]@@"C/)P0^#A"`],XO``0`"`5ZX%<"?>!7!`````)]X%<0````@0,` -M(`!\7V`N!7`?Y_8J(3`"`N_A]@H*L#*"G^/V"@ -MH`8H`)[G40'^'V"@#OLO_/\M0/R!+0@`@``(`'P`8/___^\`@``0H!O[+P'^ -M'V```0`@____?P'^YT$\^N=7!?[_)Q7^"8(`?@@4`$`H"*"@`R@N_A]@0/X? -M8```"!0@T_DO`*(H4@``'PB@X0(`(.SK+P">YU$``0`@____?P'^YT$\^N=7 -M!@8`((#]_R>@F`,H*OX_8*!#_"\`GN=1``$`(/___W\!_N=!//KG5P7^_R<` -MHBA2%?X)@@"9!B@,(@@4`"((%(#^'V````@4__\?8`@`"!0(_A]@#``(%`%Z -MYU>!!``@(,S_+P```%`!?E\4I[("``!AX2^`7>(OH"L,*'W^'Y@`-``@`(0& -M"`%ZX%>"!P`@+OX?8""'`R@K_C]@@'K/+Z"8^2\``,!A```?"*3A`@``T^LO -M`*)&$"[^'V`@@@,H`7XI0"!XSR\`'`=@`$0?"`S?`@```>!G`'R_82B_`@"! -M$P`@`'P_8`C3`@`$@0`(]($-$`B!``CX@0T0#($`".R!#1`0@0`(\($-$"[^ -M'V"@=P,H+/X_8""U_R\```!0H(WT+^S_#4`<@08([($M"`"``%#T@0T0`'P? -M8%34`@#T_RU`(.H+*.S_34``0#\($-\"``!`7P@4WP(`[/\-0`'^?V`0_I]@ -MH(/:+P/^OV`N_A]@(&L#*`M^*4"``@`@+OX?8"!I`R@M_C]@H*;_+P/^'V"` -M/.$O+OX?8"!F`R@N_C]@`7Y?%*>R`@"`-N(O@+WA+P`GX2\`?-]A,+T"`*#O -MUB\```<((,36+P```%````<(`_X_8``.`!B@"`$H``('$"[^'V"@7`,H!?X_ -M8`#_!D`@:O$O#_X_8``!(&"!`@`@(%D#*"[^'V``O@]@(!\)*-[^/T`N_A]@ -M(%8#*`;^/V"@N,XG0/Z?800^#A`@BLXO,/Z?80``8&(`@N!A``@?"*ZM`@`# -M_M]A"GY`@@"EZ5<`?+]A>+,"`*4$`"``HBA20OKG5T$!`"",HT80C:-&$``` -M`%`@0.(O`)XG8(`:`""`/<\O````8B#\TB\+_A]@D(DF"`!\7V``B`(``(1@ -M0"'^'V``A$!```!!$`*B@1`$G$$0@OX?8`6`01`&HD$0!YY!$`C^04``)BE0 -M_(--$`C^`(C]@4T0$/X`B/Z!31"@`P`@`((@4`""#4#\!0`(``!!$`%^04`! -M_@!```X@&``#YU<)_/\GE(4&"`O^/V`!@$$0`(0!"`'^7V`@FP+,"`)")00@`?)]@`(@" -M```((4`:_A]@``B!0```0A`0A`T($81-"`.`0!`"A$`0`?KG5P'^'V`"``!0 -M!'X`@`)ZX5<%@$`0JP$`(`2@0!`!?@!H!8!`$)2%`0@!_E]@`8!`$!K^'V`& -M_C]@($4'*``<9V"@U+,"`)`)(@@`?%]@`(@" -M``"$8$`<_A]@`(1`0```01`"G$$0`7X)0`.`01`(?@"(!(!!$/3^'T`%@$$0 -M"'X`B`:`01`'_@%`H`(`(`""(%``!$`0`7X`0`'^ID$!_B!```/G5XP$`"`` -MA$8(@'KA9X'[_R<`O@]@`'Q?8'#(`@`@,P@H^GXI0(#__R>4!0((`*(H8`&` -M01``A`$(`?Y?8"`H!R@`(&A@H+C.+P">!V``&,XG!#X.$`#IS2\``,!A`'R_ -M86C)`@`!>N!7`GWG5P(````!`P`@`+X/8`!\/V#I`@``H"8(*`C_1D"`__\G -M`?X?8`__)D`@VO\O``1!4`)ZYU<```!0(@4`(`_^/V``_T9``OY_8(/^GV`@ -MP/DO`(JB4````%`;_C]@H`0`(`+_1D`$_T9``OY_8(/^GV"@N_DO`(JB4``` -M`%`;_C]@!O]&0`+^?V"#_I]@(+CY+P"*HE"`_+,"`)")Z`D`?+]A`(@"``":QT$(_A]B -M`)J'00`@1A``*`I@`!PG8"#N`B@4_E]@`)J'092%"`@`($80`0!'$`*:!P`4 -M_C]@`?Y?8"`!!R@`IFE@H)'.+P`D"6``\\TG!#X.$`#"S2\`>N!7`(:A8:P! -M`"##_M^!"'K@5PP#`"``O@]@`'Q?8'#(`@`@``@H`7XG0(#__RN!7`@P`(```?P@HWP(```0!8`""(4"@U0(H$/Y?8`";YF>! -MV!7(`````$#`"``O@]@ -M`'Q?8'#(`@"@X`^!G`0,`(`"^#V``?%]@<,@"`*#N!7`GW@5PT````"`>!G`GW@5Q`````!`P`@`+X/8`!\ -M7V!PR`(`H-4'*,G^/T"`__\G@,;/+P]ZX(>$`P`@P/X?8*!E`BC+_C]``!P' -M8""Z_R\`FB9@@+?-)P($!P@#?J!AP/X?8"!A`B@3_B=`%/[FIP````(&``!!\(S+P"``#9 -M\B<$/@X0H('-+RC^GV$``>!AY?X?0@(#`"``O@]@`'Q?8!C3`@`@NP!G#/[`00(&`"`!_A]@"H!&$``$05`3A$80((2&$`O^'V`, -M@$`0*(2`$"*(!@@8?@!`H`,`(`Z`@!`'A`8(``'@9X$!`"`QA``("'X`:#&` -M0!``?#]@`L<"``"%``@!`$<0`7X`0``.0!@/>N%7`(%`$`P!`"````!0`(%` -M$``$'P@@WP(``7K@5P)]X%<"`````0,`(`"^#V``?%]@&-,"`""?!R@C?BA` -M@/__)QD`1Q`@2`%7"@$`((`!`"B`6LTG@)H`*(!9S2<$/@X0($3-+SS^GV$``"!B -M0_X?8"`$`B@`HBA@`*/H9Z+^WX("`P`@`+X/8`!\7V`8TP(`H&P'*`)^*T"` -M__\G"(`("``!X&!G,'Y(0@("`"`!_A]@ -M"H!'$*`1!R@`G@=@(._S+P">!V`@B`<($X2G"0"!YE<,`P`@`+X/8`!\7V`8 -MTP(`H%0'*!]^*T"`__\G`00)"/M_(&`!`DD0((@'"`"!YE<*`0`@!/X`:`$` -M21"@`0`@`"B*4@%^"D``#H`:`WX*@`"`QT$D!`<(`('F5P$$`"`.>NI7B_O_ -M)P"^#V``?%]@&-,"`"!(!R@L?BM`@/__)P#\9T(``@``XH4)"`/^/V```>!G -M"X2G"@)\/V`$````&OKJ5P'^`$`!#B`8X85)"`"H!D``!>!7"P,`(`"^#V`` -M?%]@&-,"`*`]!R@\?BM`@/__)P":X*<`J!Q````!4``.0!@@B`<(`('F5_]_ -M`4`!#D`8!X0'"`!ZX%>,#``@`)OF9X$%`"`6"`D(`'P`8/#_````&@!H%@") -M$""(!P@`@>97@@$`(-V%"0C[?P!@W8%)$``$"0C<@4D0`00)"`A^`&C=@4D0 -M`@@)"-Z!B1`$?DE"!/X*4``.H!H!?@%```Y`&/S_#4`@"@N!7`@0`("0$!P@`I"A`)'[@IP#R!T"P?@!` -MH/@!*`C^7V`<@&<(`"@*8`">)V``I$A`($(,*!3^84#BA4D('(`G"``B`4`` -M#B`:#H@`"``$`$`.@(`0'(!G""B((0@`@^!G`1``(.*%"0@`@`!`*("!$"`. -M`"`<@&<(%(0!"``!X&!G`1<`(`YZZE<*#0`@)@@G"`"#X&>!#@`@*``' -M"``$05"@5.XO`?Y_8`%^"D``#H`:`WX*@`"`QT$=!`<(0'K@9P'X_R<@B`<( -M`('F5XH-`"`.>NI7B@D`(``H"F`@^04H`)XG8``.@!H!_@9`H/K_)P`.H!D` -MO@]@`'Q?8!C3`@`@XP8HJWXK0(#__R<`O@]@`'Q?8!C3`@`@X`8HK'XK0(#_ -M_R<`O@]@`'Q?8!C3`@`@W08HO'XK0(#__R<]_A]@H&X!*,)^*T"@S\PG//Z? -M800^#A"@G!G`@,`(`"^#V``?%]@&-,"`*"_!B@9_BA`@/__)PH$!P@``>!G -M@@(`(`'^'V`*`$<0H(<&*``"`0`@$@0'"`-ZX%>" -M`0`@,80`"`A^`&@Q@$`0(&KS+P`N!G`@,`(`"^#V``?%]@ -M&-,"`""F!BA(_BA`@/__)PS^04````!0`!PG8``:04"@T`LH%/YA0.(%2`@< -M`"<(`!H!0``0H!D.B``(``0`0`Z`@!`@#@`@'`!G"!2$`0@``>!G`0,`(`"^ -M#V``?%]@&-,"`"":!BA1_BA`@/__)Q6$`0@``>!G`0,`(`"^#V``?%]@&-," -M`*"5!BA2_BA`@/__)Q:$`0@``>!G`0,`(`"^#V``?%]@&-,"`""1!BA3_BA` -M@/__)_R!30@,_@%``)HF8*#S[2\"_G]@`_X'@```1T`.^N=7B@D`("8((0@` -M@^!G`0L`("@``0@`!$%0(.[M+P'^?V`!_@=``!#@&0/^!X```$=`'00!"$!Z -MX&N!7#0`?4``!````@(@0`GX'@`!\_V$PO@(``!X`0)0!``C8 -M_R=`H(SX+]K_1T``'`=``!X`0+@+``@`'L=!R`='".B!AQ``BB@(ZH6'$`"` -M`%``!."G!/YA8<0``0`0`!\7V`*X`(`(OK@5P``@1`K`@`@``Q@ -M&$#ZX%?,$``@!'X`4$#ZX%<,`@`@C/K@5PH!`"!T^N!7`@D`('3ZX%=!#``@ -M]W\`0(SZX%?!"@`@#GX`0)'ZX%<"_>!7E0```$$(`"`*?@!`F?K@5P+]X%>; -M````P04`(`)^`$"=^N!7`@$`("`$`"``!H$0H?K@5T$"`"#^?P!`I?K@5P(! -M`"#\?P!```"!$(!IU"\%?N"G`/(?4`1^`)```)\0#.`"``!\'V(4F@(``'\( -M0!3_)T`@I\TO@/Y?8`"**`B,^N!7BP4`(*7ZX%>)!``@E?K@5X$#`"!:_A]@ -M)@&($"@!B!!9_A]@*@&($%C^'V`L`8@0E?K@5X(#`"!N_A]@)@&($"@!B!!9 -M_A]@*@&($%C^'V`L`8@0@/K@5XL$`""$^N!7B0,`(%K^'V`F`8@0*`&($%G^ -M'V`J`8@06/X?8"P!B!`H^N!7BP0`("SZX%>)`P`@;OX?8"8!B!`H`8@0;?X? -M8"H!B!!L_A]@+`&($&CZX%>"`P`@;OX?8"8!B!`H`8@0;?X?8"H!B!!L_A]@ -M+`&($-R%)P@`@^!G`HH`&$(!`"#:@T<0VH<'"*#.S2\#_C]@"7X`0``*0!@_ -M_C]@(`<`(+`%9P@`F@U`_`4`"``$`$``"D`8`((`0``@`$``!8`0`?X&0``. -MH!D#^N97`9JF4?__`$``#B`8`(?@5PL!`"`?>N%7C/?_)WX)"`C=@4<0(`?, -M)RC^GV$`/@X0@-'++Q"`C1``@L!A``2A80"&`6(%_@!`H)+,+P`.(!H``.!A -MH%#0+P"B"&``?)]@>+,"`)`)(@@`?%]@`(@"``"$8$`9_A]@`(1`0```01`0 -MA`T(!)Q!$`.`01`1A`T(!?XA0`*`01`@`P`@``1!4`"$!@@!?D%``(!`$`'^ -M($`!_J9!``7G5XG\_R>4!0((`*(H8`&`01``A`$(`?Y?8*#R!"@`(&A@((/, -M+P">!V"`E\TG`#X.$`"XRR\0@(T0`(*@80`$`6*@?,PO`(;A80``P&&@.M`O -M"/X?8`!\?V!XLP(`D(E!"`!\GV``B`(```@A0!G^'V`#^N9G`X!`$($#`"`` -M?%]@<,@"``!\/V`I!P``(.L%*`"^#V"`__\G````4``(@4`!@$`0"'X`B`*` -M0!`0A`T(`'Y"$`:`0!`1A`T(!YI`$`6`0!"4A0$(`OY?8`2`0!`9_A]@"/X_ -M8*#:!"@`GF=@`"`(8`":)F``!$%0H$3M+P+^?V"@:,PO`!P'8`!\S2<$/@X0 -M@)O++P``X&$@8\PO`(+`80``H&$@(=`O!OX?8`!\GV!XLP(`D`E""`!\?V`` -MB`(```8A0!O^'V``!H%!``!&$`'^'V`"@$`0`'P?8"\!```#@$`0"'X`B`2` -M0!"4!0((!9Y`$`&`0!`"!@$`!OX_8`'^7V"@Q@0H`!QG8"!7S"\`F@9@@+/+ -M)P0^#A"@D4 -MA0((`*(H8`$`0A``!`((`?Y?8""@!"@`(&A@H##,+P">!V``D,LG!#X.$(!R -MRR_R_K]"``#@80""@&(`!*%A`(8!8@`(8F(```!``7X@0@-^X*<&_AQ`H";, -M+P`.P!D``$!BH.3/+P`+,"`)`)(P@`?%]@`(@"``"$@$`;_A]@ -M`(1`0`#ZYU<#?B)`J0,`(```01``O@]@`'Q?8'#(`@"@E`4HN/XJ0(#__R<" -M(D(0`_X*0`,`0A`(?@"(!`!"$`4H0A`@!@`@````4`6$0!`!_J9!!HI`$`C^ -MHH@'BD`0``1("`;^8$`(A$`0`7X(0@%^`$``AB%@`('G5PP'`"`!_DI``X1` -M$`A^08@$A$`0`(1&"(!ZX6?S_K]`@O7_)P"^#V``?%]@<,@"`""#!2C"_BI` -M@/__)Y0%`P@`'"=@`0!"$``$`@@!_E]@('@$*`"F:6"@",PO`"0)8`!KRR<$ -M/@X0`$C++P``@&(`@F!B``1!8@"&(6(`"`)B(`',+P"*PF$``*!A`'S_86"@ -M`@``@0<("'K@5X8'`"`!7!H0`4`4$`%``@`$0((`/.````%`$/@X0 -M`!?++P``P&$`@@!B``2A82#;RR\``.$)`*`G0``#YU<.G"!0(-O++P""!A"@ -M.,LG````4"`!`"``@B!0`?X@0`7ZX%>&!0`@&/[@IP#\7$`DJP(`*``!"``` -M8`@D``$(````"`"!X5!G@0$`(`"^#V!G -M_C]@@),%*`'^YT$8_J9!!'['007ZYU<&'\LG`'P_8"2K`@```@=`$```"``! -MX&<`@@9"@>__)R@`"`@``"`()``("``"`!`P`@@0+`(($#@`"`@````(``'@ -M9P&^#V!!B`4H3OX_8#0`"`@``"`()``("`````@``^!7A0(`(`"^#V"@@P4H -M4OX_8#0`"`@``"`(*``("`````@``^!7A>S_)P"^#V`@Z_\G5OX_8"`#`"`` -M"()0``1@"`%^@D``AD`0`?X@0`%^`$``">%7C?S_)P"`#S@"?H&((`,`(`"& -M85```$`(`?YA0`"$`!`$_B!`!'X`0``'XE<.@`\X`/S_)P!\/V`DJP(`"(`` -M"`"`0`@````((,#_)P'^/V`8?N"G`/Q<0"2K`@`T``$(`()@8"@`(0@````( -M`(`@"""X_R!G`7S?80$````@T,HG``X'&`0^#A"@ILHO*/Z?80``X&$`@L!A -M_/\-0/C_+4"@N-DO]/]-0/R!#0BA_C]@``*`$/B!K0D/_C]@#()&$``(``@0 -M?@!0#H"&$*#^'V"@91A"?G$80"'['B:!ERR^@G$80^($-"/R! -M+0B@.]LO#'X`0"#1RB$O"?X?8(!=X2\@7,LO`)H&8*!BWB\!_A]@TOX?8*!B_R_X_C]` -M`+3*)P0^#A"@A!7````!($#`"``?%]@F,@" -M``!\/V`P`@``H*4$*`"^#V"`__\G@,GW+X`HRR____]_____?____W____]_ -M____?____W____]_____?____W____]_____?____W____]_____?____W__ +M.(!'"`"$!A`\@"<(`(/@9X$#`"`XG`<02)P'$`&!&0`@0`!'"``%X6<`@B!0`0(`($`"!Q`#_C]@(!8`(#P"!Q`X +M`$<(/`('$`)^88``?)]@N-8"``"((0``@^!G`0,`("2`0`@@'`$0))P`$"0$ +M!Q`@#P`@(`('$`"(@4``'`(03``G"!P`;0@`AB!H$`!M""`".P`@`)J!00`$!A`@`$T(``7A9X$!`"!,@"<(``(A<"`"#1`0 +M`"T(`(/G5P(V`"`D`"T(`OX@@`":(``@-``@$`(-$```#0@``>!G@@K<)P`D +M`"``FH%!3(`G"!P`;0C_@S]P(`"-"`""86``">)G'`8-$*$!`"``"@80`(B` +M8"`(#1``CR$8`B#(8<(*`"`"H&``"/XAB`"/(!@!`@`@`"#(80*@(``@!P`@ +M"/Y@0!#^(8@`CR`8`0(`(``@R&$"H"``H`,`(!#^8$`8_B&(`(\@&($1`"`" +MH"```"#(81C^8$`D!@T0$``M"`"#YU>"'0`@`OXA@`":(```">)G$`(-$`$; +M`"`!?B%`*`(-$```H!\`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$` +M2``!`$@$?B!@`("@'____W\H`"T((`!-"/__($`H`@T0``\A&`$$`"`@"P`@ +M`IP@`"#^/V`D`@T0$`H-$```H!^`6-TO`.7;)PA^(8@`CR`8@0$`(`*<(``@ +M!0`@"/X@0!!^(8@`CR`8@0$`(`*<(``@`@`@$/X@0!A^(8@"G"``&/X@0`+^ +M((``FF``)``M"$B`@0@`B>!7!0(`($R`(0@0!@T0``(A<"`"#1```*`?$``- +M"`P`+0@``^!7`=;;)X#)_R<$/@X0@*C;+PP`K0D`',=1`*`?"``!`$@``0!( +M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_/(`F"`"#X&>" +M#``@'(`F"!B"!A`H`"T(`(/@9P)\/V`!````0@D`(!B"!A`@@&8(`(?F5P$' +M`"!(@"8(.(!&"``#X5<"!0`@`GXA@`!\7V"XU@(``(2`020`+0@`!@80`OX@ +M@`"$(``!_M]A$`(-$```H!^@O-LG`!P'8`0^#A``D=LO``"@83P```@$>N!7 +M@@D`(`"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&`` +M@*`?____?R@`+0@!_B!`*`(-$```H!^@-/\O`)H&8("OVR<`H!\(``$`2``! +M`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W]T@,8)``"@ +M'P`=YV>!I]LG(`('.`":!F``IMLG!#X.$(!XVR\`H!\(``$`2``!`$@``0!( +M``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W\L`*T)``"@'Z""#@`@('KA +M5Q_^/V`.?"%0`0````+^0(!``"T(`(1`0#P`+0@``^%7!0(`(``"(5#\_T!@ +M.``M"`"$0$```"$(`(/@9P$$`"`0@@80%(`@"!2"!A`0F@`0```A"!2:`!"@ +M`@`@&(0&$!":!A`4F@80&(0&$``:`1```*`?((+;)P```%`$/@X0`%7;+P`` +MH&$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@ +M'____W\8@"8(`(/@9X$$`"`0@$8(`(7F5X($`"``@&`(`(?F5P`$05""```@ +M`(0`$!B$!A```*`?('/;)P```%`4@"8(%`(!$!"`9@@0A@`0&(`F"`"`0`@` +MA>97@@$`(!B"`1`0@$8(`(0`$"#X_R<`!$%0!#X.$*`_VR\`@B!0"'Z.4P": +MIE$L&@T0,!H-$#0:#1!$&@T0`'Q?8#C7`@`@`@`@``0!8``:`!`$?@!``?X@ +M0"#ZX%>%_?\G.`0-$$`$#1"`?@%`/``-$`!\'V"XUP(``'P_8#BG`@``?%]@ +MZ4D``$@`C0A,`*T(4`#-"!`:#A`4&@X0`'Q_8$U)5$$@-OXO``SC8%0:#1!8 +M&@T0"'Z.0X!7VR<$/@X0(#W;+SC^GV$`?>!734E40:$!`"``GN=1(&3;)SC^ +MGV$`FJ91^)L-$/S_34+X_\U!`_X_8B`%`"`!_A]B#``M"#RB`!!$H``0*``M +M"`'^($`H`@T0``"@'R`G_R\,``T(`*`?"``!`$@``0!(``$`2``!`$@``0!( +M``$`2``!`$@``0!(!'X@8`"`H!____]_0`!-"```(0@`@^!G_(,-$($``"`8 +MI``0`!H!$$``+0@$_D!`/``M"``#X5=`!`T0`@$`(#@`+0A``@T0(!@`($0: +M#1`0@"D(`(/I5T$$`"#\FPT0%(!)"!2$`!`0@"D($`(!$!BD`!`0@"D(_(,- +M$`"`*0@@^N!7#@(`("#^(%``@@D0H`,`(``HBE($@"D("(")"@"#X&<`@@D0 +M(0(`(`R`Z0D8G`D0(`$`(!"F"1`8F@D0``"@'P`IZF!G`?W_)]``"0@`&^!7`B?@5P(AX%!A""!0`@`)_G9P(#`"``O@]@`'Q? +M8-#(`@"@]!0H(WXJ0(#__R<`_`=H````$`"`!A``H@D0H.`&*````%"@DMLO +M`!P'8*#]VB"!P`@`'P?8(#)`@`"_C]@H`8/*``$05`% +M!"<(`_K@5P!\'V```"``B0$`(!A\`!0B,@````$`(!A\`!0",@```)OF9P%\ +M'V"$R0(``01!4,'^#B@"_C]@`)X'8*!X`"@`FB9@(!_\+P'^'V``?%]B_+T" +M``!%"0@``>!G`0,`(`"^#V``?%]@S,D"`"#%%"@J?BI`@/__)P'^'V```4D4 +M!P0G"*`C&2@`F@9@`P0'"``(*`B`?@!H#P%)$`$$!P@)`4D0``0'"``" +M`(`+^"\`"`@(`"?@5P(&`"`%!`<("7K@5X$$`"``?%]@>,D"``-^@(`)V!C_A]@H",/*``<)V`@H-HG-/Z?800^#A"` +M;-HO``"@80""(&(`!.%A`(;!82"5W"\`"`)B`GK@5P$0`"``!`@(``'@9P"( +M)PB!!0`@```'"````$`$@`@``(``4``:($``D``8`(*'$*!0W"\*_C]@(`(` +M(``0X!D`F@!``("'$`":YF$```<(````0`"`"$``&H`0```'"`%^`$"@M=LO +M"OX_8`"#X&<``@<0`@$`(`'^'V```$@0`)ZG8:!]VB<`F@9@!#X.$``V#A`` +M.&YC&'Z.4Q`:#A`4'`X0``"@80#\`&#_/P```!#`&0#\!F#_/P```!"@&1#^ +M!H``?#]@(@`@"(`8VR\`_`9``(```!!^`(``?#]@(@`@"(`5VR\`?`=``$`` +M`!!^`(``?#]@(@`@"(`2VR\`?`=``,```!!^`(``?#]@(@`@"(`/VR\```!0 +M`'P_8"(`(`B`#=LO$`"N"10`S@D$@.T+((`/.!@0;@L`?%]@),<"```!(0@` +M@`!`((`/.``!`1```!\(),8"``"`#S@$/@X0(##:+Q3^GV&@`@`H_/\-0/R! +M#0@*?@"((&_:)Q3^GV$$/@X0(#/:+R#^GV$@^MHO``#@82#W_R\``*!A``#` +M80'^'V`@`PDH_/\M0/R!#0C_@1]0`!P`0`"`!Q"@]MHO`)H&8"!DVB<@_I]A +M!#X.$``V#A``.&YC)'Z.4Q`:#A`4'`X0&!X.$!P@#A`@(@X0``#@80!\OV$` +M$3```/KG5PP"`"`.^N=7"0$`(`#ZX%>"```@`)[G40!.W"\!>N!7`@(`((!. +MW"\`>N!7@@``(`">YU$`?#]B3*@"``"%2`@!?@%@`'K@5X$V`"`"A0@(`('G +M5P$U`"`"GT@0`(`F"`#\`&@```@(`'P`:`````0`?`!@___[_P"`!A`0?@%@ +M`'K@5P$(`""`VMHO``#`80#ZYU>!`@`@`(`F"`#\`&@`"````(`&$``"`"`` +M@"8(`/P`8/_W__\`@`80`!P'8`#6VB\`)P`@@-+:+P``P&$#GT@0`'P?8`D` +M(`@`U=HO``#@80#\)V@```"``'P?8`D`(`@`T]HO<_X_8@"`)@@$_@!@`'K@ +M5P$!`"`!_A]B@```(('^'V(`@"8(`/P`:``(````@`80!?X?8(!N%R@??@A@ +M`'K@5P$4`"``^NA7`1,`((!^"&``>N!7@0,`(`"`)@@$_@!@`'K@5P$,`"!_ +M?@AB$/X_8H`+`"``@"8(!/X`8`!ZX%>""``@`'P_8DRH`@`#A0@(`"``8`!Z +MX%N!7`0$`(`#ZZ%<"[?\G`(`F"`#\`&#_]___ +M`(`&$`!\'V`)`"`(`)XG8("RVB^`U_\G$`"N"10`S@D8`.X)'``."B``+@H$ +M@.T+((`/."00;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$`$3``@$OH+X"C +MVB\`@"8(`/P@:```"`@`_"!@__?__P""!A"`HMHO````4`/^/V``K/\O$`"N +M"02`[0L@@`\X%!!N"P0^#A"@VMDO)'[@0`":IE$`!$%0"`@`"0">YU$`>N17 +M``B"4"P"`"`<`*`(`@@@"``#Y%<+`P`@`+X/8`!\7V!XTP(`H/,3*)S^/V"` +M__\G6(#"""`$`"``AF%0`(8A0`""(D!TB"`(`(@@0`"0@!@!_B%``(Y@&`"- +MX5>%^_\G`!'D9R$,`"`!"`)A`'WD5RH)``")`0`@`'WD5P`!```*`P`@`+X/ +M8`!\7V!XTP(`(.83**[^/V"`__\G`7KD9P$#`"``O@]@`'Q?8'C3`@`@XA,H +MK_X_8(#__R<+!"`(``(D4`"0`!D&>N-7#0$`(``-XV<"`P`@`+X/8`!\7V!X +MTP(`H-L3*+7^/V"`__\G`)9E45R`P@ETB$()`!!D8``((F$.^N97B@@`(`YZ +MX5>*"@`@`_XF@`""@T$`!$80`((C0@&>2!`$G`@0``?E5P`@"%(L"0`@`"1) +M4@'^7V(`!L=!``8E4"`-`"``D$`9`+X/8`!\7V!XTP(`H,P3*+W^/V"`__\G +M`+X/8`!\7V!XTP(`H,D3*+[^/V"`__\G``?E5X(!`"`!_E]BH`0`(`'^'V(! +M_A]B`I2($`"4(5``D&`8`!0B4`"0@!@!_B=``([@&0%ZZ5<"!@`@`H:($`&$ +M*`A`_B!H`8)($``&(E``D8`8`GPA0`$````"CD`8`I[G40(09&`""")A`7KH +M5P(%`"`!_B5``(Y@&0"-Y5<&`P`@`OXE@`""(D!<@,`)`)8E0`""(D!TB$`) +M`?XF0``)XF<`CJ`9`MO_)P/^)H``@F-`^84A",#^(&CY@T$0"7KA5R`$@!`+ +M`P`@`+X/8`!\7V!XTP(`(*T3*/S^/V"`__\G"P0@"`"2($``>N%7(@*`$`D# +M`"``O@]@`'Q?8'C3`@"@IQ,H__X_8(#__R<#?N&G`_X\0`":@$``?&!`(`(` +M`,*%(0@`@^!GP8E!$"$"`"``#J(8``0B0,``CJ`8"P0`"!IZX%>"H=DG +M`(0"0*"@V2?!@4$0!#X.$*!NV2\D?J!``'R_80`"```("$`(`(9A4``%X6<+ +M!``)(04`(!P`(`D"""`(``/A5PH#`"``O@]@`'Q?8'C3`@`@E!,H4_X_8(#_ +M_R=8@$0)!GKE5PT!`"``%>5G`@,`(`"^#V``?%]@>-,"`*".$RA5_C]@@/__ +M)P".XU"@`0`@``S#4`'^(T``CN`8`)7C5P82`"``CB-``((D0'2(0`@"_B.` +M`((D0%R`@`@`!"1`H`(`(`"0`!D"A(`0``1!4`'^(4``CF`8`'KA5XSV_R<. +M^N%7B@8`(`/^(8``@H)!``Q&$`""(D`$B``0`!OA5P&,0!`,^/\G`IJ`$``: +M(5``D$`8(/?_)P`:@D``O@]@`'Q?8'C3`@`@>1,H8_X_8(#__R<#_B&``()" +M0/D%(0C`_B!H^0-!$"`,@!`B$(`0`?XA0`!\`$`@`@``P0-`$"!PV2?``T`0 +M!#X.$(!%V2\``*!A'``@"`O^'V`,@$`0`'Q?8&+'`@`!!0$(#8!`$`Y^`$`! +M`4$0``X`&'%ZX%<,_L!!#`$`(!#^'V`!`4$0``0?"(#?`@`!>N!7`GW@5P(` +M``"!`P`@`'Q?8'C3`@``?#]@70$``"!C$R@`O@]@@/__)QD`1Q`@#!,H`!P' +M8``$'PAXK0(`@'K@9P$#`"`7A`8(`8`?@`!]X&?8#P``(C7O+P*:!F`@B`8( +M$X0F"`"!X%<"`@`@````4!P`AQ`@!``@(H@&"`%^`%``@>!700$`("*(!@@( +MB`8('`"'$`B(!@B@4MDG`@"'$`0^#A``)]DO``#`81P`(`@+_A]@#(!`$`!\ +M7V!BQP(``04!"`V`0!`.?@!``0%!$``.`!AQ>N!7#/Z@00P!`"`0_A]@`0%! +M$``$'PB`WP(``7K@5P)]X%<"`````0,`(`"^#V``?%]@>-,"`"!%$RC)_C]` +M@/__)QF`1A`@[A(H`)H&8``$'PAXK0(`@'K@9P$%`"`7!`<(`8`?@`!]X&?8 +M#P``@0(`(`6$!@@`!#\(/+,"```"`&@%@$80(`@'"!,$)P@`@>!7`@(`(``` +M`%`<@(80(`0`("((!P@!?@!0`('@5T$!`"`B"`<("`@'"!R`AA`("`<(H#+9 +M)P*`AA`$/@X0(`79+R3^GV$``>!G@@,`(`!\7V`DR`(``'P_8"$!```@+A,H +M`+X/8(#__R<$`"`(](,-$```(`CP@PT0`((@4/R##1`(""`(H`P7*/#_#4`` +M`*!A^($-$`!\7V`,U`(`\/\-0"!;%BCX_RU``)H&8"`VV2N!7000`($()`0@# +M>N!71`DA"$&`#S@$`X$00@D!"``#X%<,@@!@((`/.`0!@1`$/@X0`)G8+P"9 +M["\!>N!7`@$`((`!`"B`P]@G@#@`*(#"V"<$/@X0@)G8+P!\OV$\L@(`=HDF +M"```7P@N!7`@(`($J)!@A.@880(`,`($R) +M!@@">N!7@@(`($:)!@A.@8802(D&""`"`"!0@880`+X/8*`($RC9_C]`"(L& +M"#J+)@@``@!`"(&&$``,(!@\A08(``'@9SJ=AA`!"P`@3HD&"`2)1@@`!>!7 +MBP4`(/__`$``#"`8"(&&$%*)!@@&B48(``'A5XL-`"!6B08(`7X`0"`,`"!6 +M@8804(D&"``%X%<)"@`@`?X`0``,(!B@"``@"(&&$%*)!@@&B48(``'A5ZH# +M`"`!_@!`9(4&"``$7PC2K`(```'A5XP!`"#__P!```P@&`B!AA!8B08(`7X` +M0%B!AA`BBP8(`('@5\L#`"`(@8805(E&"`"%X%<)#`$820$`(`B%AA``@@!@ +M)HDF"``#X%BZ`(EHE`")"+``@`A>)7"0@`0`P``E``#``8!'Y#@``%X%<*#`$8 +M!/Y!@``%X%<+#`$8((&`$`A^`$`$?D"0``P!&!Z%@!`!?D!`(!T`((2%@!"$ +MBP`(H!L`(!Z!@!``"A\(:M\"`(QZX%>+`0`@I7K@5\P'`"`1_E]@@'K@5XL! +M`""$>N!73`4`(!+^7V`H>N!7"P$`("QZX%<,`0`@:'K@5P(!`"`@`0`@%OY? +M8!7^7V",A8`0B(D`"```?P@8M`(```8`0``0H!B&@8`0E(E@")*)@`@`!^)7 +M((L`""P"`""*A8`0CHM@""`#`"``@`%`!(E@"`;ZX5>*`0`@CHM@"``&`%`` +M#``8!/YB@``'X%<*C`$8!'Y!@``%X%<+#`$8((&`$`A^`$`$?D"0``P!&!Z% +M@!""BT`(``7@5P&`#SB"@8`0H#__)P`0`!@$/@X0@"O8+P``P&$8"``(``@_ +M"%[8`@``?+]A/+("```#X%<`GN=1K`4`(`:!AA`!_A]@(-\,*`""(%`!_A]@ +MR(%&$"!B#2@&B28(`?X?8*`&`"!D_C]@R(4&"`%ZX%<"!0`@`?X?8*#8#"AE +M_C]@R)]&$`:))@B@6PTH`OX?8`'^'V#(_C]@@-0,*!8()P@`C>`?@P$`(!X( +M1P@`#>$?!`0`("F%!@@\GT80`7X`0``.(!@$^N!7*8%&$(I7_R^`$``@`?X? +M8#R!1A`IGT80`'P!8/]___\`$$`81(&&$``$'PB;K0(``/P@8/]___\">N!7 +M0H.&$"(#`"``D&`86H4&"``!X&<"`0`@1(.&$`"&06`TBP8(`(1@4"J%1@@` +M!H!```0!0``:($`LBP`(+(>`$````E`T@880`7X!0`-^`&`J@480!`A'")B% +M!@B2A880``!_"!BT`@```>!G``R!&*('`"``C*$8`?Z?8"`#`"````!0`GX@ +M@`":($"@AX`0HH6`$`%^`$`(>N!7B_S_)YR'AA">A880("'8)YB)1A"9A<8( +M`((@4`)^`X``&@!`H`>`$*(%@!`@!0`@````4``:8$"@BT$(`(7B5PD$H6"B +MBT$(``7B5PD$@6`!_B!`!'X`0`CZX%>+^O\GGHF&$)R+AA`!?@-`!WX`8*`4 +MV">9@480!#X.$"#KUR\D_I]AC_[_02#BZR\``*!A``#`872:'U#^@8T0;/X? +M8`%ZYU?Z@8T0H0,`(!/^!D``"!\(_KP"```:`$``>N!7"1``&`P``%#\@8T0 +M`?X'0*"9#"B8_C]`@*?8+P%ZYU<``*!A@@D`("#6"2@!_A]@`'P?8!N%```" +M_C]@_O]-0*#Q"R@`AF%0_HD-"&QZX%<"`0`@:_X?8/J!C1``?!]@'(4```+^ +M/V#Z_TU`(.P+*`"&85"@S`DH`OX?8`!\'V`FT@```OX_8/S_34`@Z`LH`(9A +M4/R)#0@`?%]@/+("`````$`$?"``U,D"``!\'V!8K0(`4?K@5QH$8`@,!0`@ +MP`4A"`"#X&>"`P`@'`4A"`+ZX%<"`@`@`?X_8%H#01`@`@`@(/XA:`""(%!: +M`T$0W_\A8!H"0!`@W>LO`((@4""-V"\`F@9@D/X?0"!Z#"A/_B=`(/G7)R3^ +MGV$$/@X0`+G7+Z"VZR\``*!A=)H_4`%ZX%=L_I]@(A$`(`"0H!@3_@9``!`@ +M&&SZXE<`?+]A6*T"``*$!@@!?)]@:P````-^`&@"@$80`((`0`1\``#4R0(` +M`'Q?8#RR`@!1>N!7&H1F"`P%`"#`!0$(``'@9X(#`"`N!7"1`@&`!\OV%8K0(``H0&"`R"(%`!?@!H`H!&$`."1A`6BD80%XA& +M$`":!F`@O.LO`((@4`*$!@C\?P!@H,;7)P*`1A``/@X0H*_7+RA^X*<`BB)B +M``#`8@""H&(`!(%B`(9A8@#\'$`HQP(`)```"``(0F(8?N"G`/+<80!\OV'0 +MJ@(`H%_8+P#RYD$```!B"(`'"`%^($`4B`<(`('@5X4"`"`@7M@O`"`(8`"^ +M#V`@%1(H9OX_8`"-)G`(P<0$(!`"``C!P`!```"``&`&@``F!X`(1A>`R&`A`(A`(0!((" +M$""`#S@`@`(0``!?"*3'`@`(@``0`'QA:``"```$@$`(``9!>```07@,A``0 +M((`/.`"&`!`$/@X0("O7+RC^X:<``.!A``2A80#\'$`HQP(`!```""!)`R@` +M`L!I"(`&$``>)W@`@`!X#(`&$`2>!A"@3-`$(!&"`"F"6``)"E@``9!0*"S_R\"_G]@#(`&"`+^ +M)X```B!``)P`$`%^"$(!_@=``*'H5PWX_R>@I=N!7`(!($`(" +M`"`,@`8(`OXG@``"``````D0()#7+P`@"&"`[]8G`#X.$"#`UB\8?N"G`/R\ +M0="J`@"@B=@$$!>NA7`"(&$`("`"`` +MP`(H$(`F"`">($`$@``0`7['01#^YT$4B`8(``'G5POY_R>@9MT(``(!```"84``?,!@____[P`"(4`$@`$(`(P`$``,('@( +M@`$(`7Z"0``"`'@,@`$0`?X"0``.H!@`#^)7$`!'"*7W_R<$_B*```(!```" +M@4$`?`!@____[P``!A`0`$<(``(!```"(4``@``0($O7+P":!F`@N=8G'/Z? +M80`^#A"`==8O$(`-$!.$#0@@;O,O?WX`8(!6V"<$?HY3`#8.$``X;F,0@`T0 +M$X0-""`%`"!_?@!@!'Z.4P`V#A``.&YC$(`-$!.$#0B`?@!@`('@5P'^'V`" +M``!0`!!N"R"`#S@$?HY#`P1`"']_06```B%H((`/.`,"0!`$/@X0(&G6+P`$ +M86"@^_\O``"@80.$!@B`?P!@`X!&$*!;\R\`A@%@`X0F"``"`&@@C]8G`X!& +M$`0^#A"@7]8O``!@8*#T_R\`!(%@`X0!"(!_`&``"`!H((G6)P.`01``?#]@ +M,```"2`PUR<```!0`'P_8#````D@+M"``(`7KA5X$#`"``_4!@`(````$#`"``#>`?`P(`(`"!X%<+`P`@H`(` +M(`""`&``!>%G`O[_)P`-X!\#_?\G`(`/.`0^#A`@.M8O1/Z?80``H&$`@N!A +M``0!8@"&P6'L_PU``((@4"#YUR\0_E]@H`4`(`""(%`!_@!@`WY`@`*"!P`` +M!&"`_O\`8`"`34#L"0$(`?X@0``&`&CL`8$0$/K@5P7Z_R<`!`<("'Y(@`A^ +M((`!!`<(``(`0`($)P@`$``8`(0@:`"08!@@"P`@``1!4``$(4``@HU`[`DB +M"`%^04``@`!X`!"@&``.`!@```!``'P`0'BX`@`$"2`("/X"D````$``?`!` +M>+H"``0)``@``B!X`()A>`"0`1C%]/\G[(D-""`&`"`' +M_C]@``!`0`]^`)``!`!H`!!@&`""`$``@$U`W`D!"/__($``@&%``)`!&-P' +M@1``@^!G@OG_)P`$!P@`@$80`00'"`&`1A`"!`<(`H!&$"`%`"`#_C]@`?X` +M8`-^0(#^_P!@`(`-0-P)``@`@H9!``0`D```1A`!_B!`$/K@5X7Z_R>@0=8G +M1/Z?82`#`"``"()0`@A@``"(@$$`!D80`7YB0`".@1@`">%7#(`/.`#\_R<$ +M/@X0@`36+P```&(`@J!A(,G6+P`$X6$``,!AH(O:+Q/^'V``?)]@I+,"`)`) +M(@@`?%]@`(@"``"$8$`=_A]@`(1`0``AZ&<``$$0@0,`(`!\7V#0R`(``'P_ +M8&$'```@'Q`H`+X/8(#__R<"H$$0(`,`(````%``A$8(`(`A0`.$0!`!_J9! +M`7X`0`-ZX%>%_/\GE`4""!/^/V`!@$$0'?X?8`'^7V"@#@\H`)YG8*"WUB\` +M'`=@`!76)P0^#A``Z-4OH++6+P``P&$``*!A('7:+P+^'V``?)]@I+,"`)`) +M`@@`?#]@`(@"``7^7V```H!!``1&$)0%0@@``F!``81!$`("```"_C]@`?Y? +M8*`!#R@`'&=@H*K6+P":!F``!M8G!`A`"`2(8`@`A>%7@@0`(`((0`@"B&`( +M`(7A5X("`"``"``(`(@@"`"!X%N=7C`$`(`5ZYUNI7#`$`(`5ZZE>"!0`@`"GJ9X$#`"`` +MC^-G@@(`(``EZ6>!`@`@0H0*"`1ZX%NQ7`?X_8@L'`"`$!`@(`7K@5P$%`"`!!`@(`7K@9P)]X&<"````0@$` +M(!X("`@8"`@(8'X`8"!ZX%>"```@`*(H4@":!F`@*`(H`"@J8```@&``+`M@ +M`!PG8*`T`B@`CD-@``@@0`!\GV`(LP(```$""``"`$``H^AG``$"$($$`"`` +M'`=@(%`"*``D*6``#@`8(!H"*`".(V```2((``(`0``!`A"`7=@O```?$/B8 +M`@``U-4G!#X.$("KU2\``*!A`@@`"``D25($?@!``!``&@``'P@$]P(`H"\" +M*``0`!@``,!A'(`&"`"B*%(1!$`(`?[_801ZX6<`?']B6*T"`""$"0@"GN=1 +M@'K@9P'^/V`!@B!0"'KA9X!^H6%"`@`@`?X_8@)ZX6<"?#]B`@````"CZ&>! +M`0`@(%("*``NE7#`$`(`5ZZ5>"!``@`"7I9X$" +M`"``G^=G@@$`($*$"0@$>N!7`0$`("`!`"`!_E]@``1!4``.*1B@_P$H`*(( +M8```@&``(`A@`!PG8"`,`B@`GD=@``@@0`!\'V((LP(```$("``"`$``F^9G +M``$($($$`"``'`=@($`"*`""(%``#@`8H/$!*`">)V```2@(``(`0``!"!`` +M-=@O```?$/B8`@"`IM4G!#X.$(![U2\``,!A``H?"%JQ`@``$.`9``0?"%S8 +M`@```>!G`"`(4H$(`"``;>DO``@_"#ZQ`@`!>N!7`((@0((!`"`%_```4+$" +M```%`"`%_```5+$"```00!@`"!\(_KP"```$`$`@`@`@`!#@&0`*'PA$L0(` +M`!!`&`!\OV%8K0(`0X0F"`"#X&>""P`@`)X'0`1\```4F0(```XG&``.`!@@ +M'``H``1!4``&`"`"?B>0(`,`('2$'U``!`%``'P`0-3)`@`F"``(`GXGD``. +M`!@`CB`8H`<`*``$05````!BH`(`($.$)@@!^N!7@??_)P+ZX%%G``Q@&($``"```($0``0?"#RT`@```@!`((`/.``&`%`$ +M/@X0H#+5+P+^'V``?+]AA-\"``"`1@@`@B!0@/Y_0"#X%"@`"()0!(!&"`/^ +M'V``@B!0@/Y_0"#U%"@`"()0@%;5)_^1/Q@``H`0`@*`$""`#S@$`H`0`'Q_ +M8!``(`"@`@`@``1!4``$(4`$`B```7Y!0`""@10`?>%7``$```:`#S@`_/\G +M!#X.$(`FU2\``,!A`'S_81``(`"@"P`@`)JF40":)D``R`<(``(G0`"`@!#_ M__]_____?____W____]_____?____W____]_____?____W____]_____?___ +M_W____]_____?____W____]_____?P'^ID$`_>97``$```9`U2<`\_\G!#X. +M$*`.U2\`"()0``,`(`)^`H``?`!`A-\"`*#E_R\(```(`7Z"0"!ZXE>&-M4G +M@/O_)P0^#A``$M4O0_[_@0!\'V*$WP(```#`8:`#`"`"_K]A`OXF@`"$0$"@ +MX_\O```!$`@`QPD!_J9!`!WG9P$&`"`B^N97!@4`(`P`!P@``>!G`"!(8`+Y +M_R<`O@]@`'Q?8'S2`@`@+`\H%/XG0(#__R<``-\)`.("```#`"`"_B:``(1` +M0"#8_R\```$0"`#'"0'^ID$`'>=G`08`("+ZYE<&!0`@#``'"``!X&<`($A@ +M`OG_)P"^#V``?%]@?-("`*`@#R@A_B=`@/__)X#F`2B@`P`@``#`80+^)H`` +MA$!`H,S_+P```1`(`,<)`?ZF02+ZYE<&"0`@`!WG9P`@2&"!!``@#``'"``! +MX&<"^?\G`+X/8`!\7V!\T@(`(!4/*"_^)T"`__\G`+X/8`!\7V!\T@(`(!(/ +M*"[^)T"`__\G(OKF5P$1U2<`O@]@`'Q?8'S2`@`@#@\H-OXG0(#__R<$/@X0 +M@./4+P``OPD$X@(``)OF9__^_T$"`P`@`+X/8`!\7V!\T@(`H`!G@OC4)P"^#V``?%]@?-("`*#V#B@5_B=` +M@/__)P0^#A"`R=0O``#`80"#X&N!7BP,`(`!\7V!\T@(``'P_8.L!```@[0XH`+X/8(#__R<#!$<(``7A9P%\ +M7T"``````GX`@`!\(`"$WP(`(,<)*`1^!T``A`8(`7X`0"#EU"<`@$80``A` +M"`"$@!`""$`(`H2`$`0(``@@@`\X!("`$`0^#A``Q=0O```@8@""8&(`!`%B +M`(:A80S^7V(`GN=1`(`!$`1^`$`$@`$0"/X(0`B``1`*_@A`#(`!$``E7#!L`(`*D"``&>N!7@0D`((D1`"`%>N!7C?G_)P-\@`$T7`$` +M`'R&00U7``````8X[`+N!>X(````(@E`(/7_)Q2`!A``(@E`H//_)QB`!A`` +M(@E`(/+_)R"`!A``(@E`H/#_)QR`!A``(@E`(.__)R2`!A``(@E`H.W_)RB` +M!A`#^N=7"NS_)P`B"4"@F?`O`)XG8`%^`$"@Z?\G``[@&25^`%`->N!7C>?_ +M)P-\@`'$7`$``'R&03%7``````8X!,K*\,KJRLK*RLK*RNT``*`QWR\`(@E` +M@.'_)P/ZYU<+G@=@*[WP+PN"(%`@@$8(``7A9P$0`"`#?@B0`!!@&`0$`0C^ +M?P!@`(`A4`"!X5<`D"`8"P8`(`$$`0@#?@!0`!``&`"!X%>)`P`@``(!0`4$ +M(`@'?@A@`8`?@``"@&(@`0`@+*A&$"R<1A``*>IG@0(`(`!\/V#@EP(``(`` +M"`%^`$``@``0!`0!"`%^`&`@I-0G+8!&$"R<1A"@HM0G+9Q&$`"`#S@$/@X0 +MH'C4+RC^GV$`?#]B``(```S^J($(P"8(#,`&"`!\WV&DLP(```+@82#^'V`@ +M)PDH`)XG8)9%!P@``>!G`0,`(`"^#V``?%]@T,@"`""2#B@\_BA`@/__)Y5% +M!P@``>!G`0,`(`"^#V``?%]@T,@"`*"-#B@]_BA`@/__)P'ZYV'`P4`(+3^'V"@$PDH4?XH0(`2\2^`_A]`"(`&%""R\"\` +M``!0H+L%*$+^/V`6^N>'`P0`(+3^'V"@#0DH6_XH0`#Q[B\(H@84@&7N+Z"V +M!2@<_C]@0/KG9X$&`""]_A]@H`@)*`">)V!`_A]@"(`&%`S`!@B_?P!@#(`& +M%#!%)PB@!`DHO?X?8`'^'V`P`4<4"/KG9P$)`"````!0_X%-$`C^'V((H`84 +M(*CR+___#4```>!A`0(`(*#HY2\,@`<(()+R+P">!V"610<(``'@9P+Z_R?_ +MA0T(``'@9X+X_R>@=]0G*/Z?800^#A``2M0O``"`8@""8&(`!*%A`(;A80`( +M0F(`BB)B"/X!0"`"U2\`#L`9````8J#$V"\`'`=@`'R?8*2S`@"0"2((`'Q? +M8`"(`@``A&!`(?X?8`"$0$```$$0````4`*`@1`$GD$0!:1!$`:H01`'ID$0 +M"/XA0"`#`"``!$%0`(0&"`%^04``@$`0`?X@0`'^ID$`A>=7B?S_)Y0%`@@` +M'"=@`8!!$`"$`0@!_E]@($D-*`"B:&`@\M0O`"`(8(!3U"<$/@X0`"#4+P#M +MU"\``*!A`?X_8`!\'V!@Y]0O`)H&8`!"U"<$/@X0H"+4+S#^GV'B_E^" +M__\?8@!\OV%`@"@`@`@`)[G40?^'V*+_A]@-WXI0(#-""A, +M_P9`H-;V+P`@*&```2!B@0(`(`WZZ%>"#0`@(`0'"`%ZX%<"#``@C/X?8*#' +M""@2?BE`C/X?8"#&""@`HBA@B_X?8*#$""@`("A@(`0'"``!X&>!'@`@=(4& +M"@`AZ&>"!P`@C/X?8"#`""@+_)W6% +M)@@!^N!7`2'H9P'@_R<(>N!7@@(`(```!PCX@0T0!``'"*`!`"#\@0T0H/T0 +M*/C_#4"+_A]@(*H(*$5^*4#X_PU`H,4/*`""(%````!BB_X?8*"F""@`("A@ +M`GKH5PU\"%("````@-;_)___'V)TGT80B_X?8"#4_R=3?BE`!'X`@`!\($#T +MQP(`#(``"`!\0&@`#```!(``"``$`!0`@`\X!'X`@`!\`$#TQP(`"```"``` +M``@@@`\X`(``$`!\'V`$`"```(`/.`!\'V`$`"```(`/.`1^`(``?`!`],<" +M``0```@`0``(`7X`8""`#S@`@``0!'X`@`!\0$#TQP(`!``A"`#```@">N!G +M`H`/.`P``0@`?`!H``(```"``!0`@`\X!#X.$"#0TR\<_I]AH)G4+P``P&$` +M`*!A`!P'8*`T_2_\_RU`!'X'@`!\7V#TQP(```0@0``$0`#\@0T(```!$`R` +M``@`?$!H``$```2```@`!``4()/4+P":!F`@`=0G'/Z?800^#A``P],O``'` +M82(#`"``@J!A`*P!*(```"``F@$H(`(`(`"`!A`!>N=7@?W_)P"`!@@``>!G +M@>;3)P1^!X``?"!`],<"``R```@`?$!H`!````2```@`!``4`.+3)P0^#A`` +MLM,O`"GB+P4$(`@$!``("/X@@``"`&@`?#]@C+X"``!]X%"`P`@ +M`'Q?8$32`@``?#]@00H``"#/#2@`O@]@@/__)P(:(```&@!``01@"`!\7V"0 +MO@(``(H!&-`#@1#2!T$0`(/@9P$!X&97B@<`(`;^YJ<$_P=``'(`0*"T_2\`'"=@ +M`7K@5X+Z_RN!7 +M00$`("R)``@4B0`(8'[AIR"`#S@`@!Q``()@0`3\80#@M@(``OK@5PP!`"`% +M^N!7@@,`(`/^(8``@."G$/X\B&!^X:=@_AQ`((`/.``"`$````!`!'X`0``& +MX*<"_AR`!'X`0!!^`(@@@`\X%'X`0`0^#A"@9=,O```@8*`!`"````!0`7X` +M0``.`!@,>N!7B@(`(`)\0`#XM@(``(7@5P&-TR>`^_\G`'P_8(T!```@Z0TH +M`+X/8""*TR<,_A]@``'@9P(#`"``?!]@7.`"``"`#S@`?!]@7N`"``"`#S@! +M>N!7@?W_)R"`#SC__Q]@``'@9P(#`"``?!]@-.`"```#`"``?!]@2.`"`(`! +M`"`!>N!7@?W_)___'V``@`\X`GK@5P`$05`,`0`@!7K@5X(``"`!_E]@`(/@ +M9P`.81@!#P`@``L`&`0,`"``?"!`"+,"``"'X6=$A4`(@0,`(`)ZX%<,`0`@ +M!7K@5X(!`"``!#\(=*T"```$`"``A^%G`@0`(`)ZX%<,`P`@!7K@5P$"`"`` +M!#\("!P`@H//_)_]_`$``A^%G`04`("`%`"`"_A]@`(?A9P$" +M`"`!>N!7"7P?8`$```"``0`@"'K@5XP``"`(_A]@`(`/.`0^#A"@.=,O``1! +M4`)ZX%<`?+]A"+,"``P!`"`%>N!7@@``(`'^7V``@^!G``Y!&`(1`"``"@`8 +M`'K@5PL-`"``!>%G`04`(`)ZX%<,`0`@!7K@5P(#`"``&B!`1(5@"``$/PAT +MK0(``(?@9P)8TR<`!>%G`@4`(`)ZX%<,!``@!7K@5P$#`"``&B!`1(5@"``$ +M/PASK0(``(?@9P)2TR<@\O\G_W\`0``%X6N!7@4;3)R#Y_R?_?P!``'P_8$D"```@H0TH`+X/8"!#TR<` +M``!0``'@9P(#`"``?!]@:.`"``"`#S@`?!]@:>`"``"`#S@!>N!7@?W_)R"` +M#SC__Q]@``'@9P(#`"``?!]@8.`"``"`#S@`?!]@9.`"``"`#S@!>N!7@?W_ +M)R"`#SC__Q]@!#X.$*`4TR\H_I]A)/X_@@">YU$`(`A2`'R_842_`@`@`@`@ +M`!S'40""X&$!?L=!`((`8@"`!@@``>=7!A8`(`'^'V``'"=@("W\+_S_34`` +MG^=G_($M"`()`"`$@``(``'@9X($`"`(@``(``'@9X'V_R<`O@]@`'Q?8'S2 +M`@`@*`TH)_XH0(#__R<`O@]@`'Q?8'S2`@`@)0TH)OXH0(#__R<$@``(``'@ +M9P@""!""!``@"(``"``!X&>![?\G`+X/8`!\7V!\T@(`H!X-*"[^*$"`__\G +M`+X/8`!\7V!\T@(`H!L-*"W^*$"`__\G`)X'8*`ITRXO``'@9X$/TR<`O@]@H&H-*"%^)T"`#=,G`(@&"`%^`$`@#-,G`("& +M$!+^'V"@G`&`@`@`GX@@`#\`$!8R@(```$`"`#D_R\$@.T+((`/.!`0;@L$ +M/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$8`#````#3+P"`)@@`_"!H`(````"" +M!A```-,O$`"N"02`[0L@@`\X%!!N"P!\'V`0`#```'Q?8!@`,``````(`'P@ +M8`_/``````$(``(@8`""'U```@!H'WX`B`"`#S@`?!]@$``P``````@"?B!@ +M`((?4``"`&@??@"(`(`/.`!\'V`0`#``````"`1^(&``@A]0``(`:!]^`(@` +M@`\X!#X.$``V#A``.&YC%'Z.4Q`:#A```*!A`'P?8!``,``````(`7X@8`"" +M'U```@!H'WX`B`!ZX%>!`P`@`'P?8```(`@`Z=(O`!H@8`""'U```@!H'WX` +MB!``K@D$@.T+((`/.!00;@L`?!]@$``P``````@`?"!@`(````""'U```@!H +M'WX`B`"`#S@$/@X0`#8.$``X;F,0?HY3`'P?8'2]`@``!0`(!'K@5XT#`"`` +M!0`@(/X?8`!;_R\`"``@$/X?8(!9_R^`!@`@`+X/8*7^/T``C0PH@`0`(`)^ +M@($`?(8!]'`!````!C@R7```+UP``#)<```O7```0EP```2`[0L@@`\X$!!N +M"P0^#A``-@X0`#AN8QA^CE,0&@X0_/\-0`#,]R_\@4T(`'P_8'2]`@`(@0`( +M```!4`!]X%<`H`\`A3D`(`!\'V"@F`(```!`"`!\'V`8]P(`````"``$0$`` +M?!]@?/<"``````@`!*!!!($`"`"`!E``?>!7``(```4#`"``?#]@`)`!``!\ +M'V#DX0(```(`$``L`"``?>!7``$```4#`"``?#]@`"`#``!\'V#DX0(```(` +M$(`G`"!`>N!7!0,`(`!\/V``L`0``'P?8.3A`@```@`0@",`(!!ZX%<%`P`@ +M`'P_8`!`!@``?!]@Y.$"```"`!"`'P`@`'K@5X$"`"`R_C^8`'P?8.3A`@`` +M`@`0`!P`(`!\7V``0!\``'P?8.3A`@``!``0`(4`"`-ZX%>"$0`@!'K@5XT# +M`""`!0`@(/X?8`!%_R^`"``@$/X?8(!#_R\`!P`@`+X/8`!\/V`C`0``@%D, +M*(`$`"`"?H"!`'R&`9!R`0````8XF%P``)5<``"87```E5P``*E<```!_A]@ +M``L`("#^'V``'?\O``D`(!#^'V"`&_\O@`<`(`"^#V"E_C]``$\,*(`%`"`$ +M>N!7#?W_)P)^@($`?(8!['(!````!CBN7```JUP``*Y<``"K7```P%P````` +M`%"`=@`H`'P_8'2]`@`$FP`0_(%-"`B%`!`0`*X)!(#M"R"`#S@8$&X+!#X. +M$``V#A``.&YC$'Z.4P!\'V!TO0(```4`"`%ZX%`@```D`0!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC$'Z.4P!\'V!T +MO0(```4`"`%ZX%`@```D`0!(#M"R"` +M#S@0$&X+!#X.$``V#A``.&YC$'Z.4X`;X"]*!``(`'P_8'2]`@``@4`0!'K@ +M5X$2`"`$>N!7C0,`(``%`"`@_A]@`/3^+P`(`"`0_A]@@/+^+X`&`"``O@]@ +MI?X_0``F#"B`!``@`GZ`@0!\A@$L=`$````&.`!=``#]7````%T``/U<```0 +M70``(/X?8(#J_B\`?#]@=+T"``"%``@!>N!7`0,`($#^'V``Y_XO`((@4`!\ +M'V#VW@(```)`$````%``2``H`'P_8`"0`0``?!]@Z.$"```"`!``?#]@`$`? +M``!\'V#DX0(```(`$`!\/V``,"H``'P?8/#A`@```@`0`'P_8`"P!```?!]@ +M[.$"```"`!`$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,!7`$`?`((+`"``?+]A=+T"``"%!@@#>N!7@C$`(/S_ +M#4"`3?N!7`@$`(```!PB``0`@`'P? +M8.CA`@`````(`'R_872]`@`4@080@"@`(/S_#4"`1/N!7C0,`(``%`"`@_A]@`+O^+P`(`"`0_A]@@+G^+X`& +M`"``O@]@I?X_0`#M"RB`!``@`GZ`@0!\A@'T=0$````&.')=``!O70``N!7 +MC0,`((`%`"`@_A]@`,G^+X`(`"`0_A]@@,?^+P`'`"``O@]@`'P_8",!``"` +MW0LH@`0`(`)^@($`?(8!<'8!````!CB070``C5T``)!=``"-70``H5T```'^ +M'V``!@`H``$`(`"``%`4@080_($M"`!\OV%TO0(`$(,&$!``K@D4`,X)!(#M +M"R"`#S@<$&X+`'P_8.#A`@``@$`0`(`/.`!\/V`0`#```'P?8%BG`@`,`0`( +M`(``$`"`#S@$/@X0`#8.$``X;F,0?HY3`'P?8,!K`(``?#]@0P``"8`2TB\$ +M@.T+((`/.!`0;@L$/@X0`#8.$``X;F,4?HY3$!H.$```H&$%^N97@04`((`& +MTB\%_D:``'P_8%BG`@```D%`!`$A"`P!80@`P$`(``9!<`"$`!0`!-(O$`"N +M"02`[0L@@`\X%!!N"P0^#A``-@X0`#AN8Q1^CE,0&@X0``"@807ZYE>!!0`@ +M`/O1+P7^1H``?#]@6*<"```"04`$`2$(#`%A"`#`0`@`!D%H`(0`%(#XT2\0 +M`*X)!(#M"R"`#S@4$&X+!7Y@@`#\04!8IP(```%!"`!`00@#>N!7`@(`(`!\ +M06#___]_`(0`$``&`"`$>N!7@@0`(`!\06#___]_!7X!@``$`%`"?@"```0` +M0`)^`(@`@``0@```(`"$`!``@`\X!#X.$``V#A``.&YC&'Z.4Q`:#A`4'`X0 +M``#`80""H&$%?B>``/P`0%BG`@`(`0`(`(3^+P-ZYU>"`0`@`/RF:0```("` +M`P`@!'KG5X("`"`"_@:`??X_8(!RTB\`?*!I````@`5^)X``_`!`6*<"```! +M``@`&@`4!'KG5X(#`"`%?B>``/P`0%BG`@```0`(`$``"`"!YE>"_/\G!7KG +M5P$!`"``'`=@`-/_+Q``K@D4`,X)!(#M"R"`#S@8$&X+!#X.$``V#A``.&YC +M$'Z.4P5^H(``?']@6*<"``"&HD``@6((`,"!"`1ZX%<"!P`@``C"8`5^H(`` +M?']@6*<"``"&HD``@6((`,"!"`%^8U``!^)7`0(`(`!\HF#___]_`/KB5P+Y +M_R<%?J"``'Q_8%BG`@``AJ)`$('""`"!8@@`C`$4`WK@5X(!`"``?.)@____ +M?P`*`"`$>N!7@@@`(`!\HF#___]_!?YB@`"*85`"_F&``(IA0`+^X8@%?J"` +M`'Q_8%BG`@``AJ)``(%B"`#`@0@0@<((``WB5X+[_R>````@``CB8`".(%`` +M`@$0`/K@5X($`"`%?J"``'Q_8%BG`@``AJ)`'(%B"`"$81@`@B%```(!$(`# +M`"`%?J"``'Q_8%BG`@``AJ)`'(%B"`""(4```@$0@)W_+P2`[0L@@`\X$!!N +M"P!\GV`0`#``!7K@5X$'`"`%?D"``'P?8%BG`@```&%`#($!"```0@@``$%@ +M`(0?4``$`&@??@"(`(``$`!ZX%N%7B@,`(`*$?U`"!B```?X@0`"/ +MX!\`!F!`(?O_)P""01``@`\X```@8*`!`"````!0`7X`0``.`!@#>N!7"H`/ +M.```8$`$AD```7Y!0``1X1\`AF!`(H`/.`"$@1``^O\G``B"4``$05``?/]@ +MS+8"`"`'`"!@A<,(!GX@@`".8$"2B2$(`82_@`"+X&>!`@`@``GB9P(!`""5 +MA4$0`?Z?8)2%01`!?B%``(Y`&``-X5<*@`\X`/C_)P0^#A`@P-`O,/Z?80!\ +M_V%4U`(`%($'"`!\/V*TM0(`^($-$!B%!P@`?-]A;.("`/R!31``?!]@`/T" +M`!P<`!``?`<0;N`"``!\OV%@P0(`//\&0`0`!Q`4?`<0@+L"``'^'V`!_C]@ +M(#SG+___34#_A0T(`'P?8I29`@`#?@"````(0`-ZX&<(``<0(0,`()C^7T(` +MO@]@TGXI0*#-"B@`_T=`@/__)R3^'V``@B!0(#/G+___34#_A0T(`WX`@``` +M"$`#>N!G#``'$($"`"``O@]@UGXI0"#&"B@`_T=`@/__)V3^'V``@B!0H"OG +M+___34#_A0T(`WX`@```"$`#>N!G$``'$($"`"``O@]@VGXI0*"^"B@`_T=` +M@/__)P"`*`A)A*`($(M&$%#ZXE<`_X!0":2`0*`"`"``!$%0`@1B```:`4`\ +M!T`0`7Y!0'IZX5<+_?\G3H0`"%#ZXEM"/B'+0GYAPT)^H?M"/N'S0B@`P`@``B"4`"695$`!D5`(!=! +M$`%^`$`"?H)``?X@0!-ZX%<*(``@[81`"`]^06``>N)7``1!0(L!`"`&>N)7 +MK`H`(`R$1%$(>N)7BP$`(`]ZXE+`0`@$WKB5ZP%`"`, +MA$-1%'KB5XL!`"`>>N)7+`,`(`P$0U$?>N)7BP(`("1ZXE>)`0`@`(1"40`& +M0D`@%4$0`7Y"00=ZY5>!Z_\G)7KE5X$.`"#MAD`(!'Y!D`!ZY5<`!$%`BP$` +M(`9ZY5>LY_\G#(1D40AZY5>+`0`@#WKE5RSE_R<,!&11$'KE5XL!`"`3>N57 +MK.+_)PR$8U$4>N57BP$`(!YZY5+W_\G)'KE5XG>_R<@ +MW?\G`(1B42"'00@@`P`@````4""'(0@``^%7"X)`8`%^`$`!_F%`)7K@5XO\ +M_R<1A480``(!&`-^`%`2@480@&??+Z![T",`P`@8`8!"````$``"N`8`WP!```!``````!` +M``J`&`":IE$@!P`@`((@4`+^!T``@`-00`%'$``D`4``&@!``04`"`1^`)`` +M``!``GX`0````E!0`4<0`?ZF00+^($`'^N97BBT`(``:X4&AA,<)`'P?8O7A +M`@`/?@=@"'KG9P)\`&CP`````@H`&``2P$$`BB!!()U$$)J$)PH/_@A@"/KH +M9P)\`&CP`````@H`&``40$$`E400DX0G"@_^"&`(^NAG`GP`:/`````""@`8 +M``0("@`68$$!>NA7$)=$$`P,`"#FA`<(#WX`8`/ZX5<``"!"`@@`(``$'PBP +MM0(``'K@5PP&`"`"_@A``(`#4$"!1!``)`%``!H`0`$%``@/?@!@````0`)^ +M`$````)0(`,`(%"!1!`"_@A`(`$`(```!%`@_A]@,(%$$*&&!P@!_B!"!'X` +MD``<`$``"B`9`(K(02`!1Q":A@<(!'X`D``4`$``"D`9``%'$).&!P@$?@"0 +M`!8`0`%ZZ%<0`4<0K`8`(``*8!GFA`<(!'X`D`/ZX5<``.!!`@(`(``$'PBP +MM0(``'K@5PG._R<"_@=`(`$`(```!%`@_A]@(-'_)S`!1Q`#^N%7@@<`(``$ +M'PBPM0(``'K@5XP%`""@`P`@`((@4``D`4```@!`"`=@"`",`$`8!T`0`?X@ +M0`[ZX%>*$=`G@/O_)Z`"`"``@B!0J`9A"`",`$`8!T`0`?X@0`[ZX%<*#=`G +M@/S_)P0^#A"@V,\O``#`8""!_"\`@@!@``"@8*!Y_"\`@@!@``!`8"#&_"\` +M@@!@``!@8*"^_"\`@@!@``"`8/_[XE<"_>%7_____P)]X5?_____`GWB5___ +M__^"`P`@`'Q?8-C(`@``?#]@=00``*#["2@`O@]@@/__)P`,`V"@:/4O`(HB +M8(#USR<`?!]@%)D"``"`#S@$/@X0(,;/+[?^'V``?#]@604```"%!"@`?!]@ +M"!T```""(%`@0M(O!/Y?8`#NSR<$/@X0(,#/+[?^'V``?#]@8`4```!_!"@` +M?!]@W1P```""(%`@/-(O"/Y?8`#HSR<$/@X0H+K/+Q3^GV$`?!]@(/8"```` +M``B`>N!G`@X`(`"WXR\``&!@`'R?8/R]`@`P!0((`(XA&*!+YB___TU`_X4- +M"`-^((``?!]@E)D"``"'X6<``D!`@@8`(``*'PANX`(`^W_@IP#\'$";]___ +M"'X`D`1^($`$!@$(``(`0`!ZX%<)$``8#```4`(!@A`@Z\\G%/Z?800^#A`` +MK,\OH';0+P``P&$``*!A(#G4+P+^'V``?)]@I+,"`)`)`@@`?#]@`(@"`!3^ +M7V```H!!``1&$)0%0@@``F!``81!$`("```"_C]@`?Y?8*#%""@`'&=@H&[0 +M+P":!F``RL\G!#X.$("KSR^-_C]"``"@80!\WV&DLP(`-`'G"0'^"$"@5P0H +M`)XG8`!\'V(``"``,$`H"/#_7X(T`P<0(%0$*`'^"$`P0"@(-`,'$"!2!"@! +M_@A`-`$'"`"!YU`%``)>!7!@4`("!)!"@!_@A`-`$'"`"`!A`X`0<(H+G/ +M)P2`!A"`100HH/O_)S@!)PC__P!`.`$'$`'^"$"@_/\G4_XI0`0^#A`@A<\O +M`OX?8*!_`2AI_M^!`'R_8=30`@`\?@=``OX_8(3_1D"@F@,H`(9A4#U^!T`" +M_C]@@O]&0""8`R@`AF%0H'@!*`'^'V``?!]@"X(```+^/V"(_T9`()0#*`"& +M85``?!]@#((```+^/V"&_T9`()$#*`"&85``H,\G!#X.$`"$SR\``(!B``0? +M"('?`@`!>N!7`()@8@&BSR>@/-`O'_X?8@``0&(@_],O//X?8`!\/V*DLP(` +MD(GH"0!\OV$`B`(``)K'00":AT$`($80`"@*8``<)V`@=`0H//Y?8`":AT&4 +MA0@(`"!&$`$`1Q`"F@<`//X_8`'^7V`@B0@H`*9I8"`RT"\`)`E@@)//)P0^ +M#A`@:,\O)/Z?80```&(`@N!AH"O0+P`$H6$``,!A_/\-0`""(%"@:0DH`?Y? +M8`".1AC\_PU`H/;X+X#^/V#\@4T(`"`(8`">)V"@XO`O`?Y_8"`FT"\`'`=@ +M`#_A)P0^#A"`8,\O``#`80""(&(`!`%BH"#C+P">YU$`"!\(C+T"``'^7V(` +M?>!7($(``"("`"`5?JF!&/P&%!`0`````0`@&/P&%#(R```!^NA7`7P?8&C2 +M`@`!!$%0P:@#*`+^/V`!>N=7`@H`(`!^7Q#\X0(``?X?8`[^/V`@/NPO``1! +M4``!X&<``!\0!.("``(#`"``O@]@`'Q?8'S2`@`@;@DHH?X_8(#__R>`7_HO +M``#@80%^7Q"`WP(``"'H9P('`""@5?DO`_X?8`!\'V"(O@(`H`+R+P_^/V`` +M`2!@`04`(*#V`R@N_A]@`+X/8""_"2BP_C]@``(`(*!.^2\```!0(*H,*`E^ +M"8``1!\(;-\"```!X&]"\*?BF`!/X?8"#=]"\`@B!0!?X?8*#;]"_`_C]@ +M`7KG5X(+`"`@1/LO`?X?8`#^!A1`_A]@`(`&%```/PA$OP(`````4!:"/U"@ +M&^PO``1!4``!X&<``!\0`.("``(#`"``O@]@`'Q?8'S2`@"@2PDHU_X_8(#_ +M_R<@$?HO`)X'8(#I!B@%_A]@(,WT+P""(%````!0H,OT+P""(%`!_A]@(,KT +M+P""(%`!>N=7`@$`(`#`!BB````@`'3\+P```%"@[O0O`_X_8`!#SR<$/@X0 +M``_/+P`$``@%>N!7`GW@5P0````"?>!7$````($#`"``?%]@?-("``!\/V#/ +M`0``(#D)*`"^#V"`__\G`(/@9P&^#V#!D0DHZ?X_0`!\'V"(O@(``//Q+P`! +MX&>!,,\G`+X/8`!\7V!\T@(`H#$)*.O^/T"`__\G!#X.$(`$SR\@S\\O``#` +M80``H&&@D=,O`_X?8`!\GV"DLP(`D`DB"`!\?V``B`(``(9`0`3^'V``AH!! +M``!&$````%`"`$$0E`4""`$`01`"A@```_X_8`'^7V`@'0@H`!QG8"#&SR\` +MF@9@@"'/)P0^#A"@`\\O0/Z?80``P&$N_A]@H+`#*`3^/V``?+]A@=\"``"$ +M!@C7_E]"`7K@5P'^?V*B$P`@+OX?8*"K`R@I_C]@H*(&*`">YU$!_A]@(`S[ +M+_S_+4#\@2T(`(``"`!\`&#____O`(``$"`9^R\!_A]@``$`(/___W\!_N=! +M//KG5P7^_R<5_@F"`'X(%`!`*`B@H`,H+OX?8$#^'V````@4(,[Y+P"B*%(` +M`!\(`.("`*`:["\`GN=1``$`(/___W\!_N=!//KG5P8&`""`_?\GH)@#*"K^ +M/V`@0?PO`)[G40`!`"#___]_`?[G03SZYU<%_O\G`*(H4A7^"8(`FP8H#"(( +M%``B"!2`_A]@```(%/__'V`(``@4"/X?8`P`"!0!>N=7@00`("#,_R\```!0 +M`7Y?%-.R`@``BN$O@(;B+R!"#"A]_A^8`#0`(`"$!@@!>N!7@@<`("[^'V`@ +MAP,H*_X_8`"5SR^@D_DO``#`80``'P@$X@(`@`'L+P"B1A`N_A]@(((#*`%^ +M*4"@DL\O`!P'8`!$'PALWP(```'@9P!\OV&(OP(`@1,`(`!\/V!HTP(`!($` +M"/2!#1`(@0`(^($-$`R!``CL@0T0$($`"/"!#1`N_A]@H'<#*"S^/V`@M?\O +M````4*"(]"_L_PU`'($&".R!+0@`@`!0]($-$`!\'V"TU`(`]/\M0*``#"CL +M_TU``$`_"'#?`@``0%\(=-\"`.S_#4`!_G]@$/Z?8"":VB\#_K]@+OX?8"!K +M`R@+?BE`@`(`("[^'V`@:0,H+?X_8*"F_R\#_A]@@&7A+R[^'V`@9@,H+OX_ +M8`%^7Q33L@(`@%_B+X#FX2\`4.$O`'S?89"]`@"@#M_C]`+OX?8"!6`R@&_C]@(-/.)T#^ +MGV$$/@X0H*3.+S#^GV$``&!B`(+@80`('PBNK0(``_[?80I^0((`I>E7`'R_ +M8:2S`@"E!``@`*(H4D+ZYU=!`0`@C*-&$(VC1A````!0(&GB+P">)V"`&@`@ +M`%C/+P```&(@&],O"_X?8)"))@@`?%]@`(@"``"$8$`A_A]@`(1`0```01`" +MHH$0!)Q!$(+^'V`%@$$0!J)!$`>>01`(_D%``"8I4/R#31`(_@"(_8%-$!#^ +M`(C^@4T0H`,`(`""(%``@@U`_`4`"```01`!?D%``?X`0``.(!@``^=7"?S_ +M)Y2%!@@+_C]@`8!!$`"$`0@!_E]@()T'*`"&85`@1L\O`"`(8(Z%!@@!>N!7 +M`9XG8,%0XB\!_A]@0OKG5P'^'V!!`0`@C(%&$(V!1A"@K,XG,/Z?800^#A`` +M;,XO``0@"!3ZX%>!`P`@`'Q?8-#(`@``?#]@@@,``""8""@`O@]@@/__)P!\ +M7V#P]P(````A"!P(8`@`AB!```(!$`!\7V#H]P(````A"!`(8`@`AB!```(! +M$`!\7V``F`(````A""`(8`@`AB!```(!$`!\7V`$F`(````A"`((8`@`AB!` +M``(!$`!\7V`(F`(````A"`0(8`@`AB!```(!$`!\7V`,F`(````A"`8(8`@` +MAB!```(!$`@((`@*"&`(``(?$!"8`@``?%]@%)@"````(0@`AB!```(!$`!\ +M7V`8F`(````A"`P(8`@`AB!```(!$`!\7V`N%7!8!`$*L! +M`"`$H$`0`7X`:`6`0!"4A0$(`?Y?8`&`0!`:_A]@!OX_8"!'!R@`'&=@(/#. +M+P":!F"``]`G!#X.$(`JSB_R_E]"``#`80""H&$`!`%B!WX`0*#HSB\`#B`: +M``#@82"KTB\`H@A@`'R?8*2S`@"0"2((`'Q?8`"(`@``A&!`'/X?8`"$0$`` +M`$$0`IQ!$`%^"4`#@$$0"'X`B`2`01#T_A]`!8!!$`A^`(@&@$$0!_X!0*`" +M`"``@B!0``1`$`%^`$`!_J9!`?X@0``#YU>,!``@`(1&"(!ZX6>!^_\G`+X/ +M8`!\7V#0R`(`H#4(*/U^*4"`__\GE`4""`"B*&`!@$$0`(0!"`'^7V`@*@N=7````4"(%`"`/_C]@`/]&0`+^?V"#_I]@(+OY+P"*HE````!0&_X_ +M8*`$`"`"_T9`!/]&0`+^?V"#_I]@H+;Y+P"*HE````!0&_X_8`;_1D`"_G]@ +M@_Z?8""S^2\`BJ)0`!C.)P0^#A``_,TO``"`8B"WSB\`@F!B``!`8J!YTB\4 +M_A]@`'P_8J2S`@"0B>@)`'R_80"(`@``FL=!"/X?8@":AT$`($80`"@*8``< +M)V`@[@(H%/Y?8`":AT&4A0@(`"!&$`$`1Q`"F@<`%/X_8`'^7V`@`P%G`@,`(`"^#V``?%]@T,@"`"#P!R@B!@`OW@5R`````!`P`@`+X/8`!\7V#0R`(`(.,'*,?^ +M/T"`__\GS'O@9P$#`"``O@]@`'Q?8-#(`@`@WP
N"'A`,`(,#^'V"@90(H!?XG0``7^'T("`P`@`+X/8`!\7V!XTP(`H+T'*.7^/T"`__\G"(`'"``!X&!`0`@,80`"`A^`&@Q@$`0`'P_8&+'`@``A0`( +M`0!'$`%^`$``#D`8#WKA5P"!0!`,`0`@````4`"!0!``!!\(@-\"``%ZX%<" +M?>!7`@````$#`"``O@]@`'Q?8'C3`@"@H01V`BB`8(/'X`0/J!C1`<@`8(#'X`0"`O#"CZ_RU`'(`&"/J)+0C\@4T( +M#'X`0"#Q[B\"_G]@H*+-)RC^GV$$/@X0`&/-+P`!X&=C_K^!`@,`(`"^#V`` +M?%]@>-,"`""-!R@Z_B9`@/__)PP`0`@`!>%G`@,`(`"^#V``?%]@>-,"`*"( +M!R@\_B9`@/__)P((@0@`">)G`@,`(`"^#V``?%]@>-,"`""$!R@]_B9`@/__ +M)QP`(0@("&$($H0@"`S^(&`$^N!7`'Q!0``"```"`@`@(`0`(`3^/V`@`P`@ +M"/X_8`CZX%<"_>!7#`````']_R<`@B!0X@-!$`#ZX5<,`@`@`(GA5PH!`""` +M`0`H`'7-)X":`"@`=,TG!#X.$*!>S2\\_I]A```@8D/^'V`@!`(H`*(H8`"C +MZ&>B_M^"`@,`(`"^#V``?%]@>-,"`"!O!R@"?BM`@/__)PB`"`@``>!G`0,` +M(`"^#V``?%]@>-,"`*!J!R@#?BM`@/__)P2`"`@``>!G`0,`(`"^#V``?%]@ +M>-,"`"!F!R@$?BM`@/__)PR`Z`D`G^=G`@,`(`"^#V``?%]@>-,"`*!A!R@' +M?BM`@/__)PJ$!P@<@`<*``'@9S!^2$("`@`@`?X?8`J`1Q`@%`97#`,`(`"^#V``?%]@>-,"`"!7!R@??BM`@/__ +M)P$$"0C[?R!@`0))$""(!P@`@>97"@$`(`3^`&@!`$D0H`$`(``HBE(!?@I` +M``Z`&@-^"H``@,=!)`0'"`"!YE$!P@`>N!7 +MC`P`(`";YF>!!0`@%@@)"`!\`&#P_P```!H`:!8`B1`@B`<(`('F5X(!`"#= +MA0D(^W\`8-V!21``!`D(W(%)$`$$"0@(?@!HW8%)$`(("0C>@8D0!'Y)0@3^ +M"E``#J`:`7X!0``.0!C\_PU`H`P'*`'^/V`<@`<(@/X_8`T$``C]@4T0'(`' +M"`P$``C^@4T0_/\-0*"/]B\`HDA@`_X*0/Q_`&``#B`:XH4)"``!X&<<@&<( +M`14`(!*$`0@,>@!@`@,`(`"^#V``?%]@>-,"`*`?!RAU?BM`@/__)P";YF!G +M`0,`(`"^#V``?%]@>-,"`*`*!RB(?BM`@/__)Q6$`0@``>!G`0,`(`"^#V`` +M?%]@>-,"`"`&!RB)?BM`@/__)Q:$`0@``>!G`0,`(`"^#V``?%]@>-,"`*`! +M!RB*?BM`@/__)_R!30@,_@%`)/X_8*!<[B\"_G]@W84)"`AZX&NI7"@T`("8()P@`@^!G@0X`("@`!P@`!$%0H$_N+P'^?V`! +M?@I```Z`&@-^"H``@,=!'00'"$!ZX&*#0`@#GKJ5XH) +M`"``*`I@H/L%*`">)V``#H`:`?X&0*#Z_R<`#J`9`+X/8`!\7V!XTP(`H.4& +M**M^*T"`__\G`+X/8`!\7V!XTP(`H.(&**Q^*T"`__\G`+X/8`!\7V!XTP(` +MH-\&*+Q^*T"`__\G/?X?8*!N`2C"?BM`(.K,)SS^GV$$/@X0(+C,+RC^GV$` +M`*!A0_X?8"!J`2@`FB9@`)OF9P!\/V(``@```@,`(`"^#V``?%]@>-,"`*#4 +M!B@1_BA`@/__)PB`!@@``>!G`0,`(`"^#V``?%]@>-,"`"#0!B@2_BA`@/__ +M)P2`!@@``>!G`0,`(`"^#V``?%]@>-,"`*#+!B@3_BA`@/__)PR`Q@D`'>=G +M`@,`(`"^#V``?%]@>-,"`"#'!B@6_BA`@/__)QP`)PA8@``(``'@9P(#`"`` +MO@]@`'Q?8'C3`@`@P@8H&?XH0(#__R<*!`<(``'@9X("`"`!_A]@"@!'$""* +M!B@`'`=@@`0`(`<$!P@``>!G@@$`(!($!P@#>N!7@@$`(#&$``@(?@!H,8!` +M$"!E\R\`'`=@`"('0N$%2`C\_PU`()8&*`'^/V`<``<(@/X_8`T$``C]@4T0 +M'``'"`P$``C^@4T0_/\-0"`9]B\`FD9@"P0'""=^`$#\?Z!AX@4("``!X&<< +M`&<(H0P`(`">YU$2A`$(#'K@9P(#`"``O@]@`'Q?8'C3`@"@J`8H2/XH0(#_ +M_R<,_D%`````4``<)V``&D%`(.D+*!3^84#B!4@('``G"``:`4``$*`9#H@` +M"``$`$`.@(`0(`X`(!P`9P@4A`$(``'@9P$#`"``O@]@`'Q?8'C3`@"@G`8H +M4?XH0(#__R<5A`$(``'@9P$#`"``O@]@`'Q?8'C3`@`@F`8H4OXH0(#__R<6 +MA`$(``'@9P$#`"``O@]@`'Q?8'C3`@"@DP8H4_XH0(#__R?\@4T(#/X!0`": +M)F"@[NTO`OY_8`/^!X```$=`#OKG5XH)`"`F""$(`(/@9P$+`"`H``$(``1! +M4"#I[2\!_G]@`?X'0``0X!D#_@>```!'0!T$`0A`>N!G`?C_)SW^'V`@%P$H +M;/XH0""5S"_T9`H%\`*`"&85!^"2<( +M`'P?8)"^`@#=`T`0X`$@"`'^($"@;,PGX`,`$`0^#A`@2,PO*/Z?80``P&$` +M?#]@7-("`/S_#4`@[,TO`_Y?8`+^OV$``!\(I)@"``!\/V)JWP(`\'K@5PT` +M'U```0```("($`)^!X``?/]AD+X"```>`$"4`0`(V/\G0""*^"_:_T=``!P' +M0``>`$"X"P`(`!['0<@'1PCH@8<0`(HH".J%AQ``@`!0``3@IP3^7)#8B0<( +MWH6'$``$`$``?%]@:N`"`"+ZX%<``($0*P(`(``,8!A`^N!7S!``(`1^`%!` +M^N!7#`(`((SZX%<*`0`@=/K@5P()`"!T^N!700P`(/=_`$",^N!7P0H`(`Y^ +M`$"1^N!7`OW@5Y4```!!"``@"GX`0)GZX%<"_>!7FP```,$%`"`"?@!`G?K@ +M5P(!`"`@!``@``:!$*'ZX%=!`@`@_G\`0*7ZX%<"`0`@_'\`0```@1"`B-0O +M!7[@IP#R'U`$?@"0``"?$&S@`@``?!]B%)H"``!_"$`4_R=`H,'-+X#^7V`` +MBB@(C/K@5XL%`""E^N!7B00`()7ZX%>!`P`@6OX?8"8!B!`H`8@06?X?8"H! +MB!!8_A]@+`&($)7ZX%>"`P`@;OX?8"8!B!`H`8@06?X?8"H!B!!8_A]@+`&( +M$(#ZX%>+!``@A/K@5XD#`"!:_A]@)@&($"@!B!!9_A]@*@&($%C^'V`L`8@0 +M*/K@5XL$`"`L^N!7B0,`(&[^'V`F`8@0*`&($&W^'V`J`8@0;/X?8"P!B!!H +M^N!7@@,`(&[^'V`F`8@0*`&($&W^'V`J`8@0;/X?8"P!B!#)_/\G +ME`4""`"B*&`!@$$0`(0!"`'^7V"@]`0H`"!H8*"=S"\`G@=@`++-)P`^#A"` +MTLLO$("-$`""H&$`!`%B()?,+P"&X6$``,!AH%G0+PC^'V``?']@I+,"`)") +M00@`?)]@`(@"```((4`9_A]@`_KF9P.`0!"!`P`@`'Q?8-#(`@``?#]@-0<` +M`*#M!2@`O@]@@/__)P```%``"(%``8!`$`A^`(@"@$`0$(0-"`!^0A`&@$`0 +M$80-"`>:0!`%@$`0E(4!"`+^7V`$@$`0&?X?8`C^/V"@W`0H`)YG8``@"&`` +MFB9@``1!4*`_[2\"_G]@((/,+P`0!`!@$`0 +M`@8!``;^/V`!_E]@H,@$*``<9V"@<N=7`WX"0`H#`"``O@]@`'Q?8-#(`@"@NP4H +MWGXI0(#__R<"'$(0(`4`(``$05`"`D`0`P9`$`C^88@$!D`0`(0F0`&$(`@" +M?D%`!0)`$`9^`$``!>=7#`<`(`%^*4```D`0"/X@B`$"0!`"A"8`@/K@9_/^ +M?T""]O\G`+X/8`!\7V#0R`(`H*T%*.1^*4"`__\GE(4""`"B*&`!`$(0``0" +M"`'^7V`@H@0H`"!H8"!+S"\`G@=@@*K+)P0^#A``CN%G\_Z_0(+U_R<`O@]@`'Q?8-#(`@"@A04HQ?XJ0(#__R>4!0,(`!PG8`$` +M0A``!`((`?Y?8"!Z!"@`IFE@("/,+P`D"6"`A&!P`@ +M''[@IP">'$`@%P`H!"D`$`"!1P@%7 +M`?K_)R"`#S@```!0((`/.`'^'V`$/@X0@"'++P'^_V$$_M]AH`P`(!C^OV$X +M``@(````"``!X&<"O@]@0IX%*&'^/V`T``@(````"``!X&<"!``@)``("``` +M``@``>!G`@(`("@`"`@````(``'@9X$!`"``O@]@9_X_8`"6!2@!_N=!&/ZF +M001^QT$%^N=7ACG+)P!\/V`DJP(```('0!````@``>!G`((&0H'O_R!G`7R_ +M80$```"@\\HG`(X&&`0^#A"`R\HO``#@80!\OV%8K0(`&H0&"!!ZX&<`',=1 +M@04`(`3^!T"@Z/0O!/XF0``!X&<"`P`@$/X'0"#F]"\*_B9```'@9P%\WV$! +M````H.K*)P`.!Q@$/@X0(,'*+RC^GV$``.!A`(+`8?S_#4#X_RU`(-39+_3_ +M34#\@0T(H?X_8``"@!#X@:T)#_X_8`R"1A``"``($'X`4`Z`AA"@_A]@((#+ +M+PV`1A">GD80GYQ&$`A^QXD@@,LOH)Q&$/B!#0C\@2T((%G;+PQ^`$"@Z\HG +M*/Z?800^#A"`J\HO``0?"-S@`@`#>N!7"H$`*(!VRR\``*!A(*SA+PG^'V"` +MB.$OH';++P":!F"@B]XO`?X?8-+^'V"@8O\O^OX_0(#.RB<$/@X0(*#*+QC^ +MGV$`!!\(]MX"```!X&>"Y/@O@#H&*`%ZX%>.`@`@`-KZ+P```%``@B!0($?[ +M+P'^7V"`10(H@&@"*(`H^"\```!0H-?V+_C_+4````!0__\_8*"4^2_\_TU` +M````4""\^2_X_RU``OX?8/__/V`@D?DO_/]-0`+^'V"@N/DO^/\M0`;^'V#_ +M_S]@H(WY+_S_34`&_A]@(+7Y+_C_+4`#_A]@__\_8""*^2_\_TU``_X?8*"Q +M^2_X_RU`!/X?8/__/V"@AODO_/]-0`3^'V`@KODO^/\M0`7^'V#__S]@((/Y +M+_S_34`%_A]@H*KY+_C_+4`*_A]@(#7P+P'^/V`+_A]@H#/P+P""(%```!\( +M<+<"``!]X%<````"`GW@5P````2!`P`@`'Q?8/C(`@``?#]@-`(``""H!"@` +MO@]@@/__)P#']R\`0\LO____?____W____]_____?____W____]_____?___ M_W____]_____?____W____]_____?____W____]_____?____W____]_____ -M?P!$`"@`#O@OH,,'*`K^'X"@B/!G@@$`("V$!@@``>!G`0$`("`!`"`!_A]@````4``!X&<``!\0 -M;+\"``$"`"``?!]@<+\"`(`=\"\@@"8(`H0`"``!X&<"`P`@`'Q?8-R7`@`` -M``$(`7X`0````1`#A``(```_"`RW`@``@^!G@@$`(``(/PBLK0(`@`$`(`#\ -M($#$NP(`_X4@"``#X%<+3N!7`8`/.`!\'V!XOP(` -M``GP)P0^#A``%\HO``"@80``'P@,MP(```'@9P%`RB<`?!]@<+\"```$\"\$ -MA`8(`7K@9P$]RBYU$` -M)$E2`'P?8PRW`@`%_C]C`'R_8GS@`@``?-]A3+4"``!\?V)[2](?TA`1`$($.C!#0@`O!B]\O -M`"/,+P]ZX(>$!@`@```,"``00!H```<(`'W@9Q_W_P>A`P`@`+)*$-/^'V"@ -MOOXON?X_8"`_V2\```<(`!H'$``IZF>"`@`@`"0)8/S_+4"@M@`H[/]-0`"` -MZ0G\@0T(``'@9P$7`"``$!"``@ -M`(0*"`%ZX%<,!P`@T?X?8*"K_B_?_C]@(,7@+P;^'V``A`H(`GK@5PL"`"`` -M?!]@```(`(`HV2\``0`@H,#@+P?^'V``F,HO`)G*+^B!#12`).TO2$$H"*`X -M[2](?TA`1`$($.C!#0B`E\HO(/K++P"B*%()>N!7@0$`(`#XRR\#>N!7@@`` -M(`'^/V+XHPT4^,$-"``!X&TO -M2'](0$0!"!``)`E@_/\M0*"1`"A,?TA``(`)"`"!YU>!`0`@_)L-$"`!`"`` -MF@9@_($-"``!X&NE7C!T`(```'PA\X0(```'@9X$;`"``?#]B!``P -M`/C!#0@`@,@*``'@9P)\/V!5`0``0FW^+]'^'V"`7!G@0(`((#2["\`@B!0H.;L+TA_2$!$`0@0T_X?8*!._B_5 -M_C]``(0J""!-_B_3_A]@`&7_+PK^'V`"_C]@(`'G+P/^7V```"!B(`\`*/3_ -M#4#T@2T(H$?^+]/^'V#T@0T(``'@9P$$`"``H^AG`@,`("">RR\!_I]B!7K@ -M5P5U_R<@=_\G\)L-$/";#1`@6^`O"/X?8$Q!"`B@T``H`"B*4@"$"@@">N!7 -MB@$`("!7X"\)_A]@@'#_)Z"\V"\0_A^``&__)P0^#A`@8\DO'/Z?80``P&$` -M``!0H%3^+_R!#1```:!A`00`(``$'PA\X`(`!'K@5P/^'V`*?!]@!````*"< -M^"_\_RU``)OF9P""(%`!`@`@_($-"``!X&EG`?Y`$*$!`"`!_G]B$?X?8`&` -M0!``>LLO!GK@AX,!`""`P>4O``'@9P$!`"`@`@`@$:9&$```!PB@A>DO`?X_ -M8*#XWB\`F@9@$80&")]^`&`!>N!7`0@`(`"`*`@!A``("'X`:`&`0!``?#]@ -M&)8"``"```@!?@!``(``$!&$)@B@#?XOTOX?8"R@1Q````<(H'KI+P'^/V`& -M_A]@+(!'$`?^'V`M@$<0"'X`B*`U`B@N@$<0!WX`8"J`AQ``?#]@%)8"``"` -M``@!?@!`H%S))P"``!`$/@X0H$#)+TS^GV$`?-]B'_?_!P`!(&(`@N!A``0! -M8@":IE'PFPT0[)L-$,%J`"``F@<0H!3O+_3_#4``?-]A;,`"``0!!PCT@2T( -M`(!@4`+^2(``?`%`S+L"`/P!``@!_G]B`('A5P@!!P@.IFE2`("`4`!\`4#@ -MNP(`_`$`"`'^/V(``>)7#`$'"`ZB*%(`@"!0```?"/2[`@`!_I]B`('@5P`! -M!P@.*(I2``'@9P`D25(!`@`@```?"/B[`@``@>%7A0``(`'^7V*`0\LO!7K@ -M5P4#`"``JJI2`*?I9P*CZ&<"*>IG`B7I9X$``"`!_K]B`'P?8`D`(`@@WN!7@00`((`VRR\%>N!7`0,`(``URR\#>N!7@0$`((`SRR\)>N!7`@4`(``T -MRR\``>!G@@,`(``2XR\``>!G`@(`((#4TR\``>!G`7P_8@$`````?%]B?.$" -M`*#O_2\`(@D0`*(H4@"KZF<"I^EG`0D`(!`!)P@`@^!G@0<`(/R!+0@`@^!G -M`08`(/B!+0@`@^!G@00`(```*0@`@^!G`@'@9X$"`"```!\(3+4"```MX&!'0`@`'P?8/2K`@``+"M@``1!4.S_;4`@[.HO``B"4``` -M0&+6_A]@H,#]+P`D*6``M,DO(!G++P``8&(%>N!7`'S?87#A`@""`P`@@*#? -M+_"!#1`!_A]@```'$""QR2\`I@E@@`<`(*"OR2\`I@E@\/\-0*!-!R@!_C]@ -M("?E+P``!Q``$"`8`/W@5___```!`@`@\($-"``#X%>.```@\(,-$`=ZZ5<` -M!$%0@@,`(```!P@``>!G@0$`(/"!#0@+>N!7C@``(`'^7V``@B!0`*/H9P(% -MX6!7(`@```T#`"`#^N!7"7P_8`,` -M```@`0`@``)!$``:"!"@],@G3/Z?80!^'Q!\OP(``7Y?$,BM`@``@`\X`7X? -M$'N_`@``?E\0R:T"``"`#S@$/@X0`+C(+P``H&$`!!\(?.`"``%^`%`$>N!7 -M`!S'4:X6`"``@N!A`+X/8*!.`RB+_C]@@!``(`";YF>!!P`@`'S?873A`@`` -M``!0H*#W+P`<)V``?#]@>.$"`*">]R\!_A]@```'"``:`$``?"!0"`0``*"G -M]R\$_A]@`'S?80```/:`!@`@`)OF9P*:)F!"I/=G@1H` -M(````%"@BO"^_\G``H`(*#7]2\9 -M_@B`T_X?8"`__2^<_C]@(-_U+QG^"(```>!G@OO_)P`=YV_!7$"<```5\/V`0)P``_(,- -M$*!']R\%_A]@H(/()QC^GV$$/@X0($#(+P```%"`+/XO^($M"/R!#0@`@`!0`'W@5P`$```%_/\G@*GU+P`N!7`AK()P`IRR^@*0`@`_X?8"#MRR\`F@9@`!?( -M)Z`SRR\`F@9@@!7()P$$``@@BLLO`)HF8(`3R"<`FP,H`7K@5X$!`""`F0,H -M!'K@5X(0R">@^,HO`)H&8``/R"<@,\LO`)H&8(`-R"<@8@DLLO`)H&8(`'R"<`WN!7@0$`(`"%`R@$>N!7`OS')Z`"RR\`F@9@ -M@/K')R`MRR\`F@9@`/G')Z#KRB\`F@9@@/?')R#MRB\`F@9@`/;')R#NRB\` -MF@9@@/3')Z!#RR\`F@9@`//')X#(RB^@[N!7`?#')P3^ -M'V"`>`,H@.[')P`WS"^`[<@JLHO`)H&8(#:QR>@L\HO`)H&8`#9 -MQR<@B\HO`)H&8(#7QR<@C\HO`)H&8`#6QR<@!LLO`)H&8(#4QR@T@(@"LLO`)H&8`#*QR>@V\HO`)H&8(#(QR<` -MR,N%7`!S'4:((`"`<_JA!3OX?8"!G_"_!_C]@,H@H"*!E_"]._A]@ -M`)X'8*"^V"\`FB9@``#`80!\/V"8EP(``(``"`%^`$"@1@`@`(``$``$/PAR -MK0(`&/K@9X%&`"!0>N%7@0<`(`D3`"`0>N%7@0$`(`D/`"``!>%G`@D`("P! -M"0@!?@!`+`$)$`":!F"@!``@$/X_8*#0_"\`F@9@``4`("@!"0@(_C]@`7X` -M0"@!"1``F@9@@,3\+X`!`"`@`0`@`?X?8````%```>!G`3<`(#`!"0@!?@!` -M,`$)$*`MV"\`G@=@H#(`(``N%7`?'_)T!ZX5! -M\?\GB0$`()!ZX5%7P````('J_R<`\_\GH$'8+P"> -M!V```,!A`'P_8!B7`@``@``(`7X`0"`F`"``@``0(#W8+P">!V```,!A`'P_ -M8""7`@``@``(`7X`0*`A`"``@``0H#_9+P">!V```,!A`'P_8"B7`@``@``( -M`7X`0"`=`"``@``0($K8+P">!V```,!A`'P_8"R7`@``@``(`7X`0*`8`"`` -M@``0(.+8+P">!V```,!A`'P_8#"7`@``@``(`7X`0"`4`"``@``0(-WF+P`< -MQU$@#-@O`)X'8`!\/V`$EP(``(``"`%^`$`@#P`@`(``$`!\/V``EP(``(`` -M"`%^`$`@#``@`(``$`!\/V`DEP(``(``"`%^`$``@``0H`@`(`'^WV$@#]@O -M`)X'8*``V"\`G@=@`'P_8)R7`@``@``(`!S'40%^`$`@`P`@`(``$!!ZX5>! -MU_\G`+X/8"#B`2A3_RE``7KG5X*I_R<`J/\G`(0&"/Q^0&"0>N%7`?'_)PD$ -M`"`P>N%7B_C_)P'5_R=`>N%7`>O_)U!ZX5!VO\GB0$` -M(*!ZX5>!U/\G@//_)\!ZX5! -M,0`@#``H"@"$"`@.>N!7`)[G48(#`"``'>=G`BT`(``@J&$$`"@*!!X($"#Y -M_R<`(,AA&H@("!S^2$(=?@!``!`@&"`"`"``($A@`(``4`@`00@`$"`8``@! -M"`"!X%<)_?\G`/K@5XP2`"`,``$(``*!$``"`$#_!2`(#``("`T"0!`#_B!@ -M`_K@5P+J_R<`?#]@X+$"``"```@``%\(T-\"``%^`$``!>%G`(``$($"`"`` -M)`E@(`(!.``@*&```>!G`>3_)P`$'PBIL@(```'@9P!\/V`@WP(`@@<`(!:$ -M"`@#?@!@`7K@5P)]X%<"````@@0`(*`$`"``@$`0`'Q?8'C(`@``?#]@J08` -M`*!/`2@`O@]@@/__)P"$``@!>N!7`@,`(`!\/V"@EP(``(``"`%^`$`@`P`@ -M`(``$`!\/V"DEP(``(``"`%^`$``@``0``0)"`Q^`&`(>N!7@@(`(`!\/V"@ -MF`(``(``"`%^`$``@``0`*((8"`-!B@`)"E@`-+_)R#3_R<$(`<0H"K')P": -M!F``?!]@`!`P``````@@@`\X`!``&`0^#A``!<NA7#`$`(``EZ%<,`P`@`+X/8`!\7V!PR`(`("D!*!/^ -M*4"`__\G`!H(0``EX%<,`P`@`+X/8`!\7V!PR`(`H"0!*!3^*4"`__\G```` -M4``EZ%<"@(`000$`(`2`0!`$H$`0!8!`$`'^"%`!@!^`!H!`$)2%`0@'FD`0 -M`8!`$"'^'V`(_C]@`?Y?8"`4`"@`GF=@H*3'+P`+,"`)2%!@C^H4T0_8%-$``. -M1QC\_PU`H''P+X#^/V#ZGXT0D(D&"`!\GV``B`(```@`0"!\!2CZ_RU`D(D& -M"/J)+0C\@4T(``@`0*!9Z"\"_G]@E(4&"`%^`$``#B`8[_K@5Y2!1A`,`0`@ -M@/X?8)2!1A"@Y\8G*/Z?800^#A"`N<8OXOZ?@@YZX%<`@@!BJP,`(```(&(` -MO@]@`'Q?8!C3`@`@Z0`H,WXJ0(#__R<<`$@(`_X(@```2$(D!`D(,'YA0B1^ -MX*4_L!!H0,`("0$J0D`O@]@`'Q?8!C3`@`@X``H/7XJ -M0(#__R=&"`$(`(9A4`!\`&#P_P``KH"`$*Z(``@`&@!HKH"`$$0$`0BL@$`0 -M100!"*V`0!`,_A]@E(!`$!,$"`@`@$90'``("`T$``B6AH`0``0`0)6`0!`@ -M"$@(`(7F5P("`"`B"`@(FH"`$*`$`""8AH`0`?YF0`@("`@`!^%7FH"`$$$! -M`"`B"`@("`@(")B`@!``?.A!``(``.*%!P@``>!G`0X`(!P`"`@2!``(#'K@ -M9P(#`"``O@]@`'Q?8!C3`@"@Q@`H:'XJ0(#__R97`J8)8*($ -M`"`4_C]@`'P(0-@!```$_C]@``1!4*`:Z"\"_G]@!/X)0!#^/V``!$%0(!CH -M+P+^?V`D!`D(!/X_8"1^X*<`<@A`K'X`0``$05`@%.@O`OY_8`L$"`@:>N!7 -M`@,`(!P`"`@$_C]@2'X`0``$05"@#^@O`OY_8.*%)P@`@^!G@0,`("0$"0@` -M!$%0)'[@IP!R"$"P?@!`H`KH+P+^?V`F""D(`(/@9X$'`"`H``D(``1!4"`' -MZ"\!_G]@#OKH5XH'`"`!_@A``!`@&@/^"(```$A"'00)"$!ZX&!7(T(```(# -M`"``'`=@#/X_8*"G^B\`!$%0(`$`(/"))@CNB28(``H?"!BQ`@"2_T9```(` -M0/Z!C1`0?@A``OX_8*!>^B\`AF%0)GX(0`+^/V#^_TU`(%SZ+P"&85`U?@A` -M`OX_8`+^1D"@6?HO`(9A4`]^"$`"_C]@CO]&0"!7^B\`AF%0;7X(0`+^/V`4 -M_D9`H%3Z+P"&85`)_@B`@/X_8`!_1T`@:?HO`(9A4`'^'V"`@,XO3'X(0`+^ -M/V">?T=`H$[Z+P"&85"`3/HG``'@9X(#`""@`0`@_Y$?&`!\'V#G#P````"? -M$!RV`@``@`\X`7K@5X'[_R<">N!7`H`/.`#[_R<$/@X0``S&+Q@$(`@*^N!7 -M`0@`(``$/PB:K0(`!/K@5X(!`"`%!"`((`8`(`3^(&@`@^!G@0,`(`!\7V`8 -MTP(``'P_8%@$``"@2P`H`+X/8(#__R<%!"`(^_\@8"`NQB<%`D`0!#X.$(`$ -MQB\<`"`(``"@83"$``@,?D!@"'KA5P`!G`@```"(!`"`&_A]@`!P'8``$`$`+@$80 -M($?L+P":!F`@B"8(`/P&0``"````@^!GW!T`$($?QB<<@$8(,`0A"-@#0!`Q -M!"$(^_\@8-D#0!`R""$(H!O&)]H#@!`$/@X0`/#%+QP`(`@``*!A,(0`"`Q^ -M0&`(>N%7`!S'40("`"#P?@!@@'K@5RH!`"`"_A]@`!P'8!A^0$`QA``(`7K@ -M9P)]X&<"````(@$`(`;^'V``'`=@``0`0`N`1A`@DNPO`)H&8""()@@`_`9` -M``(```"#X&?<'0`0`0O&)QR`1@@P!"$(V`-`$#$$(0C[_R!@V0-`$#(((0@@ -M!\8GV@.`$`0^#A"`UL4O_/O@9P$#`"``O@]@`'Q?8%32`@"@&P`H,?X_8(#_ -M_R?`>^%G`0,`(`"^#V``?%]@5-("`*`7`"@R_C]@@/__)P)^08```B%H(/K% -M)P`"0!`$/@X0@-#%+P``H&$`@L!AH*7Z+_[^'V"``,@O`!WG9X$+`"`">N!7 -M`'S?8?2T`@`"!0`@```?"""^`@``FB9@`7X`0*!WQR\L_E]@``0'"``!X&![<4G(*'O+P":!F"`V.`O``$`(`)Z -MX%>"ZL4G`'P?8!RS`@``R.@O@.C%)P!\'V`)V`(@`8(`![@00%^QT$@_J9!!GKG5P:_ -MQ2>`^?\G!#X.$"".Q2\8_I]A`(*`8`5^0(``?']@!,8"``"$(4"!G`AP`**#"Q2<8_I]A!#X.$*"#Q2\` -M@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'$!@"_X?8`+^((`"?D&``OYA@*!# -M^B\"?H*`,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@H#_Z+P"*HE"P@"8(U(!& -M"+2`9@@``($("OX?8"`\^B\!_K]@4(`F","`1@A4@&8(``"!"`K^'V"@./HO -M`OZ_8*R`)@B\@$8(7(!F"`!\'V```"```$"`"`K^'V`@-/HO`_Z_8*"D\2\` -M``!0H*/Q+P+^'V"@HO$O`?X?8(```"B`D\4G!#X.$*!CQ2\%_A]@(#?K+P"" -M(%````!0H#7K+P""(%`!_A]@(#3K+P""(%`@S/(O!/X?F("<_B\`BL4G!#X. -M$"!AQ2\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'`!@`GY`@`!\'V`LG`(` -M``4`$`0+`!`._A]@`OX@@`+^88`@'_HO`GZ"@##^OX&@@"8(T(!&"*2`9@@` -M`($("OX?8"`;^B\`BJ)0L(`F"-2`1@BT@&8(``"!"`K^'V"@%_HO`?Z_8%"` -M)@C`@$8(5(!F"```@0@*_A]@(!3Z+P+^OV"L@"8(O(!&"%R`9@@`?!]@```@ -M``!`@`@*_A]@H`_Z+P/^OV`@@/$O````4"!_\2\"_A]@('[Q+P'^'V``W/\O -M`&_%)P0^#A"@1,4O'/Z?82#D!2@``,!A``'@9P*^#V!"W_\O:/X_8``7]"\` -MS`4H@*#_+X"ETR\@[P`H``"@80#N`"@!>N!7@@4`(```'PC@G@(`!GK@5X(# -M`"```!\((-,"```!X&>"`0`@`(0&"``!X&>"`0`@`+X/8*#3_R^`_C]@@)3_ -M+P#O`"@``>!G`KX/8,+0_R^-_C]@@.D`*``!X&<"O@]@0L[_+Y/^/V``D?\O -M(.$`*`/^'V``A>@O'_X_8""[Z"_\_TU```'@9P*^#V#"R/\OJ_X_8"`F^R\` -M'`=@`+X/8"#&_R^P_C]@H&/%)QS^GV%D?HY3$``.$!0"#A`8!`X0'`8.$"`( -M#A`D"@X0*`P.$"P.#A`P$`X0-!(.$#@4#A`\%@X00!@.$$0:#A!(-@X03#X. -M$%!R#A!4=@X06'@.$`*@GPE<&`X0`Z"?"6`8#A``?+]A____``":;F``&H]@ -M`)HO8`;^'V`"_B"```1!4`+^88`"?H*`(-OY+RS^OV"@JO\O9'YN0Q``#@@4 -M`"X(&`!."!P`;@@@`(X()`"N""@`S@@L`.X(,``."30`+@DX`$X)/`!N"40` -MK@E0`(X)3`#N"P%^YJ]4`(X)`/+\9Q*8'Q)<`(X)6`".#P*8'Q)@`(X)2`!N -M"P.8'Q)``(X)(`$/.&1^CD,$/@X0(`7%+QS^GV&``0`@`+X/8(7^/V``H/\O -M`.[R+P`!X&!G(G?@+P*:!F`!_J9!!?KF5P7[ -M_R<@2?(O_/\-0/R!#0@``>!G`@P`(````%`@3/$O_/\M0/R!#0@``>!G`@L` -M(`+^'V`@,?0O_/\M0/R!#0@``>!G@0P`(`"FYB\``>!G@@D`(`!\/V``^@`` -M(.OS+P7^'V"`"``@@)?P+P#G_R<`,^`O`.;_)P"5X"\``>!G@>3_)X#B_R<` -M;.`O``'@9X'B_R<`O@]@(.'_)Y7^/V``O@]@((#_+['^/V`&_A]@H"'T+_S_ -M+4#\@0T(``'@9X$(`"``?-]AK+L"````!P@``>!G`=K_)P!\/V#XJ`(``($` -M"`!\OV&PNP(``7X`>`"!`!"@0/(O`(`&"`!^!Q"@U/\G`/X&$*`R\B_\_PU` -M@-+_)Z`0Q2<<_I]A9'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H.$"@,#A`L -M#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02#8.$$P^#A!0<@X05'8.$%AX -M#A`"H)\)7!@.$`.@GPE@&`X0`'R_8?___P``FFY@`!J/8`":+V`&_A]@`OX@ -M@``$05`"_F&``GZ"@""(^2\A_K]@H%?_+V1^;D,0``X(%``N"!@`3@@<`&X( -M(`".""0`K@@H`,X(+`#N"#``#@DT`"X).`!."3P`;@E$`*X)4`"."4P`[@L! -M?N:O5`"."0#R_&<2F!\27`"."5@`C@\"F!\28`"."4@`;@L#F!\20`"."2`! -M#SAD?HY#<'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H.$"@,#A`L#@X0,!`. -M$#02#A`X%`X0/!8.$$`8#A!$&@X02!P.$$P>#A!0(`X05#8.$%@^#A!<<@X0 -M8'8.$&1X#A`"H)\):!@.$`.@GPEL&`X0`'S?80@`(`@`?/]A____``C_'YH` -MGFY@`!Z/8`">+V`&_A]@`OX@@``$05`"_F&``GZ"@"!D^2\`BJ)0,/Z_@:"` -M)@C0@$8(I(!F"```@0@*_A]@(&#Y+P"*HE"P@"8(U(!&"+2`9@@``($("OX? -M8*!<^2\!_K]@4(`F","`1@A4@&8(``"!"`K^'V`@6?DO`OZ_8*R`)@B\@$8( -M7(!F"!)^!X``0(`("OX?8"!5^2\#_K]@H,7P+P```%"@Q/`O`OX?8*##\"\! -M_A]@(%O%+P-^"$```*!AH%K%+P-^*$"@6,4O`!P'8`'ZYF=P?FY#@08`(`1Z -MX&!G"`````%]X&<"````@0,`(`!\'V``@`$`(%/%+QA^)T`!_A]@H%'% -M+SE^)T``%O\O$``."!0`+@@8`$X('`!N""``C@@D`*X(*`#.""P`[@@P``X) -M-``N"3@`3@D\`&X)1`"N"4@`S@E,`.X)4``."EP`C@E8`.X+`7[FKV``C@D` -M\OQG$I@?$F@`C@ED`(X/`I@?$FP`C@E4`&X+`Y@?$D``C@D@`0\X<'Z.0V1^ -MCE,0``X0%`(.$!@$#A``X0`J"?"5P8#A`#H)\) -M8!@.$`!\OV'___\``)IN8``:CV``FB]@!OX?8`+^((``!$%0`OYA@`)^@H"@ -M)/DO%OZ_8"#T_B]D?FY#$``."!0`+@@8`$X('`!N""``C@@D`*X(*`#.""P` -M[@@P``X)-``N"3@`3@D\`&X)1`"N"5``C@E,`.X+`7[FKU0`C@D`\OQG$I@? -M$EP`C@E8`(X/`I@?$F``C@E(`&X+`Y@?$D``C@D@`0\X9'Z.0P``'PC!G"OZ@B0$3`"``!!\(?.`"``1Z -MX%<+_"!@`/S__RL$`"`+@@%0````4"`=\R_X_RU`^($M"/R!#0@``@!0`"`` -M0```!Q#:_A]@@/OX+P'ZYE>."``@```_"'#A`@`@6`(H`)H&8-O^'V"@]_@O -M`)HF8`!\/V"TEP(``(``"``:`$``@``0`'P_8+"7`@``@``(`7X`0`"``!`@ -M"P`@`/X'$`"@`&````%``?KF5P``!Q`."``@`)H&8*!,`B@!_C]@V_X?8"#L -M^"\`FB9@`'P_8*R7`@``@``(`!H`0`"``!``?#]@J)<"``"```@!?@!``(`` -M$"!+Q"=G@@$`(`#5 -MSB\!>N!7`@$`("`#`"````!0`'P_8.D!``"@F?XO`+X/8/"!#0@*?@"((#;$ -M)RC^GV$$/@X0(/;#+QS^GV$`?+]A6*T"`%:(1@@"?B&(``(A4`K^((```^!7 -MC@8`((S^'V`@R?@OGOX_0````%#\@0T05H@&"`!\/V"LTP(`"GX`@/B!#1#X -M_PU`(#T!*`""0&"@*<0G'/Z?800^#A"@Z,,OL?X_0```H&$@P/@OBOX?8`"; -MYFN!7A0T`((`3QB\``>!GH@P`(&B!!@A(@68(`(?A9X$*`"!P@28( -M((`@"`*$(`@`@^!G`@,`('B!)@@``%\(3-,"```"(5``@^%7#@H`(``$/PAR -MK0(`"/K@9P(#`"``!#\(6)\"``'ZX%<"`@`@@```(&B!!@B`B=0O@```(`#X -MX"\```!0:($&$'"!!A`@I=```@*K:)P0^#A"@P<,O-/Z?8:+^'X(``,!A`)[G4?R?#1"*_A]@H(SX -M+Q1^*$`->N=7`_X_8@(L`""`?L0OH./%+P``H&$``,!A!WK@5P)]YU<&```` -M`A8`((K^'V"@A?@O('XH0`!\/V#8EP(``(``"`!\_V%=7"`````("`"`(>N=7`7Y?$-"L`@"!VO,OH%;$ -M+P":!F"`;@`@@,[Z+X"WQ2\``*!A!WK@5P+]YE<&`````@$`(``1`"@`#@`@ -MC/X?8"!9^"]O?BA``'P_8-27`@``@``(`7X`0""PQ2\`@``0```@8*!4^"^* -M_A]@"OKF5P+]YE<%`````OWF5P@````"_>97"0````$#`"``O@]@`'Q?8,3' -M`@"@NOTO=WXH0(#__R<@BO\O`!P'8``>7Q#2K`(`(,S2+QC^"("`60`@!#X. -M$"!ZPR\L_I]A`'R_85RM`@!H@08(]/X_0@P```@`(@!`%00`"``!X&<`',=1 -M`@T`(/R=#1`@,/DO<($&"`!\'V)8K0(`5@@H"`!\_V$(W@(`"OX@@`"`X*?X -M\PT0BOX?8*`\^"\9_BA`^/\-0!#^)T"@LP`H`)Y'8%8("`@0_B=`"GX`@/B! -M#1#X_PU`(+``*`""0&"``0`@1($&"`%^`$!$@080H$[:+P7^'V``C\4O`WK@ -M5X($`""/A08(`7X`0``.(!@!^N!7CX%&$(P!`""/G480H'[:+P7^'V``A\4O -M!7K@5X4-`""`A\4O``'@9Z(,`"!H@08(2(%F"`"'X6>!"@`@<($F"""`(`@" -MA"`(`(/@9P(#`"!X@28(``!?"$S3`@```B%0`(/A5XX(`"``!#\("!``@H$_J+VR!!@@`/O\O`'P_8*34`@`(@0`(\($-$"`# -M`"`,@0`(`'P_8`C>`@`0@``(\($-$!2```CT@0T0`&'%+P9ZX%>!`0`@@%_% -M+P=ZX%>"$0`@`%[%+PMZX%`@``@B!0H,?$)R3^7V`$/@X0@`+#+P```&(`@N!A -M(`P`(`":IE$$_B:``'Q?8`C>`@``A,!!!``'"/][X% -M!V`!_@9```Z@&0+ZYE<*&\,G`//_)P0^#A"`]\(O``#`80+^/V(`?!]BI-," -M``!\7V((W@(`H`<`(`":IE$$_B:``*0`0`0```C_>^!7@0,`(``"Z4$`G@=@ -MH#L`*``@*&`">N!7`9X'8@&:)F(!_@9```Z@&0+ZYE<+^/\G`OKH5XL#`"`` -M?%]@Q,<"``!\/V!/`P``("']+P"^#V"`__\G!/X(@``D($``)``````'$`2` -M``@@",,G!``'$`0^#A"@X,(O//Z?8?[^/YH`?/]A&-X"`"!3\R_H_PU`C/X? -M8""K]R\?_BA`Z($M"*"I]R^-_A]@`(`G"""H]R^-_A]@Z($-"`">)V``?`!@ -M`/S__^B!#1#H_PU`(#(`*/#_34#T@2T(`(/@9P`=G@0,`(`+ZYE>-`@`@C/X?8*"1]R\[_BA`5@@("/]_QT$`'."G -M"OX<@/B!#1``G@=@^/\M0"`;`"@`GD=@`7K@5P$#`"``O@]@`'Q?8,3'`@`@ -M]OPO0_XH0(#__R<`'`=@(.S")SS^GV$`@(`(``"@"`0`P`@$@``(``IB0``, -M`$``B^%7!HGA5P5\`$`!``````8!$""`#S@$``$0`(!`"```8`@`A>%7`?Z? -M8`((@E``A>%7`?Y_8`Z&85`$@"`(!```"``#X%%G(H`/.`(``%```>!G@@$`(``%X6<"A^%G`0$`(""`#S@! -M_A]@((`/.`+^'V`$/@X0H)7"+P```&$`@L!@(.__+P`$H6```>!@`@8`(``` -M`%``_@(0H`8`(`2``A``$`1@H`$`(``,(V``#`-@`!`D8"`$`"@`BD)@``(` -M(`'ZXU@OL(G'/Z?80`$ -M@!`0?D&(`@2`$`!\?V!8K0(`!81!"`A^@8`$A$$(``A!>`0$@!`'A$$("'Z! -M@`:$00@`"$%X!@2`$`F$00@(?H&`"(1!"``(07@(!(`0H#$`(``,PU`!?F-@ -M`(;A0`2.8```?+]@&+@"``"$87@`CF$8`(9A0`"*84`$B0$)!(Y@``!\GV`8 -MN@(``(1A>`C^89``CF$8`(9A0`"(84`$B6$(`)`!>0`(8`@`D&%```:`$`"0 -M(1D$_@-!!)!@``"287@`CF$8`(9A0`"*84`$B4$)!)!@``"287@(_F&0`(9A -M0`"(84`$B6$(`)0!>0((8`@`D&%``@:`$`"0(1D(_@-!!)!@``"287@`CF$8 -M`(9A0`"*84`$B4$)!)!@``"287@(_F&0`(9A0`"(84`$B6$(`)0!>00(8`@` -MD&%`!`:`$`"0(1D,_@-!!)!@``"287@`CF$8`(9A0`"*84`$B4$)!)!@``"2 -M87@(_F&0`(9A0`"(84`$B6$(`)0!>08(8`@`D&%`!@:`$`"0`1D$CF````9D -M>`".81@`AF%``(IA0`2)H0@$CF````9D>`C^89``AF%``(AA0`2)80@`BF%X -M`(1!0``001@`#$%`"`2`$``001@!?F-``([!&`AZXU<*@`\X@,W_)P1^X$"@ -M`P`@`(JB4`"*PD`$#($``(S#0``(@Q`!_H)```ZB&`7ZXE<+_/\G"`A!"``& -M04``$($8#@2`$`"(0`@`"*%X`(Y"&``$@4``?%]@&+@"```$@D`$"<(("/Z" -MD``(HD``?)]@&+H"``"(HD`$B:((`(S">`0(H`@`C*)`!`J`$`"0PA@"B*`( -M`(S">``.HQ@`BJ)``(2B0`2)X@@(?J.0`(JB0`"(HD`$B:((`([">`8(H`@` -MC*)`!@J`$`"0PA@$B*`(`(S">``.HQ@`BJ)``(2B0`2)X@@(?J.0`(JB0`"( -MHD`$B:((`([">`@(H`@`C*)`"`J`$`"0PA@&B*`(`(S">``.HQ@`BJ)``(2B -M0`2)X@@(?J.0`(JB0`"(HD`$B:((`([">`H(H`@`C*)`"@J`$`"0PA@(B*`( -M`(S">``.HQ@`BJ)``(2B0`2)X@@(?J.0`(JB0`"(HD`$B:((`([">`P(H`@` -MC*)`#`J`$`"0PA@*B*`(`(S">``.HQ@`BJ)``(1"0`0)H0@(?D.0``1!0``( -M04`$"4$(``J!>`X(0`@`!$)`#@2`$``0@1@,B$`(``A!>``"@1@!?D%@#WY! -M@``(@7@$"$`(``A!0`0$@!``$($8#HA`"`(&0!``"$%X``*!&`%^06`/?D&` -M``B!>`8(0`@`"(%`!@B`$``00A@``J$8`7Y"8`]^08``"H%X"`A`"``(@4`( -M"(`0`!!"&``"H1@!?D)@#WY!@``*@7@*"$`(``B!0`H(@!``$$(8``*A&`%^ -M0F`/?D&```J!>`P(0`@`"(%`#`B`$``00A@``J$8`7Y"8`]^08``"H%X#@A` -M"``$0D`.!(`0"/Y!D``$0!!_?D%@('Y!:`$$0!``B"`(#@A`"`"$('@`@B`8 -M((`/.`,"0!`$/@X0@.S!+P``P&$`@J!A($S#+P0```@``,<)$/X@@!!^!X@` -M`@!`($G#+P":)F`0_B"``!`'&``"`$"@1L,O"OXF@*`.PB<`@@!@`#X.$`#@ -MP2\#^N!G0_Z_@0$#`"``O@]@`'Q?8%32`@"@(OPO`?XF0(#__R<`>^%7"0,` -M(`"^#V``?%]@5-("`*`>_"\#_B9`@/__)P!]X5<``0``"P,`(`"^#V``?%]@ -M5-("`"`:_"\$_B9`@/__)P!ZX5<*`@`@`(9!8*"DZB\"_G]@`++#)P`0@1@` -MAD%@``AB8*`(ZR\!_I]@`*_#)P``'P@@TP(``'K@5P'^'V`@@`\X`0``4`0^ -M#A``Q\$O`"/E+R#SP2=(```(!#X.$(#.P2\``,!A`((`8@'^OV$`GN=1`*`? -M"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_ -M`"'H9P$H`"!``*T(/``M"`"#XE>%```@.`"M"`"`@@@`">)G`2(`(``$05`` -M`"(((/K@5R#^(%`-FF!`#IIF8`"<(5``!^=7``("$"4!`"`!_N=!``0"$!@$ -M`A``@&(($`"""``'XE<"^/\G`)_G9X$8`"`8@"$(`(/@9Q"`P0B"%0`@``?C -M5___YT%!!P`@`(0"$!2`(0@4`@,0$("!"!"(`!``@"((`(/A5P(#`"`8`"(( -M`(/@9X$``"`8"@(0$(`A"`""`A!``(T(`(`A"#P`[0@@_B!```_B5P""`1`% -M`@`@``XB4/S_@&`X`"T(``*"0```(@@`@^!G`00`(!""`1`4@"`(%((!$!"& -M`!```"((%(8`$*`"`"`8B`$0$(8!$!2&`1`8B`$0``8"$"#G_R<`#&-@`?ZF -M02#ZYE<$_J)`CMC_)RP`+0@!?D=0`(0@0"P"#1`P`"T(`(/@9P$!`"``A"!0 -M,`(-$```H!\`O\$G!#X.$("9P2\```!B`(+`80'^OV$`GN=1`*`?"``!`$@` -M`0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_`'KG5P'^ -M/V`!@B!0`((_4CP`K0A``(T(``OB5X4``"`X`(T(``!B"`"'X6!`0`@`*/@5P8"`"```0`@ -M`*/@5XX``"``@B!B$`!!"``'X5<"^/\G`?ZF02#ZYE<$?H)`#O+_)P``H!\` -MG^=G0@$`(``B"!``?@@0(*/!)P">!V`$?HY3`#8.$``X;F,0@`T0$(1M"`/^ -M`6``@$`0`OX!D```01``$&X+((`/.`1^CD,$/@X0`''!+Z3^_X$``:!A`(+` -M80+]YEN!7`0$`(`"!YEN%G@0,`(`!\7V"DR`(``'P_ -M8(1A`"?@=`H&3!)P``2!`@`P`@`(A`"``$@$$`?D80`7YA0`"001@` -MAH`0`WKA9X+\_R<`@`\X!#X.$"`WP2\``(!@`((`8``$X6$">N)7`83`"2(" -M`"``A@%B"'KG5PE\WV$(`````GZG00">)V`@2_8O`)I&8`&<1Q`@5L$G`!I( -M$`0^#A"`(\$O_/KA9P$#`"``O@]@`'Q?8*3(`@"@:/LOT?X_0(#__R<`A(`( -M``A`$`&$@`@!"$`0`H0@"`("0!`&_B&`(/X@:`,"0!`"!"$(!`)`$`,$(0@% -M`D`0!`0A"`8"0!`%!"$(($3!)P<"0!``/@X0@"'!+][^/YH0@@T0``"@81P` -MP`D`!`%B0_X?8*#M]2\'_BA`H`WH+P":!F`0_@U``?X_8*`W^R\`($A@#00' -M"`Q^YT$1@$T0#`0'"!*`31`+A`8(`OQF`.(!```G?@!`_'\`8`"'X6<<@$8( -M(0@`(``.(!@2!`$(#'K@9P(#`"``O@]@`'Q?8!C3`@`@3/LO%OXH0(#__R<` -M@@%```X@&`X(`0@`!@!`(`X`(`X`@1`4!`$(``'@9P$#`"``O@]@`'Q?8!C3 -M`@"@1/LO'_XH0(#__R<5!`$(``'@9P$#`"``O@]@`'Q?8!C3`@`@0/LO(/XH -M0(#__R<6!`$(``'@9P$#`"``O@]@`'Q?8!C3`@"@._LO(?XH0(#__R<@B`8( -M``'@9P+9PB<0@&T(`)X'8*`0_R\`!$%0,00'"`A^`&B@U<(G,0!'$`0^#A`` -M!<$O`'R_8FBT`@````!B`(0`"`""X&'\?J!A`'S?85BM`@`0_@!`H"_K+PI^ -M)T`!>N!7`*(H4J($`""C_M^"#P0H"`"J2F(0!`@(=((*$'B`BA"@L>LO@/Y* -M0'P`"1`6!`@(!'K@9R$L`"`@?B!@`(/@9P-^`&"B`P`@`*I*8@"^#V``?%]@ -M>,@"`*`B^R]_?BM`@/__)P%ZX%>""0`@#P0H"`($"`B,`XD0D`&)$!`$"`B@ -MI>LOCG])0``08!H#!`@(`@0H"""CZR^2?TE``!"`&@"F"6"@%/$O`((@4``` -M0&(@#0`@``!@8@)ZX%N!7@00`(!#^!T"@ -M!^LO"GXG0`%ZX%<"`@`@`":?$$ZQ`@``*)\04+$"``CZYE<"_>97@`````+] -MYE?0````@A<`(!#^!T`@`.LO"GXG0`%ZX%<"%0`@`.W"+P)ZX%>!$P`@`"0? -M$`3X`@``$@`@`(/@9Q`$2`H!`P`@#P0H"``D"6`@@.LO``1!4"`'`"``$``8 -M`*#4+P%ZX%<`)$E`H@4`(`\$*`@$?$$`=,D"```D*6(`#@$8$`1($"!YZR\` -M!$%0`!``&*`%`"``@B!0!'Q!`!29`@``#@$8$`1($`!\7V`2M`(`H('K+P`D -M*6(`$``8`?X_8`#E\"\``$!B"/KF5Q$D2!""!0`@!/X'0"#GZB\$?B=``7K@ -M5P(#`"``)!\0!/@"`(3^'T"@=O4O`"0I8``*`""`^N97`@D`(`#0PB\">N!7 -M@0<`(!#^!T`@W^HO"GXG0`%ZX%<"!0`@`'R_803X`@``I`80`'P?8`D!``"@ -M;?4O`"0I8`"`)@B$HPH0B(,*$!#^!T"@U^HO"GXG0`%ZX%>"Q,`G@,3"+P)Z -MX%%7B9[`)^!_06`!?@!```0`:`2`0!`@Q.\O -M`)X'8"*$1P@`F@9@(!3_+P">)V`(_@=``!PG8*"0]2\0_E]@`)?`)R.$!P@, -M>N!7`0,`(`"^#V``?%]@I,@"`*"J^B\I?BA`@/__)R2$!P@``>!G`0,`(`"^ -M#V``?%]@I,@"`""F^B\J?BA`@/__)Z"U[R\`G@=@``'@9P$!`"`@V?(O"`0" -M"`"`!P@(_B=``!!@&``!!``@`)X'8``<)V"@=/4O`_Y?8`C^!T`# -M?B=`H'+U+PW^7V``!P`@``'@9P$#`"``O@]@`'Q?8*3(`@`@DOHO37XH0(#_ -M_R9V`BA$<(`)H&8"#^_B\`GB=@@'3` -M)PAZX5B0!`!@$`0(?X?8`C^/V`"_E]@ -MH%'Y+P">9V``(`A@`)HF8``$05"@N^$O`OY_8*#?P"\`'`=@`$'`)P`$`@#0 -M$0``!#X.$`"=OR^`4OLO``'@9P(W^B^@4OLO`?X?8(!`XB^`QK\G!#X.$("8 -MOR\`?>!7`/("`(DR^B^````H`,._)P0^#A``E;\O@`,`*(`A`"@``>!G`KX/ -M8,(U^B]0_C]@@"$`*`"^OR<$/@X0`)"_+P!\'V``\P(`@'P`$`#W`@"$?``0 -M`)8"`(A\`!#@G@(`C'P`$.B8`@``?!]@`/8"`!!\`!!@GP(`%'P`$$2@`@`` -M(@(H`'._+X!,Z2\`?!]@RP````!?Z2\`?!]@Q````(!+Z2\`?!]@U````(!7 -MZ2\`?!]@[P````!?Z2\`?!]@"@$```!0Z2\`?!]@)0$```!*Z2^`X0$H@`," -M**#WZ"\!_A]@H/;H+P```%"@]>@O`OX?8`!\/V``!```('WN+P```%`!_A]@ -MH'ON+___/V"@5^XO`?X?8`!\/V`0)P``H'CN+P;^'V"`G[\G!#X.$(!QOR^` -MU@$HH)V_)P```%````!0H.#Y)P""(%`$/@X0@'*_+Z`L`2A]_M]A`%`!*("C -M`2B`D]DO(+SK+P'^'V`@N^LO`OX?8""ZZR\```!0`![M+P`Q`2@`70$H@)@! -M*`"F`2@``>!G`KX/8$('^B^"_C]@`OX?8*!G[B\(?B>`!?X?8"!F[B\)?B>` -M($GM+P":IE$`,^TO`#?M+X`!`""@/^TO`)H&8`'^ID$%^N97A?W_)P#]["\` -M&>TO`(F_)P0^#A``6;\O``0`*`-ZX%?!A+\G#OX?8`%ZX%N!7`@,`(/Z)#0@(?@"0I7K@5P3^'V`!?!]@`0```*!\OR<4_I]A!#X. -M$"`^OR\<_I]A``#`80```%#^@8T0H`,`(`":IE$`FB9`_HE-"`#\`$`@^@(` -M``2`$`'^ID$`&^=7#@,`(`":!F`@%``H_O\M0`%ZX%>!^?\G@```(`'^'V`@ -M;[\G'/Z?800^#A"@,[\O!OX?8`!\OV%4W@(``(`&$`!\_V$HO0(``(`'"`!\ -MWV$@^@(```!`0``N!7`@(`("#J_R\`@`<(`7K@ -M5P$!`""@4;\G`(`&$$)^!T"@;0`H7_X_8$`()P@``^!7!?X?8`%\'V`!```` -M@/K_)P0^#A`@'+\O%/Z?80``X&``@@!A``B"4````%#\@0T0`(JB4`""(%"@ -M50`H``1!4*!<`"@!_A]@````4`'^/V"@4@`H``1!4*!9`"@!_A]@`?X?8`'^ -M/V"@3P`H``1!4*!6`"@"_A]@````4`'^/V"@3``H``1!4*!3`"@!_A]@```` -M4`'^/V"@20`H`?Y?8*!0`"@!_A]@`?X?8`'^/V"@1@`H`?Y?8*!-`"@"_A]@ -M````4`'^/V"@0P`H`?Y?8*!*`"@!_A]@````4`'^/V"@0``H`?Y?8*!'`"@! -M_A]@`?X?8`'^/V"@/0`H`?Y?8*!$`"@"_A]@````4`'^/V"@.@`H`?Y?8*!! -M`"@!_A]@````4`'^/V"@-P`H``1!4*`^`"@!_A]@`?X?8`'^/V"@-``H``1! -M4*`[`"@"_A]@H`D`(`?^WV"`,0`H(#D`*`'^'V``C`.(`7Z`8````%`!_C]@ -M("X`*``(0F`@-0`H`?X?8`'^'V`!_C]@("L`*``(0F`@,@`H`OX?8/]_PT`` -M>N-7````4`'^/V`J]?\G``A"8``F`"B@+0`H`?X?8````%`!_C]@H",`*``$ -M05`@)P`H_/\-0/R!#0@``>!G(AP`(`/^'V"@)P`H`?X?8`'^'V`!_C]@H!T` -M*``$05"@)``H`OX?8"`,`"`/_I]@@!H`*"`B`"@!_A]@````4`'^/V`@&``H -M``1!4*`;`"C\_PU``(H"0``0(!C\@0T(`!``&``"H&B@&P`H`?X?8`'^'V`! -M_C]@H!$`*``$05"@&``H`OX?8/]_@D``>N)7````4`'^/V"J\O\G``1!4(`, -M`"@@%``H`?X?8````%``@B!0(`H`*``$05`@$0`H`?X?8`'^'V``@B!0(`<` -M*``$05`@#@`H`OX?8``*A!`!_A]@(`B_)Q3^GV$`@"`(`?K@9Q[^(&`"A"`8 -M`8(@4``"`!``@`\X`'Q_8$``,```@B!``(`@:`)^`8```@!H%WX`8""`#S@` -M@`$0`'P_8$``,```@"`(!/X@B`'^(&`@@`\X``(`$`1^CE,`?@X4/W[@IP!^ -M#A0@`@`@`_X\B`!`#@@!?@!````.%`!`#@@`@>!7#?W_)R"`#S@$?HY#``!` -M8````%`@`P`@``B"4``(8D`$!F$``7Z"0`"``7@`$``8`(G@5PZ`#S@`_/\G -M!#X.$`"NOB\`#0`H`((@4`!^'Q`8WP(``'X?$!S?`@``?!]@>+,"`)(#@!"0 -M`X`0E0-`%)8#0!0``E\4#-\"```"7Q0-WP(```(?%!3?`@```A\4$-\"`#1_ -M`$``?+]A`/8"`"#T[B\H@`80H,R^)RR`!A`$/@X0(**^+P```%``?+]A```@ -M``R`!A0`_@84@/X?8`"`!A0`B.0O(`(`(```P&$`O@]@(#KY+X_^/T``P`8( -M`7K@9X("`""`@^0O`!P`4`%ZX%>._/\G@/K_)P!\?V#DU`(``/]!0`""(%`` -MP`8(`7K@9P$#`"`$P`8(!/X@0````1`:^N!7!'Y!0([[_R<`A0$(`7K@5P'] -MX%<<`````0(`(`"^#V"@*_DOG?X_0("VOB?__Q]@"(`&%`*)`0@4_R%````? -M$-"8`@``?!]@U)@"`"`WP"\%_E]@`+&^)P0^#A`@@;XO`?Y?8`!\/V#8O@(` -MH%7A+^#_`$```>!G@:J^)P"^#V``?%]@5-("`*##^"]R_C]@@/__)P0^#A"@ -M>;XO``1!4`!\/V#4O`(`($[A+]S_`$```>!G`:.^)P!\7V!LR0(``'P_8"<# -M``"@N_@O`+X/8(#__R<`;=(G!#X.$*!SOB\`!$%0`'R_82B_`@``_P9`($7A -M+R#_)D```>!G`0,`(`"^#V``?%]@'-("`""S^"]I_C]@@/__)P```%```%\0 -M(=\"`""6OB<<@080!#X.$*!FOB\`!$%0`'P_8&BT`@!<_P!`H#KA+X3^($`` -M`>!G`KX/8$(%^2_@_C]``'X?$,#?`@``?A\0O-\"``!^GQ#$WP(``'X?$+#? -M`@``?A\0K-\"``!^'Q"XWP(``'X?$+3?`@``?A\0T-\"``!^'Q#,WP(``7Y? -M$!_?`@``A+XG!#X.$`!6OB^`"@`H`,',+P!\7V!0M@(`!`$!$(@$(`B)!``( -M``(?$$"8`@```4$0```?$*B8`@``"!\(++T"``!]X%<@0@``H@$`(`$#01`9 -M?I\0+[$"```(`"@`>+XG!#X.$"!*OB\`!$%0`'P_8(2^`@"@'N$OW/\`0``! -MX&>!<[XG`+X/8`!\7V`LT@(`H(SX+S;^/V"`__\G``@?""R]`@``?>!7($(` -M`($B[B<`K.TG!#X.$(`_OB^`Q/\O@,S_+X#6_R^`N_\O@)#_+X#E_R\`?#]@ -M[,4"`.3_`$`@$>$O``1!4``!X& -M`@`"_A]@`?X_8*#IVB\`!$%0#`"@"0``'Q`TW@(`*/X&0!R`!A`P?B!``'P? -M8OC7`@```@@0#'X`0`!\WV&8W@(````'$`""(%"@Q[\O)/Y?8```"`@`@B!0 -MH,6_+QC^7V````<(!_X_8"$"0!`(_B"((/[V+R("0!`'?B!@```'"`">YU$> -M`H`0")Z&$"#1RR\`F@9@`-S5+P`AOB<$/@X0(/F]+P`$05``?/]A8+$"`$C_ -M!T`@P^`O:/\G0``!X&AA`@KLLO`)H&8(#^O2<$/@X0@,R]+P!\/V!0K`(` -MH+O?+Z3_`$``A<`O@/:])P!\'V`XO`(`@+OC)P0^#A"@R;TO``1!4`!\OV$0 -MM`(`#/\&0"";X"]`_R9````?"`SW`@`L@080`'P?8`#V`@`D?``0V+4"`(#V -M_R^`[;TG`'S?8*#R`@``?!]@`(P"``!\GV#PX`(`#``"$`3^OV`0"@(0`(9A -M4`!^`A`$!@(0"`8"$"`(`"`!_C]@"?X`@`!\0$``_O__`'P?8`".`@``!$!` -M%/[@IP"('$`,!``0$`H`$`"(G$$`!@80!`8`$`@&`!`!_B!`!/K@5XSW_R<` -M?%]@`/4"``!\/V``\@(`0(0`$"#^'V!$@``0`'P_8%CA`@`,@``0"(0`$``` -M`P@`@``0!(``$`!\'V`0^`(``'P_8`#W`@```@!0`GX`D`%^`%``@``0`'P? -M8*R8`@``?#]@`)8"```"`%`"?@"0`7X`4`"``!``?!]@$)D"``!\/V#HF`(` -M``(`4`)^`)`!?@!0`(``$""`#S@```!0(*7:)P[^'V`$/@X0@*.]+P`@"%(` -MGN=1H`P`(``!G`@(`("B`!@@````(``'@9X$!`"``O@]@DOX_ -M8``P^"\!?@A"&'['003^YT$%>NA7AKN])P!\/V`DJP(``(('0!````@``>!G -M``*G08'O_R!G`;X/8,$E^"]T -M_C]@-(`&"```(`@D@`8(````"``#X%>%`@`@`+X/8"`A^"]X_C]@-(`&"``` -M(`@H@`8(````"`"!X%>-[?\G`+X/8"#L_R=\_C]@!#X.$``V#A``.&YC$'Z. -M4X#&["\`?#]@F)@"``"``!`(_A^8@`/K+P#[ZB^`!@`H"OX?8`'^/V``1N,O -M"_X?8`'^/V"`1.,O````4`!\/V`*`"`(`$2^+P2`[0L@@`\X$!!N"P!\?V`D -M`#```'Q?8"0!,```?#]@*`$P``!\'V``"`"``(`!$(.&'Q@```$0A88?&`"` -M`!``@`\X@'X?$,2?`@``@`\X`%@"```8```````````````````````````` +M?____W____]_____?Z!^]R_X_PU`^($-"``!X&>!V_\G`?[_'P#__R<$/@X0 +M@%+*+P`!H&&!`0`@((`F"`"#X&<"`0`@('O*)P'^'V`LA`8(``'@9X(!`"`M +MA`8(``'@9P$!`"`@`0`@`?X?8````%```>!G```?$,R_`@`!`@`@`'P?8-"_ +M`@"`&/`O((`F"`*$``@``>!G`@,`(`!\7V#!G`8`/.`!\'V#4OP(```GP)P``/PAL +MMP(``(/@9P&`#S@`!``(2'K@5P&`#S@`?!]@V+\"```$\"<$/@X0@#'*+P`` +MH&$``!\(;+<"```!X&>!6LHG`'P?8-"_`@``_^\O!(0&"`%ZX&>!5\HG`80& +M""!ZX&TO2'](0$0!"!#HP0T(@-?*+_2!#0@``>!G`;/?+X`]S"\/>N"'A`8`(``` +M#`@`$$`:```'"`!]X&IG@@(`(``D"6#\_RU`H+@`*.S_34``@.D)_($-"``!X&!`0`@`"K,+P%ZX%<"%``@`,#*+X`O[2\`@B!0H$/M+TA_2$!$ +M`0@0`"0)8/S_+4"@K@`H[/]-0/R!#0@``>!G@0@`(`"$"@@!>N!7#`<`(-'^ +M'V"@J_XOW_X_8"#PX"\&_A]@`(0*"`)ZX%<+`@`@`'P?8```"```1-DO``$` +M(*#KX"\'_A]@@++*+X"SRB_H@0T4@!_M+TA!*`B@,^TO2'](0$0!"!#HP0T( +M`++*+Z`4S"\`HBA2"7K@5X$!`""`$LPO`WK@5X(``"`!_C]B^*,-%/C!#0@` +M`>!G`24`(``IZF<")``@`*7*+X`4[2\`@B!0H"CM+TA_2$!$`0@0`"0)8/S_ +M+4"@DP`H3'](0`"`"0@`@>=7@0$`(/R;#1`@`0`@`)H&8/R!#0@``>!G`0H` +M(-'^'V`@C_XOD/X_0`"$*@B@C?XOT?X?8$Q!*`@@C/XOT?X?8$Q!"`B@_P`H +M\/\M0`"$"@@"?@"``'P@0+R7`@#\@0`(`7X`0"`,`"#\@0`0TOX?8""%_B^5 +M_C]``(0J"*"#_B_1_A]@3$$H""""_B_1_A]@H,;@+PC^'V#XFPT4`(0*"`)Z +MX%>+`0`@(!O9+Q#^'X```0`@(,+@+PG^'V``@`L(`7X`0`"`"Q"`A\HO@(C* +M+^B!#12`].PO2$$H"*`([2](?TA`1`$($.C!#0@`A\HO^,$-"``!X&<"`P`@ +M`'KI5XP=`"```!\(W.$"```!X&>!&P`@`'P_8@0`,`#XP0T(`(#("@`!X&<" +M?#]@50$``$)M_B_1_A]@`'C*+_"!#0@$?@!H`"S`:O___W____]_____?___ +M_W____]_____?____W____]_____?____W____]_____?____W____]_____ +M?____W____]_____?____W____]_`*P($/___W____]_____?____W____]_ +M____?____W____]_____?____W____]_____?____W____]_____?____W__ +M__]_____?____W____]_`&/*+_C!+0@`@^!G`8[_)X!?RB\`Q@PO`((@4*#A["](?TA`1`$($-/^'V"@3OXOU?X_0`"$*@@@3?XOT_X? +M8`!E_R\*_A]@`OX_8*`OYR\#_E]@```@8B`/`"CT_PU`]($M"*!'_B_3_A]@ +M]($-"``!X&!G`7P_8`$``````@<0H*W))QS^GV$$/@X0`'S)+P``(&(` +M!!\(Q+`"```!X&<"G,DG`'S?8>S>`@````<(`_X?8@P`H`D`?']B5-@"`!R` +MY@D@3MN"'@P$`(`#NY2\``>!G`0$`("`"`"`1I$80```'"*!^Z2\! +M_C]@(![?+P":!F`1A`8(GWX`8`%ZX%\O]/\-0`!\WV',P`(`!`$'"/2! +M+0@`@&!0`OY(@`!\`4`LO`(`_`$`"`'^?V(`@>%7"`$'"`ZF:5(`@(!0`'P! +M0$"\`@#\`0`(`?X_8@`!XE<,`0<(#J(H4@"`(%```!\(5+P"``'^GV(`@>!7 +M``$'"`XHBE(``>!G`"1)4@$"`"```!\(6+P"``"!X5>%```@`?Y?8@!N!7!0,`(`"JJE(`I^EG`J/H9P(IZF<")>EG@0``(`'^OV(`?!]@"0`@"*#U +MR2\!_G]B`GK@9P&F:5(```!0H$CU+_S_+4`"_A]@($?U+_C_+4`@4!!``@`$_++P5ZX%!`0`@`$S++PEZX%<"!0`@ +M@$S++P`!X&>"`P`@@#[C+P`!X&<"`@`@@/'3+P`!X&!!P`@_($M"`"# +MX&!!``@```I"`"#X&<"`>!G@0(`(```'PBLM0(``"W@ +M9P%\/V(!`````*/H9X$=`"``?!]@]*L"```L*V``!$%0[/]M0"#EZB\`"()0 +M``!`8M;^'V"@OOTO`"0I8(#,R2^@,!7__\```$"`"#P@0T(``/@5XX``"#P@PT0!WKI +M5P`$05""`P`@```'"``!X&>!`0`@\($-"`MZX%>.```@`?Y?8`""(%``H^AG +M`@7A9P$"`"#L@0T(`"W@9P%\/V`!`````((@8@"CZ&<`H@<0`1,`(/"!#0@` +M`>!G@1$`(`!\7V#"`P`@$7K@5PU\`(`*````#7P`0`#$ +M___-!``@```($`I^`(``?`!``-3__P``"!`%^N!7`7P_8`0``````D$0`'W@ +M5P`(```-`@`@`OK@5PE\/V`"``````,`(`!]X%<@"```#0,`(`/ZX%<)?#]@ +M`P```"`!`"```D$0`!H($"`-R2=,_I]A`'X?$-R_`@`!?E\0R*T"``"`#S@! +M?A\0V[\"``!^7Q#)K0(``(`/.`0^#A"`T,@O``"@80`$'PC-N``````8X\.[GT],````$/@X0(+K( +M+SC^GV$``,!A`'P?8M3A`@````@(`'Q?8@`$````'`!``'S@40@$````!!\( +MW.`"``%^`%`$>N!7`)JF42XX`"`;_C]B`+X/8"`L`RBV_C]@`"P`(``=YV>! +M&@`@````4""&]R\!_C]@`?X?8*!X]R_P_RU`!/X?8`">)V"@FO_@=O'X`0"!4[B\` +M`@!0T_X?8*!(_2]^_C]@^(%-"/"!+0C3_A]@($;]+P`"(5`$_A]@H*SW+_S_ +M+4`@V/4O&?X(@-/^'V`@0OTOBOX_8*#?]2\9_@B```'@9X+[_R<`"@`@(-/U +M+QG^"(#3_A]@(#W]+YS^/V"@VO4O&?X(@``!X&>"^_\G`!WG9P$#`"`#_A]@ +M`!PG8"!W]R_X_TU`^($-"`I^H(D#_A]@H)WW+_S_+4`!?A\0R^$"```9`"@` +M?!]@Q````(`9\B_3_A]@(#']+\3^/V#X@2T(H"_]+]/^'V``?#]@N)<"``"` +M``@`&@!``(``$*"JR"R2\``,!A@*_U+P"`!@@`?`!H```"`@!\`&#__?__ +M`(`&$``!7``0```7\_R<`I?4O`!P' +M8``,R2\0`*X)%`#."02`[0L@@`\X(!!N"P0^#A``-@X0`#AN8Q!^CE,`?!]@ +M0P``"8`(R2\`?`!H````@`!\/V!#```)``?)+P2`[0L@@`\X$!!N"P0^#A`` +M-@X0`#AN8Q!^CE,`?!]@0P``"0`!R2\`?`!@____?P!\/V!#```)@/_(+P2` +M[0L@@`\X$!!N"P0^#A"`*<@O`(*@80!\7V#@GP(`?`$A"`'^($!\`P$0``0@ +M"`+^(%!8^N!7#5#()P""@$$%?(8!^+\!``!\AD'^;P`````&."T`V`#8`-@` +M.``[`#X`V`#8`$(`V`#8`-@`8@!E`$L`3@!1`%0`7`!?`%H`C`":`%<`V`#8 +M`-@`:P!T`(``@P".`)0`D0!W`)<`>@!]`)T`H`#8`-@`V`#8`-@`V`#8`-@` +M:`#8`-@`V`#8`-@`V`#8`*,`V`#8`-@`V`#8`-@`V`#8`-@`V`"L`+<`L0"T +M`+H`J0"]`,``Q`#8`*8`Q@#)`,P`SP#8`-@`V`#2`-@`U0`````P[B^`I0,H +M`7K@5\$L`"`"_A]@@*,#*`1ZX%>",L@G`$;++Z`I`"`#_A]@(`K,+P":!F"` +M+\@GH%#++P":!F``+L@G`00`"""GRR\`FB9@`"S()X";`R@!>N!7@0$`(`": +M`R@$>N!7`BG()R`1RR\`F@9@@"?()R!0RR\`F@9@`";()R!^S"\`F@9@@"3( +M)R!CS"\`F@9@`"/()R"BRR\`F@9@@"'()Z"ORR\`F@9@`"#()X#URB\`'\@G +M(!3++P":!F"`'<@GH,W++P":!F``',@GH&W++P":!F"`&L@G("C++P":!F`` +M&<@GH%+++P":!F"`%\@G`(<#*`%ZX%>!`0`@@(4#*`1ZX%>"%,@GH!_++P": +M!F``$\@G($K++P":!F"`$<@G(`3++P":!F``$,@G(`K++P":!F"`#L@G(`O+ +M+P":!F``#<@GH&#++P":!F"`"\@G`.'*+Z`*RR\`F@9@@'D#*`%ZX%>!",@G +M!/X?8`!Y`R@`!\@G`%3,+P`&R">@HLLO`)H&8(`$R"<@#@ +M4\PO`)H&8(`!R">@X\HO`)H&8```R"<@*@_@F,HO`)H&8`#ZQR<@$LLO`)H&8(#XQR>@J,HO`)H& +M8`#WQR<"_A]@>`%!$""WRB\`F@9@@/3')R##RB\`F@9@`//')R#,RB\`F@9@ +M@/'')Z"CRB\`F@9@`/#')Z"GRB\`F@9@@.[')R`CRR\`F@9@`.W')P'^'V"@ +MP,HO>`%!$`#KQR>`1LPO`.K')R`0RR\`F@9@@.C')Z#NRB\`F@9@`.?')Z#( +MRB\`F@9@@.7')Z`^S"\`F@9@`.3')Z`GRR\`F@9@@.+')Z#XRB\`F@9@`.'' +M)X#@QR<$/@X0`,/'+P!\7V+`K`(`````8DG^'V`@!V``(>AA@=_')P2`!PH```!0#(`G"@2`!Q``IBA`&/X?8!2`0!`< +MA`@(_'Y`8(!ZX5<`',=1H@@`(!S^J$%._A]@(&7\+\'^/V`RB"@(H&/\+T[^ +M'V``G@=@H-W8+P":)F```,!A`'P_8)B7`@``@``(`7X`0*!&`"``@``0``0_ +M"'*M`@`8^N!G@48`(%!ZX5>!!P`@"1,`(!!ZX5>!`0`@"0\`(``%X6<""0`@ +M+`$)"`%^`$`L`0D0`)H&8*`$`"`0_C]@H,[\+P":!F``!0`@*`$)"`C^/V`! +M?@!`*`$)$`":!F"`POPO@`$`("`!`"`!_A]@````4``!X&!V"@,@`@`!S'43!ZX5`^/\GH'KA +M5X'Q_R>)`0`@D'KA5P'U_R>`]?\GL'KA5P)]X5?`````@>K_)P#S_R<@7=@O +M`)X'8```P&$`?#]@&)<"``"```@!?@!`("8`(`"``!"@6-@O`)X'8```P&$` +M?#]@()<"``"```@!?@!`H"$`(`"``!`@9=DO`)X'8```P&$`?#]@*)<"``"` +M``@!?@!`(!T`(`"``!`@:=@O`)X'8```P&$`?#]@+)<"``"```@!?@!`H!@` +M(`"``!`@`=DO`)X'8```P&$`?#]@,)<"``"```@!?@!`(!0`(`"``!"@U.8O +M`!S'4:`GV"\`G@=@`'P_8`27`@``@``(`7X`0"`/`"``@``0`'P_8`"7`@`` +M@``(`7X`0"`,`"``@``0`'P_8"27`@``@``(`7X`0`"``!"@"``@`?[?8:`J +MV"\`G@=@(!S8+P">!V``?#]@G)<"``"```@`',=1`7X`0"`#`"``@``0$'KA +M5X'7_R<`O@]@H.(!*%/_*4`!>N=7@JG_)P"H_R<`A`8(_'Y`8)!ZX5+^/\G`=7_)T!ZX5`]O\GL'KA5X':_R>) +M`0`@H'KA5X'4_R>`\_\GP'KA5P'<_R?0>N%7`>O_)P#Q_R<$/@X0@%?'+P`` +M`&(`FJ91(`0`(``!G`'P_8(#?`@""!P`@ +M%H0("`-^`&`!>N!7`GW@5P(```""!``@H`0`(`"`0!``?%]@V,@"``!\/V"M +M!@``(%`!*`"^#V"`__\G`(0`"`%ZX%<"`P`@`'P_8*"7`@``@``(`7X`0"`# +M`"``@``0`'P_8*27`@``@``(`7X`0`"``!``!`D(#'X`8`AZX%>"`@`@`'P_ +M8*"8`@``@``(`7X`0`"``!``H@A@H"$&*``D*6``TO\G(-/_)P0@!Q`@0\_BE`@/__)P!ZZ%<,`0`@`"7H5PP#`"``O@]@`'Q?8-#(`@"@*0$H +M'_XI0(#__R<`&@A``"7@5PP#`"``O@]@`'Q?8-#(`@`@)0$H(/XI0(#__R<` +M``!0`"7H5P*`@!!!`0`@!(!`$`2@0!`%@$`0`?X(4`&`'X`&@$`0E(4!"`>: +M0!`!@$`0(?X?8`C^/V`!_E]@(!0`*`">9V`@O<!G`O[_)P";YF<"`0`@@//:+P``H&$`F^9G +M`@$`((!"VR^`^O\G#(`F"`"$``@.>N!7PJ_\+QS^`$!*_A]@()_[+P":)F"@ +MF]4_L!!H0,`("0$J0D`O@]@`'Q?8'C3`@`@ +MX``H/7XJ0(#__R=&"`$(`(9A4`!\`&#P_P``KH"`$*Z(``@`&@!HKH"`$$0$ +M`0BL@$`0100!"*V`0!`,_A]@E(!`$!,$"`@`@$90'``("`T$``B6AH`0``0` +M0)6`0!`@"$@(`(7F5P("`"`B"`@(FH"`$*`$`""8AH`0`?YF0`@("`@`!^%7 +MFH"`$$$!`"`B"`@("`@(")B`@!``?.A!``(``.*%!P@``>!G`0X`(!P`"`@2 +M!``(#'K@9P(#`"``O@]@`'Q?8'C3`@"@Q@`H:'XJ0(#__R97 +M`J8)8*($`"`4_C]@`'P(0-@!```$_C]@``1!4"`3Z"\"_G]@!/X)0!#^/V`` +M!$%0H!#H+P+^?V`D!`D(!/X_8"1^X*<`<@A`K'X`0``$05"@#.@O`OY_8`L$ +M"`@:>N!7`@,`(!P`"`@$_C]@2'X`0``$05`@".@O`OY_8.*%)P@`@^!G@0,` +M("0$"0@`!$%0)'[@IP!R"$"P?@!`(`/H+P+^?V`F""D(`(/@9X$'`"`H``D( +M``1!4*#_YR\!_G]@#OKH5XH'`"`!_@A``!`@&@/^"(```$A"'00)"$!ZX&!7 +M(T(```(#`"``'`=@#/X_8""E^B\`!$%0(`$`(/"))@CNB28(``H?"$2Q`@"2 +M_T9```(`0/Z!C1`0?@A``OX_8"!<^B\`AF%0)GX(0`+^/V#^_TU`H%GZ+P"& +M85`U?@A``OX_8`+^1D`@5_HO`(9A4`]^"$`"_C]@CO]&0*!4^B\`AF%0;7X( +M0`+^/V`4_D9`(%+Z+P"&85`)_@B`@/X_8`!_1T"@9OHO`(9A4`'^'V``G?T=`($SZ+P"&85``2OHG``'@9X(#`""@`0`@_Y$?&`!\'V#G +M#P````"?$'RV`@``@`\X`7K@5X'[_R<">N!7`H`/.`#[_R<$/@X0`"3&+Q@$ +M(`@*^N!7`0@`(``$/PB:K0(`!/K@5X(!`"`%!"`((`8`(`3^(&@`@^!G@0,` +M(`!\7V!XTP(``'P_8%@$``"@2P`H`+X/8(#__R<%!"`(^_\@8"!&QB<%`D`0 +M!#X.$(`!G`@```"(!`"`&_A]@`!P'8``$ +M`$`+@$80H#_L+P":!F`@B"8(`/P&0``"````@^!GW!T`$($WQB<<@$8(,`0A +M"-@#0!`Q!"$(^_\@8-D#0!`R""$(H#/&)]H#@!`$/@X0``C&+QP`(`@``*!A +M,(0`"`Q^0&`(>N%7`!S'40("`"#P?@!@@'K@5RH!`"`"_A]@`!P'8!A^0$`Q +MA``(`7K@9P)]X&<"````(@$`(`;^'V``'`=@``0`0`N`1A"@BNPO`)H&8""( +M)@@`_`9```(```"#X&?<'0`0`2/&)QR`1@@P!"$(V`-`$#$$(0C[_R!@V0-` +M$#(((0@@'\8GV@.`$`0^#A"`[L4O_/O@9P$#`"``O@]@`'Q?8+32`@"@&P`H +M,?X_8(#__R?`>^%G`0,`(`"^#V``?%]@M-("`*`7`"@R_C]@@/__)P)^08`` +M`B%H(!+&)P`"0!`$/@X0@.C%+P``H&$`@L!A(*/Z+_[^'V"`&,@O`!WG9X$+ +M`"`">N!7`'S?852U`@`"!0`@```?"("^`@``FB9@`7X`0*"/QR\L_E]@``0' +M"``!X&!!<8GH)GO+P":!F"`!.$O +M``$`(`)ZX%>"`L8G`'P?8$BS`@"`P.@O@`#&)P!\'V!(LP(`@+[H)P0^#A`@ +MU,4O`(*@8`!\WV'___\``)QN8``)V`(@`8(`![@00%^QT$@_J9! +M!GKG5P;7Q2>`^?\G!#X.$""FQ2\8_I]A`(*`8`5^0(``?']@9,8"``"$(4"< +M?N"G`'P?832;`@``A$$`!(!@"`!\_V``6`(`"("@"`R`P`@```!0$``.$`'^ +M'V`4``X0`'($0!#^($``B(-`(*3H+P`,XV```>!G`AP`**#:Q2<8_I]A!#X. +M$*";Q2\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'$!@"_X?8`+^((`"?D&` +M`OYA@"!!^B\"?H*`,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@(#WZ+P"*HE"P +M@"8(U(!&"+2`9@@``($("OX?8*`Y^B\!_K]@4(`F","`1@A4@&8(``"!"`K^ +M'V`@-OHO`OZ_8*R`)@B\@$8(7(!F"`!\'V```"```$"`"`K^'V"@,?HO`_Z_ +M8*"?\2\```!0H)[Q+P+^'V"@G?$O`?X?8(```"B`J\4G!#X.$*![Q2\%_A]@ +MH"_K+P""(%````!0("[K+P""(%`!_A]@H"SK+P""(%`@Q_(O!/X?F`"<_B\` +MHL4G!#X.$"!YQ2\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'`!@`GY`@`!\ +M'V`LG`(```4`$`0+`!`._A]@`OX@@`+^88"@'/HO`GZ"@##^OX&@@"8(T(!& +M"*2`9@@``($("OX?8*`8^B\`BJ)0L(`F"-2`1@BT@&8(``"!"`K^'V`@%?HO +M`?Z_8%"`)@C`@$8(5(!F"```@0@*_A]@H!'Z+P+^OV"L@"8(O(!&"%R`9@@` +M?!]@```@``!`@`@*_A]@(`WZ+P/^OV`@>_$O````4"!Z\2\"_A]@('GQ+P'^ +M'V``W/\O`(?%)P0^#A"@7,4O'/Z?82#\!2@``,!A``'@9P*^#V!"W_\O:/X_ +M8``2]"\`Y`4H@*#_+P#)TR\@[P`H``"@80#N`"@!>N!7@@4`(```'PC@G@(` +M!GK@5X(#`"```!\(@-,"```!X&>"`0`@`(0&"``!X&>"`0`@`+X/8*#3_R^` +M_C]@@)3_+P#O`"@``>!G`KX/8,+0_R^-_C]@@.D`*``!X&<"O@]@0L[_+Y/^ +M/V``D?\O(.$`*`/^'V"`?>@O'_X_8*"SZ"_\_TU```'@9P*^#V#"R/\OJ_X_ +M8*`C^R\`'`=@`+X/8"#&_R^P_C]@H'O%)QS^GV%D?HY3$``.$!0"#A`8!`X0 +M'`8.$"`(#A`D"@X0*`P.$"P.#A`P$`X0-!(.$#@4#A`\%@X00!@.$$0:#A!( +M-@X03#X.$%!R#A!4=@X06'@.$`*@GPE<&`X0`Z"?"6`8#A``?+]A____``": +M;F``&H]@`)HO8`;^'V`"_B"```1!4`+^88`"?H*`H-CY+RS^OV"@JO\O9'YN +M0Q``#@@4`"X(&`!."!P`;@@@`(X()`"N""@`S@@L`.X(,``."30`+@DX`$X) +M/`!N"40`K@E0`(X)3`#N"P%^YJ]4`(X)`/+\9Q*8'Q)<`(X)6`".#P*8'Q)@ +M`(X)2`!N"P.8'Q)``(X)(`$/.&1^CD,$/@X0(!W%+QS^GV&``0`@`+X/8(7^ +M/V``H/\O`.GR+P`!X&!G(J/@+P*:!F`!_J9! +M!?KF5P7[_R<@1/(O_/\-0/R!#0@``>!G`@P`(````%`@1_$O_/\M0/R!#0@` +M`>!G`@L`(`+^'V`@+/0O_/\M0/R!#0@``>!G@0P`((">YB\``>!G@@D`(`!\ +M/V``^@``(.;S+P7^'V"`"``@`)#P+P#G_R<`7^`O`.;_)P#!X"\``>!G@>3_ +M)X#B_R<`F.`O``'@9X'B_R<`O@]@(.'_)Y7^/V``O@]@((#_+['^/V`&_A]@ +MH!ST+_S_+4#\@0T(``'@9X$(`"``?-]A#+P"````!P@``>!G`=K_)P!\/V#X +MJ`(``($`"`!\OV$0O`(``7X`>`"!`!"@._(O`(`&"`!^!Q"@U/\G`/X&$*`M +M\B_\_PU`@-+_)Z`HQ2<<_I]A9'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H. +M$"@,#A`L#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02#8.$$P^#A!0<@X0 +M5'8.$%AX#A`"H)\)7!@.$`.@GPE@&`X0`'R_8?___P``FFY@`!J/8`":+V`& +M_A]@`OX@@``$05`"_F&``GZ"@*"%^2\A_K]@H%?_+V1^;D,0``X(%``N"!@` +M3@@<`&X((`".""0`K@@H`,X(+`#N"#``#@DT`"X).`!."3P`;@E$`*X)4`". +M"4P`[@L!?N:O5`"."0#R_&<2F!\27`"."5@`C@\"F!\28`"."4@`;@L#F!\2 +M0`"."2`!#SAD?HY#<'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H.$"@,#A`L +M#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02!P.$$P>#A!0(`X05#8.$%@^ +M#A!<<@X08'8.$&1X#A`"H)\):!@.$`.@GPEL&`X0`'S?80@`(`@`?/]A____ +M``C_'YH`GFY@`!Z/8`">+V`&_A]@`OX@@``$05`"_F&``GZ"@*!A^2\`BJ)0 +M,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@H%WY+P"*HE"P@"8(U(!&"+2`9@@` +M`($("OX?8"!:^2\!_K]@4(`F","`1@A4@&8(``"!"`K^'V"@5ODO`OZ_8*R` +M)@B\@$8(7(!F"!)^!X``0(`("OX?8*!2^2\#_K]@H,#P+P```%"@O_`O`OX? +M8*"^\"\!_A]@('/%+P-^"$```*!AH'+%+P-^*$"@<,4O`!P'8`'ZYF=P?FY# +M@08`(`1ZX&!G"`````%]X&<"````@0,`(`!\'V``@`$`(&O%+QA^)T`! +M_A]@H&G%+SE^)T``%O\O$``."!0`+@@8`$X('`!N""``C@@D`*X(*`#.""P` +M[@@P``X)-``N"3@`3@D\`&X)1`"N"4@`S@E,`.X)4``."EP`C@E8`.X+`7[F +MKV``C@D`\OQG$I@?$F@`C@ED`(X/`I@?$FP`C@E4`&X+`Y@?$D``C@D@`0\X +M<'Z.0V1^CE,0``X0%`(.$!@$#A``X0`J"?"5P8 +M#A`#H)\)8!@.$`!\OV'___\``)IN8``:CV``FB]@!OX?8`+^((``!$%0`OYA +M@`)^@H`@(ODO%OZ_8"#T_B]D?FY#$``."!0`+@@8`$X('`!N""``C@@D`*X( +M*`#.""P`[@@P``X)-``N"3@`3@D\`&X)1`"N"5``C@E,`.X+`7[FKU0`C@D` +M\OQG$I@?$EP`C@E8`(X/`I@?$F``C@E(`&X+`Y@?$D``C@D@`0\X9'Z.0P`` +M'PC!G"OZ@B0$3`"``!!\( +MW.`"``1ZX%<+_"!@`/S__RL$`"`+@@%0````4"`8\R_X_RU`^($M"/R!#0@` +M`@!0`"``0```!Q#:_A]@`/GX+P'ZYE>."``@```_"-#A`@`@;`(H`)H&8-O^ +M'V`@]?@O`)HF8`!\/V"TEP(``(``"``:`$``@``0`'P_8+"7`@``@``(`7X` +M0`"``!`@"P`@`/X'$`"@`&````%``?KF5P``!Q`."``@`)H&8*!@`B@!_C]@ +MV_X?8*#I^"\`FB9@`'P_8*R7`@``@``(`!H`0`"``!``?#]@J)<"``"```@! +M?@!``(``$"!CQ"P$H\/]-0```H&&-_A]@(-7X+P":)F#P@2T( +MH-/X+XW^'V`"^N97@0\`(`!(QB\``"!@H-#X+XW^'V``1L8O`GK@5P$$`"`` +M.-XO`WK@5X$"`"``'>=G@@$`(`#JSB\!>N!7`@$`("`(`"````!0`'R_85RM +M`@!L@08(``'@9X$"`""-_A]@(,;X+R'^)T`@,``H;($&"(W^'V"@P_@O^OX_ +M0`#X_R?P@0T("GX`B"!!Q"!"@`@<($F"""`(`@"A"`(`(/@9P(#`"!X@28(``!?"*S3`@`` +M`B%0`(/A5PX*`"``!#\(`@#X +M_PU``!PG8"`9`2@0_D9````?",RL`@"`=?DO5H@G"`K^((```N"G^/,-$/C_ +M#4``'"=@H!,!*`":1F`<_`80NG@``(#&VB<$/@X0(,W#+S3^GV&B_A^"``#` +M80">YU'\GPT0BOX?8*!]^"\??BA`#7KG5P/^/V*",@`@`(K$+R#OQ2\``,!A +M``"@80=ZX%<"_>97!@```((<`""*_A]@H';X+RM^*$``?#]@V)<"``"```@` +M?+]A7*T"``%^`$``@``0`'P_8`SX`@``@``(`7X`0`"``!`&A08(``'@9P(# +M`"!VA08(`7X`0':!1A!WA08(`7X`0'>!1A``"!\(KJT"``!\_V%HW@(`"GX` +M@/B!#1#X_PU`$/XG0*#V`"@`GD=@`(`'"!"`!Q`$@`<(H-3Z+Q2`!Q`@J=HO +M!?X?8*#_TB\8_@B`=X4F"`7ZX%<,%@`@!H4&"``!X&>"%``@`?X?8/"!#1!V +MA08(]8--$/2!31`@L>,O\/\-0(`0`""*_A]@(%KX+U-^*$`%^N97`OWF5P@` +M```"_>97"@````$#`"``O@]@`'Q?8"3(`@"@P_TO5WXH0(#__R<'^N97`@,` +M(`"^#V``?%]@),@"`*"__2]9?BA`@/__)Z"4VB\#_A]@"OKF5P+]YE<(```` +M`@(`(`CZYEN!7`OWF5P8````"`0`@@!(`*``.`"",_A]@H$/X+\+^/X``?#]@U)<"``"` +M``@!?@!`(+7%+P"``!```"!@(#_X+XK^'V`*^N97`OWF5P4````"_>97"``` +M``+]YE<)`````0,`(`"^#V``?%]@),@"`*"G_2^(?BA`@/__)Z"#_R\`'`=@ +M`'P_8%RM`@!WGT`0````4':!0!"@T-(O&/X(@(!9`"`$/@X0H'W#+RS^GV$` +M?+]A7*T"`&B!!@CT_C]"#```"``B`$`5!``(``'@9P``@`*_B"``(#@I_CS#1"*_A]@H"7X +M+R3^*$#X_PU`$/XG0""S`"@`GD=@5@@("!#^)T`*?@"`^($-$/C_#4"@KP`H +M`()`8(`!`"!$@08(`7X`0$2!!A"@8MHO!?X?8("2Q2\#>N!7@@0`((^%!@@! +M?@!```X@&`'ZX%>/@480C`$`((^=1A"@DMHO!?X?8("*Q2\%>N!7A0T`(`"+ +MQ2\``>!GH@P`(&B!!@A(@68(`(?A9X$*`"!P@28(((`@"`*$(`@`@^!G`@,` +M('B!)@@``%\(K-,"```"(5``@^%7C@@`(``$/PARK0(`"/K@9P(#`"``!#\( +M6)\"``'ZX%<"`@`@@```(&B!!@@`!-0O@```(("#X"]HG080<)T&$""#PRN!7]/X_0B$F +M`""*_A]@(/WW+W3^*$!H@08(<('&"0P```@`(B!`````4'"!!A`.A``(``'@ +M9X($`""@,^HO;($&"``V_R\`?#]@!-4"``B!``CP@0T0(`,`(`R!``@`?#]@ +M:-X"`!"```CP@0T0%(``"/2!#1"`9,4O!GK@5X$!`"``8\4O!WK@5X(1`""` +M8<4O"WK@5P$0`"`@,=HO!?X?8"!AQ2\`(`A2`WK@5P!\_V%HW@(`P6/:+P7^ +M'V#\H0T0H-3X+P`!G@0$`((#7TR\```!0:($&$*!7PRN!7`'R_86C>`@`""P`@`?X?8""` +M1A``?%]@6*T"`%`(@0E."`$($'Z&@0`8`&CX@0T03`B!"4H(`0@0?H:!`!@` +M:/R!#1!6""$(7@A!"/C_#4`!_G]@('37+P3^GV``I^0O@`4`((#5PR^@!0`H +M``#`80```%`<_`805W@``"#KUB\@@$80`./N+Z#3PR\`'`=@H$'#)R#^GV$` +M?!]@:-X"``""(%`@R\0G)/Y?8`0^#A``!L,O````8@""X&$@#``@`)JF403^ +M)H``?%]@:-X"``"$P$$$``<(_WO@5P$'`"```@%`H$P`*``@*&```>!G@@0` +M(`P`!P@``>!G`0,`((C^'V"@LOPR<`\_\G!#X.$`#[PB\``,!A`OX_8@!\'V($U`(``'Q?8FC>`@"@ +M!P`@`)JF403^)H``I`!`!```"/][X%>!`P`@``+I00">!V`@.P`H`"`H8`)Z +MX%`@`@.O,OZ/\-0(S^'V"@E/_)G`@7A9R*` +M#S@"``!0``'@9X(!`"``!>%G`H?A9P$!`"`@@`\X`?X?8""`#S@"_A]@!#X. +M$*"9PB\```!A`(+`8"#O_R\`!*%@``'@8`(&`"````!0`/X"$*`&`"`$@`(0 +M`!`$8*`!`"``#"-@``P#8``0)&`@!``H`(I"8``"`"`!^N-7`?O_)P+ZXU>! +M^_\G(+O")P".`V``@&`(``"`"`0`H`@$@``(``;"4`"``E``!^)7!7P`0/__ +M__\`#`$0((`/.`0``1`$/@X0H(G"+QS^GV$``*!A(%GH+_S_#4`@6.@O^/\- +M0/R!#0CX@2T(`(``4`"!YE>-_/\GH,+")QS^GV$`!(`0$'Y!B`($@!``?']@ +M6*T"``6$00@(?H&`!(1!"``(07@$!(`0!X1!"`A^@8`&A$$(``A!>`8$@!`) +MA$$("'Z!@`B$00@`"$%X"`2`$*`Q`"``#,-0`7YC8`"&X4`$CF```'R_8'BX +M`@``A&%X`(YA&`"&84``BF%`!(D!"02.8```?)]@>+H"``"$87@(_F&0`(YA +M&`"&84``B&%`!(EA"`"0`7D`"&`(`)!A0``&@!``D"$9!/X#00208```DF%X +M`(YA&`"&84``BF%`!(E!"0208```DF%X"/YAD`"&84``B&%`!(EA"`"4`7D" +M"&`(`)!A0`(&@!``D"$9"/X#00208```DF%X`(YA&`"&84``BF%`!(E!"020 +M8```DF%X"/YAD`"&84``B&%`!(EA"`"4`7D$"&`(`)!A0`0&@!``D"$9#/X# +M00208```DF%X`(YA&`"&84``BF%`!(E!"0208```DF%X"/YAD`"&84``B&%` +M!(EA"`"4`7D&"&`(`)!A0`8&@!``D`$9!(Y@```&9'@`CF$8`(9A0`"*84`$ +MB:$(!(Y@```&9'@(_F&0`(9A0`"(84`$B6$(`(IA>`"$04``$$$8``Q!0`@$ +M@!``$$$8`7YC0`".P1@(>N-7"H`/.(#-_R<$?N!`H`,`(`"*HE``BL)`!`R! +M``",PT``"(,0`?Z"0``.HA@%^N)7"_S_)P@(00@`!D%``!"!&`X$@!``B$`( +M``BA>`".0A@`!(%``'Q?8'BX`@``!()`!`G""`C^@I``"*)``'R?8'BZ`@`` +MB*)`!(FB"`",PG@$"*`(`(RB0`0*@!``D,(8`HB@"`",PG@`#J,8`(JB0`"$ +MHD`$B>(("'ZCD`"*HD``B*)`!(FB"`".PG@&"*`(`(RB0`8*@!``D,(8!(B@ +M"`",PG@`#J,8`(JB0`"$HD`$B>(("'ZCD`"*HD``B*)`!(FB"`".PG@("*`( +M`(RB0`@*@!``D,(8!HB@"`",PG@`#J,8`(JB0`"$HD`$B>(("'ZCD`"*HD`` +MB*)`!(FB"`".PG@*"*`(`(RB0`H*@!``D,(8"(B@"`",PG@`#J,8`(JB0`"$ +MHD`$B>(("'ZCD`"*HD``B*)`!(FB"`".PG@,"*`(`(RB0`P*@!``D,(8"HB@ +M"`",PG@`#J,8`(JB0`"$0D`$":$("'Y#D``$04``"$%`!`E!"``*@7@."$`( +M``1"0`X$@!``$($8#(A`"``(07@``H$8`7Y!8`]^08``"(%X!`A`"``(04`$ +M!(`0`!"!&`Z(0`@"!D`0``A!>``"@1@!?D%@#WY!@``(@7@&"$`(``B!0`8( +M@!``$$(8``*A&`%^0F`/?D&```J!>`@(0`@`"(%`"`B`$``00A@``J$8`7Y" +M8`]^08``"H%X"@A`"``(@4`*"(`0`!!"&``"H1@!?D)@#WY!@``*@7@,"$`( +M``B!0`P(@!``$$(8``*A&`%^0F`/?D&```J!>`X(0`@`!$)`#@2`$`C^09`` +M!$`0?WY!8"!^06@!!$`0`(@@"`X(0`@`A"!X`((@&""`#S@#`D`0!#X.$(#P +MP2\``,!A`(*@82!0PR\$```(``#'"1#^((`0?@>(``(`0"!-PR\`FB9@$/X@ +M@``0!Q@``@!`H$K#+PK^)H"@$L(G`((`8``^#A``Y,$O`_K@9T/^OX$!`P`@ +M`+X/8`!\7V"TT@(`H`[\+P7^)D"`__\G`'OA5PD#`"``O@]@`'Q?8+32`@"@ +M"OPO!_XF0(#__R<`?>%7``$```L#`"``O@]@`'Q?8+32`@`@!OPO"/XF0(#_ +M_R<`>N%7"@(`(`"&06`@B>HO`OY_8`"VPR<`$($8`(9!8``(8F`@[>HO`?Z? +M8`"SPR<``!\(@-,"``!ZX%!&``@&(`A"`"#X&<0@,$(@A4`(``'XU?__^=!00<`(`"$`A`4 +M@"$(%`(#$!"`@0@0B``0`(`B"`"#X5<"`P`@&``B"`"#X&>!```@&`H"$!"` +M(0@`@@(00`"-"`"`(0@\`.T((/X@0``/XE<`@@$0!0(`(``.(E#\_X!@.``M +M"``"@D```"((`(/@9P$$`"`0@@$0%(`@"!2"`1`0A@`0```B"!2&`!"@`@`@ +M&(@!$!"&`1`4A@$0&(@!$``&`A`@Y_\G``QC8`'^ID$@^N97!/ZB0([8_R%```@.`"-"```8@@`A^%G`0D`(`'^YT$`AD%@```A""#ZX%<@ +M_B!0#9H@0`Z:)F``'>=G@0$`(`"CX%<&`@`@``$`(`"CX%>.```@`((@8A`` +M00@`!^%7`OC_)P'^ID$@^N97!'Z"0`[R_R<``*`?`)_G9T(!`"``(@@0`'X( +M$""GP2<`G@=@!'Z.4P`V#A``.&YC$(`-$!"$;0@#_@%@`(!`$`+^`9```$$0 +M`!!N"R"`#S@$?HY#!#X.$`!UP2^D_O^!``&@80""P&$"_>97`0````+]YE<" +M`````0,`(`"^#V``?%]@1-("`*"7^R_)_B=`@/__)R`Z^R\`F@9@`/KF5P'^ +MOV$!FJ91`)OF9R$G]2\!'`=@`'S?89"^`@```0<(`WK@5P$!`"``@>97`00` +M(`!\'V`A`0``H![V+]3^)T``&P<0H/;Z+P":!F``B\$G`)OF9P**P2<`"_4O +M`(G!)P0^#A``6,$O_'KA9X$#`"``?%]@!,D"``!\/V"'`0``H(3[+P"^#V"` +M__\G`(1@"`9^08``!D`0`81@""!^06@!!D`0`(9A4`(&0!`#!$`0`H1`"`0$ +M0!`#A$`(!01`$`2$0`@&!$`0!80@""!XP2<'`D`0!#X.$(!)P2_\>N%G`0,` +M(`"^#V``?%]@!,D"`*!V^R_=_C]`@/__)P"$8`@`!D`0`81@"`$&0!`"A"`( +M`@)`$`9^(8"@;L$G`P)`$`0^#A``2L$O`(*@80$$(`@(^N!7``0!8JP%`"`, +M``!0"/[@40".QQD*?@!``OXF0*!$]B\`'$=@,OX?8`"`1A`!GD80`GX'0*!H +MP2<``$@0(`,`(`"(0`@`!(!!`'Y&$`%^84``D$$8`(:`$`-ZX6>"_/\G`(`/ +M.`0^#A`@.\$O``"`8`""`&``!.%A`GKB5P&$P`DB`@`@`(8!8@AZYU<)?-]A +M"`````)^IT$`GB=@H#3V+P":1F`!G$<0(%K!)P`:2!`$/@X0@"?!+_SZX6_C^:$((-$```H&$<`,`)``0!8D/^'V`@U_4O +M!_XH0"#RYR\`F@9@$/X-0`'^/V"@(_LO`"!(8`T$!P@,?N=!$8!-$`P$!P@2 +M@$T0"X0&"`+\9@#B`0``)WX`0/Q_`&``A^%G'(!&""$(`"``#B`8$@0!"`QZ +MX&<"`P`@`+X/8`!\7V!XTP(`(#C[+Q;^*$"`__\G`((!0``.(!@."`$(``8` +M0"`.`"`.`($0%`0!"``!X& +M!V"@$/\O``1!4#$$!P@(?@!HH-G")S$`1Q`$/@X0``G!+P!\OV*4M`(````` +M8@"$``@`@N!A_'Z@80!^7Q#3K`(``'S?85BM`@`0_@!`(!/K+PI^)T`!>N!7 +M`*(H4J($`""C_M^"#P0H"`"J2F(0!`@(J((*$*R`BA`@E>LOM/Y*0+``"1`6 +M!`@(!'K@9R$L`"`@?B!@`(/@9P-^`&"B`P`@`*I*8@"^#V``?%]@V,@"`*`- +M^R^!?BM`@/__)P%ZX%>""0`@#P0H"`($"`B,`XD0D`&)$!`$"`@@B>LOCG]) +M0``08!H#!`@(`@0H"*"&ZR^2?TE``!"`&@"F"6"@^O`O`((@4```0&(@#0`@ +M``!@8@)ZX%^LOCG])0``08!H0!`@(#P0H""!YZR^2?TE``!``&*#M +M\"\`@B!0``!`8@``@&*`^N97`@8`((#[PB\">N!7@00`(!#^!T`@Z^HO"GXG +M0`%ZX%<"`@`@`":?$'JQ`@``*)\0?+$"``CZYE<"_>97@`````+]YE?0```` +M@A<`(!#^!T"@X^HO"GXG0`%ZX%<"%0`@`/#"+P)ZX%>!$P`@`"0?$`3X`@`` +M$@`@`(/@9Q`$2`H!`P`@#P0H"``D"6"@8^LO``1!4"`'`"``$``8@+'4+P%Z +MX%<`)$E`H@4`(`\$*`@$?$$`U,D"```D*6(`#@$8$`1($*!N!7@0<`(!#^ +M!T"@PNHO"GXG0`%ZX%<"!0`@`'P?8@3X`@``)`@0`'P?8`D!```@5O4O`"0I +M8```*`B$HPH0B(,*$!#^!T`@N^HO"GXG0`%ZX%>"Q\`G@,?"+P)ZX%N%7@CL`(".$!P@$>N!7@2D`(`"^#V``?%]@!,D" +M`*"M^B\[?BA`@/__)R.$1P@(>N%7`0,`(`"^#V``?%]@!,D"`""I^B\-?BA` +M@/__)R2$1P@`!>%G`0,`(`"^#V``?%]@!,D"`*"D^B_\_C]`@/__)P2$0`@# +M?@"``(``0"0$``@??F%@#WX`8`"!X5>)H,`GX']!8`%^`$``!`!H!(!`$""I +M[R\`G@=@(H1'"`":!F`@$O\O`)XG8`C^!T``'"=@('CU+Q#^7V``F<`G(X0' +M"`QZX%!V```>!G`0$`(*#`\B\( +M!`((`(`'"`C^)T``$&`8`!P'8"`7_B\8_D=`(H1G"`":!F``'"=@H"[_+P"> +M1V``A\`GH(KO+P">!V`DA`<(`7K@9X$$`"``G@=@`!PG8"!<]2\#_E]@"/X' +M0`-^)T`@6O4O#?Y?8``'`"```>!G`0,`(`"^#V``?%]@!,D"`"!\^B]-?BA` +M@/__)S$$0@@`'`=@"/XG0`-^06`@&.HO`)YG8"*$1P@`F@9@(/S^+P">)V"` +M=L`G"'KA5P'(_R<,>N%7@=O_)P"^#V``?%]@!,D"`*!Q^B\D_C^`@/__)P`` +M8`@!_B!0`(1!0`"$(&```@`0((`/.````%``?#]@`!`P````'Q#LK`(`((`/ +M.`"``!`$/@X0`#G`+P!\'V"HL`(``'P_8``"``"``>,O#7K@5P'^'V`@8L`G +M`0``4`0^#A"`1\`O@/Y_0@``0&(`@B!B``0!8@"&H6&@`,$O``CB80``P&$@ +MP\0O"/X?8`!\?V"DLP(`D(E!"`!\GV``B`(```@A0"'^'V``"(%`"'KI5P`` +M0A"I`0`@&OZ?F@!ZZ5<)`P`@`+X/8`!\7V#0R`(`H%7Z+V!^*D"`__\G`/KF +M5PP!`"``I^97#`,`(`"^#V``?%]@T,@"`*!0^B]A?BI`@/__)P"B!D``)^!7 +M#`,`(`"^#V``?%]@T,@"`"!,^B]B?BI`@/__)P```%``I^97`H"`$$$!`"`$ +M@$`0!)I`$`+^'V`%@$`0`7X)4`&`'X`&@$`0E(4!"`>B0!`!@$`0(?X?8`C^ +M/V`"_E]@H#KY+P">9V``(`A@`)HF8``$05"@G>$O`OY_8"#AP"\`'`=@@$+` +M)P`$`@#0$0``!#X.$`"=OR^`.OLO``'@9P(?^B^@.OLO`?X?8``AXB^`QK\G +M!#X.$("8OR\`?>!7`/("`(D:^B^````H`,._)P0^#A``E;\O@`,`*(`A`"@` +M`>!G`KX/8,(=^B]0_C]@@"$`*`"^OR<$/@X0`)"_+P!\'V``\P(`@'P`$`#W +M`@"$?``0`)8"`(A\`!#@G@(`C'P`$.B8`@``?!]@`/8"`!!\`!!@GP(`%'P` +M$$2@`@``(@(H`'._+P`MZ2\`?!]@RP```(`_Z2\`?!]@Q``````LZ2\`?!]@ +MU``````XZ2\`?!]@[P```(`_Z2\`?!]@"@$``(`PZ2\`?!]@)0$``(`JZ2^` +MX0$H@`,"*"#8Z"\!_A]@(-?H+P```%`@UN@O`OX?8`!\/V``!```(&#N+P`` +M`%`!_A]@H%[N+___/V"@.NXO`?X?8`!\/V`0)P``H%ON+P;^'V"`G[\G!#X. +M$(!QOR^`U@$HH)V_)P```%````!0H,CY)P""(%`$/@X0@'*_+Z`L`2A]_M]A +M`%`!*("C`2B`I]DO()_K+P'^'V`@GNLO`OX?8""=ZR\```!0``'M+P`Q`2@` +M70$H@)@!*`"F`2@``>!G`KX/8$+O^2^"_C]@`OX?8*!*[B\(?B>`!?X?8"!) +M[B\)?B>`("SM+P":IE$`%NTO`!KM+X`!`""@(NTO`)H&8`'^ID$%^N97A?W_ +M)P#@["\`_.PO`(F_)P0^#A``6;\O``0`*`-ZX%?!A+\G#OX?8`%ZX%N!7`@,`(/Z)#0@(?@"0I7K@5P3^'V`!?!]@`0```*!\OR<4 +M_I]A!#X.$"`^OR\<_I]A``#`80```%#^@8T0H`,`(`":IE$`FB9`_HE-"`#\ +M`$`@^@(```2`$`'^ID$`&^=7#@,`(`":!F`@%``H_O\M0`%ZX%>!^?\G@``` +M(`'^'V`@;[\G'/Z?800^#A"@,[\O!OX?8`!\OV&TW@(``(`&$`!\_V&(O0(` +M`(`'"`!\WV$@^@(```!`0``N!7`@(`("#J_R\` +M@`<(`7K@5P$!`""@4;\G`(`&$$)^!T"@;0`H7_X_8$`()P@``^!7!?X?8`%\ +M'V`!````@/K_)P0^#A`@'+\O%/Z?80``X&``@@!A``B"4````%#\@0T0`(JB +M4`""(%"@50`H``1!4*!<`"@!_A]@````4`'^/V"@4@`H``1!4*!9`"@!_A]@ +M`?X?8`'^/V"@3P`H``1!4*!6`"@"_A]@````4`'^/V"@3``H``1!4*!3`"@! +M_A]@````4`'^/V"@20`H`?Y?8*!0`"@!_A]@`?X?8`'^/V"@1@`H`?Y?8*!- +M`"@"_A]@````4`'^/V"@0P`H`?Y?8*!*`"@!_A]@````4`'^/V"@0``H`?Y? +M8*!'`"@!_A]@`?X?8`'^/V"@/0`H`?Y?8*!$`"@"_A]@````4`'^/V"@.@`H +M`?Y?8*!!`"@!_A]@````4`'^/V"@-P`H``1!4*`^`"@!_A]@`?X?8`'^/V"@ +M-``H``1!4*`[`"@"_A]@H`D`(`?^WV"`,0`H(#D`*`'^'V``C`.(`7Z`8``` +M`%`!_C]@("X`*``(0F`@-0`H`?X?8`'^'V`!_C]@("L`*``(0F`@,@`H`OX? +M8/]_PT``>N-7````4`'^/V`J]?\G``A"8``F`"B@+0`H`?X?8````%`!_C]@ +MH",`*``$05`@)P`H_/\-0/R!#0@``>!G(AP`(`/^'V"@)P`H`?X?8`'^'V`! +M_C]@H!T`*``$05"@)``H`OX?8"`,`"`/_I]@@!H`*"`B`"@!_A]@````4`'^ +M/V`@&``H``1!4*`;`"C\_PU``(H"0``0(!C\@0T(`!``&``"H&B@&P`H`?X? +M8`'^'V`!_C]@H!$`*``$05"@&``H`OX?8/]_@D``>N)7````4`'^/V"J\O\G +M``1!4(`,`"@@%``H`?X?8````%``@B!0(`H`*``$05`@$0`H`?X?8`'^'V`` +M@B!0(`<`*``$05`@#@`H`OX?8``*A!`!_A]@(`B_)Q3^GV$`@"`(`?K@9Q[^ +M(&`"A"`8`8(@4``"`!``@`\X`'Q_8$``,```@B!``(`@:`)^`8```@!H%WX` +M8""`#S@`@`$0`'P_8$``,```@"`(!/X@B`'^(&`@@`\X``(`$`1^CE,`?@X4 +M/W[@IP!^#A0@`@`@`_X\B`!`#@@!?@!````.%`!`#@@`@>!7#?W_)R"`#S@$ +M?HY#``!`8````%`@`P`@``B"4``(8D`$!F$``7Z"0`"``7@`$``8`(G@5PZ` +M#S@`_/\G!#X.$`"NOB\`#0`H`((@4`!^'Q!XWP(``'X?$'S?`@``?!]@I+," +M`)(#@!"0`X`0E0-`%)8#0!0``E\4;-\"```"7Q1MWP(```(?%'3?`@```A\4 +M<-\"`#1_`$``?+]A`/8"`"#7[B\H@`80H,R^)RR`!A`$/@X0(**^+P```%`` +M?+]A```@``R`!A0`_@84@/X?8`"`!A2`:.0O(`(`(```P&$`O@]@("+Y+X_^ +M/T``P`8(`7K@9X("`"``9.0O`!P`4`%ZX%>._/\G@/K_)P!\?V!$U0(``/]! +M0`""(%``P`8(`7K@9P$#`"`$P`8(!/X@0````1`:^N!7!'Y!0([[_R<`A0$( +M`7K@5P']X%<<`````0(`(`"^#V"@$_DOG?X_0("VOB?__Q]@"(`&%`*)`0@4 +M_R%````?$-"8`@``?!]@U)@"`"`WP"\%_E]@`+&^)P0^#A`@@;XO`?Y?8`!\ +M/V`XOP(`(#;A+^#_`$```>!G@:J^)P"^#V``?%]@M-("`*"K^"]R_C]@@/__ +M)P0^#A"@>;XO``1!4`!\/V`TO0(`H"[A+]S_`$```>!G`:.^)P!\7V#,R0(` +M`'P_8"<#``"@H_@O`+X/8(#__R>`>](G!#X.$*!SOB\`!$%0`'R_88B_`@`` +M_P9`H"7A+R#_)D```>!G`0,`(`"^#V``?%]@?-("`"";^"]I_C]@@/__)P`` +M`%```%\0@=\"`""6OB<<@080!#X.$*!FOB\`!$%0`'P_8)2T`@!<_P!`(!OA +M+[C^($```>!G`KX/8$+M^"_C_C]``'X?$"#@`@``?A\0'.`"``!^GQ`DX`(` +M`'X?$!#@`@``?A\0#.`"``!^'Q`8X`(``'X?$!3@`@``?A\0,.`"``!^'Q`L +MX`(``7Y?$'_?`@``A+XG!#X.$`!6OB^`"@`H@,S,+P!\7V"PM@(`!`$!$(@$ +M(`B)!``(``(?$$"8`@```4$0```?$*B8`@``"!\(C+T"``!]X%<@0@``H@$` +M(`$#01`9?I\06[$"```(`"@`>+XG!#X.$"!*OB\`!$%0`'P_8.2^`@`@_^`O +MW/\`0``!X&>!<[XG`+X/8`!\7V",T@(`H'3X+S;^/V"`__\G``@?"(R]`@`` +M?>!7($(``($%[B<`C^TG!#X.$(`_OB^`Q/\O@,S_+X#6_R^`N_\O@)#_+X#E +M_R\`?#]@3,8"`.3_`$"@\>`O``1!4``!X&`OV/\`0`!^7Q!YU$>`H`0")Z&$"#AA`@N!G`@(`("B`!@@````(``'@9X$!`"`` +MO@]@DOX_8``8^"\!?@A"&'['003^YT$%>NA7AKN])P!\/V`DJP(``(('0!`` +M``@``>!G``*G08'O_R!G`;X/ +M8,$-^"]T_C]@-(`&"```(`@D@`8(````"``#X%>%`@`@`+X/8"`)^"]X_C]@ +M-(`&"```(`@H@`8(````"`"!X%>-[?\G`+X/8"#L_R=\_C]@!#X.$``V#A`` +M.&YC$'Z.4X"I["\`?#]@F)@"``"``!`(_A^8@.;J+P#>ZB^`!@`H"OX?8`'^ +M/V"`)N,O"_X?8`'^/V``)>,O````4`!\/V`*`"`(`$2^+P2`[0L@@`\X$!!N +M"P!\?V`D`#```'Q?8"0!,```?#]@*`$P``!\'V``"`"``(`!$(.&'Q@```$0 +MA88?&`"``!``@`\X@'X?$,2?`@``@`\X`%@"```8```````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3868,7 +3869,7 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M````````B`(`*&(````````````````````````````````````````````` +M````````````````B`(`B&(````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3962,340 +3963,22 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````0````````````````` -M`````````````$%"1SHY+C`N,BXV``````!-87(@,C(@,C`P-0`````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````![`'H`>@!Y`'@`>`!W`'8`=@!U`'0`=`!S -M`'(`<@!Q`'``<`!O`&X`;@!M`%@`6`!7`%8`5@!5`%0`5`!3`%(`4@!1`%`` -M4`!/`$X`3@!-`$P`3`!+`$H`%@`6`!4`%``4`!,`$@`2`!$`$``0``\`#@`- -M``P`"P`*``D`"``'`!YL"1``````'G$)$``````>=@D0`````!Y["1`````` -M'H`)$0`````>A0D1`````!Z*"1$`````'H\)$0`````>E`D1`````!Z9"1$` -M````'IX)$0`````>HPD2`````!ZH"1(`````'K0)$@`````,V`,`_0$!``S< -M`P#]`0$`#.`#`/T!`0`,Y`,`_0$!``SP`P#]`@$!#/0#`/T"`0$,^`,`_0(! -M`0P*!``'`@("#`P$``<"`@(,#@0`"`("`@P0!``*`P("#!($``H#`@(,%`0` -M"0,"`@P6!``)`P("#!@$``D#`@(,'`0`"0,"`@P@!``)`P(##"0$``D#`@,, -M*`0`"`,"`PQ,!``(!`,$#%`$``<$`P0,5`0`!@0#!`Q8!``$!`,$#%P$``0$ -M`P0,8`0`"04#!0QD!``(!0,%#&@$``<%`P4,;`0`!@4#!0QP!``&!0,%#'0$ -M``,%`P8,>00`!08$!@Q]!``%!@0&#($$!0,&!`8,@P0`!`8$!@R%!``$!@0& -M#(D$``0&!`8,C00``P8$!@`````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M``````````````````````````8`````````L)@"`!```0#`F`(`$``!`-"8 -M`@`$``$`U)@"``4``0#3`P$````P`3``&``P```@````!``````````$``#___]_`0```%-Y%1R9P`````````` -M`````````````@`'```````'`/W_``````````#]_P`````````````````` -M````````'``````````````````4`!L`"P`7```````!`!X`````````/@`` -M`"4````$````````````````````````````-``Q`#$````````````(```` -M%0`0``(```!````````````````````````````````````````````````` -M`````````````````````````````````````````````0``````"@&Z`(H` -M1``X`'@`-``P`"P`+``H`"@`V@"B`(``/``T`'0`,``L`"P`*``H`"@``0($ -M``$(`@0($"!``0("```"```````````````````````````````````````` -M``````````````````````````!M96%S=7)E7W1X%]E```` -M```````*`;H`B@!$`#@`>``T`#``+``L`"@`*`#:`*(`@``\`#0`=``P`"P` -M+``H`"@`*``!`@0``0@"!`@0($````````````````````````````H````` -M```````````````````````````!`P,``0(#``,#```````````````````` -M```````````````````````````````````````````````````````````` M``````````````````````````````````````````````````0````````` +M`````````````````````$%"1SHY+C`N-2XR-P````!$96,@,3(@,C`P-P`` M```````````````````````````````````````````````````````````` -M```````````````````````````````4"`-:YP\``"@Y2&)YFK&ZJBIQ'%45 -M.`ZJ"AP'506]!`T/!0<)"P$#```````````!`0("`P0$!0<-(SK__P"`BRY% -M%PH4-VX!`0$!`0(#!0<-(P``.DQH@JB_R@<-(P``.@!077%[??__`("++JHJ -M<1Q%%U45.`ZJ"AP'506]!`H4-PT/;@4'"0L!`P$!`0```0````````$!`0(" -M`@,#!`0%!0`````````````````````````````````````````````````` -M``````````````````!@Z@`````````````````````````````````````` -M`````````````P```*7&A/B9[HWV#?^]UK'>5)%08`,"JU(^W7%>EQ/UIFBY```L -MP6!`'^/(>>VVOM1&C=EG2W+>E-28Z+!*A6N[*L7E3Q;MQ8;7FE5FE!'/BA#I -M!@2!_O"@1'BZ)>-+\Z+^7<"`B@6M/[PA2'`$\=]CP7=UKV-","`:Y0[];;], -M@108-28OP^&^HC7,B#DN5Y/R58+\1WJLR.>Z*S*5YJ#`F!G1GG^C9D1^5*L[ -M@PO*C"G'TVL\*'FGXKP=%G:M.]M69$YT'A3;D@H,;$CDN%V?;KWO0Z;$J#FD -M,3?3B_(RU4.+66ZWVHP!9+'2G.!)M-CZK`?S)<^ORH[TZ4<8$-5OB/!O2G)< -M)#CQ5\=S49%!ZI8\# -M^%F`"1<:VF4QU\:$N-##@K`I=UH1'LM[_*C6;3HLQJ7XA.Z9]HW_#=:]WK&1 -M5&!0`@/.J59]YQFU8DWF[)J/11^=B4#ZA^\5LNN.R?L+0>RS9U_]1>HCOU/W -MY):;6W7"X1P]KDQJ;%I^0?4"@T]H7%'TT33Y".*3JW-B4RH_"`R54D9EG5XP -M*#>A"@\OM0X))#8;F]\]S29.:7_-ZI\2&QV>6'0T+C8MW+*T[EO[I/9V3;=A -M?]T^7G$3EZ;UN6@``,$L0&#C'WG(MNW4OHU&9]ER2Y3>F-2PZ(5*NVO% -M*D_E[1:&Q9K79E41E(K/Z1`$!OZ!H/!X1"6Z2^.B\UW^@,`%BC^M(;QP2/$$ -M8]]WP:]U0F,@,.4:_0Z_;8%,&!0F-<,OON$UHHC,+CF35U7R_()Z1\BLNN#8M*SZ\P?/ -M)74),Z*5Z`X]9^`F`&A=EVM\NH_&W6 -M+#H``````````````````"@`*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H -M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H```````````````````@`P`````` -M`````````````````````````````````````'=A:71?;65A@!Y`'@`>`!W`'8`=@!U`'0`=`!S`'(`<@!Q -M`'``<`!O`&X`;@!M`%@`6`!7`%8`5@!5`%0`5`!3`%(`4@!1`%``4`!/`$X` -M3@!-`$P`3`!+`$H`2@!)`$@`2`!'`$8`1@!%`$0`1`!#`$(`0@!!`$``0``) -M``@`"``'`*H!``"L`0``K@$``+`!``"R`0``M`$``+8!```Q,2PL+"PI`/C_ -M"``P`$``;`"``)T```#[^P4`"@4%````````````````,@`````````````` -M```````````````````````````````````````````````````````````` -M`````&QM86-?<&]W97)?<')O8V5S)A\G'R)ATE'"0:(A@@%AX5 -M'10<$AH2&A$9$!@0&!`8$!@0&!`8````````'Q\?'Q\?'Q\?'Q\?'R$```,) -M"0L#"`@*`@<'"0$&!0SN```````````````` -M```````````````````````````````````````"`@;Z^OKZ^OS^```````` -M_/X```````````````````````````(````````````````````````````" -M`@;Z^OKZ^OS^````````_/X`\WOS=?-N\VCS8O-=TV[3:--BTUVS;K-HLV*S -M79-NDVB38I-=V)[75MN6VA;8EM=.VX[:#MB.UT;;AMH&V(;74-N0VA#8D-=(VXC:"-B(UT# -M;@-H`V(#76MN:VAK8FM=2VY+:$MB2UTK;BMH*V(K70MN"V@+8@M=\WOS=?-N -M\VCS8O-=TV[3:--BTUVS;K-HLV*S79-NDVB38I-=^W'[:_ME^V#;;]MJVV?; -M8]M=NVZ[:+MBXVGC8^->PVS#9L-BPUVC;J-HHV*C78-N@VF#9#MB.UT;;AMH -M&V(;74-N0VA#8D-=(VXC:"-B(UT#;@-H`V(#76MN:VAK8FM=2VY+:$MB2UTK -M;BMH*V(K70MN"V@+8@M=\WOS=?-N\VCS8O-=TV[3:--BTUVS<+-JLV2S7Y-O -MDVB38OM[^W7[;OMH^V3[7]MQVVO;9=M?VUF[;+MGNV&[6N-_XWCC"MQ*VLK92M>`$T9'QX`+`$" -M`````$TA(=3^+`$``````$T9(",`+`$!`````$TA)",`+`'_____`$T?("@` -M+`$"`````$T.%-3^^O\#`````$T2%-3^\/\"`````$T5&!X`+`$"`````$T1 -M%-3^!0`$`````$TD)M3^YO_]____`$TA*QH`+`'_____`$TA*QX`+`'_____ -M`$T@(-3^YO_^____`$T@(-3^YO\"`````$TA)M3^^O\"`````$TA)M3^\/\# -M````\`[T#_@0_!$($@P3$!0B%206)A"9\)X`HA"F(*HPKD2R5+9DNFR^=,*$QI3(````````````````` -M```````R/PX1`````/K_,C\A)P```````#(_*"Q#````]O\R/R@L(P```/;_ -M,C\H+`,```#V_S(_+3!#`.#_```R/RTP(P#@_P``,C\M,`,`:````#(_,3%# -M`.#_^O\R/S$Q(P#@__K_,C\Q,0,`:`#Z_S(_,C)#`.#_]/\R/S(R(P#@__3_ -M,C\R,@,`:`#Z_SY-#A$`````^O\^32@K`````.__/DDL,```X/\``#Y),3(` -M`.#_^O]*32TR`````.+_,DT.(``````&`#)-(20`````^O\R324G`````/3_ -M,CDQ,@`````,`")-#A$````````B31(4```````````````````````````` -M`````````````````````````````````"@````````````````````````` -M```````````````````````````````````````````````````````````` -M`````````````````````````````````&-M9%]W86ET7V9O7,@26YI="!487-K````FG(````````` -M!```!0```$9R86UE($AA;F1L97(```#,(``````````$```+````5%@@4V-H -M961U;&5R`````%18``````````0```0```!D:7-P871C:&5R(%1A`'!W5]C;VUP=71A=&EO;BYC``````````````#__________W-P96-T%!O=V5R0V%L:6(N8P````````````````````````$````" -M````!`````@````0````5'AC=')L+F,`````CX[ZB,+LJ:VP````L0(``+$# -M``"I_ZK_J_^H/P```````(A_+S`#,!0`,W\',`,P%``S?S\P`S`4`#-_!S`` -M`!@0,W\`,`,`&!`S?P!`!$`8$(B!='5N97(N8P!_`'X`?@!]`'P`?`![`'H` -M>@!Y`'@`>`!W`'8`=@!U`'0`\`E@&8`?-`]"```(`!@0*(0(Y`J2*J(JLBU0+6!?7X@(.?$*@0J8BJ -M,ZLSKA"SD;8#P!SU$```@0**`*``L0*Y`L(`@0"*`:`!L0*Y`<(?[X2CN./LM`"0`+0`X^RCN^^'1Y\P![A@2$ACN`'[[BC[.``M`"0`+?LX[BCA^^?1`?,`>X8$A(8[@',Y]'A^^XH^S@`+0`D`"W[..XHX?OGT0',&.X2 -M$NX8S`'1Y_OA*.XX^RT`)``M`#C[*.[[X='GS`'\`@;?[=K:!=8GUR36_]/< -MV-WK_P@@'1T;]PC.^\$&T27G._(O\0CJYN7@Z?#\^QOP+]P@U_3GS?;+\>K> -M!]H.]`T8&"(M`B[3$\+WV_H&%QTD%PH,W1++)N`M`!H1_A7W'0HF(QDI\1[. -M%=,;^2(7%A;U"-H/X"8$*RL/.O0O_A -M%^7YZ]/BSM?QW1GV)@D=`A7F$=,`VN#NR_3=Z0KC)/H7)?H^]RT3_B[>+>D8 -M#`TF#B('#^H*RQG-*?0D(!`O!1L0_"#I&N7XZM'QQ?+;Y_K1!<'XSN7WXQWX -M(!7_*-TMW"K_*20J)R8%%]@`P^G8V@76)]SA73&_DB%Q86]0C:#^`F -M!"LK#SKT+_X7)@`]Z2;1_L;TU0_\*R`F)@\+".H6WA?E^>O3XL[7\=T9]B8) -M'0(5YA'3`-K@[LOTW>D*XR3Z%R7Z/OO_""`='1OW",[[P0;1)><[\B_Q".KFY>#I -M\/S[&_`OW"#7].?-]LOQZMX'V@[T#1@8(BT"+M,3PO?;^@87'207"@S=$LLF -MX"T`&A'^%?<="B8C&2GQ'LX5TQOY(A<6%O4(V@_@)@0K*P\Z]"_^%R8`/>DF -M$A(!`!```````````````````````````0`"```````!``(```````(``0`` -M`````@`!`````````````````````````````````0(```(!``````!T`0(# -M!`4&!P@)"@L,#0X/$!$2$Q05%A<8&1H;'!T>'R`A(B,D)28G*"DJ*RPM+B\P -M,3(S-#4V-S@Y.CL\/3X_0$%"0T1%1D=(24I+3$U.3U!14E-455976%E:6UQ= -M7E]@86)C9&5F9VAI:FML;6YO<'%R7I[?'U^?P`&```PF`!U,/AK -MU0``R\!@`",``!(```````$!`18!$````````0$.``,!`0`!``0#`P,#`P`* -M``0*```````!`@```@($!!@8&!@8&!@8&!@8&!@8&!@8&!@8(!@8&!@8&!@8 -M&!@8(!0:&!B4&A@8$!H8&!`:&!@*&A@8"AH8&!`:&!@0&A@8&"`<'!@L)!@8 -M)2`=&CD]\4T?8H=[@YO'PWCV`0`!``$``0#0````_P`> -M`/S_```]````)``*`!X`%@````$``@!T`"`````````````````!"BQ>?W]> -M+`H!`````````````````````````````QA4?U08`P````````````$````1 -M````$0`3`!``/P`!`#\`_P#_``$````9`"H`"@#_````E@`R`&0````!``!A -M```4`````0`"``,`!``%``8`!P`(``D`"@`+``P`#0`.``\`$``1`!(`$P`4 -M`!4`%@`7`!@`&0`:`!L`'``=`!X`'P`@`"$`(@`C`"0`)0`F`"<`*``I`"H` -M*P`L`"T`+@`O`#``,0`R`#,`-``U`#8`-P`X`#D`.@`[`#P`/0`^`#\`0`!! -M`$(`0P!$`$4`1@!'`$@`20!*`$L`3`!-`$X`3P!0`%$`4@!3`%0`50!6`%<` -M6`!9`%H`6P!<`%T`7@!?`&``80!B`&,`9`!E`&8`9P!H`&D`:@!K`&P`;0!N -M`&\`<`!Q`'(`0!Z`'L`?`!]`'X`?P```!@`+@!"`%4` -M9P!X`(<`E0"B`*X`N0##`,L`TP#:`.$`Y@#K`.\`\P#V`/@`^@#\`/T`_@#^ -M`/\`_P#_`/\`$@````````#_`/\`KP#M``````!P:'E?:6YI=&EA;&EZ871I -M;VXN8P`````!``$`KA\``*X3``#O@````````````````````````'!O=V5R -M7W)E9@@"!@@``V8#; -M@-V`WX"7@)F`1$-/9F9S970N8P``D)^HKH&`K(*5````1FEL=&5RW5N:&)=5U). -M2D5"/CHW-#$```!4>%!O=V5R0V%L:6)"1RYC`````%1X4&]W97)#86QI8D%" -M1RYC``````````````!,;6%C+F,``%!K='1X+F,`\/#P\``````````````` +M``````````````````````````````````![`'H`>@!Y`'@`>`!W`'8`=@!U +M`'0`=`!S`'(`<@!Q`'``<`!O`&X`;@!M`%@`6`!7`%8`5@!5`%0`5`!3`%(` +M4@!1`%``4`!/`$X`3@!-`$P`3`!+`$H`%@`6`!4`%``4`!,`$@`2`!$`$``0 +M``\`#@`-``P`"P`*``D`"``'`!YL"1``````'G$)$``````>=@D0`````!Y[ +M"1``````'H`)$0`````>A0D1`````!Z*"1$`````'H\)$0`````>E`D1```` +M`!Z9"1$`````'IX)$0`````>HPD2`````!ZH"1(`````'K0)$@`````,V`,` +M_0$!``S<`P#]`0$`#.`#`/T!`0`,Y`,`_0$!``SP`P#]`@$!#/0#`/T"`0$, +M^`,`_0(!`0P*!``'`@("#`P$``<"`@(,#@0`"`("`@P0!``*`P("#!($``H# +M`@(,%`0`"0,"`@P6!``)`P("#!@$``D#`@(,'`0`"0,"`@P@!``)`P(##"0$ +M``D#`@,,*`0`"`,"`PQ,!``(!`,$#%`$``<$`P0,5`0`!@0#!`Q8!``$!`,$ +M#%P$``0$`P0,8`0`"04#!0QD!``(!0,%#&@$``<%`P4,;`0`!@4#!0QP!``& +M!0,%#'0$``,%`P8,>00`!08$!@Q]!``%!@0&#($$!0,&!`8,@P0`!`8$!@R% +M!``$!@0&#(D$``0&!`8,C00``P8$!@`````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -4316,6 +3999,10 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` +M``````````````````````````````````8`````````L)@"`!```0#`F`(` +M$``!`-"8`@`$``$`U)@"``4``0#3`P$````P`3``&``P```@````!``````````$``#___]_`0`` +M`%-Y``T`#``+``L`"@`*`#:`*(`@``\`#0`=``P`"P`+``H`"@` +M*``!`@0``0@"!`@0($`!`@(```(````````````````````````````````` +M`````````````````````````````````&UE87-U``T`#``+``L`"@`*`#:`*(`@``\`#0`=``P`"P`+``H +M`"@`*``!`@0``0@"!`@0($`````````````````````````````````````` M```````````````````````````````````````````````````````````` +M````F``````````H(P``*",````````N````,@`````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` +M`````````````````````````0````$!`0`````````````````````````` +M``````!R>%]E```````````*`;H`B@!$`#@`>``T`#``+``L`"@`*`#:`*(` +M@``\`#0`=``P`"P`+``H`"@`*``!`@0``0@"!`@0($`````````````````` +M``````````H````````````````````````````````!`P,``0(#``,#```` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` +M``````0````````````````````````````````````````````````````` +M```````````````````````````````````````````````4"`-:YP\``"@Y +M2&)YFK&ZJBIQ'%45.`ZJ"AP'506]!`T/!0<)"P$#```````````!`0("`P0$ +M!0<-(SK__P"`BRY%%PH4-VX!`0$!`0(#!0<-(P``.DQH@JB_R@<-(P``.@!0 +M77%[??__`("++JHJ<1Q%%U45.`ZJ"AP'506]!`H4-PT/;@4'"0L!`P$!`0`` +M`0````````$!`0("`@,#!`0%!0`````````````````````````````````` +M``````````````````````````````````!@Z@`````````````````````` +M`````````````````````````````P```*7&A/B9[HWV#?^]UK'>5)%08`," +MJ'718+C0M-K+<[K3[6_:D379AM\Y]>U(^ +MW7%>EQ/UIFBY```LP6!`'^/(>>VVOM1&C=EG2W+>E-28Z+!*A6N[*L7E3Q;M +MQ8;7FE5FE!'/BA#I!@2!_O"@1'BZ)>-+\Z+^7<"`B@6M/[PA2'`$\=]CP7=U +MKV-","`:Y0[];;],@108-28OP^&^HC7,B#DN5Y/R58+\1WJLR.>Z*S*5YJ#` +MF!G1GG^C9D1^5*L[@PO*C"G'TVL\*'FGXKP=%G:M.]M69$YT'A3;D@H,;$CD +MN%V?;KWO0Z;$J#FD,3?3B_(RU4.+66ZWVHP!9+'2G.!)M-CZK`?S)<^ORH[T +MZ4<8$-5OB/!O2G)<)#CQ5\=S49%!ZI8\#^%F`"1<:VF4QU\:$N-##@K`I=UH1'LM[_*C6;3HLQJ7X +MA.Z9]HW_#=:]WK&15&!0`@/.J59]YQFU8DWF[)J/11^=B4#ZA^\5LNN.R?L+ +M0>RS9U_]1>HCOU/WY):;6W7"X1P]KDQJ;%I^0?4"@T]H7%'TT33Y".*3JW-B +M4RH_"`R54D9EG5XP*#>A"@\OM0X))#8;F]\]S29.:7_-ZI\2&QV>6'0T+C8M +MW+*T[EO[I/9V3;=A?]T^7G$3EZ;UN6@``,$L0&#C'WG(MNW4OHU&9]ER +M2Y3>F-2PZ(5*NVO%*D_E[1:&Q9K79E41E(K/Z1`$!OZ!H/!X1"6Z2^.B\UW^ +M@,`%BC^M(;QP2/$$8]]WP:]U0F,@,.4:_0Z_;8%,&!0F-<,OON$UHHC,+CF3 +M5U7R_()Z1\BLNN#8M*SZ\P?/)74),Z*5Z`X]9^`F`&A=EVM\NH_&W6+#H``````````````````"@`*"@H*"@H*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H```````````` +M```````@`P```````````````````````````````````````````'=A:71? +M;65A@!Y`'@`>`!W`'8`=@!U +M`'0`=`!S`'(`<@!Q`'``<`!O`&X`;@!M`%@`6`!7`%8`5@!5`%0`5`!3`%(` +M4@!1`%``4`!/`$X`3@!-`$P`3`!+`$H`2@!)`$@`2`!'`$8`1@!%`$0`1`!# +M`$(`0@!!`$``0``)``@`"``'`*H!``"L`0``K@$``+`!``"R`0``M`$``+8! +M```Q,2PL+"PI`/C_"``P`$``;`"``)T```#[^P4`"@4%```````````````` +M,@`````````````````````````````````````````````````````````` +M`````````````````````&QM86-?<&]W97)?<')O8V5S)A\G'R +M)ATE'"0:(A@@%AX5'10<$AH2&A$9$!@0&!`8$!@0&!`8````````'Q\?'Q\? +M'Q\?'Q\?'R$```,)"0L#"`@*`@<'"0$&!0SN +M```````````````````````````````````````````````````````"`@;Z +M^OKZ^OS^````````_/X```````````````````````````(````````````` +M```````````````"`@;Z^OKZ^OS^````````_/X`\WOS=?-N\VCS8O-=TV[3 +M:--BTUVS;K-HLV*S79-NDVB38I-=V)[75MN6VA;8EM=.VX[:#MB.UT;;AMH&V(;74-N0VA# +M8D-=(VXC:"-B(UT#;@-H`V(#76MN:VAK8FM=2VY+:$MB2UTK;BMH*V(K70MN +M"V@+8@M=\WOS=?-N\VCS8O-=TV[3:--BTUVS;K-HLV*S79-NDVB38I-=^W'[ +M:_ME^V#;;]MJVV?;8]M=NVZ[:+MBXVGC8^->PVS#9L-BPUVC;J-HHV*C78-N +M@VF#9#MB.UT;;AMH&V(;74-N0VA#8D-=(VXC:"-B(UT#;@-H`V(#76MN:VAK +M8FM=2VY+:$MB2UTK;BMH*V(K70MN"V@+8@M=\WOS=?-N\VCS8O-=TV[3:--B +MTUVS<+-JLV2S7Y-ODVB38OM[^W7[;OMH^V3[7]MQVVO;9=M?VUF[;+MGNV&[ +M6N-_XWCC"MQ*VLK +M92M>`$T9'QX`+`$"`````$TA(=3^+`$``````$T9(",`+`$!`````$TA)",` +M+`'_____`$T?("@`+`$"`````$T.%-3^^O\#`````$T2%-3^\/\"`````$T5 +M&!X`+`$"`````$T1%-3^!0`$`````$TD)M3^YO_]____`$TA*QH`+`'_____ +M`$TA*QX`+`'_____`$T@(-3^YO_^____`$T@(-3^YO\"`````$TA)M3^^O\" +M`````$TA)M3^\/\#````\`[T#_@0_!$($@P3$!0B%206)A"9\)X`HA"F(*HPKD2R5+9DNFR^=,*$QI3(` +M```````````````````````R/PX1`````/K_,C\A)P```````#(_*"Q#```` +M]O\R/R@L(P```/;_,C\H+`,```#V_S(_+3!#`.#_```R/RTP(P#@_P``,C\M +M,`,`:````#(_,3%#`.#_^O\R/S$Q(P#@__K_,C\Q,0,`:`#Z_S(_,C)#`.#_ +M]/\R/S(R(P#@__3_,C\R,@,`:`#Z_SY-#A$`````^O\^32@K`````.__/DDL +M,```X/\``#Y),3(``.#_^O]*32TR`````.+_,DT.(``````&`#)-(20````` +M^O\R324G`````/3_,CDQ,@`````,`")-#A$````````B31(4```````````` +M`````````````````````````````````````````````````"@````````` +M```````````````````````````````````````````````````````````` +M`````````````````````````````````````````````````&-M9%]W86ET +M7V9O7,@26YI="!487-K +M````:7(`````````!```!0```$9R86UE($AA;F1L97(```#.(``````````$ +M```+````5%@@4V-H961U;&5R`````!18``````````0```0```!D:7-P871C +M:&5R(%1A +M`'!W5]C;VUP=71A=&EO;BYC``````````````#_____ +M_____W-P96-T%!O=V5R0V%L:6(N8P`````````````` +M``````````$````"````!`````@````0````5'AC=')L+F,`````CX[ZB,+L +MJ:VP````L0(``+$#``"I_ZK_J_^H/P```````(A_+S`#,!0`,W\',`,P%``S +M?S\P`S`4`#-_!S```!@0,W\`,`,`&!`S?P!`!$`8$(B!='5N97(N8P!_`'X` +M?@!]`'P`?`![`'H`>@!Y`'@`>`!W`'8`=@!U`'0`\`E@&8`?-`]"```(`!@0*(0(Y`J2*J(JLBU0+6 +M!?7X@(.?$*@0J8BJ,ZLSKA"SD;8#P!SU$```@0**`*``L0*Y`L(`@0"*`:`! +ML0*Y`<(?[X2CN./LM`"0`+0`X^RCN^^'1 +MY\P![A@2$ACN`'[[BC[.``M`"0`+?LX[BCA^^?1`?,`>X8$A(8[@',Y]'A^^XH^S@`+0`D`"W[ +M..XHX?OGT0',&.X2$NX8S`'1Y_OA*.XX^RT`)``M`#C[*.[[X='GS`'\`@;? +M[=K:!=8GUR36_]/K>!]H.]`T8&"(M`B[3$\+WV_H&%QTD%PH,W1++)N`M`!H1 +M_A7W'0HF(QDI\1[.%=,;^2(7%A;U"-H/X"8$*RL/.O0O_A%^7YZ]/BSM?QW1GV)@D=`A7F$=,`VN#NR_3=Z0KC)/H7 +M)?H^]RT3_B[>+>D8#`TF#B('#^H*RQG-*?0D(!`O!1L0_"#I&N7XZM'QQ?+; +MY_K1!<'XSN7WXQWX(!7_*-TMW"K_*20J)R8%%]@`P^G8V@76)]SA73 +M&_DB%Q86]0C:#^`F!"LK#SKT+_X7)@`]Z2;1_L;TU0_\*R`F)@\+".H6WA?E +M^>O3XL[7\=T9]B8)'0(5YA'3`-K@[LOTW>D*XR3Z%R7Z/OO_""`='1OW",[[P0;1 +M)><[\B_Q".KFY>#I\/S[&_`OW"#7].?-]LOQZMX'V@[T#1@8(BT"+M,3PO?; +M^@87'207"@S=$LLFX"T`&A'^%?<="B8C&2GQ'LX5TQOY(A<6%O4(V@_@)@0K +M*P\Z]"_^%R8`/>DF$A(!`!```````````````````````````0`"```````! +M``(```````(``0```````@`!`````````````````````````````````0(` +M``(!``````!T`0(#!`4&!P@)"@L,#0X/$!$2$Q05%A<8&1H;'!T>'R`A(B,D +M)28G*"DJ*RPM+B\P,3(S-#4V-S@Y.CL\/3X_0$%"0T1%1D=(24I+3$U.3U!1 +M4E-455976%E:6UQ=7E]@86)C9&5F9VAI:FML;6YO<'%R7I[?'U^ +M?P`&```PF`!U,/AKU0``R\!@`",``!(```````$!`18!$````````0$.``,! +M`0`!``0#`P,#`P`*``0*```````!`@```@($!!@8&!@8&!@8&!@8&!@8&!@8 +M&!@8(!@8&!@8&!@8&!@8(!0:&!B4&A@8$!H8&!`:&!@*&A@8"AH8&!`:&!@0 +M&A@8&"`<'!@L)!@8)2`=&CD]\4T?8H=[@YO'PWCV`0`! +M``$``0#0````_P`>`/S_```]````)``*`!X`%@````$``@!T`"`````````` +M```````!"BQ>?W]>+`H!`````````````````````````````QA4?U08`P`` +M``````````$````1````$0`3`!``/P`!`#\`_P#_``$````9`"H`"@#_```` +ME@`R`&0````!``!A```4`````0`"``,`!``%``8`!P`(``D`"@`+``P`#0`. +M``\`$``1`!(`$P`4`!4`%@`7`!@`&0`:`!L`'``=`!X`'P`@`"$`(@`C`"0` +M)0`F`"<`*``I`"H`*P`L`"T`+@`O`#``,0`R`#,`-``U`#8`-P`X`#D`.@`[ +M`#P`/0`^`#\`0`!!`$(`0P!$`$4`1@!'`$@`20!*`$L`3`!-`$X`3P!0`%$` +M4@!3`%0`50!6`%<`6`!9`%H`6P!<`%T`7@!?`&``80!B`&,`9`!E`&8`9P!H +M`&D`:@!K`&P`;0!N`&\`<`!Q`'(`0!Z`'L`?`!]`'X` +M?P```!@`+@!"`%4`9P!X`(<`E0"B`*X`N0##`,L`TP#:`.$`Y@#K`.\`\P#V +M`/@`^@#\`/T`_@#^`/\`_P#_`/\`$@````````#_`/\`KP#M``````!P:'E? +M:6YI=&EA;&EZ871I;VXN8P`````!``$`KA\``*X3``#O@``````````````` +M`````````'!O=V5R7W)E9@@"!@@``V8#;@-V`WX"7@)F`1$-/9F9S970N8P``D)^HKH&`K(*5```` +M1FEL=&5RW5N:&)=5U).2D5"/CHW-#$```!4>%!O=V5R0V%L:6)"1RYC`````%1X +M4&]W97)#86QI8D%"1RYC``````````````!,;6%C+F,``%!K='1X+F,`\/#P +M\``````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -4426,8 +4333,6 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````#W`@#@!``````````` -M````````Q`D````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -4454,6 +4359,104 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -;```````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````````````````````````````````#W +M`@#@!```````````````````Q`D````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +G```````````````````````````````````````````````````` ` end diff --git a/sys/contrib/dev/iwi/ipw2200-ibss.fw.uu b/sys/contrib/dev/iwi/ipw2200-ibss.fw.uu index a6d5249359a7..b3e2e9cc9719 100644 --- a/sys/contrib/dev/iwi/ipw2200-ibss.fw.uu +++ b/sys/contrib/dev/iwi/ipw2200-ibss.fw.uu @@ -1,213 +1,216 @@ -/*- - * TERMS AND CONDITIONS - * IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE - * - * Do not use or load this firmware (the "Software") until you have carefully read - * the following terms and conditions. By loading or using the Software, you agree - * to the terms of this Agreement. If you do not wish to so agree, do not install - * or use the Software. - * - * LICENSEES: - * - * Please note: - * - * * If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, - * applies. - * * If you are an Original Equipment Manufacturer (OEM), Independent Hardware - * Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement - * applies - * - * -------------------------------------------------------------------------------- - * - * For OEMs, IHVs, and ISVs: - * - * LICENSE. This Software is licensed for use only in conjunction with Intel - * component products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. Subject to the terms of this Agreement, - * Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up - * license under Intel's copyrights to: (i) copy the Software internally for your - * own development and maintenance purposes; (ii) copy and distribute the Software - * to your end-users, but only under a license agreement with terms at least as - * restrictive as those contained in Intel's Final, Single User License Agreement, - * attached as Exhibit A; and (iii) modify, copy and distribute the end-user - * documentation which may accompany the Software, but only in association with - * the Software. - * - * If you are not the final manufacturer or vendor of a computer system or software - * program incorporating the Software, then you may transfer a copy of the - * Software, including any related documentation (modified or unmodified) to your - * recipient for use in accordance with the terms of this Agreement, provided such - * recipient agrees to be fully bound by the terms hereof. You shall not otherwise - * assign, sublicense, lease, or in any other way transfer or disclose Software to - * any third party. You may not, nor may you assist any other person or entity to - * modify, translate, convert to another programming language, decompile, reverse - * engineer, or disassemble any portion of the Software or otherwise attempt to - * derive source code from any object code modules of the Software or any internal - * data files generated by the Software. Your rights to redistribute the Software - * shall be contingent upon your installation of this Agreement in its entirety in - * the same directory as the Software. - * - * CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything - * to the contrary hereunder, solely with respect to the requirements for - * compliance with the terms hereunder, any contractors or consultants that You - * use to perform the work or otherwise assist You in the development or products - * using this Software shall be deemed to be End Users and accordingly, upon - * receipt of the Software, shall be bound by the terms of Exhibit A, Software - * License Agreement. No additional agreement between You and such consultants or - * contractors is required under this Agreement to detail such compliance. - * - * TRADEMARKS. Except as expressly provided herein, you shall not use Intel's - * name in any publications, advertisements, or other announcements without - * Intel's prior written consent. You do not have any rights to use any Intel - * trademarks or logos. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if - * any, are owned by Intel or its suppliers and licensors and may be protected by - * copyright, trademark, patent and trade secret law and international treaties. - * Any rights, express or implied, in the intellectual property embodied in the - * foregoing, other than those specified in this Agreement, are reserved by Intel - * and its suppliers and licensors or otherwise as set forth in any applicable - * open source license agreement. You will keep the Software free of liens, - * attachments, and other encumbrances. You agree not to remove any proprietary - * notices and/or any labels from the Software and accompanying materials without - * prior written approval by Intel - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS - * BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND - * (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST - * INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE - * INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR - * SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS - * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT - * EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR - * INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE - * OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. - * - * EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH - * FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND - * LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR - * OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant - * or assume responsibility for the accuracy or completeness of any information, - * text, graphics, links or other items contained within the Software. You assume - * all liability, financial or otherwise, associated with Your use or disposition - * of the Software. - * - * APPLICABLE LAW. Claims arising under this Agreement shall be governed by the - * laws of State of California], excluding its principles of conflict of laws and - * the United Nations Convention on Contracts for the Sale of Goods. - * - * WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of - * this Agreement shall be effective unless in writing and signed by an officer of - * Intel. No failure or delay in exercising any right, power, or remedy under - * this Agreement shall operate as a waiver of any such right, power or remedy. - * Without limiting the foregoing, terms and conditions on any purchase orders or - * similar materials submitted by you to Intel, and any terms contained in IntelÂ’s - * standard acknowledgment form that are in conflict with these terms, shall be of - * no force or effect. - * - * SEVERABILITY. If any provision of this Agreement is held by a court of - * competent jurisdiction to be contrary to law, such provision shall be changed - * and interpreted so as to best accomplish the objectives of the original - * provision to the fullest extent allowed by law and the remaining provisions of - * this Agreement shall remain in full force and effect. - * - * EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to - * applicable import and export regulations of the United States and of the - * countries in which each party transacts business, specifically including U.S. - * Export Administration Act and Export Administration Regulations. Each party - * shall comply with such laws and regulations, as well as all other laws and - * regulations applicable to the Software. Without limiting the generality of the - * foregoing, each party agrees that it will not export, re-export, transfer or - * divert any of the Software or the direct programs thereof to any restricted - * place or party in accordance with U.S. export regulations. Note that Software - * containing encryption may be subject to additional restrictions. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - * - * TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate - * its terms. Upon termination, you will immediately destroy the Software or - * return all copies of the Software to Intel. - * - * -------------------------------------------------------------------------------- - * - * EXHIBIT "A" - * - * SOFTWARE LICENSE AGREEMENT (Final, Single User) - * - * IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. - * - * Do not use or load this firmware image (the "Software") until you have carefully - * read the following terms and conditions. By loading or using the Software, you - * agree to the terms of this Agreement. If you do not wish to so agree, do not - * install or use the Software. - * - * LICENSE. You may copy and use the Software, subject to these conditions: - * 1. This Software is licensed for use only in conjunction with Intel component - * products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. - * 2. You may not copy, modify, rent, sell, distribute or transfer any part of the - * Software except as provided in this Agreement, and you agree to prevent - * unauthorized copying of the Software. - * 3. You may not reverse engineer, decompile, or disassemble the Software. - * 4. You may not sublicense the Software. - * 5. The Software may contain the software or other property of third party - * suppliers. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software - * remains with Intel or its suppliers. The Software is copyrighted and protected - * by the laws of the United States and other countries, and international treaty - * provisions. You may not remove any copyright notices from the Software. Intel - * may make changes to the Software, or items referenced therein, at any time - * without notice, but is not obligated to support or update the Software. Except - * as otherwise expressly provided, Intel grants no express or implied right under - * Intel patents, copyrights, trademarks, or other intellectual property rights. - * You may transfer the Software only if a copy of this license accompanies the - * Software and the recipient agrees to be fully bound by these terms. - * - * EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED - * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING - * WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR - * PURPOSE. Intel does not warrant or assume responsibility for the accuracy or - * completeness of any information, text, graphics, links or other items contained - * within the Software. - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR - * ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS - * INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO - * USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR - * IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE - * LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY - * BETWEEN JURISDICTIONS. - * - * TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if - * you violate its terms. Upon termination, you will immediately destroy the - * Software. - * - * APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the - * laws of California, excluding its principles of conflict of laws and the United - * Nations Convention on Contracts for the Sale of Goods. You may not export the - * Software in violation of applicable export laws and regulations. Intel is not - * obligated under any other agreements unless they are in writing and signed by - * an authorized representative - * of Intel. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - */ -#define IWI_FW_VERSION 3.0 + TERMS AND CONDITIONS + IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE + +Do not use or load this firmware (the "Software") until you have carefully read +the following terms and conditions. By loading or using the Software, you agree +to the terms of this Agreement. If you do not wish to so agree, do not install +or use the Software. + +LICENSEES: + +Please note: + +* If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, + applies. +* If you are an Original Equipment Manufacturer (OEM), Independent Hardware + Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement + applies + +-------------------------------------------------------------------------------- + +For OEMs, IHVs, and ISVs: + +LICENSE. This Software is licensed for use only in conjunction with Intel +component products. Use of the Software in conjunction with non-Intel component +products is not licensed hereunder. Subject to the terms of this Agreement, +Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up +license under Intel's copyrights to: (i) copy the Software internally for your +own development and maintenance purposes; (ii) copy and distribute the Software +to your end-users, but only under a license agreement with terms at least as +restrictive as those contained in Intel's Final, Single User License Agreement, +attached as Exhibit A; and (iii) modify, copy and distribute the end-user +documentation which may accompany the Software, but only in association with +the Software. + +If you are not the final manufacturer or vendor of a computer system or software +program incorporating the Software, then you may transfer a copy of the +Software, including any related documentation (modified or unmodified) to your +recipient for use in accordance with the terms of this Agreement, provided such +recipient agrees to be fully bound by the terms hereof. You shall not otherwise +assign, sublicense, lease, or in any other way transfer or disclose Software to +any third party. You may not, nor may you assist any other person or entity to +modify, translate, convert to another programming language, decompile, reverse +engineer, or disassemble any portion of the Software or otherwise attempt to +derive source code from any object code modules of the Software or any internal +data files generated by the Software. Your rights to redistribute the Software +shall be contingent upon your installation of this Agreement in its entirety in +the same directory as the Software. + +CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything +to the contrary hereunder, solely with respect to the requirements for +compliance with the terms hereunder, any contractors or consultants that You +use to perform the work or otherwise assist You in the development or products +using this Software shall be deemed to be End Users and accordingly, upon +receipt of the Software, shall be bound by the terms of Exhibit A, Software +License Agreement. No additional agreement between You and such consultants or +contractors is required under this Agreement to detail such compliance. + +TRADEMARKS. Except as expressly provided herein, you shall not use Intel's +name in any publications, advertisements, or other announcements without +Intel's prior written consent. You do not have any rights to use any Intel +trademarks or logos. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if +any, are owned by Intel or its suppliers and licensors and may be protected by +copyright, trademark, patent and trade secret law and international treaties. +Any rights, express or implied, in the intellectual property embodied in the +foregoing, other than those specified in this Agreement, are reserved by Intel +and its suppliers and licensors or otherwise as set forth in any applicable +open source license agreement. You will keep the Software free of liens, +attachments, and other encumbrances. You agree not to remove any proprietary +notices and/or any labels from the Software and accompanying materials without +prior written approval by Intel + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS +BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND +(INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST +INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE +INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR +SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT +EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR +INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE +OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. + +EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH +FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND +LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR +OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant +or assume responsibility for the accuracy or completeness of any information, +text, graphics, links or other items contained within the Software. You assume +all liability, financial or otherwise, associated with Your use or disposition +of the Software. + +APPLICABLE LAW. Claims arising under this Agreement shall be governed by the +laws of State of California], excluding its principles of conflict of laws and +the United Nations Convention on Contracts for the Sale of Goods. + +WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of +this Agreement shall be effective unless in writing and signed by an officer of +Intel. No failure or delay in exercising any right, power, or remedy under +this Agreement shall operate as a waiver of any such right, power or remedy. +Without limiting the foregoing, terms and conditions on any purchase orders or +similar materials submitted by you to Intel, and any terms contained in IntelÂ’s +standard acknowledgment form that are in conflict with these terms, shall be of +no force or effect. + +SEVERABILITY. If any provision of this Agreement is held by a court of +competent jurisdiction to be contrary to law, such provision shall be changed +and interpreted so as to best accomplish the objectives of the original +provision to the fullest extent allowed by law and the remaining provisions of +this Agreement shall remain in full force and effect. + +EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to +applicable import and export regulations of the United States and of the +countries in which each party transacts business, specifically including U.S. +Export Administration Act and Export Administration Regulations. Each party +shall comply with such laws and regulations, as well as all other laws and +regulations applicable to the Software. Without limiting the generality of the +foregoing, each party agrees that it will not export, re-export, transfer or +divert any of the Software or the direct programs thereof to any restricted +place or party in accordance with U.S. export regulations. Note that Software +containing encryption may be subject to additional restrictions. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + +TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate +its terms. Upon termination, you will immediately destroy the Software or +return all copies of the Software to Intel. + +-------------------------------------------------------------------------------- + +EXHIBIT "A" + +SOFTWARE LICENSE AGREEMENT (Final, Single User) + +IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. + +Do not use or load this firmware image (the "Software") until you have carefully +read the following terms and conditions. By loading or using the Software, you +agree to the terms of this Agreement. If you do not wish to so agree, do not +install or use the Software. + +LICENSE. You may copy and use the Software, subject to these conditions: +1. This Software is licensed for use only in conjunction with Intel component + products. Use of the Software in conjunction with non-Intel component + products is not licensed hereunder. +2. You may not copy, modify, rent, sell, distribute or transfer any part of the + Software except as provided in this Agreement, and you agree to prevent + unauthorized copying of the Software. +3. You may not reverse engineer, decompile, or disassemble the Software. +4. You may not sublicense the Software. +5. The Software may contain the software or other property of third party + suppliers. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software +remains with Intel or its suppliers. The Software is copyrighted and protected +by the laws of the United States and other countries, and international treaty +provisions. You may not remove any copyright notices from the Software. Intel +may make changes to the Software, or items referenced therein, at any time +without notice, but is not obligated to support or update the Software. Except +as otherwise expressly provided, Intel grants no express or implied right under +Intel patents, copyrights, trademarks, or other intellectual property rights. +You may transfer the Software only if a copy of this license accompanies the +Software and the recipient agrees to be fully bound by these terms. + +EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED +"AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING +WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR +PURPOSE. Intel does not warrant or assume responsibility for the accuracy or +completeness of any information, text, graphics, links or other items contained +within the Software. + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR +ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS +INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO +USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR +IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE +LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY +BETWEEN JURISDICTIONS. + +TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if +you violate its terms. Upon termination, you will immediately destroy the +Software. + +APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the +laws of California, excluding its principles of conflict of laws and the United +Nations Convention on Contracts for the Sale of Goods. You may not export the +Software in violation of applicable export laws and regulations. Intel is not +obligated under any other agreements unless they are in writing and signed by +an authorized representative +of Intel. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + + + + + +#define IWI_FW_VERSION 3.1 begin 644 ipw2200-ibss.fw -M```#`$`9``"P/P``/'P"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` +M`0`#`$`9``!H/P``G'L"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` M_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P`` M'S@5````4````!0&````@`\X`'X?$@(```D``0\X`/X?8`#^/V``_E]@`/Y_ M8`#^GV``_K]@`/[?8`#^_V``_A]A`/X_80#^7V$`_G]A`/Z?80#^OV$`_M]A @@ -351,11 +354,11 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M```'L`L`%@`$`!0`&P````!@$&(FH```!6X`:@)P*$$!$`Z0M88!8"A!EXL` +M```'L`4`"0`&``L`!`````!@$&(GH```!6X`:@)P*$$!$`Z0M88!8"A!EXL` M8!!!_F`100!J&4KP:H!*`6I`2@``0%`CH```FK#,L%*QHK$_LLBRY++XL@`` M`&"I0$!0,:```)NP^[!`6D`:(54"8`#7*$%!4```_]U MABA%,`^7BZ`&`)R00>`6`&R2$> -M!&`#R2(0B8\(``T`%P`'S`;8(E$``");04IIH"RP0[/(L,BP1;-'LU:S9K/I +M!&`#R2(0BH\(``T`%P`'S`;8(E$``");04IIH"RP0[/(L,BP1;-'LU:S9K/I MM.ZTR+#(L&JWR+#(L">U*;4KMP+]6I4`$?`LB"MP!@4$`A42(?`L[8H,BP0[/(L,BP4+`TL%"P4+!0L%"P MR+#(L&JWR+#(L%"P4+!0L,BP4+!0L%"P4+!"L\BP0K-0L%"P4+!0L#2PR+!0 ML,BP4+!0L!;<1=W]@G2(_8($@_V"-(/]@@W+`&"I0$!0ST`' +M!F!`0""P`&#$0"[=0%`#'PK(P5`A,P?(/X^UAH-@$HXH09>+`&"I0$!0ST`' M8'9"=T)`0#`/```P#@U@*$%!4+6&*$&7B\]0`1\-R2!0(3,*R`!@SD`,8*5` M^+,!9`!F`A""P````8,1`J4`(8$!`,`]9#C`."F`H04%0M88H09>+(+`# MLD?<(&I52V):(2$!:E5+!W)`&HM2G.X M+ELA(>?)=(@N6R$AX\F6N(!0_!_@R"!0(3,*R0+B?[$#8,A`6U`A-`+(#+(' -MLA]0(3,/R%!1(3(,R,Y0(3`)R2$S!LD(&T`;SD#P;`F.4K$`8!-`CU`A,03) +MLA]0(3,/R%!1(3(,R,Y0(3`)R2$S!LD(&T`;SD#P;`J.4K$`8!-`CU`A,03) M(3,"R9ZYY+@1L0=@0$`+8*5`^+-9#\P.$;'XW,Y001G.0"Y;(2%;R<`!Q@]+ M#P``&%$94\8.`&07`!3((%`A,P;)`N*[L05@R$`'LL8/2@X#XD=0P;%$4!A! -M&4-*#\8.R;&"4"$P*,@B5/&!%P`8SAF.8&!>0(!0]!F`0`-@0$`*8*5`^+-9 +M&4-*#\8.R;&"4"$P*,@B5/&!%P`8SAJ.8&!>0(!0]!F`0`-@0$`*8*5`^+-9 M#\P.Q%`A,`7((P\C#@)@0$``9,1$(+``'P+)`16#0(90`!\"R0$5AD`D#H)@ M"K$@L`!B`&9V4!<`!\P`8'9`#U"+0!!0C$!V4`$1=D"#4`$1@T`!`%M0[QE; M0`&S``!+#P``$5'*0`!@R%`#'P3(+EM`(!O(%&2%9M&$#P`/&01D%P`8R+"&"E0/BS60_,#DA0`1M(0`?<_8)TB/V"!(/]@B"P$;%!L0K!,D"8$!`\K(!8$!`SUH!'@+((+#]@G2(_8($@_V"(+`$W:8/`6!`0""P -M+ELA(0+)`0``8!!BZJ%/4!D`@@$:41<`!%#$&XJE#U:&TL@4`$9`1\,R01D#T4;1P5D#T4O6_,8 M+TN%:B]+A;0"XM0!+UOS&"]+$&Y"E"!0(3,HR,Y:(24'R4!:!1X"R$^T!!X? MR`!@&UL]2OX8&TM?9)!FX4?A10``X4'A0Q9N7)0;6P$:&TLD9(5FX4?A10`` MX4'A0Q!N:)0]6AM+"N)OM"$U!\D,9`]%&T<-9`]%>[0,9`]%!V0;10YD#T5` -M6@0>!,B/6B$A!!,B/6B$A!15XU;2N":\``(1*Q%`A,`+(,K^`4/09@$`84&0P M#,@":E5+P%`!:E5+0#(%R(@T&\F)-`;)=E!W4@!D%P`*R`]0BT`04HQ"#%`- -M4HU`CD)@N(M0C%(CC@!@J4`#8$!`8&!>0""P"CU2X:+&`4"$R$\G&#TL/```841E3Q@X`9!<`%LB`4`0;@$!/4!I!7E"` +M4HU`CD)@N(M0C%(DC@!@J4`#8$!`8&!>0""P#CU2X:+&`4"$R$\G&#TL/```841E3Q@X`9!<`%LB`4`0;@$!/4!I!7E"` M&UY``0#&#TL/```841E3Q@X`9!<`!,F`4/L9@$`!`%Y0(35+R(!0(3("R7"Q M@%`A,P+(<+%>4"$P&LD!&UY`7%!=4BM4%P`$S1(`"`"ON`!DC5".4A<``\H` M8+:X$@"-0(Y"*U`L0`!@7$!=0(U0CE(L5!4``&07`!W)7E`A-QW)@!M>0"Q0 M`&07``O)`14L0!<`$\B-4(Y2`&07``O)X[B-4(Y2`16-0(Y"`&07``+)<+&` -M4`@;@$!PL8]:(2$.9(10`\F$4!1D!&I`2NF[@H\$:D!*CUHA(0;)M&#<0#A0 -MW4#_N,1@W$`X4-U`0E`NN8=4B%8&4!+B`&JK2BN^"0!%5!``$``0``@`A%`9 -M`(4!DA")CQ@`$`!IN810`6I*2I"/`UH09%5%(2("R001A@%``3`?`L@!8@%J +M4`@;@$!PL8]:(2$.9(10`\F$4!1D!&I`2NF[@X\$:D!*CUHA(0;)M&#<0#A0 +MW4#_N,1@W$`X4-U`0E`NN8=4B%8&4!+B`&JK2BR^"0!%5!``$``0``@`A%`9 +M`(4!DA"*CQ@`$`!IN810`6I*2I&/`UH09%5%(2("R001A@%``3`?`L@!8@%J M54L(`$I0**G^N0``"0!"5!``$`#>0-]"2EH"'@3(.E0[5CBYAU2(5@1:(2`& -M4!3(AP$$:CE*`&`08C*N```)``-:(2("R6`18!'>5-]6$`!"5!(`8KD%:JM* -M*[X&6@5@K4``8!!B"*\```!@J`$9`(4!DA")CQ``1500`-Y4WU80`$I:`AX" +M4!3(AP$$:CE*`&`08@ZN```)``-:(2("R6`18!'>5-]6$`!"5!(`8KD%:JM* +M++X&6@5@K4``8!!BY*X```!@J`$9`(4!DA"*CQ``1500`-Y4WU80`$I:`AX" MR.&YWD#?0MQL!&Y%`4!+;9F/6B$A"\D":E5+Q&P,;D4!0$MWF0%J54N%N09N MKFQ%`4!+?YD`8$)0BKD#XD90BKE#4!<1`0\`:JQ*GHP$8$!``&""0(]:(2$" -MR2"PAU2(5@!@$&(9K@!@$&+KJY*+AU2(5@90`&JF2NF[```!9`!F!F#6A(*/ +MR2"PAU2(5@!@$&+UK0!@$&+%JY*+AU2(5@90`&JF2NF[```!9`!F!F#6A(./ M`FI52P!@PD##0@%J54N!4"$R+L@*4`M2`UHA)0C)"&00`(%:(28%R2$G`\D$ -M9!``"``Z0#M"!E`6X@%JJTHKOI`!`^)%5-"Y0E00`!``$``(`(10&0"%`9(0 -MB8\/`!``$``!N@)J2DJ$4!>Y`;H#4"$W)\@5XH10A0$@4"$W!\@&6@A@K4`` -M8!!B"*\``*@!&0"%`9(0B8]%5!```;J$4`!J2DH7N0D`0E00``)J54O"0,-" +M9!``"``Z0#M"!E`6X@%JJTHLOI`!`^)%5-"Y0E00`!``$``(`(10&0"%`9(0 +MBH\/`!``$``!N@)J2DJ$4!>Y`;H#4"$W)\@5XH10A0$@4"$W!\@&6@A@K4`` +M8!!BY*X``*@!&0"%`9(0BH]%5!```;J$4`!J2DH7N0D`0E00``)J54O"0,-" M`6I52X%:(24"R)NY`FI52\!L0`$!:E5+0$%!,A+(I0^*-`3(:5`0&VE``%H! M%*\!`FI52T`!0$$?F@%J54O0NH%0`FI52Q=N0@%`12F:(30&R`)N0@%`12^: M.;HA,07(!FY"`4!%-IH!:E5+@5HA)A+("&H"8%5!X&RO`4`!0$%#F@%@54&) M4(I2J@$2`)P.D@]LNB$G`\@$:C^Z(2`(R0-:(29$R8E0BE*#C="Z\%%`0?%1 -M0$'R44!!!5*2C\`90$$"_JC`5@0$``8()`(+"&8`JQ$;$`:JQ*GHS\W/G5C(`>9!<`]$$B47E!(E%Z02)1>T$B47Q! -M(E%]02)1?D$B47]!D0\":E5+P&P8;B)1``%XFP%J54L89+2+X(TB#R(.)`^! +M(E%]02)1?D$B47]!D0\":E5+P&P8;B)1``%XFP%J54L89+2+X8TB#R(.)`^! M4/,9(2("R`0;@4`@8%5!8E`A,0%@54$"R:6Y=K(`#@$.`@X##@$````$VP!J M*$N7NP$``FI52\!0P5(!:E5+&&2%`0@>",B-`4,@!<@>9(%J`AJ!2HT!(2*! M6@+(!!J!2@!0`5(2``1:(20&R`)D$@"!6A`:@4J)0(I"`%`!4@1D$``#6B$E M'\D$6D,B!\@$9!``@5I`&H%*YKM`(@?("&00`(%:`1J!2N:[0B('R`AD$`"! M6B`:@4KFNP1D$`"!6H`:@4J'0(A"`0"%`0%@`&(``.%#X4$``.%#X4.H`1IN -M])N'`<=.`UH*&``>!,D@6B$G(,D$6B$@'!,D@6B$G(,D$6B$@'`LC[&0X`J`$!9(!FUH2" -M`0T`EP$(``%J.4H`8!!B,JX```D``&2`9M:$J`'^&00;`V2`9M:$Q%`A,`+( -M/;]9#B];@!HO2P!@QD"LO13B+UOS&"]+(%HA(`?)<8T/6_P8`1H/2W.\ZFHO +M`0T`EP$(``%J.4H`8!!B#JX```D``&2`9M:$J`'^&00;`V2`9M:$Q%`A,`+( +M/K]9#B];@!HO2P!@QD"LO13B+UOS&"]+(%HA(`?)<8T/6_P8`1H/2W.\ZFHO M2P];_!@!&@]+<[PO6_,8+TOJ:B]+#UO\&`(:#TLC;G2\0E#'#DH.&$$90TH/!&"E0!!J54L21!-&`6I52_BS M$&I52Q)4$U8!:E5+!N#.4"$P"LDA-0C(!P\&#B`.G`Z9#LD!!PYU4(`?!`'PL8/2@X811E'2@_&#@%D`&888`!B``#A1^%%``#A0>%#```@ -M8%5!`&!B0`%@54&L4""M`0``8!!B%:@`8!!BUZ@`8!!B**L``,8/2@X#XD=0 -M,;U$4`45&$$90TH/Q@[.4"$U!09P/'U`A-!+( M4%$A,@_(SE`A,`S)(3('R2$Q!J=];TA,0?(!FXB50(!\)TB52)5X!D`'P[)`6I5 -M2PAJ(3<"R`1J`F151:\!X&PB50(!`I[!6@%D544!`+^1+Y!OE2^3;X;8))! -M5KX88))!5KX28))!5KX,8))!5KX)8))!5KX&8))!5KX)8))!"0`"9!``&`!9 -MO@-@DD$)``)D$`"009%#P0\`````T@&049%3`600`!@`&`"J`1``"```8*M0 -M:ZX&NG4KD&8F=#(0\/42`;#T%P;01N(E$``<)!>9X`8F=#(0\, -M;B)1``'"08&>#U'?&0]!`0"$#P``\%%P0?%1<4'R47)!D0\!````Q%`"&\1` -MQ%`!&\1`+5`"&RU`.]PZU2%1"Q\WR"(/(@XD#R)1C(`B9!<`+,T2`");PTK$ -M6B$A`\G#6D%*(E4B5P!$`487`![,(E$"0"$W&LA+#\)4"%$7``G,%,X&40=3 -MP%3!5A<`!+(%`A-Q[(!%`A,!O)8%%A4P]D$`!@06%#`FI52P9N -MQ&PB40`````B40`!(I]@46%3%V02`&!!84,!:E5+(E'NN```W;<#4"$S!,AA -M4`,9!T"'5(A6!E`"X@:\(;REN0``"V`H04%0*$'$4"$P`\C#4$%`@U`H00-0 -M(3,%R890`!\"R89`AE`H00!@AD"#0'9`=T`H02A!*$$H02A!*$$M4"A!0%`% -M'P+)`0``8!!B9JE``7-!0`%T04`!=4%``79!0`%W04`!>$%``7E!0`%Z04`! -M>T%``7Q!0`%]04`!?D%``7]!`0``8%Q`74!>0"M0+$`!`*X!$&I52T`!`6I5 -M2P$`&0`9`!D`&0`!`!@`&``8`!@``0`````````````````````````````` +M#@];WQ@/2PB[(%`A,P7)`60`9@!@UH26N@```&3'4!D`A0$08%5!&^*J$(J/ +M"@`08%5!@&#E04`!YD$*8-)BX4/A04(!X47A1R-@TF+A0^%!``#A1>%'%&[, +MG=N]@&#E01Q0YD$%8()BX4/A01U4X47A1RANVIT!8%5!QE#?K5:\2;V!4`)J +M54LA-`G((E4"`2)5`@$";B)5ZYWVO2$Q!\@&;B)5`@'QG2)5(E7@&0`?#LD! +M:E5+"&HA-P+(!&H"9%5%KP'@;")5`@$#GL%:`61510$`MP%``4$!`1&^`0`! +M`0$!`,Y4`&(/`$`9%0``9,Y$`0`I9"IFBU",4A<`!ZX``#=MP-0(3,$ +MR&%0`QD'0(=4B%8&4`+B!KPAO*6Y```+8"A!05`H0<10(3`#R,-004"#4"A! +M`U`A,P7)AE``'P+)AD"&4"A!`&"&0(-`=D!W0"A!*$$H02A!*$$H02U0*$%` +M4`4?`LD!``!@$&)`J4`!4%``7I! +M0`%[04`!?$%``7U!0`%^04`!?T$!``!@7$!=0%Y`*U`L0`$`K@$0:E5+0`$! +M:E5+`0`9`!D`&0`9``$`&``8`!@`&``!```````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M``````````````````````````````````````````````!)#\8/20_&#@!O -M`&P`:@4!+I`":E5+L&Y1;`!J!0$UD`%J54L`8,U`9F!+0"!J54L`8&%`"&I5 -M2QA@ST!`8,Y``&#M0`=@[$`"8.M``6I52QY@;D``8&]`&F"C0`!J4$LO6^\8 -M@!HO2P%@*$$!8"A!6F`H0=%@*$$#8"A!"6X`8"A!9Y`$;M!L0`$H06N0`&`H -M02A!`&`08@N@"&I52Q_J:&"08M^!A0'(0,E"$!@A-P+)0&`@8(.PJ@$5`,%` -M:6"08M^!RT#,0@%D@6;B1^)%Y%'C4Q@`&`#P0EBQ`6I52PA@:%4(:E5+%P#Y -MSFA@D&+?@11XU,8`!@`\$(9`&`9 -M@@$(8%5!P5"?&14`P4!'8)!BWX'D0.5"0F"08M^!&0`9`.-"`6"!8M^!A0$8 -M`!@`YD*H`1D`&0`9`!D``QG@0`$?#,DX8)!BWX'G0.A"%F"08M^!/QGI0.NP -M-V"08M^!YT#H0A9@D&+?@1@`&`#I0@!@`&3C5.E0%1$2`.9`ZU00`(4!/Q@` -M8*@!&`"%`0`0ZH[D5.56%P`#SP%JZDKF4.Q4$`"%`3\8,!X"S#!J`&"H`1@` -MA0$`$.J.YU3H5A<`!,_J6@(:ZDH!:E5+%F"08M^!A0$8`!@`#@`_&=I`/QC; -M2@%@@6+?@1@`&``8`!@`#@`#&4$P`\C:4#*QVU`(:E5+`&3/5!<`!\SJ6B$@ -M$11XU,!`.%'X44``.%!X4,!``````#L4.U2 -M`1'L0.U""&!500!@ZD`!8%5!`&RRCT!0!1\'R00?!15XU>G1*A&A0$.``H?",D4'PG)-Q\*R6X?#\F9L@D`SH^(L@D`SX^(L@D` -MU(\0`!@`$`#-CXBR"0#4CQ``&``0`,Z/(2<"R`$5B++_9`]F%``.9!<`3LPF -M9`EF%P!*SG!`<4*X`0/BS8\/&6A`#.(A,`K)!.(&;+*/G[(4;+*/XFR^C^*R -M`6"!8M^!%N(A/_+(03($R`-D542TLD(R!,@'9%5$M+(`9%5$U(]@0M2/#@`# -M&6%`S+(`9%5$(3';R"$T(LD8`&!"SH\A,P/)0!O)LK\90QD@&V%`'U`@,`C) -M85#\&0\`DU`9`!4`84`+W86]!.(&;+*/WK(4;+*/XFR^C^*RB[D`:`%J54M9 -M#M0!`6"E0`!@$&+XHP``6`]9#\P.5^+4`0@/`6"!8M^!&0`9`!D`!AD!&X(! -M`V"!8N)#XD$``.118$#X&>-384(5`!]:("`$R`-D@6;D@2)@TF+?@:)`(F32 -M9@!@Y($`#@!@#6(*``1J`&X!8(%BWX'4CPX`_QD(``T`$``,``$4`!X&R0T` -M%FXJDPP`&[-N5&]6HU`0``@`#0#X0/E"%P`0S`L``14*``!D%P#=R`3!``\> -M;!FS]E#W4@$1]D#W0DRS`&#(0`!@$&('H@``Q@]*#@!@`^)'4%2S1%`801E# -M2@_&#@[B'UH@(`;(`V2!9F!085+D@2)DTF:B4.2!`&"(N0,.@%#[&8!`@E`! -M&X)``&`30#=0_ADW0`3B!&RRCWFS%FRRCP+=?+,:M$A1:D!`,`3)``X!#KNW -M_!ET0,^/AP%(6VM*2%%L0$A1;4!P4'%2!&02`$,@!,@`#@$/O;>]`0\`4A#C -MCFM:(28"R`@1%P`$S0`/`0Z]MW1003(0R,V/"1\"SK*S"A6LH]2W:[CKN#NY -M>KEZN0`.`0^[MV%0_!F"`3Y0!QD5`#Y`.&I82P4/`M+"L]&W.0]NCP$.`@YP -M4'%2!&02`"A!*$,/42`;#T'1#M`.(&3/1\]%<%!Q4@1D$@`6:@@`:E",&8@? -M"<@)``)D$@`(%M-ZTX;3!N5_&`61E1">Z"&`#9&1$HKH(;M!!>)0R -MM0!@=4`##FE0!!MI0!E0(30)R0Y@!&1D1**Z#F[008F4,K4&9&5$)[H"8&9` -M0+H+PVE0(3)!R!E0(38"R=*T:5`@&VE``F`%9&1$HKK00=!!,K494"$TR<@" -MQHRTSK0$9&5$)[H!9&-$AKH94"$T`LCJPP8>Z,D=M6E0"!MI0*2T&5`A-`+) -M';4"QQVU!61E1">Z!&!F0$"Z`L,=M0)N2%$H0ZYE#G4@$1YD#G0K1L`VX!#\:/0@%#`1<``\CVE`:U`0[D4.52`1'D -M0.5"!;7&CP25`MT)M;.ZQH\96B$@"\EK4$`P#L@A(@/((38*R!A093`&R07# -M(2`"R1VU`P[DM,&Y=%#-CP\9(J4=M1VU';4=M:JTM[2RL[*S>[2[M!VU;[1O -MM+*SLK.RLQA@9T`!#@(.:5`A,@O(>&P(;DA1*$$``3N59U`($6=`/;9J4(P9 -MB!\.R$A1*$&>0$$U`\@$8,5`2%,H0Y]"9U`"$6=`'.?%4"$R&LD9Q@+38[46 -MZDL/```8404?$!5`6!50491$D`A,"S)K+4":E5+1U!(4DE42E8!:E5+H&TH00`!*$,!`2A% -M`@$H1Y@!9UH$$&=*(35UR`!J$TJ`:G5*/;8":E5+2E#`&1@`&``.`$-D$`"& -M`4`!`6I52Q-`SZ4"QSVVA0$9`!D`EF00``H`0`$A(03)`QD30,RU,!G-CQ-` -M`6151<^ED;73M2V[UK6`:G5*/;8/4=\9#T$":E5+!&Y';$(!*$7=E:!%`FI5 -M2V)48U9'4$A28D!C0A<`2%$H04A3*$-D5&569$!E0@%J54L*R!<`",@`#P(/ -ME@^3#Q!JE$L!M@`.DPX"#L50(3(*R`G!`&`30&=0!A%G0(!@=4`]MDA5*$6& -M14A5*$6'16=0"!%G0,4.,&IU2L4//;;/CS`9A@$/4=\9#T'%#@(/E@^3#P!J -M=4K%#\4.Q0\":E5+0`$!:E5+`!^4007(@&IU2I,.`@X$;DA1*$$WEF=0!!%G -M0`+G0+;GMF=4!&`0``@`<%!Q4A<``\\`8$NV$@`,``#K.0ZD#YT.=5"`'P7) -M$U!",`+(J+L-`+!#GT$`9!<`%<9&T%U4!4``^5` -M&\FVP!O)MIT.E0^"`0]1WQF_&0]!D`&TB9R,*$'EM@!D@@&=#FE0(3(AR2$S -M',D#8!4`@@$`8!-0TH\5`+V)G(PH0:>,A[?1M\V/"Q$0:E5+A@%%`0%D546G -M4*A2!600`*H!(+5(0`!!!$4,`9'I0>U(1 -M`!)!$T-\4'U2$0`4015#?E!_4A$`%D$70P%HP0%)#QA0!!\@R&E0(3(NR"$U -M+,D`8`)3TH\(``!1`5/-CQ4`B&039A<``LX)`)!!D4-/8))!P0\`````T@&0 -M49%37X;<##E[&&%`!'P3)`A\"R3^X -MU&P&;DA1``'JEP+=\+=JN`#360X"YO6W:;@`\P1@JD``8!!B0*T``-1@T$`X -M4-%``--"SE`!&\Y`T&P*;D`!0$$(F`/B1U0/N$14`0\!8*Q``&`08I^L -M``#.4/X9SD!9#F%0_!F"`3Y0!QD5`#Y`;H\08"A!*$-J4"A!:U`H06Q0*$%M -M4"A!KFP&;D`!*$$OF-1L!FY``2A!-)BD#P-@G(PH0:>,60_,#HBY`-,IYFA0 -M&0"%`9(0XXX#XD542KA"5!``AP$050!F`&)+#P``$%$7``3+$@"%`5VXA0'_ -M8!(`J@$0`(4!J@&X`1(`5502`,8/2@X801E#2@_&#@B]RKF+N0%@9(^N;`9N -M`P\#ZTA1=+A(44(!%P`#R'"8>K@##L8/2P\#XD=4@+A$5!A1&5/&#A<`*,SH -MN&A:!&"M0`2_J`$9``7BA0%J;K1SM&ZT;K2MM,2TC[3NM+.ZYE#G4@$1YD#G0FE:`0^T -M5$A1*$'0049!M%2U5DA3*$/00T9#(28#R=1`U4(7``?)Y%#E4@$1Y$#E0@$. -MME1(42A!T$%&0;=6R8]&0R$F`\G60-="%P`"R0$.N%1(42A!T$%&0;E6R8]& -M0R$F`\G80-E"%P`"R0$.`&X`;#7=9E"!JN2T;K22M)ZZQ[0!#P!J2%$H0?\? -M#<@%;DA1*$'_'P+)`0XAW8V:`L(&:@$.GKH#9&9$M&P#;@$/3+IC4*"J;K2P -MM`#KL$.?09T/`O:FNIT."MUD4*RJ;K1NM&ZT=[2(M*&TY+0Z#CD.B[D4Q)4/ -MW8K*NOY0_U(!$?Y`_T(!8,U`GU&P4PP``&07`/#)56#7B@#3-UHA(`+)G0Z. -MB9R,*$&GC,U*`^;YB0B]RKD"Q)4/`-EM@#S#6"J0`!@$&)`K0``4+\$#M!L"FY%`4!+^)H& -M#LY0`1O.0!-00S`'R`[`=5IP'A3)`F!F0!'$=5!`'P[)$+MP:G5*&;L":E5+ -MR(X!:E5+FP^8#T!@=4#%4"$R`\@##BR[`^)'5"*[1%0!#P=@K$``8!!BHJP` -M`,Y0_AG.0*6V=5`@&W5`&U'G&1`;&T$/42`;0!L/00)J54M98,=!`6#&00%J -M54MP4'%2+&02`!9J"`!J4(P9B!\,R)Y0#QG'0<9!T$$`8-!!"0`"%1AJ6;L) -M``!DQT7&10)D546`0(%"0F3+1=4/J@$@8!(``A6"0`%D544&;M1L0`''0<9! -M:9L"9%5%#6`";D=L0@$H1=%!TD$!%<=%QD5RFTE4*$5*6BA+!&Y(52A%T4'2 -M00$5QT7&17^;#F#10=)!@5+'0X!0QT&!4@@``&#&00%@QD$!9%5%9U`($6=` -M`F151<`8`&*H`1D`&0"&`1!N0`'%0:*;`61513VV`61517!0<5($%6=4$@"P -M0Y]!T0\W4`$;-T`"9%5%`&*"4`P``�N;`61519T/<;;`&`!@J`$8`!@` -M#@"%`:\!$E"%`1D`&0":9!``N@$*`$`!`&(A(0_)AP$#&1<``\@`:@$`N`$9 -M`!D``QD7``C(`6H!`!D`&0`9`!D`U;N`:G5*`0```!M1YQD0&QM!#U$@&T`; -M#T'1#@``T`\":E5+66#$00%@PT$!:E5+`%`!4B!D$@`6:@@`!%`A-`O(`FY5 -M3]A0#QG$0<-!"0`"%1AJ%KP)``!DQ$7#10)D546`0(%"0F3)12!DS4?-12`1 -MS$/,0=4/J@$@8!(``A6"0-(/`O\IO```````````T$?01!L"&Y``4!!;YSG;+4!!&Y``<1!PT$!%*X! -M=9SA4,1!PT'@4,1!PT&!4L1#@%#$08%2"```8,-!`6##0=$/`&*"4`P``� -M09"U:`61510`>!,D%;M0!NYQ' -M8-)B`6K#O`%@@6+B0^)!Y%'C4P?B#P`@4"$P#P`$R!@`&``.`/\9`N+6O!@` -M&`#DO`@`#0`0``P``10`'@?)#0`6;N"\X)P,`*^\#0`(9%5%[5H!9%5%`!X, -MR/1`#@"`&_5`"&1510%J[4H!9%5%`+W\0`X`@!O]0`!@"&151>U``61510$` -M`6"!8M^!(3$"R9FR`.H"X@N]60X;4><9&T$/4=\9#T$!:E9+!6"E0`!@$&+X -MHP``60_,#B!J54L`8#-0`6I52P$?8<@`8"!J54LS0`%J54LNO8IXE5:`!Y1R`-@@6+?@5="5D#X&1I:("4"R0,;`V2!9N2!U`$@)0+)U`&M -MC!I:("4*R5=25E#X&04;`V2!9N2!U`'4`:V,5U)64`-D@6;D@8.]!&"!8M^! -M5T)60/X9`1L$9(%FY($%8(%BWX&50I1`_!D!&P5D@6;D@0AHP0&MC)52E%#\ -M&0(;!62!9N2!"&C!`:V,5U)64`1D@6;D@952E%`%9(%FY('TB8BY``X+ZDL/ -M55`$$55``^)%4(^]0E`"%4E`<%!Q4@YD%P!%R$!0!1\HR`/B15"=O4)0`15) -M0(%0(3("R9R^"E`+4@1D$`"!6B$G`\DA)@/(!&2SO2$@`\DA)0/("&00``@` -M85`#6B$B`\F_&;R]0!MA0`90QT#LO00?&<@$6B$@!LD@6B$G`\E%4,N]0E`" -M%4E`85`#6B$B`\F_&=2]0!MA0(=4B%8&4,=`[[UP4'%2%&07``YD`<@#XD50 -MY+U"4`$524!H6@!@K4`$OZ@!QT"%`2OB\[T$6B$@A0$FR?*.J@&/6B$A!LDA -M(P3(Q%HA(!O)E0$`9(!FX4?A1>%!X4.34"$P`\@9``J^85`#&0X`&0`9``X` -M`605``%D@&;A1^%%X4'A0YR^=;X```90QT#RCH]:(2,&R2$A!,C$6B$@#A$$5?I1A)1ZD`34>M`%%'L0!51[4`64>Y`%U'O0`91L$`'4;%`"%&R0`%J -M54M34,:N_+GYMD`!HT%``:1!0`&E04`!ID%``:=!0`&H04`!J4%``:I!0`&K -M04`!K$%``:U!0`&N04`!KT$!`*X!$&I52T`!`6I52P$`K@%`:E5+0`%!`0AJ -M54L!`!M;_A@;2PX`&``8`!@`&``5``$`````8*@!&0`%'QQ:.R05@(2$;R0]@(2`8R0U@0K\```!@J`$<6@H?#\D4 -M'PK)-Q\%R3B_;F`A(PC)-V`A(@7)%&`A(0+)"F"%`:U01:_JO0!@$&(XJ(JX -M`&`08EBI`&`08O&IU�#A0T4``8&M:(2("R(:(TD#30O6Z&``8`"``'``< -M`!@`+``D`"]4%0!A6D`8J@$5`"]`:%`N0`$`"6`H04%0*$$(8%5![E`H0>]0 -M*$$!8%5!"FX`8"A!>Y]H4"A!(%`A,Q#(/E`A-0W('U`@,`K)"&!50?!0*$'O -M4"A!`6!509R_8%`H06%0!>)!,`/(VE";O]M0*$$%;@!@*$&>GR!0(3,$R#Y0 -M(34"R6%0*$$`8"A!+E`H02]0*$$`8"Y`+T`!`"!@54&W`4`!00$!$;X!``$! -M`0%@54$!`+`"``&(Y3(`$`(`1^ -MCE,D_I]A(!L`(``8CE,@`0`@!'Z.4RC^GV$@&``@`!B.4R`!`"`$?HY3+/Z? -M82`5`"``&(Y3(`$`(`1^CE,P_I]A(!(`(``8CE,@`0`@!'Z.4S3^GV$@#P`@ -M`!B.4R`!`"`$?HY3./Z?82`,`"``&(Y3(`$`(`1^CE,\_I]A(`D`(``8CE,@ -M`0`@!'Z.4T#^GV$@!@`@`!B.4R`!`"`$?HY31/Z?82`#`"``&(Y3(`$`(`1^ -MCE-(_I]A`!B.4T0T#A!`,@X0/#`.$#@N#A`T+`X0,"H.$"PH#A`H)@X0)"0. -M$"`B#A`<(`X0&!X.$!0<#A`0&@X0`!A.00`V!1`@@0\X`!AN0R`5`"`0_I]A -MH!,`(!3^GV$@$@`@&/Z?8:`0`"`<_I]A(`\`("#^GV&@#0`@)/Z?82`,`"`H -M_I]AH`H`("S^GV$@"0`@,/Z?8:`'`"`T_I]A(`8`(#C^GV&@!``@//Z?82`# -M`"!`_I]AH`$`($3^GV%(_I]A1`!."T``+@L\``X+.`#N"C0`S@HP`*X*+`". -M"B@`;@HD`$X*(``N"AP`#@H8`.X)%`#."1``K@D$@.T+((`/.`@8;@.H?HY3 -M$#X.$("1`"B@83-3&``8`/!"6;$!:E5+"&!H50AJ54L7 +M`/G.:&"08K>!R$#)0L%`;&"08K>!RT#,0@%D@6;B1^)%Y%'C4Q@`&`#P0AD` +M8!F"`0A@54'!4)\9%0#!0$=@D&*W@>1`Y4)"8)!BMX$9`!D`XT(!8(%BMX&% +M`1@`&`#F0J@!&0`9`!D`&0`#&>!``1\,R3A@D&*W@>=`Z$(68)!BMX$_&>E` +M[+`W8)!BMX'G0.A"%F"08K>!&``8`.E"`&``9.-4Z5`5$1(`YD#K5!``A0$_ +M&`!@J`$8`(4!`!#&CN14Y587``//`6KJ2N90[%00`(4!/Q@P'@+,,&H`8*@! +M&`"%`0`0QH[G5.A6%P`$S^I:`AKJ2@%J54L68)!BMX&%`1@`&``.`#\9VD`_ +M&-M*`6"!8K>!&``8`!@`&``.``,903`#R-I0,[';4`AJ54L`9,]4%P`'S.I: +M(2`1R2$A#\E9L0AJ54O!6B$D%LGJ6B$@!LDA(03)*FR.C[JR!M,N6R$A`LA, +ML;JR!.(!:E5+W;$.;(Z/W;$";(Z/"&I52UD.#U'\&0]!```"&P]!&UL#&AM+ +M+UOS&"]+$&YKD05J+TL!8`1D@6:\@0%D544?4`AD544@,`?)`60A,0+(`F20 +M`8*QP5"OCPX``&(%9(%FO($!9%5%'UH@(`/)!&05`#Y`"&!50D1M;_A@;2P%@4&209KR!$&ZGD1M;!QH; +M2RE@A6*W@2$Q_,@A,`+(4K%9#@QLCH^ZLN)#XD'D4>-3`0#A1^%%``#A0>%# +M`0``````[%#M4@$1[$#M0@A@54$`8.I``6!500!LCH]`4`4?!\D$'P7)(%`A +M,P+(=;`N6T,@_L@,XA9@D&*W@84!L(\.`#\9VD`_&-M*[[$`8*%BMX&%`7\8 +MVTH$XA)LCH_UL1!LCH_@;)J/`F!80,5":5`0&6E`6U`A-0G(WQE;0,8/2@X` +M8!A!&4'&#EY0(38-R%Y0OQE>0(U0CE)<5%U6%P`$SP!@7$!=0"M0+$`"V:L@3B`&"!8BFR:5`"&VE``F"!8K>!CP$"XEVR(3`$R2$S`LDS +MLMN\`&2!9N)'XD7D5>-7IT2H1H4!#@`*'PC)%!\)R3R +M%&R.C^)LFH^ZL@%@@6*W@1;B(3_RR$$R!,@#9%5$C+)",@3(!V151(RR`&15 +M1+"/8$*PCPX``QEA0*2R`&151"$QV\@A-"+)&`!@0JJ/(3,#R4`;H;*_&4,9 +M(!MA0!]0(#`(R6%0_!D/`)-0&0`5`&%`"]U?O03B!FR.C[:R%&R.C^)LFH^Z +MLF6Y`&@!:E5+60[4`0%@I4``8!!B^*,``%@/60_,#E?BU`$(#P%@@6*W@1D` +M&0`9``89`1N"`0-@@6+B0^)!``#D46!`^!GC4V%"%0`?6B`@!,@#9(%FO($B +M8-)BMX&B0")DTF8`8+R!``X`8`UB"@`$:@!N`6"!8K>!L(\.`/\9"``-`!`` +M#``!%``>!LD-`!9N`I,,`/.R;E1O5J-0$``(``T`^$#Y0A<`$,P+``$5"@`` +M9!<`W<@$P0`/'FSQLO90]U(!$?9`]T(DLP!@R$``8!!B!Z(``,8/2@X`8`/B +M1U`LLT10&$$90TH/Q@X.XA]:("`&R`-D@69@4&%2O($B9-)FHE"\@0!@8KD# +M#H!0^QF`0()0`1N"0`!@$T`W4/X9-T`$X@1LCH]1LQ9LCH\"W52S\K-(46I` +M0#`$R0`.`0Z5M_P9=$"KCXWO0$/`%(0OXYK6B$F`L@($1<`!,T`#P$.E[=T4$$R$,BICPD?`LZ*LPH5 +MA*.NMT6XQ;@5N52Y5+D`#@$/E;=A4/P9@@$^4`<9%0`^0#AJ6$L%#P+2FK.K +MMSD/2H\!#@(.<%!Q4@1D$@`H02A##U$@&P]!T0[0#B!DST?/17!0<5($9!(` +M%FH(`&I0C!F('PG("0`"9!(`"!7.0\Y!&&K"LPD`"!7.0\Y!<%!Q4BAD%P`" +MSLNS:U`A-@3)(&#.0\Y!T@\"_\^S``"J`0!FT$?016I0:U(A/@?(0C(%R4`R +M`\B+-`')*$&/&=!!:U`H0?<9SQG006Q0*$%M4"A!!MT(Q@]1WQD/05JY.@XY +M#F6Y`@X##Z*/`VX?6D`C#D +M``!&M$:T1[3XM/>T`0X84$"D``!&M$:TMK2VM+NTF[E?Q@%D940!N@A@`V1D +M1'RZ"&[005"4#+4`8'5``PYI4`0;:4`94"$T"T`L?WM`5D940!N@1@9D`:N@+#][0";DA1*$&BE`RU&EHA +M)+3)][0:6B$CQLGWM!I:(23%R?>T&EHA(ZC)][094"$T`\DA-SW(&%H$'@C/ +M(2!-R4S'-L0A(4G)][0'9&5$`;KF4.=2`1'F0.="M&P#;@$/HH]"`4,!%P`# +MR-"4X+0!#N10Y5(!$>1`Y4+?M**/WI0"W>.TC;JBCQE:(2`+R6M00#`.R"$B +M`\@A-@K(&%!E,`;)!<,A(`+)][0##KZTF[ET4*F/#QG\I/>T][3WM/>T@K2/ +MM(JSBK-3M).T][1'M$>TBK.*LXJS&&!G0`$.`@YI4"$R"\AX;`AN2%$H00`! +M%95G4`@19T`7MFI0C!F('P[(2%$H09Y`034#R`1@Q4!(4RA#GT)G4`(19T`< +MY\50(3(:R1G&`M,]M1;J2P\``!A1!1\1S@#3/K59#@SF#,8`\P%@JD``8!!B +M0*T```%@6$!+M9NY`&IU2FM:(28VR,Q:`1X%R1E:(2,&R!>V&EHA(0+(%[8` +M8!-`!&Y';`)@54%(40`!894!8%5!1E$20"$P+,F&M0)J54M'4$A2251*5@%J +M54N@;2A!``$H0P$!*$4"`2A'F`%G6@009THA-77(`&H32H!J=4H7M@)J54M* +M4,`9&``8``X`0V00`(8!0`$!:E5+$T"II0+'%[:%`1D`&0"69!``"@!``2$A +M!,D#&1-`IK4P&:F/$T`!9%5%J:5KM:VU![NPM8!J=4H7M@]1WQD/00)J54L$ +M;D=L0@$H1;>5H$4":E5+8E1C5D=02%)B0&-"%P!(42A!2%,H0V14959D0&5" +M`6I52PK(%P`(R``/`@^6#Y,/$&J42]NU``Z3#@(.Q5`A,@K("<$`8!-`9U`& +M$6=`@&!U0!>V2%4H189%2%4H18=%9U`($6=`Q0XP:G5*Q0\7MJN/,!F&`0]1 +MWQD/0<4.`@^6#Y,/`&IU2L4/Q0[%#P)J54M``0%J54L`'Y1!!$L@`X9T.@@$(;@!@*$&4 +MEAM1YQD;0750%0`#Y4`;H[;`&Z.VG0Z5#X(!#U'?&;\9#T&0`8Z)=HPH0;^V +M`&2"`9T.:5`A,B')(3,)*$&!C`!@:%!I6B$C`\@A(=W)W.)P5'%6&0"'`84!`F"K0`!@$&(O +MK@```&!54!``"`"]`:(0OXX/`!(`64!:0@@``FI52^A0Z5(2``!D`V[J;"A! +M*$-``4$!$P`&ERA!*$.P4"A!L5`H0;)0*$$`8"A!`6I52R!@54$!8#-``6!5 +M05E0*$%:4"A!`&`H07:,*$&!C&E0(3,XR2$U-LD94"$U,\@RY@)J54OH5`%J +M54L!:,$!2P\``!!1%P`#RQ(`0[>%`?]@$@"J`1``651:5A```A$(`$D.>%!Y +M4A``$$$10P!D>E![4A$`$D$30WQ0?5(1`!1!%4-^4']2$0`601=#`6C!`4D/ +M&%`$'R#(:5`A,B[((34LR0!@`E.NCP@``%$!4ZF/%0"(9!-F%P`"S@D`D$&1 +M0T]@DD'!#P````#2`9!1D5-R0'-"AK=T4$`R#\@#4"$P#,A`4`,?"<@``(5@ +MA4!R0G-"`&`08@NAXKPZ#CD."\,$X@ALCH^>MQALCH_H;)J/SHFZL@#3!>;J +M;)J/TXFIMZ2YSHGBO/ILFH^;N:YL!FX##P/K2%&UMTA10@$7``/(L9>[MP,. +M7L884`$?!,D"'P+)&;C4;`9N2%$``<27`MW*MT2X`--9#@+FS[=#N`#S!&"J +M0`!@$&)`K0``U�#A0T4``8-)`TT+.4`$;SD#0;`IN0`%`0>*7`^)'5.FW +M1%0!#P%@K$``8!!BGZP``,Y0_AG.0%D.85#\&8(!/E`'&14`/D!*CQ!@*$$H +M0VI0*$%K4"A!;%`H06U0*$&N;`9N0`$H00F8U&P&;D`!*$$.F*0/`V!VC"A! +M@8Q9#\P.8KD`TRGF:%`9`(4!DA"_C@/B150DN$)4$`"'`1!5`&8`8DL/```0 +M41<`!,L2`(4!-[B%`?]@$@"J`1``A0&J`;@!$@!55!(`Q@]*#AA!&4-*#\8. +MXKRDN66Y`6!`CZYL!FX##P/K2%%.N$A10@$7``/(2IA4N`,.Q@]+#P/B1U1: +MN$14&%$94\8.%P`HS,*X:%H$8*U`X+ZH`1D`!>*%`3A_151\N!D`&0`9`&%: +M$&1512$F`LD$$88!0`$P'P+(`6(!:E5+0E00``\`;%!M4A<``\K(8(6X$@`! +M`&"(TD#30M1L!FY(40`!BY@`TS7=,^8"Q[:X`PX`\P=@JD``8!!B0*T``,1@ +MT$`X4-%`T&P*;D4!0$NAF,Y0`1O.0`$/`^)'5*RX1%0$8*Q``&`08I^L``#. +M4/X9SD!BN6"(3U`8`!```^)%5+ZX0E00`&Q`;4+3B>*\I+EEN0)@0(\@4"$S +M!,@"XLVXS`^N;`9N`P](44(!%P`#R-"8U[@##@#3/.8"QQ*Y0%`$'S7(`&!V +M0`-0]QF/0````/,!:,$!60X@6B$G"\@$6B$@",D;6_@8&TL/6_P8`1H/2X]0 +M(3$,R1]00#,)R5!1(3(&R"!@SD``8!!B*JT*8*I``&`08D"M````8!!B`VI` +M2L1:(2`"R#"OI:G3B>*\I+FN;`9N`P](44(!%P`#R!B9'[D##@#3,^8"QTZY +M0%`%'P7)`&!L0&U`3KDD#@!@=D!W0(%0(3(@R0]0BT`04(Q`Q%`!&2U`Q$(` +M8!!BE*X```!@$&(_KP```6#.5`\`0!D5`':,*$&!C`)@0$``8&Q`;4#3B>*\ +M`&`08@NKI+D/`!`?`\@##XVS>+,##@`/<%!Q4@AD$@`,`">V`&`08B"@`&`0 +M8D&A:5`A-`7(`&!I0`1@<+D`8`+F`1L36@(>%\@W6B$@%,@`X9T."&X`9"A% +M>YD;6^<8&TMU5!4``^5`&X>YP!L/6]\8OQ@/2P+G`AL*Q)4/`N:5N94/&&[4 +M`9.9=505``%J5DN5#P$`#U'?&0]!.@XY#@#3`^;3B>*\`&8054L/```041<` +M!,L2`(4!M+F%`?]@$@"J`1``A0'&#TH.`^)>8+JY;&&J`1(`5502`!A!&4-* +M#\8.6U`@&UM`!.(*;(Z/R[D:;(Z/[FR:C^*\``X!#@(.`PX!``!@4T"&O@!F +M2P\``!!1%P`$RQ(`A0'EN84!_V`2`*H!$`"%`6Q0;5(A/QC)Q@]*#@7B1U00 +M``-D\[E$5!``!602`*H!$@!55!(`&%495Q<``\P801E#2@_&#@$`U&P#;DA1 +M``$H0=!!1D%(40`!*$'0049!`YH+W650$:I&M$NT1K1&M(6TG+1GM,BTC;KF +M4.=2`1'F0.=":5H!#[142%$H0=!!1D&T5+562%,H0]!#1D,A)@/)U$#50A<` +M!\GD4.52`1'D0.5"`0ZV5$A1*$'0049!MU:ECT9#(28#R=9`UT(7``+)`0ZX +M5$A1*$'0049!N5:ECT9#(28#R=A`V4(7``+)`0X`;@!L-=UF4%NJOK1&M&JT +M>+J?M`$/`&I(42A!_Q\-R`5N2%$H0?\?`LD!#B'=9YH"P@9J`0YXN@-D9D2T +M;`-N`0\FNF-0>JI&M(BT`.NP0Y]!G0\"]H"ZG0X*W610AJI&M$:T1K1/M&"T +M>;2^M#H..0YEN13$E0^WBJ2Z_E#_4@$1_D#_0@%@S4"?4;!3#```9!<`\,E5 +M8+&*`-,W6B$@`LF=#FB)=HPH08&,S4H#YM.)XKRDN0+$E0\`URA!LYH&Q`+9 +MM[J;#IH.DPX!`-?G`N;"NN3VP+K%4"$R`LD"QW^V`/,-8*I``&`08D"M```L +MOP0.T&P*;D4!0$O2F@8.SE`!&\Y`$U!#,`?(#L!U6G`>%,D"8&9`$<1U4$`? +M#LGJNG!J=4KSN@)J54NDC@%J54N;#Y@/0&!U0,50(3(#R`,.!KL#XD=4_+I$ +M5`$/!V"L0`!@$&*BK```SE#^&<9$!L;00]1(!M`&P]! +M`FI52UE@QT$!8,9!`6I52W!0<5(L9!(`%FH(`&I0C!F('PS(GE`/&<=!QD'0 +M00!@T$$)``(5&&HSNPD``&3'1<9%`F1518!`@4)"9,M%U0^J`2!@$@`"%8)` +M`615109NU&Q``<=!QD%#FP)D544-8`)N1VQ"`2A%T4'200$5QT7&14R;250H +M14I:*$L$;DA5*$710=)!`17'1<9%69L.8-%!TD&!4L=#@%#'08%2"```8,9! +M`6#&00%D545G4`@19T`"9%5%P!@`8J@!&0`9`(8!$&Y``<5!?)L!9%5%%[8! +M9%5%<%!Q4@059U02`+!#GT'1#S=0`1LW0`)D544`8H)0#```8-!!E9L!9%5% +MG0]+ML`8`&"H`1@`&``.`(4!KP$24(4!&0`9`)ID$`"Z`0H`0`$`8B$A#\F' +M`0,9%P`#R`!J`0"X`1D`&0`#&1<`",@!:@$`&0`9`!D`&0"ONX!J=4H!```` +M&U'G&1`;&T$/42`;0!L/0=$.``#0#P)J54M98,1!`6##00%J54L`4`%2(&02 +M`!9J"``$4"$T"\@";E5/V%`/&<1!PT$)``(5&&KPNPD``&3$1<-%`F1518!` +M@4)"9,E%(&3-1\U%(!',0\Q!U0^J`2!@$@`"%8)`T@\"_P.\``````````#0 +M1]!%P%!`08\9T$'!4$!!I0_W&<\9T$'"4$!!PU!`0<1L!FY``4!!T$$;G`9N +M0`%`0<1!PT'002"<`O\FO`9N0`%`0=!!*9Q``4!!#QG004`!0$$`&=!!`615 +M1010(30,R`)D54784$!!#QG00=E00$$`8-!!1[P"9%5%X&P(;D`!0$%)G.=L +MM0$$;D`!Q$'#00$4K@%/G.%0Q$'#0>!0Q$'#08%2Q$.`4,1!@5((``!@PT$! +M8,-!T0\`8H)0#```8-!!:IR<#@D`"&00``%J54L(``!@$&+-JL0.`_O##P$` +MQ`\#^\,/`0#X^L(/`0````3;`&HH2X&\`0`$:@!N$N(@4"$P#\D(9%5%[5H! +M9%5%`!X$R05NU`&5G$=@TF(!:IV\`6"!8N)#XD'D4>-3!^(/`"!0(3`/``3( +M&``8``X`_QD"XK"\&``8`+Z\"``-`!``#``!%``>!\D-`!9NNKRZG`P`B;P- +M``AD547M6@%D544`'@S(]$`.`(`;]4`(9%5%`6KM2@%D547:O/Q`#@"`&_U` +M`&`(9%5%[4`!9%5%`0`!8(%BMX$A,0+)<;(`Z@+BY;Q9#AM1YQD;00]1WQD/ +M00%J5DL%8*5``&`08OBC``!9#\P.(&I52P!@,U`!:E5+`1]AR`!@(&I52S-` +M`6I52PB]S%H!'E?(5L55YBGB55H`'E'(`V"!8K>!5T)60/@9&EH@)0+)`QL# +M9(%FO('4`2`E`LG4`8>,&EH@)0K)5U)64/@9!1L#9(%FO('4`=0!AXQ74E90 +M`V2!9KR!7;T$8(%BMX%70E9`_AD!&P1D@6:\@05@@6*W@95"E$#\&0$;!62! +M9KR!"&C!`8>,E5*44/P9`AL%9(%FO($(:,$!AXQ74E90!&2!9KR!E5*44`5D +M@6:\@]0E`!%4E`@5`A,@+)>+X*4`M2!&00`(%:(2<#R2$F`\@$9(V] +M(2`#R2$E`\@(9!``"`!A4`-:(2(#R;\9EKU`&V%`!E#'0,:]!!\9R`1:(2`& +MR2!:(2<#R450I;U"4`(524!A4`-:(2(#R;\9KKU`&V%`AU2(5@90QT#)O7!0 +M<5(49!<`#F0!R`/B15"^O4)0`15)0&A:`&"M0."^J`''0(4!+>+-O01:(2"% +M`2C)SHZJ`8]:(2$&R2$C!,C$6B$@'%#DU`A,`/( +M&0#EO6%0`QD.`!D`&0`.``%D%0`!9(!FX4?A10``X4'A0WB^4;X```90QT#. +MCH]:(2,&R2$A!,C$6B$@#^#P`8`!@`1[X/`!@`&``8 +M`!@`+KX!:J\!#P`8`!@`&`"009%#"VJ22\$/`````-(!D%615Y);DE&]`0`? +M`\@)`$>^(2`%R`!J`Q\"SH`:"0`!$0@`.5!*K@$``&`08D"L`&`08D*I"0`" +M9(!FO($,``!@85"ICP09`&1A5!4`!QD*'@+(^QD.`*@!`62`9KR!@@$-`)A$$5?I1A)1ZD`34>M`%%'L0!51[4`64>Y` +M%U'O0`91L$`'4;%`"%&R0`%J54M34**NUKG3MD`!HT%``:1!0`&E04`!ID%` +M`:=!0`&H04`!J4%``:I!0`&K04`!K$%``:U!0`&N04`!KT$!`*X!$&I52T`! +M`6I52P$`K@%`:E5+0`%!`0AJ54L!`!M;_A@;2PX`&``8`!@`&``5``$````` +M8*@!&0`%'QQ:.R05@(2$;R0]@(2`8 +MR0U@'K\```!@J`$<6@H?#\D4'PK)-Q\%R12_;F`A(PC)-V`A(@7)%&`A(0+) +M"F"%`:U0(:_$O0!@$&(XJ&2X`&`08EBI`&`08O&IU�#A0T4``8&M:(2(" +MR&"(TD#30L^Z&``8`"``'``<`!@`+``D`"]4%0!A6D`8J@$5`"]`:%`N0`$` +M"6`H04%0*$$(8%5![E`H0>]0*$$!8%5!"FX`8"A!5Y]H4"A!(%`A,Q#(/E`A +M-0W('U`@,`K)"&!50?!0*$'O4"A!`6!507B_8%`H06%0!>)!,`/(VE!WO]M0 +M*$$%;@!@*$%ZGR!0(3,$R#Y0(34"R6%0*$$`8"A!+E`H02]0*$$`8"Y`+T`! +M`"!@54&W`4`!00$!$;X!``$!`0%@54$!`+`"``&(Y3(`$`(`1^CE,D_I]A(!L`(``8CE,@`0`@!'Z.4RC^GV$@ +M&``@`!B.4R`!`"`$?HY3+/Z?82`5`"``&(Y3(`$`(`1^CE,P_I]A(!(`(``8 +MCE,@`0`@!'Z.4S3^GV$@#P`@`!B.4R`!`"`$?HY3./Z?82`,`"``&(Y3(`$` +M(`1^CE,\_I]A(`D`(``8CE,@`0`@!'Z.4T#^GV$@!@`@`!B.4R`!`"`$?HY3 +M1/Z?82`#`"``&(Y3(`$`(`1^CE-(_I]A`!B.4T0T#A!`,@X0/#`.$#@N#A`T +M+`X0,"H.$"PH#A`H)@X0)"0.$"`B#A`<(`X0&!X.$!0<#A`0&@X0`!A.00`V +M!1`@@0\X`!AN0R`5`"`0_I]AH!,`(!3^GV$@$@`@&/Z?8:`0`"`<_I]A(`\` +M("#^GV&@#0`@)/Z?82`,`"`H_I]AH`H`("S^GV$@"0`@,/Z?8:`'`"`T_I]A +M(`8`(#C^GV&@!``@//Z?82`#`"!`_I]AH`$`($3^GV%(_I]A1`!."T``+@L\ +M``X+.`#N"C0`S@HP`*X*+`"."B@`;@HD`$X*(``N"AP`#@H8`.X)%`#."1`` +MK@D$@.T+((`/.`@8;@.H?HY3$#X.$("1`"B@*SN%7!)!@"($!`"`$!``1(/W_)P0&`!$`?#]@ -M=.\"``3^($!(`@T0`'Q?8``"``!,!`T0`/Z?8%`(#1``A"!`!/X@0/S_(&`$ -M`@T0`(`/.```'SAK`0`````?.&\!`````!\XN!7@?[_)P2` -MOQ____]_#``-$`0`8`@8`(`(`?YA0`0&`!`(`(`+,`@-$```+@@`^N!7`@D` -M(`0`[@L(`&X+#`!."Q``+@L4``X+&`#N"AP`S@H@`*X*)`"."B@`;@HL`$X* -M,``N"C0`#@HX`.X)/`#."4``K@D@@0\X1'Z.0P0`#@@"@!\2"``N"`."'Q(, -M`(X/$`#N"Q0`K@L8`&X+'`!."R``+@LD``X+*`#N"BP`S@HP`*X*-`"."C@` -M;@H\`$X*0``N"D0`#@I(`.X)3`#."5``K@E4`(X)6`!N"8@`#@@!?N"O7`!. -M"6``+@ED``X):`#N"&P`S@AP`*X(=`"."'@`;@A\`$X(@``N"(P`#@@2@!\2 -MA``."""!#CBH?HY#`/SO8_____L`@0\X`/SO:P````0`@0\X`/P/8`````0` -M_.]C____^P"!#S@`@.]K`($/.`#\#V`````$`($/.""`#S@`(``(((`/.`"` -M`!*``@X0A``.$```#0AX!@X0`'K@5WP$#A`A"@`@`7X`0```#1!4&`X06!8. -M$%P4#A!@$@X09!`.$&@.#A!L#`X0<`H.$'0(#A`"H%\)`Z`_"0QX#A`$%`X0 -M"!(.$(AR#A",=@X0((`/.!0Z#A````T0#``M"%08#A``^N!76!8.$`$)`"!< -M%`X08!(.$&00#A!H#@X0;`P.$'`*#A!T"`X0`J!?"0.@/PD,>`X0!!0.$`@2 -M#A"(<@X0C'8.$!0Z#A`(N``0((`/.`@`C0L@@`\XJ'Z.0P2`OQ____]_```- -M"`%Z`%````T0`0T`(`0`#@@"@!\2"``N"`."'Q(,`(X/$`#N"Q0`K@M4`(X) -M6`!N"8@`#@@!?N"O7`!."6``+@ED``X):`#N"&P`S@AP`*X(=`"."'@`;@A\ -M`$X(@``N"(P`#@@2@!\2A``."""!#CBH?HY##``-"`!ZX%"#0`@"`"`"P0`#@@"@!\2"``N"`."'Q(,`(X/$`#N -M"Q0`K@M4`(X)6`!N"8@`#@@!?N"O7`!."6``+@ED``X):`#N"&P`S@AP`*X( -M=`"."'@`;@A\`$X(@``N"(P`#@@2@!\2A``."""!#CBH?HY#"`#@"`'^WV`` -MC`,0&+8#$!RT`Q`@L@,0)+`#$"BN`Q`LK`,0,*H#$#2H`Q`XI@,0/*0#$$"B -M`Q!$H`,02)X#$$R<`Q!0F@,0,`!-"`!ZX5<`_O]@`0$`(!@$`!`P#@T0#`X- -M$`"'_R>090``@+J,`0@$#A`L``T(,`!-"`%^`$``>N%7+``-$`P`#A`0`@X0 -M%`0.$!@&#A`<"`X0(`H.$"0,#A`H#@X0+!`.$#`2#A`T%`X0.!8.$#P8#A!` -M>`X0`J!?"0.@/PD`H!\)1!0.$$@2#A!,$`X04'(.$%1V#A!8/@X0$'Z.4X`Z -M-R@0?HY#4``."`%^X*]$`$X)2``N"4P`#@D"E!\2`Y(?$AE^Y(@`@*,?$``N -M"!0`3@@8`&X(5``."!*`'Q(<`(X((`"N""0`S@@H`.X(+``."3``+@DT`$X) -M.`!N"3P`C@E``(X/#``."%@`[@LA`P`@`/X_8`%Z05`P!`T0`@$`(`'^/V`T -M`@T00``-"```0`@`>N%7@0$`(`'^/V`@!``@1`(-$#P`30@$?@!```7@5T`` -M#1`"`0`@.`!-"$`$#1``^N!7`0\`(```#@@$`"X("`!."!`^#A"`BO\O1`!- -M"`!ZX5N!7@@$`(`P`#0@8`$`(,`0-$#1\#1`` -M````@)C_)P``#@@$`"X("`!."""!#CBH?HY#````0````$````!``'P`%``` -M'S@$`@`4`%4`(`0^#A``-@X0`#AN8P```$````!`````0`!\`!0``!\X!`(` -M%"!0`"@0?HY3!(#M"R"`#S@0$&X+`(-`8`#^/V`"!``@`!\`(`"#0&``_C]@ -M@1T`("04`"```>!'____?X41`"`/>N!7`?[?8`T+`"`'>N!7!/Z?9PT$`"`# -M>N!7`_Z?9PT#`"`!>N!7`OZ?9PT"`"`@`@`@`?Z?9P`&`!@`!@`8``8`&``& -M`!B``@`P``$`0`""($@`A>!7!@P`0`:$(%``@0\X``'@9R#^OV"!`@`@!`(` -M(``!`$`!_J)00___)P`!`$`@^/\G`(J"9Z`!`"``_A]A`?X?80"$0%``$`1) -M!8$`4`'^WV`@_I]G@`(`,``!`$``@B!(`(7@5P8,`$`&A"!0`/[_8`-ZY%<" -M@`-0`7KD9P*"(U``@0\X_X4?&""!#S@`_C]@$`!@"/S_86"X_F%0`/P!$`$` -M````_K]@!(H!$`B*`1`,B@$0$(H!$`#\P&@````,%(P!$!B*`1`N%7``"`8`!ZX5?_?T%``8`/.``"0A`` -M>N%7_W]!0"&`#S@!?H)`H/W_)P`"0A````````6!9P`"@&@!@0\X`WKB9P`$ -M@1B"$0`@``2"&``$@A@`!8(?!/X@4`1^8%`"!``P!)"`"`20H`@$D,`(!)#@ -M"`2(`1$$B@$1!(P!$02.`1&E!0`@!'KA9____W\B!P`@`WJ!9P/^($`!@0\X -M`_YA0``!`#`!E(`(`8A!$0"!#S@$D(`(!)"@"`2(`1$A^O\G!(H!$0-Z@6<$ -MD(`(H/C_)P2(`1$!_B!0`7Y@4``!`#`!E(`(`8A!$0"!#S@@%0`@$/Z?8:`3 -M`"`4_I]A(!(`(!C^GV&@$``@'/Z?82`/`"`@_I]AH`T`("3^GV$@#``@*/Z? -M8:`*`"`L_I]A(`D`(##^GV&@!P`@-/Z?82`&`"`X_I]AH`0`(#S^GV$@`P`@ -M0/Z?8:`!`"!$_I]A2/Z?840`3@M``"X+/``."S@`[@HT`,X*,`"N"BP`C@HH -M`&X*)`!."B``+@H<``X*&`#N"10`S@D0`*X)!(#M"P@8;@,@@`\X!'Z.0P"# -M0&``_C]@@1,`("0(`"```>!'`?[?8(4%`"`&%*`8`?ZB0""*GE<`"@"`@@(` -M,``!`$``@B!(`(7@5P8,`$`&A"!0`($/.*`!`"``_A]A`?X?80"$0%``$`1) -M!8$`4/__OV`&%*`8`?ZB0""*GE<`"@"``?[?8(("`#```0!``((@2`"%X%<& -M#`!`!H0@4`#^WV`#>N17`@`#4`%ZY&<"`B-0`($/.```(&`@@0\X__\?8``# -MX%?_?V%`#@(`(`"$@$``">!7____?X4&`"``!>%G____?P&`#S@``(!@`(1` -M"``$0A`!?H)``/KA5___84`A@`\X`?X@0*#\_R<`A$`(``7A9____W\!@`\X -M`H9````&@$$`^N%7__]A0"&`#S@`!$80(/W_)P*&0`!$-`X00#(.$#PP#A`X -M+@X0-"P.$#`J#A`L*`X0*"8.$"0D#A`@(@X0'"`.$!@>#A`4'`X0(($/.!`: -M#A!$`$X+0``N"SP`#@LX`.X*-`#."C``K@HL`(X**`!N"B0`3@H@`"X*'``. -M"A@`[@D4`,X)(($/.!``K@D``!\(;+,"``"`#S@`?%]@9+0"``@!(0@"_B"` -M`(``0``$`$`0!0`(((`/.`@!`1```!\(R*L"`""`#S@`#@`8```?",BK`@`` -M?`!@`/\``""`#S@(?@"(```?",BK`@``@`\X!#X.$(#"_2\`"!\(-L("``)Z -MX%>,[?TG`+X/8`!\7V!DS@(`H*XT*';^/V"`__\G%OZ?8`"(0!`@`0`@`(JB -M4`'^HD`E^N)7"@0`(`"*@D``?,)`U,H"`!0%@P@`">!7@OO_)Q4%@P@`B$`0 -M#GK@5P%^`%`)``!0`(!!$""`#S@``$$0!#X.$`"W_2\``>!G@0$`(`"&0A`@ -MW_TG``A#$`",H1D`?-]AU,H"`&0'AQ``#&(99@F'$``0!%%D"T<)9@LG"6H+ -M!PAL"X<(H`0`(``0Y&``$(1@`!`$8``:0D$`#*49`!8@00",9!D!_N-``(SC -M&!GZXU>*"@`@"O[CIP"<'$!P!8`(``GA5XOX_R=Q!8`(``GA5PGW_R=R!8`( -M`(G@5XOU_R=S!8`(`(G@5PGT_R=T!8`(``GB9P*)X5<"\O\G=@N`""#R_R=X -M"P`(;`F'$&H!AQ!H#X<09A.'$&05AQ``FD(0(,7])P`60Q```$!@````4`!\ -M7V'4R@(```S#4`!\?V#4Q@(`$X4A"22!`0D@#0`@`(JB4`#\@D#4R`(`5`1B -M"``'X5<+"0`@501B"``'X5>)!P`@5@1B"`"'X%<+!@`@5P1B"`"'X%>)!``@ -M6`IB"``,Y!@`C^%7B0(`(%H*8@@`A^-7"0$`(%P`8@@`@`%``7[#0`S^HD`` -M$^-7B_+_)R"`#SA@`040``(`4``"`!@@@`\X``!!$`0^#A"@D/TO-/Z?80`` -M`&(`@N!A``2A80"B*%*@)C@H_*,-$``!X&<`',=1H@<`()W^?YJ`2/XO(``? -M*```P&$`@B!0H!,?*/S_34```>!G`0,`(`"^#V``?%]@P,T"`"!C-"@7_BE` -M@/__)P```%`@!`0`@^($-"``!X&>!#@`@`'Q?8B2R`@"5 -M10D(``'@9P$#`"``O@]@`'Q?8,#-`@"@630H'_XI0(#__R!G@@0`(*`\'"@`F@9@@$,-*``@"&`@^A@H`)XG8*"U#2@`F@9@@`$` -M(``@"&`@]Q@H`)XG8)4C210`"C@H``'@9X(+`"`@,/XO`!P'8(#D'BC\@2T( -MH/@>*/S_34```>!G`0,`(`"^#V``?%]@P,T"`"!(-"@Z_BE`@/__)_R!#0@` -M`>!G`0,`(`"^#V``?%]@P,T"`*!#-"@\_BE`@/__)R"1_2!G`6G])P"K$R@`:/TG@$$<(`"` -M#S@$/@X0@#O]+P!\/V"XK`(`(`@F*```H&$``#\(3-T"``":!F"@!28H"OX@ -M0```/PA0W0(``)H&8"`#)B@*_B!``'P_8-R8`@`@`28H`)H&8(!=_2<`?#]@ -M-*X"``$$0`B@<"\@`GY!0`#8$R"`\00@!#X.$``K_2\````(``'@9P$"`"`` -M?!]@`````@#4%"B`5/TG`(4J*"!Y$B@```!0@%+])P!\/V"XK@(``01`"*!F -M+R`"?D%``'P_8+"M`@`!!$`((&0O(`)^04```$`(!`@@"``$`6"@W"H@!OY? -M8`````@`?#]@"/<"`/Q[`&`A@`\X`(``$`!]X%<``0``!H`/.(#^'T`@@`\X -M`(``$`0^#A``%_TO@-02*`!T-2B`0OTG!#X.$(`4_2\!!(`)``0@"`A^AH$` -MF"!H`@2`"1!^AH$`F"!H`P2`"1A^AH$`F"!HH&$6*`".`!@`?!]@``"``("I -M"BB`.?TG``0@"`!\?V`4L@(``()!$``$(`@&_N"G`/)<8`1^`$`@2R\@!/XA -M0`!\/V"TK@(``01`"*!(+R`"?D%```\4(`0^#A"@`_TO8/Y?8`!\/V`0IP(` -M@$0O*``$'P@XKP(``'K@5P'^'V`@Q!(H`@``4``T_R\%>N!7!2K])X`W_R\/ -M>N"'A"C])P!\'V"TK`(`($8/*`""(%``)OTG`'P_8,RM`@`!!$`((#HO(`)^ -M04`$/@X0@/K\+P``H&$!!``(`'S?8;2L`@`C`$<0`(0&""`H_R\B`$<0!7K@ -M5X4"`"``*_\O#WK@AP,,```@`@9'$`"((F@$`D$0`GY@@!J$!@@```!```8`0`.` -M/X`(!`$(``(@<`@"01`:A`8(````0``&8$`"A`8(``8`@``"`&@(`$$0`(0& -M"`Q^)T`&?N"G!OY<4!3^!D`@DB4H`(0@0`"$!@@:A"8(!/Y&0"`#+"@`AF%0 -MH`0`(`($9P@!_B%0`(Y@&`("1Q`"?@"`#X`_@`@$`0@``@!P"`!!$`"'X6>! -MY_PG`!P'8"!C*B@`@B!0@.7\)P0^#A"`NOPO``"@80""`&``?-]A,*T"``)^ -M)T"@]2XH`)I&8*#@_"N!7`0$`(`5ZX%<"V?PG`'P_8%BP`@``B``(`8`?<`"`@!``?!]@ -M```!`(!#"BB`U/PG!#X.$`"H_"\``*!AH#82*````%"@QA,H`)H&8`"`!@@! -M?@!@``"?$%BP`@"`UOXO`7K@5P$!`"`%>N!7@LS\)P!\'V````$`@#D**(#* -M_"<$/@X0`)[\+P``H&&@^#@H````"(#W-"@!>N!7@L;\)P```%``FB9@H)4D -M*``$05``Q/PG!#X.$("7_"\``*!AH+LA*``(``@`B"8(``"?$&"P`@```A\0 -M!/@"````GQ!TIP(`@+W\)P0^#A``EOPO``"@80`$``@(?B"``H0&"``"`&@` -M?>!7``$``"$%`"``',=1B1X`(``!X&>"!P`@`'S?852M`@``"0`@`'S?892M -M`@"`!P`@`'S?862M`@``!@`@`'S?872M`@"`!``@`'S?882M`@```P`@`7K@ -M5P'Y_R<`?#]@2@(``*#),R@`O@]@`)[G40""(%`@`0`@`81F"`'^($``A^!7 -MB@,`(`""!D`$!$`(``('0`($``@``>%7@?O_)P'^_V$!!D<0`81&"`3^!D`@ -MN"XH`GXG0`"J_B\%>N!7!:/\)X!F$R@`G^=G`G80*`!\OV&TK`(`;(@&""#" -M$"@`@B!0`!8(*`"I_B\/>N"'!)W\)P":!F`@N`XH`((@4`";_"<`?>!7`0$` -M``'G_R<`?>!7``(```'D_R<`?>!7`0(```'D_R<`YO\G!#X.$`!J_"\)!"`( -M`OK@5P!\WV&TK`(`H@(`(```H&$```!0'P!'$"`!`"``@B!0'P)'$`F$!@@` -M`%\0=+`"`&`$!P@``>!G`0$`(`3^`&@?`$<0`X0F"!D$!P@`@^!G`GP`:`$` -M``!"`@`@&0!'$/Y_`&`9`$<0``X`&`2$)@@`@^!G`GP`:`(````!?`!@_?__ -M_QD`1Q``#B`8`X0&"``!X&!G -M!/X`:`'\`&#[____&0!'$``.(!@&A`8(``'@9PC^`&@!_`!@]____QD`1Q`' -MA"8(&@0'"`"#X&<"?`!H`0```$("`"`:`$<0_G\`8!H`1Q``#@`8"(0F"`"# -MX&<"?`!H`@````%\`&#]____&@!'$`J$)@@@!`<(`(/@9P)\`&@$````0@(` -M("``1Q#[?P!@(`!'$``.`!@+A"8(`(/@9P)\`&@(`````7P`8/?___\@`$<0 -M`H0&"'(`1Q`"A`8(H&O^+W(`1Q`%>N!7A0(`((!N_B\/>N"'`QP'8"-^#B@# -M@B!0`(0&"`A^7Q"TL0(```!?$`RG`@`.A`8(``!?$`VG`@`-A`8(``!?$#"R -M`@`/A`8(``"?$%3=`@``6?PG!#X.$(`K_"\``*!A`@0`"`!\?V#LLP(`!GY` -M@`&$!@@`A"%`(X!`$!2`!@@`A$%````!$!B`!@@$@``0`X0&""2`0!``A`8( -M(H!`$`3^!D`(_B!`(&N!7!D;\)X"6"2@`1?PG!#X.$"`7_"\``"!@``0`"`&$ -M0`@@4`0H`OX@0`!R-"@#>N!7`D#\)X!-_B\/>N"'A#[\)X!>!"B`/?PGH'(K -M(`""(%``?#]@6*\"``$$0`B@4"X@`GY!0```0`@$`(`(``1"4!=^X:<(`&`( -M`/*\8`"(05`/?N&G#```"`#R7&``!@!0"W[@IP`*`4``<@!``(``$""`#S@` -M``!0!#X.$"`&_"_\?X!@`'Q?8"2R`@"2"2$(`'R_80`$`````@)`!'Y@0`"0 -M`1@`&^!7D@>!$*L#`""0`X$0````4)`!@1``@B!0!'YB0`"0`1B2!X$0`)O@ -M5XL#`"``?%]@P,T"``!\/V!W`0``H.8R*`"^#V"`__\G`!O@5XLB_"<`O@]@ -M`'Q?8,#-`@"@XC(HO/X_0(#__R<$/@X0(/'[+Q3^GV&`>N!7"P,`(`"^#V`` -M?%]@A-<"`"#=,BB,_C]@@/__)P```$``#@`8`7X`:/Z!C1!I_A^``OX_8/[_ -M34`@0"TH`(9A4````%`@*?PG%/Z?800^#A"@[_LO+/Z?80``H&$`@N!A```@ -M"`0```@``B!`"(`&"``"($`,@`8(``(@0!"`!@@`@"!0%(`&"`"`(%`8@`8( -M`(`@4!R`!@@`@`!0`'P_8,JT!G`?X?8""`#S@"``!0!#X.$*#+^R\'_A]@H%0?*`'^/V``!!\( -M<+,"``%ZX%<`?+]A(/8"``("`"``@`8(*WX`:"#Q^R<`@`80`$X#**#?`B@! -M_A]@``@?"`##`@``?>!7(T(``(("`"`D_A]@($H?*`""(%"@V@(H````4("8 -M`RB`]O\G!#X.$"#,^R]L_I]A]OY_0@``X&&`_C]B`'R_8<#%`@`%HT80!*-& -M$`>C1A`&HT80":-&$`BC1A`@`0`@`!S'40%^QT$$>N=7"@\`(``:!T`4!0`( -M`GX'@@J!1A#`_TU`!/\&0`""(%`@K@`H`"!!0``!X&?@_TU"`@8`(`3_!D`! -M_C]@H*H`*``@24```>!G@?7_)P"^#V``?%]@W-<"`*"6,B@%_BE`@/__)P"^ -M#V``?%]@W-<"`*"3,B@!_BE`@/__)Y[^'V`%@480!(%&$`>!1A`&@480":-& -M$`BC1A`@`0`@!/[?80%^QT$(>N=7"@\`(``:!T`0!0`(`GX'@@J!1A#`_TU` -M!/\&0`""(%`@F0`H`"!!0``!X&?@_RU"`@8`(`3_!D`!_C]@H)4`*`"@2$`` -M`>!G@?7_)P"^#V``?%]@W-<"`*"!,B@5_BE`@/__)P"^#V``?%]@W-<"`*!^ -M,B@1_BE`@/__)\#_#4``GB=@(#<`*"#_1D```>!G`0,`(`"^#V``?%]@W-<" -M`*!X,B@9_BE`@/__)P```%"@Q?LG;/Z?800^#A"@E/LO:/Z?84/^7X(``,!A -M@/X?8`!\_V'`Q0(`"8%'$`B!1Q`@`0`@`)JF40'^ID$$^N97"@\`(`">!D`8 -M!0`(`OX&@@J!1Q#`_TU`!/\'0`""(%`@>P`H`"!!0``!X&?@_RU"`@8`(`3_ -M!T`!_C]@H'<`*`"@2$```>!G@?7_)P"^#V``?%]@W-<"`*!C,B@*?BE`@/__ -M)P"^#V``?%]@W-<"`*!@,B@&?BE`@/__)Y[^'V`)@4<0"(%'$"`!`"`$_K]A -M`?ZF00CZYE<*#P`@`)X&0!0%``@"_@:""H%'$,#_34`$_P=``((@4"!H`"@` -M($%```'@9^#_+4("!@`@!/\'0`'^/V"@9``H`*!(0``!X&>!]?\G`+X/8`!\ -M7V#!G@0,`(`!\7V#N!G@B@`(!]_"$"@,BTH='XH0*!4*B@"_A]@($\`*``!G`0,`(`"^ -M#V``?%]@W-<"`"`C,BAZ?BA`@/__)P!\_V'`Q0(`#/V'$``$````?!]@&9`` -M``+^/V`,_T=`H(4L*`"&85"@`1A`F -M@$80(`0`(`""(%``_!Q`@N4"``("0```G@!`!`5`$`'^`$``#B`8!/K@5XO[ -M_R<,H8<0`'P?8!F0```"_C]@#/]'0"!S+"@`AF%0()3_+_[_#4```>!G`0,` -M(`"^#V``?%]@W-<"`*`&,BB:?BA`@/__)_Z%#0@H@$80_X4-""F`1A`@`P`H -M`!P'8)#^'T"@"RTHHGXH0"!1^R!G`0``4`)\'V`"`````H%&$`!\7V#,UP(``OX?8`/^/V`"_V9`H,DL*``( -M@E`7?@=``OX_8!+_1D"@72PH`(9A4*3^'V"@C2PH`((@4`!\7V!JSP(`3'X' -M0`+^/V`@62PH`(9A4(";*"B`+OLG`#X.$*`"^R\D_I]A$(*-$```8&``!*%A -M`'S?8<38`@`'_A]@`_X_8`!_1T`@NRPH``B"4`!\'V`]T@```OX_8!#^34"@ -M3BPH`(9A4"`$_R\&_A]@``'@9X$"`"``O@]@^?X_8*#B,2@8?T=`@/__)Z`M -M`BCT_PU```'@9X$"`"``O@]@_?X_8"#>,2@8?T=`@/__)_R)+0B`^N!G`OP@ -M:`#_```!CB`8$/Y`@/J)+0@`A"!``((&$"#@_"!G -M`'R_8<#%`@"B`@`@:?[_@87^'V`<@480(`(`(!3^/V`E_A]@'(%&$!;^/V`` -M@T80(&DL*`""(%``?%]@:,\"`$S^!T`"_C]@H#0L*`"&85``?-]AQ-@"``Q_ -M!T`,_C]@H'0L*``$05`"_A]@`_X_8`A_1T``_V9`()@L*``(@E`"_@=``OX_ -M8`[_1D`@+"PH`(9A4!?^!T`"_C]@$/]&0*`I+"@`AF%0H`#[)P```%`$/@X0 -M`-3Z+P!\7V#$V`(```'@9P)]X%YU$"_>A7`0````$#`"``O@]@`'Q?8/37`@"@I#$HXOX_8(#__R<` -M```(`GK@9P)2`"`9?@E`(*LL*.G^/V`@S2DH`OX?8*!6`B@`H@A@H+S^+PG^ -M'V```>!G`'S?8>C8`@"!`@`@`+X/8//^/V`@FC$H#']'0(#__R<@Y0$H]/\- -M0``!X&>!`@`@`+X/8/?^/V"@E3$H#']'0(#__R?XB4T(``X!&!!^((#TB0T( -M``(`0`A^`(@`#"`8"'X!D!!^0(#VB0T(`(+@IP`$`$`(?@"(``P`&`#R/&`` -M`."G`((<0""R$BCL_RU```'@9X$"`"``O@]@`7XI0*"(,2@,?T=`@/__)^R! -M#0@`?!]B\,4"``-^X*<`\AQ@H/K[+P7^/V#L@0T0"_X?8/*!C1`#_@E``OX_ -M8/+_34"@Z"LH`(9A4"`$`"``FJ91Z($-".R!+0@`@>!7A@``(``%Z`D!_@9` -M``Z@&0;ZYE>*&P`@!9H?4`&`'X``'@!``0%($``!2!`"_A]@`_X_8`!_1T`` -M?VA`($!G@@\`(/B) -M30@`#@$8$'X@@/2)#0@``@!`"'X`B``,(!@(?@&0$'Y`@/:)#0@`@N"G``0` -M0`A^`(@`#``8`/(\8```X*<`@AQ`H(X2*.C_+4```>!G@>?_)P"^#V`G?BE` -M(&4Q*`Q_1T"`__\G`+X/8!-^*4"@8C$H#']'0(#__R<`O@]@%WXI0"!@,2@, -M?T=`@/__)P$?2!``'T@0`*((0`!\`$!>Y0(`,1Y`$#`>0!``H^AG`0``4`)\ -M'V`"````"`%($`7^'V`#_C]@!']'0`A_:$`@*"PH``B"4`!\7V!JSP(`3/X) -M0`+^/V"@NRLH`(9A4`#^)RB@!`(H````4)#^'T"@6BPHH?X_0*">^B=$_I]A -M!#X.$`!H^B\`?/]AZ-@"```!X&<"?>!7`0````$#`"``O@]@`'P_8$\!```@ -M23$H#/]'0(#__R<``*!!`'P?8E[E`@`P?LA!`OX?8`/^/V``_T=``!IG0"`5 -M+"@`"()0`OX?8`/^/V`"_T=``!IG0"`2+"@`"()0`*`&0#`$``@``!\0;)@" -M`(!^^B<$/@X0H$_Z+RS^GV$`@J!AH%G^+P`.`!@``>!G`0,`(`"^#V``?%]@ -M"-@"`*`W,2BZ_C]@@/__)Z""`2CT_PU```'@9P$#`"``O@]@`'Q?8`C8`@"@ -M,C$HOOX_8(#__R?XB4T(``X!&!!^((#TB0T(``(`0`AZX(<$?`!H````_P5^ -M`)``#"`8``/@5P$#`"``O@]@`'Q?8`C8`@"@*3$HR_X_8(#__R<(?@&0``X` -M&!!^0(#VB0T(``0`0`AZX(<$?`!H````_P5^0)``#`$8``'A5P$#`"``O@]@ -M`'Q?8`C8`@"@(#$HU_X_8(#__R<`@N"G`/(\8```X*<`@AQ`H$,2*`":)F`` -M`>!G`0,`(`"^#V``?%]@"-@"`*`9,2C@_C]@@/__)R!J^B!G``HA"$$!`"`""@$(!`H!"`"!X%<)@`!0#`(`4""`#S@`$``8!#X. -M$``C^B\`?!]@(/8"``````@$>N!GUOZ_08)+^B=S_P9`H!8L*(W^)D"@."DH -M`OX?8``$'PAELP(``WK@5P$!`"`1>N!7"P@`(*`&`"``BJ)0`/P"0!#&`@`` -M!0`(`OY"@`!\?V!PY0(`_O\A0`"$($"@!``H`(1!0`'^`D``#J`8!?KB5POY -M_R>0_A]`(`DL**+^)D``//HG``"?"&BS`@`"`&(````"0`$$``@`A^%G``H` -M&`$!X&``(`-0.P# -M`!`!?L=!`)X?4``*X!D">N=7"A,`("J+!@@"_C]@`!X`0/Z!C1``?!]@!M(` -M`/[_34"@-"LH`(9A4`!\'V`^D````OX_8.;_34"@,2LH`(9A4`'^'V"@BO\O -M^/\M0``!X&<"!@`@`OX?8""(_R_T_RU```$`8@'N_R<`?%]@"-@"``!\/V`) -M`0``H,$P*`"^#V"`__\G`+X/8`!\7V`(V`(`H+XP*(/^/T"`__\G\($M".R! -M30@`A`!```,A4`=^`(!!!``@`?X?8H#$^R^@V!$HZ/\M0"J+!@CH@2T(``(` -M4"J!AA``(`A@(`;Z)SS^GV$$/@X0H,[Y+SS^GV$`GN=1`'R_81#&`@`LBP8( -M`?[?8>:!C1``?!]@!M(```+^/V#F_TU`(!8K*`"&85`@!0`@`"`(4O2!#0CX -M@2T(`(`@4`)^"(``@`U`[`,`$`%^"$(`G!]0``S`&0)ZZ%<*$``@+HD&"`+^ -M/V``'`!`_H&-$`!\'V`^D```_O]-0"`+*R@`AF%0`_X?8"!D_R_X_RU```'@ -M9P(&`"`$_A]@H&'_+_3_+4```>!A`?'_)P!\7V`(V`(``'P_8$4!```@FS`H -M`+X/8(#__R<`O@]@`'Q?8`C8`@`@F#`HH?X_0(#__R?P@2T([(%-"`"$`$`` -M`R%0!WX`@$$'`"`!_O]A`)[[+R"R$2CH_RU`Z($-""Z))@@`@`!0+H&&$`!\ -M'V`^D````OX_8"[_1D"@]2HH`(9A4*#6_R<`G@=@!#X.$("B^2^/_O]!``'` -M80!\'V`@]@(``GWG5P$````!`P`@`+X/8`!\7V`(V`(`H(4P*,G^)T"`__\G -M````"`1ZX&<"P_DG`?X'0"",*RCW_C]`(*XH*`+^'V``"!\(`,,"``'^/V`` -M?>!7(T(```&"(%!]_A]@`_X@0*`D`"@`'$=@H`$`(`":IE$!_@9```Z@&0/Z -MYE<*"0`@@)O_+P`!X&>"!``@@,'_+P`!X&` -M`'Q?8!#&`@`J"P$(`/P@0%[E`@`(@(`0+@D!"`J`@!"0_A]`(',K*(+^/X`` -MJ/DG!#X.$`!W^2\`?']@$,8"```!X&!7(T(```(#`"`` -M?%]@Z,T"``'^'V`"_C]@(*$J*`"&85`!_@A`#/X_8!#_1D"@GBHH`(9A4!?^ -M"$`$_C]@)/]&0""<*B@`AF%0//X(0`3^/V`<_T9`H)DJ*`"&85`*_@A``OX_ -M8"#_1D`@ERHH`(9A4"/^"$`"_C]@(O]&0*"4*B@`AF%0`'P?8!F0```"_C]@ -M*/]&0*"1*B@`AF%0@&KY)P0^#A"`//DO``'@9P)]X%!7(T(```3^'V`" -M?!]@`P````/^/V``_T9`"/]F0"#=*B@`"()0`'P?8!?2```"_C]@%/]&0*!P -M*B@`AF%0:?X?@`+^/V`6_T9`(&XJ*`"&85"`L"8H@$+Y)P0^#A``&_DO`'R_ -M80##`@``B"8(:?[_@0#]X%=G(/X?8`)\'V`B````!(%&$`#]X%"&ODGH-?_+P": -M!F"@^?PO"?X?8``!X&!7(T(``*)`_R\"F@9@`+K^+P`)^2<$ -M/@X0`.3X+P``P&$`?+]A9+0"``B!!@@!>N!7_?X?0H('^2>2_A]`H,\J*`%^ -M*$``Z2PH"($&"`!\_V$$PP(``GX`@``:`$`2!0`("($&$*`T_R\`@`<(()?_ -M+P"`!P@`?#]@7N4"``"*``@"@(`0```?$$B8`@`(@08(`GX`@``:`$`3!0`( -M"($&$*`&&R@"_A]@`7KG5P%\'V"TK`(`H1(+*`&"(%"`W"PH*W\(0*"^*BA4 -M?BA`@/3X)P0^#A``Q?@O`'R_833%`@`<@28(`(/@9P()`"`<@080`'P?8`"0 -M```,_C]@`?Y?8*"G)R@'_G]@`/\&0*#1&2C__S]@``'@9P$$`"``O@]@`'Q? -M8(37`@`@J"\H8?X_8(#__R>@Y/@G`?X?8````%`@X_@G'($&$`0^#A"`L_@O -M`(/@9P!\OV`TQ0(`@0$`(""!(@@`@^!G`@,`(`"^#V``?%]@A-<"`"">+RC9 -M_C]@@/__)P($0`B@I2`H`WX`0*#D&2@`_P)```'@9X'6^"<`O@]@`'Q?8(37 -M`@"@ER\HWOX_8(#__R<$/@X0@*7X+P"#X&<`?+]@-,4"`($!`"`<@2((`(/@ -M9P(#`"``O@]@`'Q?8(37`@`@D"\H=_X_8(#__R<"!$`(`GY!4``.01B@EB`H -M!7X`0*#5&2@`_P)```'@9X''^"<`O@]@`'Q?8(37`@"@B"\H?/X_8(#__R<$ -M/@X0H)GX+R#^GV$`@^!G@@,`(`!\7V"8UP(``'P_8!Y0(```(`0``,(!@`@(80 -M``(?$$28`@"@7?XO`?X?8`-ZX%>,`0`@@-``*`"*!@@$@(80D_X?0"![*BB> -M_C]`(,+X)R#^GV$$/@X0@(CX+X_^'T(``.!A`(+`80%^"$`@=BHHIOX_0`!+ -M^2\``*!A((7_+P">!V"@2_DO`)H&8`%ZYUY0(`H`,`(`""(%"`_E]@`(8`0"0$0!`J!$`0 -M`?X`0``.(!@&^N!7"_S_)P`('P@`PP(``'W@5R-"```"`@`@`((@4`B"@1`@ -M`@`@@/X?8`[^/V`(@H$0A_X?8`J`@1`,@H$0#H"!$*`$`"````!0`GX@@``( -M@E``AD!`$`B!$(#^/V`2`H$0`7X`0``.`!@%>N!7"_O_)R#^'V`P@$$0,8!! -M$#*`01`@@`\X,X!!$``!X&<"?%]@X,T"``%\7V#DS0(``'P?8!?2```$_C]@ -M(+$I(`"&85`$/@X0H%_X+R#^GV%I_O^!__X_8/Z#C1``?+]A\,4"```!X&<< -M_A]@`GP?8!X````0@4803/X'0`+^/V#^_TU`(*@I*`"&85``?-]AZ-@"``7^ -M'V`#_C]@!']'0!#_9D"@#2HH``B"4`'^!T`$_C]@!/]&0*"A*2@`AF%0`'P? -M8!F0```"_C]@'/]&0*">*2@`AF%0//X'0`3^/V`8_T9`()PI*`"&85"@Y?\O -M`?X?8"#^'V``@480`8%&$`+^'V`#_C]@`']'0`#_9D`@`"HH``B"4`/^!T`" -M_C]@'O]&0""4*2@`AF%0('SX)R#^GV$$/@X0(#SX+\+^/T```*!A`'P?8"$! -M````,2HH`7Y?$&^S`@``?#]@7N4"``":!F`@=RHH:/Y?8`!A^"<$/@X0@#3X -M+P``H&$@3BN!7"P,`(`"^#V`` -M?%]@,,X"`*`5+RB1_C]@@/__)P-\```XY@(``%#X)P0^#A"@)_@O)/Z?8:+^ -MWX$`FJ91])L-$/3_#4#\_RU`('\%*/C_34```>!G`KX/8,)G+R@6?B=`_($- -M"!3^/V`,`D`0:/X_8`X"@!``?!]@7N4"`/B!+0B@6BHH:/Y?8``('P@`PP(` -M`'W@5R-"```"`P`@^($-"(#^/V`(&H`0"@*`$`P:@!`.`H`0D?X?0*`**B@I -M?B=`_($-"/2!+0B@X`8H#'X`0"!/^"N=7"H(@4/G[X%<+?#]@^?__ -M_P?^`$``#@`8!7Y`@`/^!H``!`!``WX`0`"HIT$`J(="``!*$`+^`(````=0 -M`H`_4`"*`!@1>N!7"0-)$`L#`"``?#]@:0$``*#U*2@+_A]@$/X?8`D!21`` -M>N!7B@(`(`O^'V`@\BDHM_X_0````%`)`4D0`"H`0!`%``@!_BA"`8!&$`+^ -MYT$%^NA7"A@`(`!\GV+TP`(``R+(`0!\7V)4Q@(``GKG5P!\OV(4V0(`#`(` -M(`+^'V``(HA!``!&$`+^WV&U>^=7B@$`(+7_WV$`(HA!`!Q&$-A[YU>)W_\G -MR'OG5PP)`"``_`E`Q-H"```'(`@0!P`(`GX`0`"``%``"L`:$'X'0``L`$`` -M"L`9!?X?8"#<*2@`HBA@!?X?8*#:*2@`+"M@H-;_)P/^OV'">^=7"9JF4:D! -M`"`>?@=``?Z_82Q^!T"@TO\G``K`&8```"@`$?@G!#X.$*#;]R\0_A]@`'R_ -M8?3!`@`4_C]@`/]&0`K^?V`"_I]@("0A*`"*HE``A08(```?$'"8`@`!A08( -M```?$'28`@`"A08(```?$'B8`@`#A08(```?$'R8`@`$A08(```?$("8`@`% -MA08(```?$(28`@`&A08(```?$(B8`@`'A08(```?$(R8`@`(A08(```?$)"8 -M`@`)A08(```?$)28`@``\_)V"@=PPH__]-0``!X&<`?#]B],$"`('U_R<` -MO@]@`'Q?8##.`@"@I"XHH?X_8(#__R>@\O!7($(```$Z`2``!!\(9;,"`!)ZX%` -MQ?\G!#X.$`"K]R\`?!]@(/8"``````@0>N!G`'P_8B3;`@`"S?!G`'R_8=3&`@`"(@`@ -M`)?E9T$!`"!J!`<(:P0'"````$``&@!`/`4`"'``!Q!T``<0;`0'"``:`$"H -M!0`(>``'$#B%!@A*>N!71/YF0`+\9D`(`````(8!"`R'!A!\``<0$(5&"`+Z -MY5<"_>57`0````($`"`,AB$($88!"(0`!Q`2A@$(@`('$(@`!Q"@$``@$X8! -M"%!ZX5>,"P`@:@0'"`Y^(%``C@`8!WK@5Y`"1Q"+`@`@'WK@5XH!`"`!?B!` -M`(X`&)`"1Q``(@!`(`<`"``"(!@2AP8(`('@5PD#`"``@B!0C`('$(@"!Q"$ -M`@<0(`8`((`"!Q`DAB$(*88!"(0`!Q`JA@$(@`('$(@`!Q`KA@$(H`$`((P` -M!Q"``"<($(5&"```?PAHLP(`BX0!"`A^@("*A`$(``A@:`",`1@`!I\0I.8" -M```*GPA>Y0(`%($&$!B)!A`E?N"G"/X^!7BP$`(-Q[X%=,+0`@`?Y_8-U[X%>+ -M`0`@X7O@5\PJ`"`"_G]@XGO@5XL!`"#F>^!73"@`(`/^?V#G>^!7BP$`(.M[ -MX%?,)0`@!/Y_8.Q[X%>+`0`@\'O@5TPC`"`%_G]@\7O@5XL!`"#U>^!7S"`` -M(`;^?V#V>^!7BP$`(/I[X%=,'@`@!_Y_8/M[X%>+`0`@!7K@5\P;`"`(_G]@ -M!GK@5XL!`"`*>N!73!D`(`G^?V`+>N!7BP$`(`]ZX%?,%@`@"OY_8!!ZX%>+ -M`0`@%'K@5TP4`"`+_G]@%7K@5XL!`"`9>N!7S!$`(`S^?V`:>N!7BP$`(!YZ -MX%=,#P`@#?Y_8!]ZX%>+`0`@(WK@5\P,`"`._G]@)'K@5XL!`"`H>N!73`H` -M(`_^?V`I>N!7BP$`("UZX%?,!P`@$/Y_8"YZX%>+`0`@,GK@5TP%`"`1_G]@ -M,WK@5XL!`"`W>N!7S`(`(!+^?V`X>N!7*@$`(!/^?V``AF%0`)?E9RB'!A`" -M"0`@:@0'"`YZX%<+`0`@('K@5PP$`"`A>N!7BP$`("MZX%?,`P`@`?X?8"MZ -MX%57`@````'Z_R=0 -M>N%7C"<`(`"7Y6<`!$%0@@<`(&H$9P@._@%0``X`&`=ZX%<`HHA@"P(`(!]Z -MX%<+?`!``0````L.`!@`"`!`(`<`")`&1Q`!?@!0D0!'$`'ZY5<"`P`@;`1G -M"`"B`4``!P`(D`9'$`%^`%"1`$<0`OKE5P($`"!K!&<(`*(!0!`'``@!?H!0 -M``H"&)$(1Q"@`0`@D`9'$)`$9PB1!@<(`_R!``#!`@"2"$<0``G@5PL`8&`* -M"&)@``G@5Y0$!Q"A`@`@DP9'$``'XE<"`0`@``A`4)0$!Q"@_Q4HF'Z'0)$& -M!PB$`"<(E`!'"),&9PB@_!4HG'Z'0)$&!PB(`"<(E`!'"),&9PB@^14HH'Z' -M0)$&!PB,`"<(E`!'"),&9PB@]A4HI'Z'0)$&!PA\`"<(E`!'"),&9PB@\Q4H -MJ'Z'0(``)PAP``<*=``G"7@`QPA\`&<(A``'"8@`YPB,`$<),(&F"`!\_V'4 -MR`(``)?E9[C_1T`B!0`@-(&&"&H$!P@A>N!7BP$`("MZX%N!7#"D`((``9PA->N%7F``G"$D"`"!-_A]@ -M`'KA5PH!`"````!0K``'$$UZY%=)`@`@3?X?8`!ZY%<*`0`@````4+``!Q!- -M^N-720(`($W^'V``^N-7"@$`(````%"T``<03?KB5TD"`"!-_A]@`/KB5PH! -M`"````!0N``'$$UZXU=)`@`@3?X?8`!ZXU<*`0`@````4+P`!Q"1!@<(`'R? -M8#CF`@``AB!`H##Y+P`(0F"1!@<(G``G"(0`1P@`A"!`H"WY+P%^0D"1!@<( -MH``G"(@`1P@`A"!`H"KY+P)^0D"1!@<(I``G"(P`1P@`A"!`H"?Y+P-^0D"1 -M!@<(J``G"'P`1P@`A"!`H"3Y+P1^0D"@`P`@`((@4`.(8``"_D"``'P!0/R8 -M`@``!@`0`?X@0`7ZX%<+_/\GK`!'"+``!PFT`.<(N`"G"+P`QP@$@28)``2! -M0`*(9```?/]A],`"``"&1Q``B(1``02""`B!!@@!B$<0`!!$00*4!`%J!"<( -M`I!'$`"4!$$!!`0)``S#0`.01Q``C@-!`I#D``".!1H$CD<0`)#D0`&$XP@% -MCD<0`(KB0`*.I``&BD<0`(ZD0`&$H@@'BD<0`@R@``B*1Q``#`!``00`"`#_ -MID`)@$<0`"`(8*#7^"\!_\9``(4&"&H$)P@`@$<0`84&"+``1P@!@$<0`H1G -M"`.$AP@`(`A@`/^F0*#1^"\!_\9``(4&"&H$)P@"@$<0`84&"+0`1P@#@$<0 -M!(1G"`6$AP@`(`A@`/^F0*#+^"\!_\9``(4&"&H$)P@$@$<0`84&"+@`1P@% -M@$<0!H1G"`>$AP@`(`A@`/^F0*#%^"\!_\9``(4&"`:`1Q`!A08(!X!'$,`` -M!P@!?@!`H)K^+\``!Q"`I?8G!#X.$*!_]B\H_I]A`'P?8L3:`@``?!]@(/8" -M``````@`?+]A5,8"`!!ZX&"!P`@`"!" -M0"`'`0@``'\(:+,"`"!^`$``"B`8!X%&$``'`0@(@480BX0!"`A^0("*A`$( -M``0`:*`"`"``@(<0`+X/8*"<+2@=_BA`!X!G`'Q?8#CF -M`@`"#``@`(9A4*`%`"`'A\8(``J`&`"$@4$`C@!`,`<`"``(1A```>)7#`@" -M8`"$@4$``$80`?YA0`7ZX5<*%0`@`/P!0!39`@`(!0`(```#4`"!XE<`(.A@ -MB?;_)Z#V_R<`BH)@````4`!\'V$4V0(`!X?F"*`$`"``H,!``(IA&``$@$$` -M!D80`(GA5PR&@6``!(!!``A&$`%^`$``$&!`"(5A"`1ZX%<`AF-0B@(`(`"' -MXE=`!X,("?C_)R#X_R<`BF)@`(?B5PF*H1@`!(!!4`=C"``*1A``A^)7#(IB -M8``$@$$`!D80``H?"%[E`@``BF<(`(`A41"+!@@2BP8)`!+@IQ2+Y@@`D!R0 -M`(##0`6-1A``AF%0"(<&"*`#`"`>?J!``X0!`````T``"H!0`)H!0``)0!`! -M_F%`!/KA5PO\_R<.BP8(`!+@IP"0')``#F!`"H<&"``*@$``F@!`&`<`"``( -M@$`$!@$(`(`!0``(`%`.>N=7!(%&$*("`"`&AT80!(<&"":'9@@`!@!`!(%& -M$"`%`"``AF%0`X2!``+^H8`??@*(``@`0``"`!@`_()`_)@"`````A`!_F%` -M!?KA5XOZ_R<@`OXO`/\&0"!.]BN!G`C?V)P`2""@`>N!7"0,`(`"^#V``?%]@,,X"`*#V+"B`_C]@@/__)P`P -M""B`6?XO`#'V)P0^#A"`!?8O`'R_8;C#`@`#A08(`7K@5X(!`"``A08(`7K@ -M5X$-$2@```!0`(%&$`.!1A`@*_8G!(%&$`0^#A"@_O4O'/Z?8?C_+4`@/2@H -M!?Y?8`!\'V`K`0``(/(G*%W^/V#\A4T(``7A9P!\OV&XPP(`@@$`(`2%!@@! -M>N!7@0D`(`"%!@CZA2T(`('@5X$#`"`!^N!7`@$`((#X$"B````@@/T0*/R% -M30CZA2T(^X4-"`*%1A`!@480`(-&$`'^'V``!>%G`X%&$($%`"@```!0!(%& -M$*`J]B<<_I]A#``@"`#\`$#H`0``%`0`"``"`$"@Z/\G'GX`0`0^#A`@Z?4O -M'/Z?89;^'T`@W"" -M"``@`*WV+P``P&$!A08(H+0.*`""(%`!A08(``!?$/"L`@``"!\(`,,"``!] -MX%N!7@NCU)P*%!@C_?P!```_@'Z+F]2<"@480`-/_+P'^'V"@Y/4G -M!(%&$`0^#A"@NO4O'/Z?80``P&$```!0__K@5_R!#1`L!``@`(*@80!\7V"L -MUP(``'P_8-\!```@GRPH`+X/8(#__R<`CD88_/\-0*""+"@"_C]@_/\-0"!' -M'2B`_C]@`'P?8*C$`@#\@4T(!/X_8``<9V"@RAPH`)J&8(`@`"`$/@X0(*OU -M+QS^GV$``,!A`(*@80"`!@C^_RU`(*@P*/W_34#^A2T(`OK@5P*$!@@!`@`@ -M%7K@5P(9`"`5>N=7`1@`(``!X&<"`0`@`OK@5P(3`"#]A2T(H(@<*````%`` -M``!0`)HF8*#6'"C__TU`_X4-"``!X&`>`\H``'@9P*^#V#"W2PHFOX_8````%``FB9@(,X<*/__34#_A0T(``'@ -M9X$(`"``@`8(H",=*(#^/V`!>N!7`>C_)P"^#V``?%]@K-<"`"!Z+"BC_C]@ -M@/__)P"^#V``?%]@K-<"`"!W+"B%_C]@@/__)R#']2<<_I]A!#X.$""']2\< -M_I]A``"@80`$(`@@?"N!7 -M`0,`(`"^#V``?%]@K-<"`*!@+"C8_C]@@/__)P```%``@B!0(*(<*/S_34#\ -M@0T(H`(=*(#^/V```>!G`@,`(`"^#V``?%]@K-<"`"!9+"C;_C]@@/__)_R! -M+0@@82N!7!0,` -M(`"^#V``?%]@K-<"`"!0+"CH_C]@@/__)P)^`(``?$``)+$"``"$!@@!_C]@ -M`GK@5P&"(%``!>%G@0$`(`!]X5<`!`(`!0,`(`"^#V``?%]@K-<"`"!'+"CN -M_C]@@/__)R`"`3@`F@9@_($-"/O_+4`@63`H^O]-0/J%+0B@/QPH````4``` -M`%#\_RU`H(T<*/G_34#YA0T(``'@9P$%`"#\@0T((.,<*(#^/V```>!G@@(` -M((`O#R@``>!G`KX/8,*4+"B#_C]`H(KU)QS^GV$$/@X0(%3U+S3^GV$``,!A -M``0@""`_)R@8_A]@H!?V+Y?^/T(``>!G@08`(`#M+R@``>!G,/X_@((!`"`8 -M@``(``'@9P$#`"``O@]@`'Q?8*S7`@`@+2PHD/X_0(#__R<```!0(%$<*`"" -M(%`!>N!7`0,`(`"^#V``?%]@K-<"`*`G+"B1_C]`@/__)P```%``@B!0(&D< -M*/S_34#\@0T(H,D<*(#^/V```>!G`@H`(``6#R@``>!G`KX/8$)[+"B6_C]` -M````4*!$'"@`@B!0`7K@5P$#`"``O@]@`'Q?8*S7`@`@&RPH`?XH0(#__R<` -M``!0`((@4*!<'"C\_TU`_($-"""]'"B`_C]@``'@9P(#`"``O@]@`'Q?8*S7 -M`@"@$RPH!?XH0(#__R<`!`<(('O_+_S_+4`!!`<(_84-"@`!Z%<.?BA`"0$` -M(``#X%<+`P`@`+X/8`!\7V"LUP(`H`LL*!/^*$"`__\G_($-"/O_+4"@'C`H -M^O]-0/N%#0@!>N!7`0,`(`"^#V``?%]@K-<"`"`%+"BB_C]`@/__)Z"B'"C\ -M@0T(``&@80(#`"``O@]@`'Q?8*S7`@`@`"PHI/X_0(#__R<,@.8)`)_G9P(# -M`"``O@]@`'Q?8*S7`@"@^RLHI?X_0(#__R<#!`<(!H!'$`($!P@%@$<0`00' -M"``@(%`3A`<(``(`0!.`1Q`+!`<($8!'$`L$!PB_?T!@`7KA5Y]^(&`!!P`@ -M@OK@5PL!`""&^N!7#`4`(*!ZX%<"?>!7X`````$#`"``O@]@`'Q?8*S7`@"@ -M["LHMOX_0(#__R!G`BP`(`#.#B@``>!G@2H`(`"^#V"@'0`@6_XH0(!2`B@` -M`>!G(@(`(`'^'V"@NQ,H!/X?8`+^'V`0@$<0^H5-"/S_#4"@MRLH`_X_8/R! -M+0B@*1PH````4(`;]R\```!B`)H&8"`2#"CT_RU`````4!"`1Q#T@0T(``'@ -M9X(=`"``(>AG`0$`(`)ZZ%>.&``@`+X/8`!\7V"LUP(`H,8K*)G^*$"`__\G -M"P0G"*#.)B@:_A]@^H4M"*#`&R@```!0````4/S_+4"@#APH\_]-0/.%#0@` -M`>!G`1$`(/R!#0@@9!PH@/X_8``!X&>"#@`@@+`.*``!X&!V"@_?0G-/Z?80%ZX%>!YO\G`GK@5P'R_R<`O@]@`'Q?8*S7`@`@ -MJ2LHH?XH0(#__R<$/@X0H-7T+T3^GV'"_A^#``!@8@""P&$`!$%B`(:A8@`( -MXF$@@_4O`(K"8@``X&(@K?@O&/X?8`!\/V(`B`(``'R?8B2R`@"0"0H*$/X? -M8``BB$$`'>=G``!&$*(#`"``(JA!`+X/8`!\7V#`S0(`H)DK*`-^+$"`__\G -M`?KJ5X(#`"`$@`D(.`$*$`"`"0@T`0H0COX?0"`)`"`*?BQ``OKJ5X(#`"`T -M?PI``*8I8"!L+B@``$!@COX?0*`$`"`1?BQ``_KJ5X(&`"`T?PI``*8I8*!\ -M+B@``$!@COX?0!A^+$``E28H`(`I"""4)BB._A]`!(`I"*"2)BB._A]`,/X' -M8`/^*F``@`!H`H!&$``0)QB@(B\H`*8)8`"`*0@$@@80!(`I"!#ZYU<(@@80 -M`@L`(`I^)X``@`!0`"7I9P""(%`A!``@``1!4``D)U`"_B"`#X1&$!""1A`( -M_B"((`(`(!&"1A`1A$80$()&$`^"1A`,A$80`GXG@`V"1A`&?B>(H`(`(`Z" -M1A!`^N=G`0$`(/^!'W`!?@!``'P`8/__#P#\@0T0_(4-"!C^/V`5@$80_84- -M"`'^7V`6@$80_H4-"!>`1A"4!0H(`8!&$`(B"`"@:RHH`"QK8*!.]2\`K@M@ -MH+?T)T3^GV$$/@X0H'ST+R#^GV'\_PU`^/\M0"#8`2CT_TU`%/X_8/R!#0B@ -M1?4O``*`$```H&'\@0T(``!?".2O`@`@/1,H"OX_8"!$]2\`F@9@H++T)R#^ -MGV$$/@X0`'3T+P`('P@`PP(``'R_8;2L`@``?>!7(T(``*($`"`^A"8(`(/@ -M9P+]X%<#`````@(`("":]B\!_A]@H(S[+P```%"`-O4O``#`83Z$!@@``>!G -M`@<`(*`$`"`,_A]@0X0&"``!X&<"`@`@``0?".;C`@`!>N!7@<8?*````%`` -MV0`H(#'U+P`N!7`??_)P"^#V``?%]@K,T"`*!) -M*RC8_C]`@/__)P0^#A"@;O0O./Z?80``'PB`XP(``)[G40`!X&?\GPT0H@,` -M(#O^OYH`O@]@`'Q?8*S-`@"@02LH"OXJ0(#__R<,`,`)`'R_8:BP`@``_P9` -M`((@4*`#]B\P_E]@`'P_8H3C`@``@"@(`'P?8K2L`@`%A``(`'Q_8JBM`@!_ -M?P!@07X`:`6`0!`/_A]@(8!`$`A^`(@@_"DH(H!`$`]^(&``@`@(`'Q?8C"M -M`@`>`H`0```?".#C`@"`_C]@``)`$`$>0!`,_A]@(@"'$(K^'V`@."8H'OXJ -M0$P(B`E*"`@($'Z&@0``/PB@XP(``!@`:`2``!!0"(@)3@@("!!^AH$`&`!H -M`(``$%(("`@,_N!!"H"`$%8("`@(@(`07@@("`"#!A`"@$D0"'X`D`.`21`$ -M_@!`!($&$`C^`$`(@080"OX`0`R!!A`0GP80`01)"``D"6``GB=@('`F*`)^ -M04`!!`D(.``H"`)^`$``#D`:`!Y)0!2%!A!#!`@(H),O*/S_;4#\@0T(`"0` -M0``.0!I#!`@(``'@9P`>B4(!#``@`(`("!_^/V`A`D`0"/X@B*#8*2@B`D`0 -M'WX@8`"`"`@>`H`0/`0("`!\/V*DK0(``H!($!BI!A`!A$@(`*((8``H*F"@ -M7B8H`GY!0`&$"`@"?@!``"0`0``.0!H`'HE"'*D&$`&$20@`I@E@`"@J8"!9 -M)B@"?D%``80)"`)^`$``)`!```X@&D`("`@$>N!G`0H`(`!\'V"PK0(``00@ -M"`+^0$``!"`(!_K@5_R%#1`!`P`@`+X/8`!\7V"LS0(`(/PJ*%;^*D"`__\G -MH$TF*`">*$#\@0T(`"(`0``.(!I`"`@(`GK@9P$+`"``?!]@S*T"``$$(`@" -M_D!```0@"/R%#1`P^N!7`OW@5]T````!`P`@`+X/8`!\7V"LS0(`(/`J*&3^ -M*D"`__\GH$$F*`">*$#\@0T(`"(`0``.(!I`"`@(`7K@9X$)`"``?!]@6*\" -M``$$(`@"_D!```0@"-WZX%?\A0T0`0,`(`"^#V``?%]@K,T"`"#E*BAP_BI` -M@/__)Z`V)B@`GBA`_($-"``B`$``#B`:0P0("`)ZX%>"$P`@`'P?8*RM`@`! -M!"`(`OY`0``$(`@J^N!7_(4-$`$#`"``O@]@`'Q?8*S-`@`@VBHH>_XJ0(#_ -M_R<`GBA`("LF*"2#!A#\@0T(`"(`0``.(!HX``@(`)[H00">)V`@+R\H_/]- -M0/R!#0@``>!G@0$`("B?!A``(@!```X@&@R!!@@`"``(('K@9P("`"`D@28( -M`H0`"`1^`&@"@$`0(@@'"``B`$`B`(<0H!CT)SC^GV$`@^!G@@4`(`W^/V`8 -M`D`0!@0@"*`"`"#^_R!@"OX_8!@"0!`&!"`(`?X@:""`#S@&`D`0`?K@5P+] -MX%<"`````?O_)P"^#V"@&RL@Q?X_8``$05`3!$`0"@1`$`0$0!`#_C]@%@)` -M$!($0!`&_C]@'```"""`#S@L`D`0!#X.$"#4\R\H_I]A``#`80P```B]_A^: -M)GX`0""7'"CX_RU````?"(#C`@`,`*<)#```"`":)F`@!B8H@/Y?8"C^YD$< -MG@80^/\-0""1'"@T_B=`H.__+P":!F`"_A]@5(!&$"*(1@@``!\(H.,"`"#_ -M)2A(_B=`.80&"/Y^`&"`?@!H.8!&$%#^'V!8@$80````4%F`1A!\_A]@H+`E -M*`Q^*$``?#]@#)8"``"```@!?@!``(``$``` -M_@AB@>__)P`,96@`CD$9`"'H9P(,9&@"?+]A`0```*#O_R<"C@$90P0""`)Z -MX%=G`7P_80H````">N!7`9OF9P%\'V$/``````7A9X$"`"!L#H(0'!!" -M$!L20A`>%$(0'19"$`"#X&_C]@@/__)P!0]"\`&A\0Y*\"``!1]"\` -MK/,G!#X.$(!_\R\->N!7``"@804#`"``O@]@`'Q?8*S-`@"@:2HHS_X_8(#_ -M_R<`2/0O`'Q?8*BP`@`\`2$(`(/F5X4``"`\&P$0`$?T+P"B\R<`/@X0('?S -M+QS^GV&C_M^!``"@81"`#1"W_A]@(&HE*$9^)T"W_A]@H&@E*`":)F``F@9@ -M__\M0"!R+BC^_TU`_X4-"``!X&<"?>!7`0````)]X%<"````@04`(`"^#V`` -M?%]@P,T"`*!6*BA+?B=`@/__)Q*$#0@&>N!7`@0`("`$`"#^A0T(``'@9X'\ -M_RN!7`GW@5P(````!_/\G````4"!7]2<<_I]A`#X.$*!A\R\<_I]AH_[? -M@0``H&&W_A]@(%4E*&I^)T"W_A]@H%,E*`":)F``F@9@__\M0"!=+BC^_TU` -M_X4-"``!X&<"?>!7`0````)]X%<"`````0,`(`"^#V``?%]@P,T"`*!!*BAN -M?B=`@/__)P%ZX%<"?>!7`@```$'O_R?^A0T((.[_)P```%``?!]@(/H"``"` -M#S@$/@X0(%KS+T#^GV$``0!B]/Y?0J(#`"``@N!A`+X/8`!\7V#(S0(`(#8J -M*.#^/V"`__\G#`"H":!,!2@`I,9!(&X%*`R`1A`7A"8(``'@9_[_`&`"_`!H -M`0```!>`1A`:B`8(`(`&0!P$(`@#_@!@`WK@5Z(>`"`"HBA2,/K@9P$#`"`` -MO@]@`'Q?8,C-`@`@*2HH_OX_8(#__R?`^N!G`0,`(`"^#V``?%]@R,T"`"`E -M*BC__C]@@/__)P``'P@8Y0(`'00`"$!ZX&!G`00`(%#ZYU<"!``@`'P_8+BL`@"@0ALH(/X&0``! -MX&<"`0`@(#$`(!4B1Q`!_A]@^($-$/RC#1``'`=@^/\M0*#Y+"@`'$=@-(`& -M"/#_+4#P@0T0.(`&"/2!#1``'`=@H/4L*/C_34```"!B^($M""`.)2@P_A]@ -M`?KH5P'^/V("HBA2-7\)0"`+)2B?_C]`\($M"*`))2@U?PE`]($M""`()2@U -M?PE`@/KG5PXB1Q""'P`@`$0?"%SD`@```>!G@1T`(`!$'PA=Y`(```'@9X$; -M`"#P@0T(`'P_8%BQ`@``@``0]($-"`'ZZ%<$@``0@@(`(/C_#4`!_C]@(#XD -M*``$05``%0`@`'S?8`) -M,/X?8"#V)"@`GB=@``@("`"`!D#\`0`*,/X?8"#S)"@`("A@/(@F"""%+2CP -M_PU`/(@F"`K^0(```&%0`!X(0``&`%`4>@!`!``!0`!ZX%>*`@`@`+X/8-7^ -M/T`@X2DH`']'0(#__R?H@0T0Z/\-0``$05``AF%08/Z?8"`U_B\`BJ)0H"OS -M)T#^GV$`?%]@9)<"``!\?V!$EP(``?K@9P!\GV`TEP(``H`/.``$/PCWK`(` -M`?K@5P(-`"`4>N!7@0,`(`D)`"`*>N!7`H`/.````@@!?@!`((`/.````A`$ -M``((`7X`0""`#S@$``(0"``""`%^`$`@@`\X"``"$`P``@@!?@!`((`/.`P` -M`A`W>N!7`?O_)VYZX%<"@`\X@/O_)P+ZX%>"(``@;GK@5P(8`"`4``$(`7X` -M0""`#S@4``$0```!"`%^`$`@@`\X```!$`0``0@!?@!`((`/.`0``1`(``$( -M`7X`0""`#S@(``$0#``!"`%^`$`@@`\X#``!$!```0@!?@!`((`/.!```1`8 -M``$(`7X`0""`#S@8``$0'``!"`%^`$`@@`\X'``!$"```0@!?@!`((`/."`` -M`1`D``$(`7X`0""`#S@D``$0*``!"`%^`$`@@`\X*``!$"P``0@!?@!`((`/ -M."P``1`W>N!7`>W_)P%^`%`3>N!7#8`/.`-\@`$D:P```'R&0N!7#8`/.`-\@`%@ -M:P```'R&0=@:``````8X'"0@)`PD$"04)!@D!"0(``"``0@!?@!`((`/.`"` -M`1`$@`$(`7X`0""`#S@$@`$0"(`!"`%^`$`@@`\X"(`!$`R``0@!?@!`((`/ -M.`R``1`0@`$(`7X`0""`#S@0@`$0%(`!"`%^`$`@@`\X%(`!$!B``0@!?@!` -M((`/.!B``1`<@`$(`7X`0""`#S@<@`$0`(`/.`0^#A``IO(O``#@80""H&$` -M!,%A````4`'^/V`@W`TH``1!4``!X&<`@`<0@00`(`P`(`@`@@80H/X?8`V` -M0!``@`8($'X`0```!Q"@Q?(G````4*#$\B<(_A]@`$0?"+FQ`@``@`\X!#X. -M$""2\B\4_I]A0/X?8/__+4#^_TU`H-'T+_W_;4#_A0T(`'P?8=3&`@````!` -M`!``0#P%X`AD_A]@__\M0/[_34`@S/0O_?]M0/^%#0@```!``!``0#P%``@` -M@>-7"PX`4`J``U`$>N!7$/X?8`Q\'V`-````$P%$$"#%\B<4_I]A!#X.$*"+ -M\B\H_I]A````4*`M'"C\_RU`_($-"``!X&!G`O4-*`"N"'@P0`(`!\/V!@M`(` -M`($`"`#\1F#__\?_``0`:`"!`!``_*9A```X``#]YF_C]@_($M -M"`2```@``>!G`@(`(*#>_R\$@0<(_($-"`0```@```<0_($-""8B@!````<( -M``'@9P("`""@`_,O`)H&8*`#`"`!_C]B!($'"/__/V``)`!`_P)`$*#_\B\` -MF@9@`*((8"!K\B!7!`````)]X%<#```` -M@O3_)_R!+0@`?`=`*,$"`/\"0!````!0(%KR)R#^GV$$/@X0@!GR+P!\OV'\ -MY@(`&(0&"``!X&>!0O(G'(`&"``((`@`@^!G@@$`((!;!B@``"!@'(`&"!P` -M0`@``A\0'.<"`!`$`0A_?P!@(#SR)Q``01`$/@X0``_R+R!O!2@`@J!A`'Q? -M8+S%`@``"2$(``/@5P!\_V"TV@(``1``(``!@1"@`@`@`(JB4`!]`Q"2"0`` -M`?XB0`".H!@$^N)7B@L`(`S^XJ<`_)P`K.,"``+^(H``">)G`([`0('Y_R>" -M_E]`@OY_0"`$`"``!P,0`WX@@`"$X*<0_CR0`(G@5P4$86`4?B%``)!`&`!] -MX5>2"0``#/O_)R#S_R<`!P,0`OX&@``.`$```0`(("3R)P`0`!@$/@X0`/?Q -M+R#$\B\``*!A&(1&"`%ZX6>!`@`@`'Q_8/CF`@``B"$(`?X@0`""@1`">N%G -M`'Q?8/SF`@`!`@`@"``A"``"`1`,`"$(!`(!$!@`(0@0`@$0'``A"!0"`1`` -M@B!0(+OR+Q@"01"`%?(G!#X.$"#V\2\P_I]AH+7R+P``P&$``"!B`?X?8!P` -M1PCX@4T0)`0!"`!\_V'\Y@(`^H%-$!8&!P@0A"<(``X`&OF!31``@^!G^($- -M"($!`"`8@`<0H`$`(!R!G&82G"2("`"`1A$<* -MH"$&*``)```@`)KF80`* -MIQD$^N97"_3_)R#E\2G`'P?8JSC`@``H#Q" -M!(AH"`0:Z0$`AD=0``P!&`!ZX%<`F&EJ20$`("J$@!`JAH`0`%TG*``F(&`$ -MB`@(`!J)00"``$```(80H`0`(`"B*%(@62,^?\G`*)(0@0:20``)@%0`('@5PGT_R>@]?\G``(!4"`R_R\2\H_I]A``#`80P```@`@J!A'```"A8&``@!?@!```[@&0`N!7@@L`(/C_#4"@1/\O`?X_8/B!#0@,`"`('(``"``A -MX%>"!@`@`H@`"`B(0`@``>%7"0$`(``%X6>"`P`@$(0`"`%ZX%'X`@O_$G -M*/Z?80P```@6!@`(`7X`0``.`!@@&/\G`8`?@`0^#A"@B?$O./Z?80'^'V`` -M?/]AZ+P"``!\WV$8P@(``'R_8;2L`@``?!]B1*L"`"`#`"#X@0T0`,H6*`#? -M%B@`F@9@(+X#*`""(%``(`A@`'P_8!_W_P$`0`@`(0'"``!X&#`0`@((+X+P'^ -M'V#\@2T("?K@AP,!`""`R`$H_($M"![ZX&>!%0`@(`,`(`'^/V(@*O(O`"0) -M8"`I\B\`)`E@`?XH0@3ZZ%<-$0`@_($-"`&B/X``@>!G@?S_)P`B\B\``$!B -M`*((8`""(%"@W@HH\/]-0`%ZX%>!]_\G\($-"`0```@``>!G#``@"`'U_R<2 -MA"`(`OK@5P+]X%"]?\G@.O_)P`3\B\``"!B]/\-0"#Z_B\`@B!0`7K@ -M5P""(%"!`0`@]($-"``!X&>"```@`?X_8`"/X!\"!P`@H,P%*/2!#0CT@0T( -M(+4'*/C_+4`@#/(O`*((8/2!#0@``>!G`0,`(/B!#0@``>!G@?+_)P`!`""@ -M!_(O`*((8/R!+0@8^N"/@<'_)P?ZX(>#`@`@``0'"``!X&N!G`ARG -M88!ZX&! -M3O$G(`$`*``\2\``:!A@08`((#J\2\`?%]@C,("```! -M(0@`@^!G@@$`(`0;`1`@`@`@`!L!$`0!(0@$&P$0!)H`$`#G\2^`O`HH@$'Q -M)P0^#A``%?$O`.+Q+Z![_R\``*!A(./Q+P":!F"`/?$G!#X.$(`.\2\,`"`( -M`/Q@0.@!```<_D!`%(0A"`"$8$`"A"```(/@9P()`"`!A"$(!/K@5PX$`"`` -MO@]@H%(H*.[^/T"`!0`@@`P!*(`$`"``'?LO@`,`(`/\@`'@>````'R&03@> -M``````8X]P("`OD```"@+?$G`?X?8`0^#A"`!O$O``'`81K^_YD"`P`@`+X/ -M8`!\7V"LS0(`H.LG*`3^)T"`__\G`'R_8:BP`@`\@08("WK@5P8!`"`*>N!7 -M!@$`(*`F\2!G`0,`(`"^#V``?%]@K,T"`"#< -M)R@/_B=`@/__)Z`:\2<```!0!#X.$`#X\"\``>!AO?Y?F@(#`"``O@]@`'Q? -M8*S-`@"@U2!G`?X?8H$X`"`&>N!7AC<`(`*(*`@@ -MU2(HN!7#0@`(`2( -M"`@``>!G`_X?8`)\'V`$`````%7]+R`,$BA(?P=```'@9X$L`"``O@]@`'Q? -M8*S-`@`@ORN!7 -M`A4`(`+ZX%>-)``@-!\'$''^'V"@P2(H27XI0`2("`@``>!G`"`(4@(#`"!Q -M_A]@(+XB*$Q^*4`@1?TO`_X?8``(`""`D?$O``"@87'^'V`@NB(H57XI0`2( -M*`B@N"(H!V`@A@\H"_X_8""-\2\`F@9@(/,1 -M*$A_!T```>!G@1,`(`"^#V``?%]@K,T"`""F)RAA?BE`@/__)P1ZX%!!@`@`+X/8`!\7V"LS0(`()DG*'1^ -M*4"`__\G`?KF5P*;YF<"_>97`@````*^#V!"\"N!77/X_FH(!`""@>0XH -M``0("(`T`"``!!\(?.,"``%ZX%>",@`@`'R_87"L`@`&A08(``'@9P(P`"`% -M>N=7!2\`(`!\WV&TK`(`$'X(0""X&"@*?B=```'@9X$K`"`@_A]@_X%-$`I^ -M"$"@2@$H__\M0`%ZX%<""@`@_X4-""!ZX%<+`P`@`+X/8`!\7V"8S0(`H'PG -M*!;^*$"`__\G`'Q?8%CC`@```"$(`8!_@`#```@`!@!H`(``%````0@`0"`( -MH(`B*(;^'T"A_A]@('\B*"#^*$``NO(O```@8"!](BBA_A]@+($&"``!X&*!0`@H,XK*#2!!@@T@08(H`T`*/^%+0@`#^`?`AP'8"*]`B@"@B!0 -MH)DK*#2!!@@`?#]@"/@"``"```@!?@!``(``$""F$2@0_P9```'@9P$$`"`` -MO@]@`'Q?8)C-`@`@62@2O\O`)X'8````%`@IO`G*/Z?800^ -M#A"@9/`O``!`8"#ZX%<```!0BP,`(`!\7V"8S0(``'P_8%D%```@4"%G`8OP)P!\OV"TK`(`0X1B"`+ZX5<@A(((@@@`("0`00@`!>%G -M`0(`(`($(0@"^N!G@04`((`#`"`&_B"``/P@0.RS`@`FB"`(`/W@9]@/``"" -M`0`@@'XB:"`!`"`@@D(0``@B8``#XEX_A]@(#0B*#%^)T``?#]@)+("`);% -M``@!>N!7`0,`(`"^#V``?%]@P,T"`"`E)R@R?B=`@/__)X"?_2\!>N!7`0,` -M(`"^#V``?%]@P,T"`*`@)R@T?B=`@/__)P```%"6@4`4`%WP)P"^#V"@52*`":!F``_?\G`WR``W^+>WM[?U]?7U];?UM_4` -M````4/`G!#X.$*`J\"\D_I]A````4/^!31`(_A]B`'S_80``(```?-]A)+(" -M``B@!Q2@`PTH__\-0``!H&$!`@`@(,G_+PR`!@B@[0PH`)H&8)9%!P@``>!G -M`OK_)_^%#0@``>!G@OC_)Z!4\"N!7#@,`(`"^#V``?%]@K,T"`"#L)B@W?BA`@/__)P'^WV$@ -M*_`G`!P'8`0^#A`@#?`O-/Z?80`@"%(,`.`)`)JF40#\!T#H`0``%`1@"AS^ -MQT$:B`<(`)R)0@`F`%`#?@!0_X%-$`!\/V"^K`(`H!,8*`I^!T```>!G`WXJ -M0B$?`"``)$E2`*((8/__+4"@B@@H_O]-0``!X&>""``@_H4-"`%ZX%<"&@`@ -M':!'$`I^!T"@N!@H!'XG0`!\'V#@``@H`)H&8*`-\"!G@0``(`'^/V``CD`:H/GQ+P`@"%(`#@`8!7K@ -M5XL&`"`$_@A`H.,7*`3^)D```>!G`B7I9X(!`"!PA`8(`7K@5P("`""`]/$O -M`GK@5P)\'V(!``````XH&@!\/V`PK0(`H.,7*`">!V`!>N!7`"`(4H$$`"!R -MA`8(``'@9X$#`"`!A`<(``'@9P("`"``A`<(``'@9X(``"`!_A]B``X(&`"C -MZ&<"`>!G`0(`("#E^R\`'`=@H.'O)P```%"@X.\G`?X?8`0^#A``L>\O(",7 -M*```H&$,^@9@1/[?@0(#`"``O@]@`'Q?8,#-`@"@ER8H#7XG0(#__R<(>N!7 -M`GW@5P0````!`P`@`+X/8`!\7V#`S0(`H)(F*!%^)T"`__\G`'P_8```(``` -MQ``(!/KF5P$:`'`"?`!@\____P"`0!0@51DH````4`#+[R<`@B!0!@)`$`4" -M0!`2`D`0"`*`$`H"0!`+`D`0!`)`$!,"0!`,`@`0!P)`$!$"0!`0`D`0&`)` -M$!P`(`@`?H`0#H@@"`("@!`@@`\X````4`0^#A"`L>\O`'S?8HCC`@````L( -M&OX_FPP`(`H`?+]AM*P"`!R`"`@`JJI2#'Y`0I#^'V!8@$@0"OX&0*!:&"AH -M_BA``'Q_8HSC`@``@`D((JJ($`!^`!0`?/]A6.,"``"`!P@!_C]@`'X`%`!\ -M'V.0XP(````,"``"`!1#A"8(H*?[+P`D"6`@`0`@`"B*4@`J1Q0`M?$O"WK@ -M5P(S`"``?-]AE.,"``!$!P@!@#^````?")CC`@``0``(``/@9P$K`"``1`<( -M`8`_@`"`"0@`0``(``/@9P(H`"``1`<(`8`_@`"`!P@`0``(``/@9P(E`"`` -M1"<(H&PA*'K^'V"@H?LO`*((8`!$!P@``+\)G.,"``-^`((`H.9"`'P_8'"K -M`@`@D!_BQ`@/__)X!^`&@%`$D0 -M!OX?8"``21````L((/4-*`'^/V`1A"@(G_X`8`%ZX%<""0`@`$0'"`"`)P@! -M@%^``,``"``$`&@`@``4`(`'"`!`(`B@4R$HAOX?0`!$!P@`@"D(`8!?@`#` -M``@`!`!H`(``%"`'`"`!_I]B`_X`8`-ZX%>"`P`@`$0'"`"`*0@!@%^``,`` -M"``$`&@`@``4@`$`('K^'V`@22$H/?XL0`!$!P@!?@!```!'%`!$!P@@>N!7 -M`LS_)P#+_RNI7@5XC*'O^'V`@0R$H3OXL0```#`@`*@`4`('O)P0^#A"` -M3>\O``#`80""X&&@`0`@`)JF40'^!D``#J`9(/KF5XH%`"`#_D:````_")SC -M`@``'`=@H&(7*`"$($`!>N!7`OK_)P":1Q`@;>\G`?X?8"!L[R<```!0!#X. -M$`!"[R\`?/]A-,,"`"!T\2\0@:<)!GK@AX-G[R>`$PHH``'@9P)F[R<`F^9G -M`67O)PR`Q@D2!`<(@'K@5P$'`""@^@XH`!P'8!P`!PB@"B(H,'X`0""Z'B@` -MF@9@@/X?8!(`1Q`.A0<(`7X`0``/X!^A`0`@#H%'$*#U_R<$@*8)`'Q?8&3. -M`@``?#]@WP$``*`8)B@`O@]@@/__)P0^#A`@*>\O+OX?8`!\OV',UP(``OX_ -M8%S_1D"@>R`H`(9A4````%`$_C]@8/]&0"!Y("@`AF%0'/X?8`3^/V!D_T9` -MH'8@*`"&85`@_A]@!/X_8&3_1D`@="`H`(9A4"3^'V`$_C]@9/]&0*!Q("@` -MAF%0*/X?8`3^/V!D_T9`(&\@*`"&85``1.\G!#X.$*`7[R\(_A]@`'R_8N!7`GW@5P0```""!``@``@?"`##`@``?>!7($(```("`"`@ -M_A]@,OX_8"`"`"!J?T%`(/X?8#+^/V!H?T%``OY_8`/^GV`@31@H`(JB4`7^ -M'V`B_C]@D/Y&0)#^?V`@7"LH``B"4`!\7V#LU`(`!_X?8`""(%!B_G]@H%@K -M*``(@E"`).\G!#X.$*#Z[B\"_C]@`'S?85:0````?+]AS,\"`!I^!T"`_T9` -MH$D@*`"&85`??@=``OX_8(+_1D`@1R`H`(9A4!Y^!T`"_C]@A/]&0*!$("@` -MAF%0(GX'0`+^/V"&_T9`($(@*`"&85`A?@=``OX_8(C_1D"@/R`H`(9A4`)^ -M!T`"_C]@BO]&0"`]("@`AF%0`WX'0`+^/V",_T9`H#H@*`"&85``'`=@`OX_ -M8([_1D`@."`H`(9A4`%^!T`"_C]@D/]&0*`U("@`AF%0#'X'0`+^/V"2_T9` -M(#,@*`"&85`-?@=``OX_8)3_1D"@,"`H`(9A4`Y^!T`"_C]@EO]&0"`N("@` -MAF%0#WX'0`+^/V"8_T9`H"L@*`"&85`0?@=``OX_8)K_1D`@*2`H`(9A4`#_ -M[B<$/@X0H-3N+QS^GV$`?-]A#84```!\OV',U0(`"7X'0`+^/V"6_T9`H"(@ -M*`"&85``"A\(8+`"`*B))@@`@`!0_H&-$`Y^!T`"_C]@_O]-0*`=("@`AF%0 -M`!P'8`+^/V":_T9`(!L@*`"&85`%?@=``OX_8)S_1D"@&"`H`(9A4`M^!T`" -M_C]@GO]&0"`6("@`AF%0#'X'0`+^/V"@_T9`H!,@*`"&85`-?@=``OX_8*+_ -M1D`@$2`H`(9A4!A^!T`"_C]@I/]&0*`.("@`AF%0`'P?8`:7```"_C]@IO]& -M0*`+("@`AF%0`'P?8`2!```"_C]@JO]&0*`(("@`AF%0`'P?8`6!```"_C]@ -MK/]&0*`%("@`AF%0`'P?8`&1```:_C]@L/]&0*`"("@`AF%0`'P?8`"A``"` -M_C]@'/Y&0*`6("@`AF%0`'P?8$"A``"`_C]@G/Y&0*`3("@`AF%0%GX'0`+^ -M/V"8_T9`(/H?*`"&85``?%]@;L\"``!\'V``E````OX_8*#V'R@`AF%0(-_N -M)QS^GV$$/@X0(*'N+P+^/V``?-]A`)0```!\7V!LSP(``!P'8*#P'R@`AF%0 -M`'R_8!V`&_C]@#/Y&0""M'R@`AF%0 -M)/X'0`;^/V`,_D9`H*H?*`"&85!M?@=``OX_8!3^1D`@J!\H`(9A4`!\7V#H -MU@(``'P?8`#;``!`_C]@H+L?*`"&85``?%]@:L\"`$Q^!T`"_C]@H*$?*`"& -M85"`>.XG!#X.$"!2[B^(_I]A`'S_88"E``!I_A^"`'R_8N=7"_K_)X#_ -M!T"`_C]@H/Y&0""@'R@`AF%0`'R_8!V"`_C]@H/]&0"":'R@`AF%00/X'0(#^/V`@_D9`H)!\H`(9A4$U^"$!`_C]@J/]&0*",'R@`AF%0`'Q?8#C7 -M`@`^?@A``OX_8*!R'R@`AF%0(%KN)XC^GV$$/@X0(!WN+Z3^'V"@H!\H`((@ -M4`!\OV',SP(`I/\&0"[^/V`@KQ\H``1!4``('P@`PP(``'S?80``(```?>!7 -M(T(``((#`"#H_P9`%OX_8*"I'R@`!$%0&'P'%"(R``"`.^XGU/\&0!3^/V`@ -MIA\H``1!4!A\!Q0`$`````0?"&2S`@```>!G'/X&0`+\!D`8`````OX_8*"@ -M'R@`!$%0@#/N)P0^#A``!NXOH`,`(`":IE$$_P%`$/X_8""<'R@`!$%0`?X& -M0``.H!D/^N97B2SN)P!\?V`$Q`(``((@4`?ZX%>)^?\G`_X&@``"`&B`?D!H -M`((`0``&`$`$!4`0`?X`0"#[_R<`#B`8``0?"*#"`@``@`\X@/Y_0$+ZX%N!7`@,`(`S`8`B`_A]`"(``%`#\`6@` -M`0``#(``%(T%`0@!>N!7@@8`(`S```@(B``4``@`:`R``!0`!``@````4(X! -M01`,P``(`'P`8/S^__\,@``4"/P`%`,!````@`\X```?"`3#`@``@`\X!#X. -M$(#2[2^`S?\O@+C_+X`__R\`J?XO``;R+P``'P@$PP(`@)OU+P#Y_R\@3O4O -M`((@4`!H&R@`^>TG!#X.$(#-[2\``!\(N,0"``QZX%<&]^TG@)CN+R"H"B@` -M`*!AH)GN+P":!F``].TG!#X.$(#'[2^`E.XO`'Q?8/SD`@```*$)`((@4``" -M'Q``Y0(`H)/N+P!^`1``F^9G@0$`("`^(R@`F@9@`.SM)Z#K[2<```!0!#X. -M$("^[2^`B^XO`'Q?8`3E`@```*$)`((@4``"'Q`(Y0(`H(KN+P!^`1``F^9G -M@0$`("`U(R@`F@9@`./M)Z#B[2<```!0!#X.$(#.[2\``*!A`()`8J"![B\` -MGN=1```@8@!$'PAPP@(``7K@5]O^_T*"`0`@`?[_82!]#2@!_A]@('SN+P;^ -MWV(```!B(*;Q+SC^'V``?-]A)+("`)`)APH`?+]B`(@"```J:D(`*HI!`"Q& -M$`":!F``IBE@H.P?*#C^7V``*JI"`*Q*$!B$!@@$>N!7`0,`(`"^#V``?%]@ -MP,T"`*"/)"@!_BM`@/__)R"$*0@"^N!G`0,`(`"^#V``?%]@P,T"`""+)"C@ -M_C]`@/__)P3ZX&N!G -M`?X?8,("`"```$$4````4`!^010``%\47>0"`!^$!@@#?@!@`7K@5S$!1Q"" -M`0`@`7Y?$&_D`@```@`@`WK@5P(!`"`"?E\0;N0"```$'PCWK`(``GK@5X(! -M`"`@)`$H((0&"""$*0B/`T<4E`4'"#C^/V`!@$D0`(0)"`'^7V`@:",H`"1I -M8"!+[B\`(`A@`?KG5R%'#2@!``!0H$CN+P"B"&``K>TG!#X.$(!V[2\`?+]A -M_.0"``"`!@@``>!G@I_M)P``'P@$Y0(```'@9X*=[2<`?!]@-+("`""$#BC_ -M_S]@``'@9X'Y_R<`?%]@R,T"``!\/V!>!P``(%HD*`"^#V"`__\G!#X.$(!Y -M[2\``&!B`(+`80`$H6$`AD%B``@B8B`U[B\`GN=1````8@!$'PAPP@(``7K@ -M5X(!`"`!_O]A(#$-*`'^'V``'!\48.0"```:'Q1DY`(``7KI5P'^?V`"AF%0 -M`*8)8``<)V``FD9@$/Z?8*"B^"\`HJA@`?KG5R$I#2@!``!0H"KN+P`@"&`` -MB^TG!#X.$`!;[2\``*!A`(+`86/^'V`@3A\H`)HF8``$'PB@P@(``('F5P$# -M`"``&E\0U:P"``":!F`@W!`H`!PG8(!][2>`F_4O@'SM)P0^#A"@3.TO!GY` -M@`!\/V#LLP(``(0`038$)`@X`D00-P0D""`/`"@V`D00H'3M)S<`1!`&?B"` -M`'P?8.RS`@```J!`-H3B""B$P@@!CA^``!!`&`".`V``#>!7"@<`(``$(4`` -MD$`8``@_"""M`@`!?@!``(2`8``(/PCPNP(`)HAB"`"&(&``B>!G``X`&`*` -M#S@`^/\G((`/.`".`V`&?B"``'P?8.RS`@```J!`-H3B""F$P@@!CA^``!!` -M&`".`V``#>!7C`8`(``$01@`"#\((*T"`/]_`$``A(!@``@_"/"[`@`FB&(( -M`(8@8`")X&<`#@`8`H`/.(#X_R<@@`\X`(X#8`0^#A"@*^TO!GY`@`!\/V#L -MLP(``(0`038$)`@W`D00.`0D"*#@_R\V`D00H%/M)S@`1!````!0`'R?8("T -M`@`@!``@8`5""`)^((``AF%0`(@@0#"'`!``AP`0`7X`0``.`!@`!>!7B_O_ -M)P"`#S@&?B"``'P?8.RS`@```D!`````4#P`01`]`$$0.@!!$*`"`"``@B!0 -M__Y_8``"`4`J!D`0`?X@0`SZX%<+_?\G`(`/.!P`8`@`?+]@@+P"``B$(0@0 -M@(((!OY`@`!\/V#LLP(``(1`0#8$(0@"`B(`)()!$#8$(0@<`&`(%P)`$!*$ -M(0C^_R!@$H)!$#8$(0@4@&((`H)!`!P`(`@2A``(```!:""`#S@2@$`0`'P_ -M8+2L`@!#A(`(`7KB5P``?PB0O`(`(0(`(!P`0`@@A"`(@/K@9P$$`"`!A"$( -M)`)!$`'^/V`7`D`0'``@"!*$``@@!0`@`7X`:`)ZXE>"!``@"(0A""0"01`( -M_C]@%P)`$!P`(`@2A``(_G\`8""`#S@2@$`0!(0A""0"01`$_C]@((`/.!<" -M0!`$/@X0(`WM+P9^((```.!A`'P?8.RS`@```F!"/81)"CR$R0D`'`E```Z` -M&B`%"2@`G@=@`'R_88"\`@!NA08(``'G5P`@"%*)`0`@;84&"``!Z5>,(NTG -M-X2I"C:$*0HXA,D)````4#R`21`]@$D0!WX)@*#C[B\`*"I@(("&"```8&$" -M(@(``*))0@`6X*=`_AQ`!WX`B``.(!DJ`$D0`*H)0"H$(`@`G`E`*@0`"/_Z -MX%A7@@0` -M(`"'X6*#@`@@`T`(`"#Y%<*#0`@``P`(`"KZ%%G`@4`(`"!Y%>*^/\G@`,`(`"!Y%<*!P`@``(`(`"#Y%<, -M`@`@``7A9X'\_R<@!``@`?X?8@"#Y%>*`@`@``7A9P(!`"``@>17C/C_)P+^ -M'V(`(>AG@0\`(`%ZZ%>"#0`@H)O_+P">!V``#0`@`'S?8;2L`@!#!"<(`OK@ -M5P+]X%57A@,`(``('PA4Y`(``('H5XP!`"`@57I6[_+P6>!V```0`@`GKH5P'S_R+`0`@H)?_+P">!V`J$DD0$(`&"#:$ -M*0@"`@`````?$`3W`@``Z.PG!OZ`@`!\?V"`M`(`;/\A0`"(@$`\!"((`GY! -M@`"`($`\`D(0``:!0#`!(@@`@"!`,`,"$&2!(0@`@"!`9(,!$&B!(0@`@"!` -M:(,!$```?PBPO`(``(0A``"``$``A$%`((`/.````1`&?@"``'Q?8("T`@`` -M!&!`J84!"`%^`$"I@4$0`OX`@``$($``@0`(`7X`0`"!`!!D`0$(`7X`0""` -M#SAD`0$0!GX`@`!\`$"`M`(`H@4`"```($```!\(G+P"`""`#S@$`@``!#X. -M$""D["\`"()0``#`80P`H`D`@B!B$81F"!R`Y@F@_D%@H'KA5P>$)@@A`@`@ -M"(0'"@'^`$``#B`8!X!&$)_^`6`!>N!7`GWA5Z`````"?)]@`0```!&$!P@( -M>N!G0@$`(`:$1@@%A$8(`(0`0`>`1A``"`%```X`&!>$1@@@UO\O`"`H8!&$ -M!@B??@!@`7K@5P$0`"``!%\(Y+$"``>$!@@`!>!7`?X_8`H"`"``@D@0!/X? -M8"`E`"`2@$80`/Y($!*"1A``?#]@Y/<"``"```@!?@!``(``$""(!@@``#\( -MK+P"``%^`$``$&`8%X0&"`)^0(``A`````8`0`"$0$````$0^OX?8*!P'B@` -M'"=@@!D`(`+^'V`2@$80`/Y($#2$!P@@B"8(`7H`8`'^($``D&`8%X0F"*$$ -M`"`"_D"``'R?8'SW`@```"((`(8@0``"`A```)\(J+P"`(`#`"``?)]@&/<" -M````(@@`AB!```("$```GPBDO`(```0B``"&($``!$)```(!$`>$)@@`?%]@ -MX/<"``'^8%```"$(`(8@0``"`1``?%]@`/@"````(0@"B&8(`(8@0``"`1`1 -MA"<(@/K@9P(!`"```>!G@@$`(!>$)@B@M_\O`"`(8"!D_R\`(`A@@(SL)P"` -M#S@``#\(J.,"``"((`@`@^!G`H`/.(!ZX&<`?#]@@+P"``$"`""GD1\8<(&` -M$"`"`"#(_P!`3`P"!X%<4@P80"P@`(!B%Q@D9A08(&H4F""!`[B\!?@!``!WG9P". -M`!@"`@`@`?X?8!B!1A`@!@`@&8-&$``!X&<9@T80`@(`((`#`"````!0&(%& -M$!F!1A"@%?(O````4!MZX%<,`0`@``(`*(!I[">@:^XO````4`!H["<$/@X0 -M(#CL+P```%``"#\(`,,"``#]X%!G@6#L)P!I[B\% -M>N!7!5_L)R!C[B\!_A]@`'P?8```!```S/DO`%SL)P0^#A"`,.PO@&CN+P!\ -MOV&\L@(`*84F"`'^($`/>N"'*8-&$`18[">`LP0H`GK@5X%6["<`L@0H`WK@ -M5P%5["&"``@(#,0*/S_#4``?+]A#,,"``"!!@C\@2T(`(`@ -M4`2!!@@`@>!7C@,`(`!\'V`````!@*KY+P'^'V`0@480_($-"`"!!A"@3>PG -M&/Z?800^#A"`#.PO@#GN+P%ZX%>!S_\O`#[N+P5ZX%<`?+]A#,,"`(4&`"`. -MB08(`7X`0``0(!@.@880"(D&"`"!X%<"!@`@`+'_+Z`@$"@`_P9`````4*`# -M`"`.@880$(4&"``!X&>!`0`@````4""L_R\0@480`,W_+X`I["<$/@X0H/_K -M+P"*HE``!!\(]ZP"``!\WV"`M`(``'Q?8("\`@``?']@5N0"```!X&<`?)]@ -M6.0"`((+`"`(_C]@8`-#$(Q_(4`0`@$0E'\A0!0"`1"""P`@!/X_8&`#0Q"P?R%`$`(!$+1_(4`4`@$0N'\A -M0!@"`1"H?R%`'`(!$"1\`1`<]P(`*'P!$(#W`@`L?`$0-)8"`#!\`1"@E@(` -M`_Z_8:1_(4`@`@$0(`P`(`/^/V`,_C]@8`-#$.Q_(4`0`@$0^'\A0!0"`1`$ -M?B%`&`(!$-1_(4`<`@$0)'P!$$SW`@`H?`$0L/<"`"Q\`1!DE@(`,'P!$-"6 -M`@``?+]A;P$``+Q_(4`@`@$0"/X_8`""@1`@:2(H``J"$"`$`"``',=1`)H& -M8*`?`"@`'"=@H*W^+P`+^_\G`*/^+P)^7Q#"L0(` -M@/;K)QP`X`@`?!]A@+P"``B$(P@&_D"``'P_8.RS`@``A(!`-@1"""D$P@@! -MA#^``)!@&"`"`"`4`*0(`(1A&/]_(4``CD`8``WA5PP#`"`F""((`(?@9P'\ -M_R<"A"(``?K@5X+Z_R<0`"0(`H0@`"2"0Q`<`"`(%P1`$!*$``@!?@!H((`/ -M.!*`0!`<`"`("(0@"`;^((``_"!`@+0"`**%(`@`@D!````_")R\`@`$A"`` -M`_Y`@`(((`@`A."G$/Y!G@@<`("F$)0@`@^%72P(`(#:"11"@4_XO`)($ -M8#:$)0@``!\(D+P"``("`````!\0!/<"`*!^_B\`D@1@`!``(``$'PCWK`(` -M``1?"&NO`@```>%7`0T`(`!\/V"`O`(``7KA5P%]X%<"````@@,`(#2```@! -M?@!``_KA5S2``!""!P`@H`0`(`7^'V`">N%7`7W@5P$````"`P`@.(``"`%^ -M`$`X@``0`_X?8"`"`"`V@$40/(``"`%^`$`\@``0(%+^+P"2!&`W@$40($/^ -M+P"2!&`@MNLG.(!%$`0^#A``C^LO``#@8:#]&"@!_A]@`'P?8,BQ`@"@F@PH -M??X_F``(&`<@`8(`'S_8;RR -M`@`J`H`0$00'""R!)PCU?T!@$01'$`*(9@@`@^%7``0!8(X"`"``A2<(`OK@ -M5P$!`"`(?@%H$0!'$(!ZX&!`0`@H#G^+P":!F```0`@($7^+P":!F`*A`8(``'@9P$# -M`"`0!`<(?W\`8!``1Q`D!`<(``'H5P(Q^2\(A4<(!X0&""B%)P@``&%``(/A -M5PP#`"```^!7"@``4`N``%`+?`!0`0```(```"`!?@%0('/K)RP`1Q``@^!G -M`BP`(/!ZX%<+!P`@_'K@5PD&`"#P>@!0!'P`0`,````"?@"0("8`(`Y^`$`` -M>N!7#"@`(`YZX%<))P`@(",`(`%^`%`(>N!7"P0`(!!ZX%<)`P`@"'H`4`1\ -M`$`#`````GX`D"`>`"`2?@!`(GK@5PL$`"`P>N!7"0,`(")^(%`?_@"(``(` -M0``"`!@@&0`@%7X`0#1ZX%<+!``@0'K@5PD#`"`T>@!0!'P`0`,````"?@"0 -M(!0`(!U^`$!D>N!7"P0`((QZX%<)`P`@9'H`4`1\`$`#`````GX`D"`/`"`A -M?@!`D7K@5PL$`""9>N!7"0,`()%Z`%`$?`!``P````)^`)`@"@`@+'X`0)MZ -MX%<+!``@G7K@5PD#`"";?B!0'_X`B``"`$```@`8(`4`("]^`$"A>N!7"P<` -M(*5ZX%<)!@`@H7H`4`1\`$`#`````GX`D#%^`$```$$0((`/.````%`!^N!7 -M`OW@5P(````!U_\G((`/.`'^'V`$/@X0(!/K+XS^'V``?#]@B`0``*`('2@% -M_K]A`'P_8'"L`@`YA0`(`7K@5X(!`"````!0.8%`$`;^OV&@-^LG`(X&&`0^ -M#A"`%.LO1/X_@@!\OV%!7__\``"$$`"``GN=1@)T% -M*```P&$@TR0H`)HF8`)ZX%=!`0`@`?X?8@":QF&,_A]@H/@<*#+^*$`0@`8( -M``'@9X(!`"`4@`8(``'@9X$$`"",_A]@(/0<*#;^*$``'`=@H)8C*``@*&`" -M>N!7`G[@406>YU$@*.LG`)X'8`0^#A``]^HO`,3K+P!^7Q!VJP(`()0D*``` -MH&$``>!G@0(`(`!\/V!-!```H.D<*(S^'V``5A0HH,#K+P":!F``&^LG!#X. -M$"#TZB\D_I]A//[_F8S^'V`@Y!PH'_XG0``A[2\!>N!7@00`((`=[2\(>N!7 -M`0,`(`!P`R@">N!7@0$`((!N`R@#>N!7`@\`((S^'V"@W!PH+/XG0`!\OV%< -MXP(`$(`&"``!X&>"`0`@%(`&"``!X&>!"0`@@*WK+P``P&$!?E\0=:L"`!#^ -M!D``FB9@(+HD*/C_34`">N!7`@(`(`"`!@@0@`80!(`&"!2`!A``/A0HH*CK -M+P`!G@@,`(`!\7V"8S0(``'P_8)X$```@MB$H`+X/8(#_ -M_R>@QP\H`"`(4EX(!PCTH0T0"GX`@/"!#1``?/]A!-D"`/#_#4``GB=@((HD -M*/C_34#\@0T(]*$-$$H`AQ`0?@"(3`"'$/B!#0@`?!]B7.,"`$X`AQ`0?@"( -M4`"'$%8(!P@`GB=@"GX`@/"!#1#P_PU`(($D*!!^2$``?!]@J*\"`(")'2A6 -M""<("OX@@`"`X*?P\PT0\/\-0`">)V"@>R0H`"!(8!Q\"!`9<@``H('K+P": -M!F"@[NHG,/Z?800^#A"`Q>HON_[?0@```&)4_A]@H*0<*`%^*T"@>>LO`*(H -M4@``0&(`?+]AR*P"``"!!@@`?+]B`````0`.P!D`?(!B`/_^_PM^YZ<`H!Q` -M`!H`0`EZZ%<`)H@8`(`"F:5(*>N=7`GWG5P@````"!``@5/X?8""8'"@3 -M?BM`@(O_+P``X&%3_A]@H)4<*`">)V`!_@=0"7K@5XT(`"``$@`@`?X_8@'^ -M?V(`?E\0=ZL"```J*F@`C@<8H`8`(``"`&@`?"I@_____@".!Q@`@`!H`'P` -M:````0*``P`@`?X_8@!\*F#____^`(X'&`"``&@`?`!H`````@"!!A"@7^LO -M`"0)8`OZYU>""0`@"WKG5X$(`"``"!\($JT"```!X&>!!0`@H"3X+P+^"I`` -M!0`@`WR``!`@`@`)L5*``3%B@@$_@O -M@/X?0``Z^R]1_A]@H&X<*``<)V!2_A]@(&T<*``@*&!3_A]@H&L<*`">)V`, -M^N=7`J?J)P"^#V`@NB$H_?X_0`"EZB<$/@X0H'3J+YS^/T```.!AH&4<*%C^ -M'V"`.NLO`'Q_8,BL`@``@4$(`'PA8`#_```(_L")!G[GIP">/$``AB!`!(6@ -M"0!\06#_`/__"/XF@`"$(&B@->LO`(,!$%7^'V"@6QPH`!PG8%;^'V`@6APH -M`)XG8%?^'V"@6!PH`)HF8`3ZYE<"C>HG`'P_8&/`4(0!#X.$*!#ZB\```!0@)+_+P!\OV%HK0(`B(4&""#G -M_"^/A28(3/\&0*"(_"\`@B!0`+05*`!IZB<``>!G`@``4`5^`(``?&!`$*<" -M``!\OV"LXP(`H`D`(`""(%``@H!``(@!0!@(P`@,_N"G`(J<00`,!A`("``( -M`(I<0`@`@1`$B`$`!@"!$`""@4`0!`((!`"!$!0$`@@*`$$0`?X`0``.(!@$ -M^N!7"_;_)P"``@@`?#]@:*T"`'"!@!`(B`((8%`$!B``@AZ@8`0((@" -M"'R!@!`!G`4'J)P"^#V``?%]@I,T"`"`! -M(2@4_B9`@/__)P0^#A"`$>HOH$3L+V3^OX$+>N!7`0,`(`"^#V``?%]@F,T" -M`"#[("@R_B9`@/__)X!A%RB@6_\O"OX?8'O^'V"@`1PH-?XF0(`TZB<$/@X0 -M`!+J+P`$'P@QK0(```'@9R3^/X("`P`@`+X/8`!\7V"LS0(`(/$@*!;^*$"` -M__\G`'R_8;2L`@`\A`8(``'@9P(#`"``O@]@`'Q?8*S-`@"@ZR`H%_XH0(#_ -M_R=N_A]@H/,;*!G^*$``1`0H@!P"*(#S\R\`,NPO#WK@AP,#`"``O@]@`'Q? -M8*S-`@`@Y"`HH/XH0(#__R<^A`8(!'K@5P(*`"```!\(Y*\"``QZX%!G`'P_8&"P`@""`0`@`)R`$"`!`"````!0`(H` -M"```$"B`;?4O```?".2O`@`,>N!7@@L`(```'PA,W0(`$'X`0""J$B@*_B9` -M(-W]+P'^_V$9A`8(<'X`:!F`1A`@`_\O`?X?8EZ(!@@``>!G`@(`(```'PA8 -MXP(`__\_8``"`!1#A`8(``'@9P%`%2B`"@`@``'@9P$#`"``O@]@`'Q?8*S- -M`@`@O2`H8_X_@(#__R<9A`8(SW\`8!F`1A`?A`8(^W\`8!^`1A"@WQTH`"`( -M4B#;%"@"_O]A()\5*````%"``@\H`)H&8*`0_"\$_C]@`*\)**`F(R@`(`A@ -MH!3_+P">!V"`1O4O`!P?$`CX`@``'!\0#/@"`(#PZ2<$/@X0(,#I+P```%`` -M`#\(Z.,"``!\OV%0W0(`((!`$"#^'V`%@$`0`(`&"$#^/V```D`0(!42*!!^ -M`$``@`8(H!,2*`1^`$``X^DG!#X.$""YZ2^!_A]@HO[?@:"L&R@U?B=```0? -M"$[D`@```>!G`@8`((`Y`B@">N!7@00`(``X`B@#>N!7`0,`(`#=\R\!>N!7 -M@0$`(`!$!"@`>N!7C`4`(('^'V`@HQLH0WXG0``$OPE`L`(`@'X'**`X_R\# -M_A]@()`'*`":!F"`T^DG`-KK+P%ZX%>"`@`@@-KK+P%ZX%<"`0`@@.D'*(#/ -MZ2<`UNLO!7K@5P+.Z2>`UNLO`7K@5X+,Z2<`?%]@M*P"`%X((0@`@^!G@0$` -M('$$`0@``>!G@LCI)P"#X&>"`0`@<`0!"`%ZX%N"'@P$`((!=!"@``>!G@0(`(`'^'V````<0 -M7?X?8*`<`""I_C]@`'P_8C3#`@`"B0@(`GK@5XL"`"`!_A]@```'$%W^'V"@ -M%P`@L/X_8`P`J`D<@"8("(3@"2#ZYU<+`P`@`+X/8`!\7V!DS@(`(&0@*+K^ -M/V"`__\G```?")SC`@`#_D>```0`0*"3$2@T_B!```'@9P(&`"``?#]@G)8" -M``"```@!?@!``(``$`7^'V`2@$80`'X'$*#L]R\`(`A@H`<`(%[^'V```!\( -M6.,"``&>/X``0``(``/@9P'^7V`"!0`@`'P_8)26`@``@``(`7X`0`"``!`` -M!`<07_X?8`">)V``6QLH@)+I)R`H"2@`F@9@`HD("`%^`$`"@8@0(';W+P": -M!F"@%QDH`"`(8(#^'V`2@$80H(SI)P!^!Q``?%]@:*\"`-`%(0@``^!7`8`/ -M.-`!01```>!G`@``4`%\'V`!````@!G_)P0^#A"`7>DOXOX?@@``X&%U_A]@ -MH$L;*`9^*$``?+]AJ+`"`#R!!@@``>!G`GW@5PD````"?>!7#`````$#`"`` -MO@]@`'Q?8*S-`@"@.B`H"GXH0(#__R<,>N!7@@4`(`*$!P@``>!G`GW@5P$` -M```"`P`@`+X/8`!\7V"LS0(`(#0@*!%^*$"`__\G&H@'""*()P@`@>!7"P,` -M(`"^#V``?%]@K,T"`"`O("@6?BA`@/__)P"#X&!V"@;QLH*/Y?8$,$!P@``>!G`A$` -M("`$!PA>?P!@0'X`:"``1Q`DA"<('P0'"`"#X&<"?`!H!`````%\`&#[____ -MH`X`(!\`1Q`@!`<(/WX`8"`(`"`A?@!H(`0'"%]^(&!2"`<(%7K@AP,$`"!! -M_@!H(`!'$`"^#V``?%]@K,T"`*`,("A>?BA`@/__)[_^`&`!?@!H(`0`("`` -M1Q`!>N!7@?3_)P)ZX%>!]?\G`+X/8*!A("AF?BA`@`D`*#@`!PAL?B=`H&3U -M+P'^7V`P@08(``'@9P(#`"``O@]@`'Q?8*S-`@`@`"`H;'XH0(#__R>@-/4O -M0P0G"`!\'V````(``*GV+P`]Z2<$/@X0@`WI+P!\OV&TK`(`0X0&"``!X&<" -M"P`@`'P?8%2M`@`X@`809/P&$&BL`@`@!P`@"/X_8`!\'V!DK0(`.(`&$&3\ -M!A"`K`(`H`,`(`3^/V``?!]@=*T"`#B`!A!D_`80C*P"``S^/V`@!0`@:()& -M$`%ZX%>!]_\G`GK@5P'Z_R<`?#]@?P,``"!%("@`O@]@.(`&"&S^)D"@2/4O -M`?Y?8&R(!@@``)\0Y.,"`(`CZ2<$/@X0@/3H+P````@%>N!7#B#I)P!\7V#P -MS0(``'P_8"\!``"@X!\H`+X/8(#__R<`?+]@[.,"`"`#`"``AF%0\/X@8``" -M(6@Z`D(0`?XA0`".8!@`!B!``X0@"`"#X&<`BD%``08`(`0"01``A"$8`(J` -M0`'ZX6!G`((@8J$!`"""_E]"`GK@5XP$`"`. -MA0<(``'@9P(#`"``O@]@`'Q?8&3.`@`@LA\H`7XI0(#__R<,`*<)8OX?8!R` -M!@H@N1HH`!PG8#`$"`@,>B!@@0$`(/Q^`&!(>N!7`BH`(`Z%!P@``>!G`@,` -M(`"^#V``?%]@9,X"`""H'R@/?BE`@/__)_]_`$`.@4<0`?X?8`"`"!`1A`8( -MH'X`8*!ZX%!G`0,`(`"^#V``?%]@9,X"`""<'R@A?BE`@/__)R`'`"`,H@80$00(""P$ -M*`@(>N!G0@$`(`:$!@@%A`8(`(``4"P`2!`$_A]@$H!&$`'^'V"@:/DO`(%' -M$#`$"`CP?B!@T/K@5X(#`"!]_A]@H)H:**#^/T"@(P0H`!P'8#`$"`CP?B!@ -M@/K@5X('`"`1A`8(GWX`8`%ZX%>"!0`@`*\<*`!\/V`0E@(``(``"`%^7Q`C -MK0(``7X`0*`G'2@`@``0,`0("/!^(&!0^N!7@L?H)WS^'V"@C1HH47XI0*`6 -M!"@`'`=@@,3H)PCZX%!`P`@`)H&8""4]B\`@B!0`HD'"/]_`$"@NN@G -M`H&'$!*$!@@$>N!7`0,`(`"^#V``?%]@9,X"`*!S'RBS_C]`@/__)X#^'V"@ -MM.@G$H!&$`0^#A"`C.@O``"@80!\_V$TPP(``HD'"``!X&>[_C]"`0$`(`)Z -MX%>,!``@#H4'"``!X&<"`P`@`+X/8`!\7V!DS@(`(&@?*`'^*$"`__\G#(#& -M"6+^'V`<``<*(&\:*`":)F`P!`@(#'H@8($!`"#\?@!@2'K@5X(3`"`.A0<( -M``'@9P(#`"``O@]@`'Q?8&3.`@`@7A\H#?XH0(#__R?_?P!`#H%'$`/^'V`2 -M`$<0("@(*`":!F`,``<(``'@9X$%`""`H0DH``'@9P$#`"``O@]@`'Q?8&3. -M`@`@51\H'?XH0(#__R<```!0#``'$#`$"`CP?@!@4'K@5P(,`"!\_A]@(%H: -M*"?^*$`@XP,H`)H&8``)`"`(^N!7`0,`(`"^#V``?%]@9,X"`"!+'R@Q_BA` -M@/__)P`"]`@"@C.HO!($&$`]ZX(>B_M^!A`,`(`2! -M!@@`?>!7`````@(&`"``JR`H`WK@5X($`"`O_A]@($4:*!Q^)T`!_A]@"(%& -M$`!\'V```"``@.3U+X!VZ"!7"0````)]X%<$`````GW@5P,```""`P`@`WK@5P)]X%<) -M````09#]+PC^'V"@9A8H````4`#!&B@`:.@G!#X.$"!"Z"\@_I]A(&_J+Z7^ -M_T$(>N!7@00`(`!MZB\">N!7`0,`(`"^#V``?%]@\,T"`"`D'R@!_B=`@/__ -M)]3^'V`@+!HH`_XG0`!\WV',Y0(```0'"`-ZX%N!7 -M`IJF40";YF>!!0`@H#[Z+P```%"`/?TO``&@80(#`"``O@]@`'Q?8/#-`@"@ -M%Q\H$_XG0(#__R<`A!4H`)OF9P$,`"#\_PU`(`PC*`'^/V"`R`(H`!`@&`#] -MX%?__P```0(`(/R!#0@`@>!7A@``(/R##1``-AHH_($M"`GZX%<%`0`@``'@ -M9P(#`""`EQHH`'P?8+2L`@`@9OHO`((@4``'`"``!`<(`?X_8`1ZX%<+@B!0 -M!7K@5P'^'V`+``!0(-\5*``$05"@9OTO!_X?8-3^'V"@#!HH/_XG0*!2Z"<@ -M_I]A!#X.$(`HOS/X_0@IZX%>!!``@@$/J+P1ZX%*`'^*$"`__\GU?X?8*`"&B@#_BA`H#$6*`'^'V"@/.HO`?X? -M8@IZX%<"(`A2`'P?8+2L`@"@3_HO`((@4*`'`"``FJ91%/[FIP!\_V%@L0(` -M`IX<```!X&<`\MQA@0(`(`"YT$`_D<0`?X&0``.H!D$ -M^N97"_C_)P`AZ&>!!0`@@,CH+Z`"_2\``*!AH$G]+PG^'V"@R.@O`)H&8"`( -M^B\!_A]@@`H#*``!`""@1?TO"?X?8-7^'V"@ZQDHZ/X_0(`BZ"<`>N!7`(!? -M4,L!`"``A``0`(``$```0&!`?D%`!WY!D`!ZX%<`A``0"@$`(`"$'U``@``0 -M`(`/.`0^#A"@[>!G`0?H -M)___'V`@818H'/X_8`!A`"@#>N!7H>#\+P":IE$`?!]@-,("``0;`!`(&T`0 -M`!M`$``:7Q!WJP(`(`L#*`$;0!``&A\0Y.4"`(#]YR<$/@X0(-3G+R#^GV$` -M`&!@`'Q?8$#/`@```0$(`((@4/B!#1`$`0$((%0`*/R!#1```>!G@A$`("`< -M`2@!_A]@`'R_8=#E`@```0`@`?X`0``.(!@8_N"G`)I<0"$$`0@``>!G`0$` -M(`"#X5>)^_\G`'S?833"`@```T<0#_X?8!\`01`>_@9``'(`0`9^`$`@CB$H -M^/\M0``!X&<"`0`@`!8'*(`#`"``!0<(`'P_8/(^```8?N"G)/X&0""(!B@` -M<@!`(/CG)R#^GV$$/@X0(+CG+RS^GV'H_PU``((@4"!IZ2\8_E]@T/X?8.B! -M31````!0Z8%-$`!\OV&^K`(``)H&8"!_$"CL_RU``'P?8-R8`@`@?1`H\O\M -M0`":!F"@>Q`H^/\M0`!\7V#NY0(`Z/\-0`""(%`@B``H$?Y_8"#IYRDO&/Y?8-#^'V#H@4T0````4.F!31`` -M?+]AOJP"``":!F"@;Q`H[/\M0`!\'V#!GM/_-00(#`"``O@]@`'Q?8"#.`@`@AAXHX?X_ -M8(#__R<`HBA2`'S_8=#E`@`@!P`@`!RG81C^Z*<`GEQ"'P0)"`)^0$``F@9@ -MH%OI+QY^*4`?!`D(`GX`0``:H$$!_@A```X@&@`$"`@`@>A7B_C_)QJ$)P@` -MG`90``Y@&.C_#4"@:``H`!Q'8"#'YR=T_I]AH,4`(````%`$/@X0H(KG+R#^ -MGV$`"!\("JT"``!\OV'0Y0(`"G[`@12`!@@``>!G@08`(`":!F`(_B9`H%XA -M*/C_34`!>N!7H@8`(`(``%#\@0T(``'@9X(!`"#X@2T(``/G5P8"`"````!0 -M$(`&$*#!_R?__Q]@$(`&"`"``$"@O_\G$(`&$```'P@XP0(``(`/.`0^#A`@ -M=N/PO`'R_833"`@``A08(&'[@IP#\'$#0Y0(`+@0`"`AZX&<$_A]@H+P` -M*`$``%"@3OLO`?X?8`#`_R\`?1LH````4""3YR<`@480`'P_8&3!`@#D_P!` -MH&0((``$05`$/@X0('CG+TS^GV$``,!A`(*@80!\/V!`SP(`"($`"``$`6+H -M@0T0#($`"`">YU'L@0T0`*(H4@!^01"@!@`@`"1)4@7^"D``G"=`H&GI+P`> -M05`#_A]@`8!*$`"$!@@+?@!0`(!&$`O^!U``#N`9`"A($"`*`"``A`8(`!X' -M0`$$``@`A$8(`GX`0``.8!H`G@E```[@&0"%YU>*`P`@`*H*8`"<)T`@7NDO -M`!Y!4`"F!U``A$8(``[@&0`F`5``@$80``X`&`"!YU>*'P`@`)RG0B?^'V`` -MG(=!``!&$`.$"@@``>!G`O+_)P2$"@@``>!G`?Z?8H(-`"`@QA0H\/\-0`;^ -M"D#X_RU`((,9*`C^7V#X_PU`H`\A*.C_+4```>!G@0(`(/C_#4`@#2$H\/\M -M0`%ZX%<"!``@`,3_+P`!X&>"`0`@`Z)*$"`$`"``)"E@H`(`(`3^/V`#J$H0 -MH`$`(``H*F`"_C]@`X)*$``>!T`!!``(`GX`0``>`$``@^!G`(1&""+7_R<` -M#N`9`?YG0@"<"4``G"=`H#_I+P`>05`/_A]@`8!*$!#^'V``'N=!`(!'$`"$ -M!@@!?@!``(!&$"#5_R<`CND9````4*!EYR=,_I]A!#X.$(`HYR^@SODO`(*@ -M80!\'V"TK`(``)OF9T#^/V`"?#]@"0```"`"0!`@;?DO`((@4`!.YR<$/@X0 -M`#/G+P``@&(`@B!B``0!8@"&P6$```!0`?X_8"!<`B@`!$%0``&@88(#`"`` -M?%]@(,X"``!\/V`%`0``H`<>*`"^#V"`__\G#(!&"@""(%``)`E@H,KH+X#^ -M7V`H?@E`'``)$`Q^X$$@0O,O`"0)8!P`:0H`*"I@,/X)0*#;Z"\8_E]@'``I -M"!&$``@@?@!H$8!`$!P`*0@2A``(\W\`8!*`0!`#?@=`(@")$`;^'V!4`$D0 -M!_X?8%4`21`(?@"(H+T<*%8`21`'?@!@4@")$*#^'V`Y`$D0`)X'8*`I\R\` -M@B!0````4#@`21`(`(D02(!)$`'^'V!)@$D02J))$$O^"4``("A@(,KH+P`< -M1V``F@9@()$%*`""(%"`,.@$`0#_X?8!^`0!````!0H/'X+R*`0!``!2<(&/[@IP": -M/$`C@$`0(&H4*/C_#4#X_PU`#'\G0*##("@``$!@``4'""3^)D`8?N"G^/\- -M0`#R($"@(QDH"/Y?8``%!PC(_C]@&'[@IP":'$`L`H`0(![G)R3^GV$$/@X0 -M@-OF+P!\/V`TP@(`"(4`"`%^`%`#>N!7#A,`(`!\/V`O`0``H`D`(`"^#V`@ -M*@`H!/X?8`'^'V"@VO\O`?X_8(`=_R\``.N!7C?S_ -M)P-\@`&LR@```'R&0:LR``````8XY.OKZPX.``"`4O\O@//F)X`;`"B`\N8G -M`WR``=C*````?(9!MC(`````!CCM]_D!`#O_+X#NYB<`[N8G!#X.$*#%YB\D -M_I]A``#`8?S_#4#X_RU`(![T+_3_34#\@2T(%/X?8`"`@!#X@:T)`!WG9Q7^ -M'V`!?!]@%@````R`1A``B``($'X`4`Z`AA"@_A]@#8!&$!#^!D``@B!0H&KH -M+P3^7V``!!\(-,$"`/R!+0@8?N"G`/P<0-#E`@`C!``($(!&$/B!#0@@@?4O -M#'X`0*#OYB[E`@"`%?TOH(SZ+P```%``N1HH(!L4*`O^ -M'V`4?P=`H+@'*'W^/YB`*_\O`WK@5X("`"``L_LO`*@!*`6$!@B@=_\O`((@ -M4*#<_R\!_A]@@,OF)P0^#A``GN8O`(/@9P!\OV'0Y0(`@8G%/Z?80"`X*?___]_____?____W____]_____?___ -M_W____]_____?____W____]_____?____W____]_____?R"`#S@`]AU@!#X. -M$"!VYB\<_I]A`(*`8``$P6$4?N"G`'R_8$#F`@``BKQ!`(H\``2`1@@``^%7 -M`/)\8($$`"``">)G`@(`(`R`1@@'_@"`(`@`(``$`$``"0`H``'B5P4!`""@ -M!@`@`?X?8`"*`0`0@"8(_($-$/S_#4`@O2(H``A"8/R!#0@,@"8(!WX`@``" -M`$````<0````4""@YB<<_I]A%'[@IP!\'V!`Y@(``(`\0`"`'``$@$`(``'A -M5R:`#S@&``%0$(`@"`"$($`@@`\X`(``4`0^#A"@=^8O2/Z?88`EYR\``"!C -M`'S_8J#_`@``?!]BJ.8"``0`"`@`@"L(`('@5P!\'V.,P@(`@@(`(-#^'V`@ -M21@H0OX_8(```"``*!$H``%L"@"GZ6>!)@`@!``("`"`*P@`@>!7@20`(`)^ -M((`(``@(`*JJ4@`"H`$$@`D(#(!)"@`!#!"@"``@`*;)807^'V#\@4T0`)KF -M80@`)PH#?FM`_(&M"`3^'V``*"I@`)I&8/S_86`@K@PH`*J*8"#Q#R@"_A]@ -M`)ZG80"BR&$`'>=G@1(`(`P`APH`",<*_/\-0`""(%"@V`TH`*9)8`@`)PH` -MH^AG@@L`(``$"0@#>N!7`?Z_8H(&`"`*_A]@_(%-$`P`!P@-!``(('K@9P(" -M`"`@`@`@````4`S^'V#\@4T0`?X?8*#K_R?]@4T0"7K@5P'I_R<.>N!7@?O_ -M)Z#I_R<`FN9A``@'"``:X$$$_A]@H.;_)_R!31`$?@A`(/X_8""#(B@!_E]@ -M!``("`"`*P@`@>!7@MC_)X#7_R>@]^8O`+(,8"!@YB=(_I]A!#X.$*`EYB\8 -M_I]A``"@80":!F"@<1@H_/\M0/R!+0@`@^!G`0(`(""L!2@`F@9@`7K@5P+[ -M_R<@7N8G&/Z?800^#A`@)>8O*/Z?82`$`"``(`A2('$8*`">!V````!BH(80 -M*`C^'X"@\O\O`)X'8````%#\_RU`H%$-*/O_34#[A0T(``'@9P$<`"#\@0T( -M(*<-*`""(%```>!G@1D`(````%`@_`PH`?X_8/R%#0@``>!G`O?_)_V%[0D` -M?-]A0.8"`!3^YZ<`G!Q`!`"@"01^!T#^A4T(`'(`0"!B(B@$_C]@_H4M""!B -M&"@`G@=@`)_G9P```&*""``@`"`(4OZ%+0@``^A7!NG_)P"@!D`'?B"`#``' -M"``"($`$_@!`(,$:*`C^($``'`=@!/X_8*!7(B@!_E]@H/C_)P%^"$(`?%]@ -M$/<"`````0C^A2T(``(`0````1#&_A]@H/$7*`">)V"`8/0O@.#_)P`@"&"@ -M->8G*/Z?800^#A"@]N4O'/Z?8:`+`"``FJ91R/X?8"#K%RBQ_C]@@#T8*`!\ -M'V"HY@(`(/X_8*!((B@!_E]@``"@82!<$"@"_A]@`'P_8)27`@``@``(`7X` -M0`"``!`@>`TH_($-"`""(%"@:P$H!`(`$`+^'V#\_RU`(",-*/O_34#[A0T( -M``'@9P$2`"#\@0T(H'@-*`""(%```>!G@0\`(`+^'V"@S0PH`?X_8/R%#0@$ -M?@!0"'K@5XWV_R<#?(`!&-(```!\AD&&-``````&..C2Z.CHZ`/H`P```,G^ -M'V"@TA!G`>O_)P#H_R<`F@9@H!+F)QS^GV$$/@X0H-GE+R3^GV$``,!A -M`"`(4ORA#1`4?N"G`/P<0$#F`@`$_C]@("4B*`'^7V``'`=@H"$8*`'^/V`` -M`.!A`'P_8!3W`@``@``(`'R_87S"`@`!?@!``(``$`2!!@@!?@!`!($&$`%^ -M!U```#^``!````B!!@@``@!H"($&$`;^'V`@NA$H_/\M0`R!!@C\@2T(`('@ -M5PY\/V`0)P``SL(1*`;^'V``@08(!($F"`"!X%<%`@`@!*$&$*`G$"@(@08( -M"*$&$""3_R\`'`=@`)X'8*#UY2=G`'R_8<##`@"!?P`H`WXG -M@`":`$(*!0@(`7K@5XP'`"`@%P`H`!P'8/B!#0C\@2T(((``*``<1V`!>N!7 -M`0(`(`%^!T``#L`9`WKG5XOW_R<`'`=@(-[E)RC^GV'ZA0T(``'@9X(&`"#[ -MA0T(``'@9_]_!T`A^_\G`0[`&03_1D`"_@=```(A0"#:%R@&_E]@^X4M"*`# -M`"`$`T@0!/]&0`+^!T```B%`(-87*`;^7V`$!2@(`GX'@``:0$#^B0T('`.! -M$!X!@1`!_A]@"@%($"`!`"@`'`=@@.[_)P)^`(``?#]@P,,"```"0$``"!\( -M"JT"`!P)80@`!N"G'@D!"`!R`$``$``8%'K@5Q1^`%`)$$`8,(D`"`P$05`` -M`>%7"H`/.#"%@!``$`$8"GX`@#2!`!````!0.($`$`!\'V#8Y0(`-/\@0*!) -M'R``@D!@!#X.$(""Y2\``:!AH0$`(`""P&$`'>=G`0,`(`!3`"@``@`@```` -M4`J!0!`!_@9```Z@&0/ZYE<*IN4G`_X&@`!\($#`PP(`"H4`"`%ZX%<,^O\G -M`!WG9P+Y_R<$>N!7*^7_+PN:!F``^/\G``!@8*`"`"````!0`()A4`"081@! -M?@!``!``&`"#X5<*_?\G((`/.``&@1``"($(``G@5XH"`"``?)]@P,,"`"P' -M`A`H`T(0``"!$`"`#S@`!!\(P,("``"`#S@$/@X0H&?E+QS^GV&@YQ(H^/\- -M0`!\OV'`PP(`^/\-0"`R'R@T_R9``7K@5X$!`""`C^\O`7K@5P("`"#X@0T( -M-($&$/R!#0@X@080-/\&0""=Y2<<_I]A``@?"/#"`@``@`\X!#X.$"!EY2\H -M_I]AT/X_0@``H&$`"!\("JT"`*`M`"C^@8T0H`8`(``N=7"B,` -M(`-^!X``?/]AP,,"```>0$`*!0$(!'K@5PX9`"``O@]@H!T`(!G^*$``F^9G -M`14`(`)^!X``'B!`'(D`"/]_`$``$>`?(A(`(!R!@!`"_A]@"@%!$`"%!P@` -M?']@U#X```%^`$``@4<0(`P`(!Z)``@"?@>``!X`0@";YF<<"0@(@08`(``! -MX&<"!``@E/X?0"`T%R@!_BA`+/T'$(H^```@/@`H*)U'$!P)"`C_?R!``)`` -M&!P#B!```>!G`@,`(!X)"`@`?']@BCX````<)V#^_TU``,;_+R"D_R\`'`=@ -M@.'_)P-\@`&$UP```'R&0>$U``````8XOLRTW@(````!^N97`MW_)P"^#V#: -M_C]``'4<*`#;_R?^B0T("GX`@"!HY2!7`@(`(!:(#0@("2@( -M`('@5P$!`"`@%P`@````4`)^`8``!N!!'(DG"`"#X&<2A,T)H@D`()3^'T`@ -M#A!$``@"@4("`-ZX%<%!:@)@@T`(`@)"`@&"2@(``(`0``0 -M`!@`"#\("JT"`""<_R_^_TU`H`@`(`"`!E``!1!G`@$`((!+$B@`A08(`7X` -M0"`@Y2<`@480!#X.$(#PY"\`?%]@\,$"```%`0@`>N!7C`$`(/]_($``C@`8 -M``-!$``!X&>"&.4GH(?R+X#^'T"`KO4O@!;E)P0^#A`@[N0O-/Z?8:!K$BCX -M_PU``'S?8=CE`@#X_PU``!PG8"#$'BCP_TU`\($-"``(/P@*K0(`"GX`B``0 -M`!@@*``<1V`@#0`@`((@4`/^`(``?+]@P,,"```*@$`*!4(( -M`'KA5PP(`"`$>N%7"@<`(`+^`(``"F!`'(D!"``:`%`<@8$0`!'@'P%]X5!"@`@``B"4`2` -M!@H`@B!0H`(`(``@2&`(`&$(`?X@0``$@6``AD%@`)W@5P7]_R<(B"8(`)[H -M00"<(%`(@H80``HG0`""AQ``@B!0"`("$"`!`"`$A`80`"`(4H!\Y2^@V^0G -M`"`(8`P`(`@`?H`0`/P@8`#^__\@@`\X#`(`$`0^#A`@I>0O``!@8`""@&`@ -M!``@`'X!$*#Y_R\`A@%@```!"`%^`$````$0``8"$`B`80@`A^%G@@```@````4`0^#A"`GN0OH&OE+P``H&$```!A`'Q_8("G`@`P@`$(``'@ -M9P(!`"`P_`$0``0"``#ZYE&\_\G!/XD@`"&0$$W$D40-@A%$#"``0@)_F2!`(`%0$``!1`T_@%```)@ -M0:#8_R\`E@5@$``!"!`6`1`\``40`?X$0``.(!D@]?\G`(DB"*!/Y2\`$`1@ -M`*KD)P0^#A`@B.0O+/Z?80``(&(```!0`H3("?B!#1`,?N>G`/(<8@!\OV&, -MIP(``/+F00"B"&#X_RU`H,[_+_S_34"`0^4O^($M"`2`1P@(A``0"(@G"/R! -M30@`A"!`"(*'$`2@)@`$H@<0`(0@4`"@!D(@0.4O``*($``=YV<"`0`@@)_V -M+X```"``5_,O(*KD)RS^GV$$/@X0H'7D+S#^GV$D_C^"``#`80""H&$```!0 -MH`$`(/:!C1"@F@XH]O\-0````%`@9`LH^/\M0"`$`"#VB2T(````4"`"`3@` -M@B!0]HD-"`"`!T#V@8T0`!`@&/B!#0@`@>!7!BD`(````%"@CPLH_/]-0/R! -M#0@@\`LH@/X_8``!X&>!\_\G_($-"/7_+4"@7!\H]/]-0/2%[0D1_A]@($\6 -M*`">)V#UA2T(`_K@5X(!`""@3!8H$OX?8(#Q_R?\@0T((`('.`":)F````!B -M$?X?8*!(%B@`("A@`)_G9P$$`"``(>AG]HD-"`'L_R<``>!G@00`(""4[B\` -M("A@@`8`(`"^#V``?%]@K-<"`"`W&R@G_BA`@/__)P```%"@,@LH`"`H8`"> -MYU$```!0($0+*/C_+4#UA0T(`7K@5X(#`""@SPLH_($-"(#^/V`,`$`(H+W[ -M+Q$"01#UA0T(``'@9X+<_R>@S@LH_($-"``!X&>!VO\G`GX`@`!\0``DL0(` -M``7A9X$!`"``?>%7``0"``75_R<`O@]@`'Q?8*S7`@"@)!LH2OXH0(#__R<1 -M_A]@H"P6*%/^*$"@<>0G,/Z?800^#A"@,.0O%/Z?80`(/PA"!0`@`'P_8)S,`@`` -M@0`(`7X`0`"!`!`*>N!7!00`(`!\'V`````$`,7[+P`"`"````!0`'P_8)S, -M`@``@0`0!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC('Z.4Q`:#A`4'`X0&!X. -M$!P@#A```.!A`((`8@`$P6$`FJ91`'KG5XP&`""`#P`H`7K@5X("`"``?#]@ -MG,P"``2!``@!?@!`!($`$`">!V"`^QTH`?ZF00`;YU>)^?\G`'P_8)S,`@`$ -M@0`(``'H5XT"`"``?!]@````!("O^R\!_A]@``$`(````%`$@0`0$`"N"10` -MS@D8`.X)'``."@2`[0L@@`\X(!!N"P0^#A``-@X0`#AN8Q1^CE,`?!]@#``@ -M"(#/Y"\`?#]@`!$P`/R##10`?$!@```!``-^(&#\P0T(````"`!\`&`````! -M`'KA5P("`"``^N!7`@$`(`!ZX%"```@4(`&"@`!X&>"```@2(`&"@`#Z%<`(!\0 -MR.4"``4#`"!`@`8(``'@9X(!`"``L`8H5(`F"$"`!A```^A7!@(`(````%!` -M@`80(`$`(%R`!A!`@`8(``'@9X$0`"``J@8H0(`F"``"(%!$@`8(`('@5XX- -M`"`@IP8H`"`(4D"`!A`"_A]@V($-$-RA#1!$@`8([*$-$/2!#1"B!0<(Z*$- -M$/"!#1!#A`<(Y*$-$/R!#1!<@`8(X*$-$`%^`$!<@`80^($-$"!_`BC8_PU` -M6(`&"``@'Q"8L@(``7X`0%B`!A`@!N0G2/Z?800^#A"@QN,O````4`!\OV$4 -MLP(`Z($&$.R!!A#P@080]($&$/B!!A"@DP8H_($&$*"2!B@,@`80H)$&*!"` -M!A`4@`80B/\&0`""(%`@<>4O(/Y?8*C_!D``@B!0(&_E+R#^7V#(_P9``((@ -M4"!MY2\@_E]@`?X?8*")!B@D@`80+(`&$`'^'V"@X>,G*(!&$`0^#A"@M^,O -M0/Z?80!\OV$4LP(`)(`F"```P&$!^N!7]($&"`()`"``AF%0)(8&$"`$`"`` -MAD%@`!P`0`)^(8``FB!`B)T`$*B=`!#(G0`0`7Y!0`AZX5>%^_\G_($&$/B! -M!A`(G`80(`$`(`2."0`@ -M^($&"`"`9@CL@48(`("!0`)^`8``&B!`J($`"*B'`!````)0^($&$`%^`4`' -M?@!@(&D&*.R!!A`0@`80^($&"`-^`(@@`0`@!(`&$`2`!@@``>=7C@<`(``( -M@E`#?F=0``A"8"`#`"``"`)@`(`!0`)^(8``FB!`J(<`$`%^04`(>N%7A?S_ -M)_B!!A`$A@80[(D&$(!!7C@D`(/R!!@@$@"8( -M\(%F"`"`@$`"_@&``!I`0,@!`0C(`P$0```"4/R!!A`!_@%`!WX`8*!3!BCP -M@080%(`&$/R!!@@#?@"((`$`(`B`!A`(@`8(`(!F"``'X%>&"@`@,(`&"``( -M@E`%?@!``('A5_R)!A".```@A(D&$/R!!@@@`P`@``A"8`"``4`"?B&``)H@ -M0,B'`!`!?D%`"'KA5X7\_R?\@080"(8&$/")!A``A@%@@"8`*`"`)@@``D!` -M*(0&"``!X&<8A`80@00`(`!`!B@L@"8(``(`4`!]X%?)7#@T`("B$!@@``>!G@@L`(`""(%#8@PT0`(!F"-R= -M#1`$@`8(X(<-$.2!#1#HB0T0[(4-$/2##1#P@PT0^(,-$/R##1`PA@80H!," -M*-C_#4`<@`8(`7X`0*"6_R\<@`80@"X&*"`!`""$@080A($&"``!X&2!#1`(@`8(])T-$.B!#1`8@`8(\)T-$.R!#1#XG0T0((`&"/R= -M#1`!?@!`((`&$"`!`BC8_PU`A)T&$""+XR=`_I]A!#X.$(!*XR\`?+]A%+," -M`'B!)@@``B!0@($&"``"X*<`\AQ@(*KD+V3^/V!\@28(H'#C)P"``$`$/@X0 -M($3C+R#^GV$!_A]@H$,**/S_+4#\@0T(``'@9P":IE$!$0`@`_X?8/C_+4"@ -MC0HH]/]-0`!\/V"XQ0(``($`"``!X&<"`P`@`+X/8`!\7V"XUP(`H"8:**+^ -M/V"`__\G](&M"?]_`$``F^9G`($`$`$'`"````!0!(`&$`B`!A#X@0T(`'W@ -M5P`"```.`P`@`+X/8`!\7V"XUP(`H!T:**S^/V"`__\G`("&$`":!F`@;>,G -M(/Z?800^#A"@*>,O```@8````%``_H`0!(``$*"R"2@,@``(`'P_8+C%`@`` -M@0`(`7X`0`"!`!"@U0PH`?X?8(!/XR<``!\(N,0"``9ZX%<&@`\X````(`0^ -M#A"@(>,O````4```/PBXQ`(`#((_4"!=_B\!_E]@@`(`(`@`H`D`@B!0H.__ -M+P@"`!``F@9@``'@9P%&XR<`_/\G!#X.$(`OXR\`?+]B`.4"```!P&'T_M]" -MH@,`(%W^GYH`O@]@`'Q?8,C-`@"@`1HHCW\J0(#__R<`?D<0`'R_813E`@`` -MB`8(``'@9P">YU$")@`@@,K_+P`!(&*!/``@#(!("@!\'V(8Y0(``"0($``$ -M"0@)>N!7`GW@5PX````"?!]@`0```,(W`"```$<0#GK@5P(3`"``?#]@%+," -M`#R!``@"GD@0`7X`0#R!`!``B`@(``'@9PP`B1`"`P`@`+X/8`!\7V#(S0(` -MH.T9**Y_*D"`__\G`'W@5P`"```,`P`@`+X/8`!\7V#(S0(`(.D9**]_*D"` -M__\G`(@&"``B'Q`,Y0(```'@9P`B'Q`0Y0(``1``(`"^#V``?%]@R,T"`*#B -M&2BR?RI`@/__)QH("0@=?@!`H/CT+P`08!H,`$D0`"(?$!#E`@``B`@(`"(? -M$`SE`@``@>E7``!("@P&`"``@"E0`)``&"`%`"``@H80`(0`4`"`AA`@`P`@ -M`!``&`!\'V(8Y0(`(`$`(```2`H`B`8(``'@9P$)`"``!`D(#GK@5P$0`""` -MG_\O``'@9X$1`"``?%]@$.4"````(0@```$0"(``$``(0`@`B"8(`(7@5P`` -M2`J)\O\G``*`$`">AA``!`D(#GK@5P!\/V(,Y0(``4,`(!P$:0H,^@E@_/ZI -M88(^`"`,'P`@`!X`(`"^#V``?%]@ -MR,T"`"#`&2CF?RI`@/__)P">)V(@!>,G`*((8!P$*0B@QA0H,OX?8$CZYE<" -M`0`@H!8`(`"`"`@`?#]@H)@"``"```@`?+]A%+,"``%^`$``@``0'(4&"`%Z -MX%<"!@`@`(4&"``!X&>!!``@(`0)"`%ZX%<"`P`@H+$,*"!^"4```>!GH@$` -M(`"`"`@`"P`@`(`("`!\7V#\Y`(````A"`"#X&<"JDI@PC``(`"`*@@```$0 -MH/,#*"#_!D```>!G`0,`(`"^#V``?%]@R,T"`*"F&2A-?BI`@/__)P"J2F`@ -M*@`@`(`("(`W_B\`*0`@`'Q?8`3E`@```"$(`(/@9X$"`"``?%]@".4"```` -M(0@@"``@!(``$````1``?!]@-+("`(#E`R@``>!G`0,`(`"^#V``?%]@R,T" -M`""9&2AM?BI`@/__)P"`"`@`?%]@".4"`````1````@(()(,*``L`$"`^N97 -M`OWF5U````""&``@`(`(""!6[R\`IBE@@!8`(!P$*0B@F10H,?X?8.3ZYE<" -M_>97]````(("`"```!\('.4"```!X&<"`@`X@,__)P"^#V``?%]@R,T"`*"( -M&2BG?BI`@/__)P1ZX%`^O\G,OX?8"".%"BS?BI``'P_ -M8/SD`@``@``(``'@9X$)`"``@"H(!(``"``!X&<`JDI@`0,`(`"^#V``?%]@ -MR,T"`*!\&2BV?BI`@/__)P"`"`@$@``0```!$"!G_R\`G@@0`?X?8""Y_R<` -M`$<0`(`("`"``!``?!]@-+("`("^`R@``>!G@<[_)P"^#V``?%]@R,T"`"!R -M&2B^?BI`@/__)P0^#A"@F^(O````4""2]"___]]B@+_X+P!\'V*TK`(`(`1H -M"A\$2`H9!"@*````4!D`2!`@#/@O`?X?8"`?^2\```!0`'P_8"4"```@<10H -M@OX?8`!\WV$@L0(`(`4G"#;ZX%>*)0`@`'S_8>SC`@``G@!`!`1@"`"'X6>! -M(@`@(P5'"``%X6<"$0`@(@4'"`%^`$`B`4<0!OX!D"$!1Q`__P%@``Y`&",! -M1Q`!_@!```X@&*`+`"`@`4<0(`4'"``HRF(`'@!`!`0@""!A%"B'_A]@(`4' -M""$%)P@`'@!``(!*"`0$``@`$&$8H"@`*`":1F`@!0<(`7X`0``.(!@@`4<0 -M(P4'"/]_`$``#D`8(P%'$``%X6`$!6"``(H$SW+P"` -M"A```(!B`(0+"``!X&<"`P`@`"WJ5PT"`"``@`H(!'X`0``!ZE>-YO\G(P5' -M"``%X6!G`08`("#5]R\"_A]@(-3W+P/^'V`B!0<((`4G"`"``%`@%P`H``Y`&"`I -M`"@`!`%@``$`("#/]R\"_A]@@$;W+Z!.]"\!_A]@@'+B)P0^#A"`0^(O``"@ -M80`$P6$`"%\(6+`"`*!S`"@`A@%B`'S_84WD`@``FD<0(*SV+P":!F`">N=7 -M`GWG5P,```"A0@`H`0X'&`1ZYU<"`@`@H$``*`+^'V"@/P`H`_X?8`'^'V`` -M?+]A3.0"``"`1A``?!]@)+`"`"!!`R@`("A@`/Y&$*`(]B\`A`<(@%GB)P`` -M`%``?#]@(+$"`""!0!`B@4`0(X%`$`/^'V`@@`\X(8%`$`0^#A``*.(O`'R_ -M82"Q`@`@A28(`(0`&`!\`$#LXP(``?K@9SH$``C"`0`@#WX`8/!^`&`$?@"0 -M`'S?84SD`@``!"<(`(/@9X%)XB<``>!G@DCB)P!\/V"G`@``(!(4*(;^'V"@ -M4`,H!/\&0"!%XB<`?D<0!#X.$"`:XB\D_I]A``#`80":IE'\FPT0_/\-0/C_ -M+4"@<>\O]/]-0``!X&<"!``@^($M"`W^'V`,@$`0!/X?8`Z`@!#T@0T(H`(` -M(`$<0!``?#]@)P$``"!5&2@`O@]@`'P_8$[D`@``A``(``'@9P(/`""`D/HO -M`GK@5X$%`"``C_HO`WK@5P$$`"``-.PO`7K@5X$"`"``F_PO`'K@5_2!+0B, -M!``@@```(/2!+0@`?%]@_/<"`````0@!?@!````!$*`#`"`#_A]@`'Q?8/3W -M`@````$(`7X`0````1`!_A]@H`0`(`*`0!``FD`0`'P_8/CW`@``@``(`7X` -M0`"``!#T@0T(`GY`$(7^'V`@[1,HH_X_0/B!#0C\@2T((,/P+PQ^`$"@,>(G -M)/Z?800^#A`@`^(O-/Z?80``(&(`(`A2H!?T+_^A31``#D`:`'S_88CC`@`` -M@`<(#`#`"2`9[B\`'`=@```?"%#=`@`"^NA7&'Z@08(%`"``?#]B,*T"``&$ -M2`@`H@A@`)HF8"`F%"@"?D%``80("`)^`$`@`P`@``Y@&@```%``FB9@("(4 -M*`+^7V`"_G]B`"7I9P!\/V+HXP(``0H`(`!\GV*$K0(``OX?8``H*F``FDE` -M($0=*/__;4#_A0T(`"8`0``.0!H`*`I@`!HI0*`@'2C__TU`_X4-"``D`$`` -M#J`9`(`(""`&`"`!_C]@`'P_8)2M`@````!0`)I)0*`Z'2C__VU`_X4-"`"" -M(%``)@!```Z@&0"`"`@`\NTO'``'""(:AQ`L($`0`(`'""!>`"@!_C]@$00' -M")]^`&`!>N!7@@(`(`!\/V`(E@(``(``"`%^`$``@``0H`+B)S3^GV$$/@X0 -M@,?A+P""H&&@:O0O``3!80!\7V"TK`(``)OF9P`<)T""`@`@0/X?8"``01`% -M_```<+`"```"`"`)_A]@(`!!$`7\``!LL`(`'P0A"/O_(&"@V@;C`@"@`@`@ -M(`%)$"`%"0@!?B!``(X`&"`#21`V>N!7"AT`(``@`$`$!"`(`(/@9P$;`"`! -M?@=```[`&0;^`)``#^`?`'P_8D[D`@"B`0`@(0%)$``2#2@``@`@`(0'"`%Z -MX%<"`@`@@`8-*"`%"0@`(`!`!`0@""`(`"`__P!@#WZ@80`@`4`$!"`(H)43 -M*(?^'V`@!0D((04I"``@`$`$!``(`)I&0``@04!6"&$(H%S_+P":1F#__PI` -M``Z@&@"KZF<`A&@(`0<`("`%"0@!?B!``(?A9R`#21"B!``@`(Y`&``$`1@` -M(`!``?K@9SH$``@"\?\G\'X`8*#P_R<$?J"1`(?A9P'@_R>@,?@O`?X?8``* -M'PA@L`(`H*L'*"`F2A"@&O(O%((& -M$/B!#0C\@2T((#_P+PQ^`$"@K>$G)/Z?800^#A"`?N$O``#@80P`H`D`@B!B -M'(!F"F#^'V"@81,H`)XG8*`VXB\`',=1````8@`D25(2I$80(!8!*`">!V`` -MH^AG0_Z?@H$$`"``?!]@3,("``R`!A`PA`D(0'K@5Q3^WV$"?-]A9````(`` -M`"`,I`80`"'R+P"CZ&>A$``@`"`(8``MXB\`?+]A-,,"`!C_!D"@;@(H`!PG -M8``!X&@!@_OX_F@(#`"``O@]@ -M`'Q?8,#-`@`@%!@H`?XH0(#__R<(>N!7`GW@5P0````!`P`@`+X/8`!\7V#` -MS0(`(`\8*`7^*$"`__\G`'S?822R`@"610<(``'@9X)-X2!G`?[_88('`""X_A]@H!$3*`G^/V"`!0`@(!`3*+W^'V!`_A]@"(`& -M%`S`!@B_?P!@#(`&%#!%)P@@#!,HO?X?8#`?1Q0P10<(``'@9P("`"`(P"8( -M0/K@9P']_R<`]_\GN/X?8*`&$R@'_C]@````4#`!1Q0`P`8(#'K@9P$#`"`` -MO@]@`'Q?8,#-`@"@]Q6'T<4M_X?8"#_$B@`("A@@'($*`AZ -MZ%>B`@`@O_X?8"#\$B@N_BA`(`(`((S^'V`@^A(H,_XH0(3^'V``@`84`##A -M)P!ZX5<,`P`@``(`4`"!X5<+`@%0"@``4""`#S@```(0((`/.``$`A`$/@X0 -MH`3A+P'^/V````!B````4*`V_"\`!$%0``&@88(#`"``?%]@(,X"``!\/V"= -M`@``(.(7*`"^#V"`__\G#(#&"0""(%``'`=@(*7B+X#^7V`H?@=`'``'$`Q^ -MX$&@'.TO`!P'8!P`)PJ@P>@O````4!T`2!``(`A@,/XH0*`K$R@@_E]@'``G -M"!&$``@@?@!H$8!`$!P`)P@2A``(\W\`8!*`0!`'_C]@(@*'$`;^'V!4`$<0 -M50)'$`C^((@@EQ8H5@)'$`=^`&!2`(<0H/X?8#D`1Q``G@=@(`/M+P""(%`` -M``!0.`!'$`@`AQ``F@9@H&[_+P""(%``"^$G!#X.$"#;X"\8_I]A``"@80!\ -M/V`[`0``H,\2*)7^'T``X_LO`_X&@`3^/V``?+]@P,,"```*@$``A0(("@-" -M$/]_`$``@4(0!04""``!X&>!"P`@!@D""``(/P@*K0(`H%O[+_[_34`%!2(( -M`(!`4`+^!H``"B!`"`D""!R%@!`>@8`0'(D`"``!X&<"`P`@`OX?8`H!0A`` -MA0((`7X`0*`"`"``@4(0(`$`(`'^'V````!0"@%"$*`#X2<8_I]A!#X.$*#` -MX"\8_I]A`'P_8!#/`@`(@0`(^($-$`R!``C\@0T0`'P_8"T"```@M1(HBOX? -M8/C_#4`@BO\O`((@4/__'V`@00\H'/X_8*`)^B\$_A]@`'P?8```@`"`4>XO -M(/?@)QC^GV$$/@X0H+C@+QS^GV&*_M]!``"@815^!T"@JA(H`7XG0`"X^R\# -M_@:``_X_8`!\GV#`PP(```@`0`H#0!`&"2`("`D`"``"`$``$``8``@_"`JM -M`@`@./LO_O]-0`+^)H``B"!`'(&`$/Z)#0@>@8`0(.?@)QS^GV$$/@X0H*G@ -M+RC^GV$`?#]@$,\"``"!``CP@0T0!($`"/2!#1``!!\(-,$"`!A^X*<`_+Q! -M[N4"`*`A#BCX_PU`H";Y+__^WT$!>N!7@0$`((`D^2\``>!G`AT`(``$'PCP -MK`(`!80F"`"!X%<"_A]@`GP?8`,```"`Z?DOBOX?8*".$B@'?B=`!X2&"0:$ -M)@@(?H:!`)@@:`B$A@D*A`8($'Z&@0"8(&@)A(8)&'Z&@0"8(&@+A(8)`(/@ -M9PA^AH$`&`!H#(2&"1!^AH$`&`!H#82&"1A^AH$`&`!H`0'@9P$!`"#X@PT0 -M_($-$`^$A@D.A`8("'Z&@0`8`&@*?@"`\($-$/C_#4#P_RU`H$T:*```0&"* -M_A]@H'L2*!1^)T``?#]@NCX``"!0_R_X_PU`(-'Y+P/^'V``?!]@``"````9 -M[B^@O>`G*/Z?800^#A"`>N`O`'P?8-CE`@``_0TH@/+X+R`!#R@<_C]@H`$` -M(`'^'V``?/LO````4``<^R\``>!G@?W_)Z#\#BA"_C]@@+/J+P"?X"<$/@X0 -M((/@+SC^GV$``"!B`()@8@`D25+TI0T0%'[@IP!\_V%`Y@(``)Z\00B`!@@` -M\AQB_($-$!"`)@C\_PU`(,0<*`'^7V#\@2T(`!X(``"!X%>.```@$(`&"``" -MP%$`'>=GH@$`(`"B"&``#0LH``4`(`!'"R@`G>E7#J;)80B`!@@0@"8(`(`` -M4``!YU<-`,!A`!WG9P(!`"`@#P`@`?X?8/BE31#YHTT0^IU-$`"B"&`@P!(H -M]/\M0`B`!@@,@&8*!WY`@OC_#4`@]``^(&M"````%`` -M)DE`H,(&*`'^GV"@!0HH````4`C^!T`0@"8(`"``0*"K'"@`'$=@`*((8""P -M$B@`'"=@H(W@)SC^GV$$/@X0`$W@+P`!X&<"`P`@`+X/8`!\7V!DS@(`(#H7 -M*.[^/V"`__\G`'Q?8#3#`@`0`2$(`(/@9X$!`"`4`2$((`$`(`2``!`0`0$0 -M%`$!$`""(%`@<.`G!`(`$`0^#A"`0>`O`'Q?8#3#`@`0`2$(``/@5P$#`"`` -MO@]@`'Q?8&3.`@`@+1`G!`8`$`0$(`B`^N!G'`!`"((%`""`_B!H!`)`$!`$`0@'?@!@```` -M0`!\($`TPP(`!(D`"!!^`$`$@8`01@"!$`"`#S@$/@X0`"_@+P`!X&<`?!]@ -MC,0"`($!`""@0@$H__\_8(```""`9`$H``'@9P%7X"<`O@]@`'Q?8*S7`@`@ -M&!(O`WK@5P(#`"``O@]@`'Q? -M8*S7`@`@#!``-$````%!\``T0((`/.(``#1`$/@X0@`_@+W@`X`D``*!A`*`? -M"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_ -M=(`F"`"#X&<"G^=G`1H`(`"`)P@`_>!73D161`(8`"!\@"8(`!S'40"#YE=T -MG`8000,`(!"!G@0$`("#D`BA8_@9`@```(%BA7@@(` -M(``!`"``!>%G`0$`("`!`"``',=1!_[?80`=YV<"`P`@`?KH9P`""1"!%P`@ -M`*`@<*`6`"`(@@80`)_G9X$4`"`,`,T)='P'$"I```"$(`<0C"('$(@D!Q!X -M&@<0$(`F"`"#X&>!!``@?`('$("`(`B``@<0$(`F"("`(`A\G``0$(`F""`" -M`""`G``0$)P&$'P"%P`@C(`G"(2`1P@"^N!G(0(`(``<(6```^%7 -M@@(`(``!`"``@^!G`0$`("`!`"``@B!0!_X_8`"#X&<"#P`@B(`G"`"<`!", -M@"<(`?K@9X$!`""$@"<(``(G<`@""A``FJ91$!H*$!0:"A`H`"T(=)H'$`'^ -M($`H`@T0``"@'W"`!P@``>!G@0$`(*!Y`BA8_@=`@```(%B:!Q"0F@<0H'T! -M*`">!V```>!G`4<`((`AX2\`1@`@``"@'P!%`"``HBA2$"(*$`"F:5(H`"T( -M`"1)4@'^($`H`@T0`)ZG80``H!\`H!\(``$`2``!`$@``0!(``$`2``!`$@` -M`0!(``$`2``!`$@$?B!@`("@'____W\,`"H(`(/@9P$$`"`,(@H0"``J"`"? -MYV<`G,!I(1L`(!0`"@H@`0`@`)Y'8`":1F",`&$(A``A"`+ZX6"`@`@``$`(``)XFPA"@MK_ -M)Q`>"A```*`?@`H`("!(`BA8_@E``*`?"``!`$@``0!(``$`2``!`$@``0!( -M``$`2``!`$@``0!(!'X@8`"`H!____]_*``M"`'^($`H`@T0``"@'Z!%`2@` -MI@E@`)IF8@"GZ6@:]\G -M````4``AZ&"K>`O -M@```(```H!]P@`8(``'@9X$!`"`@_@$H6/X&0(```"!8G`80`*`?"``!`$@` -M`0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_``"@'P`N -MWR<$/@X0@/_>+P``H&$$`@`0"`0`$````%`,@`80$(`&$`"@'P@``0!(``$` -M2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?UP`+0@`@^!G -M`/P&$$%-15,!`P`@&(!`"!B:`!`4&@$0&(0&$"`"`"`4@@807!H-$!2:!A`8 -MF@808``M"`'^($!@`@T0``"@'Z`8WR<```!0!#X.$(#PWB\``,!A`(+@80"@ -M'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____ -M?P@`)P@`@^!G`0(`(/__($`(`@<0(!4`(`":IE$`G^=G`1,`(`P`K0ET_`80 -M]D$``'B!A`!_B!`*`(-$```H!__^^=70JH!*%C^!D"@(`$H`)H& -M8*`!`""0@*8)#?Z_80``H!\@^=XG`)H&8````%!<``T0((`/.&``#1`$/@X0 -M`,W>+P``P&$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$ -M?B!@`("@'____W\,`*<)`)OF9P">YU$!#P`@?(`F"`"#YE=!`P`@#!X'$`P" -M!Q"`@$8(@(0`$'R`)@A\`@$0$``G"/__($`0`@<0*``M"'2>!A`!_B!`*`(- -M$```H!]P@`8(``'@9X$!`"`@J@$H6/X&0(```"!8G@80D)X&$""N`"@`F@9@ -M``'@9X)2X"\``@`@"``G"`'^($`(`@<0``"@'Z#;WB<```!0!#X.$("LWB\` -M`*!A-`(`$%`$`!!4!@`0`((@4`@"`!`,"``0%`H`$`'^`E``"`!`$(`&$!]^ -M0V`?_@-@2(`&$!"`#0@XA`80&(`&$!R`!A`$@@80`_X?8#R`!A!`@@801((& -M$&#\!A"X10``9)H&$'""!A!<@@80=((&$'B"!A!\@@80@((&$`&$'X!,@`80 -M*((&$"R"!A`P@@80`'P_8)9$``"@'N`O`)H&8`"@'P@``0!(``$`2``!`$@` -M`0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?Q0`+0@`@^!G`/P&$$12 -M2%0!`P`@F(!`")B:`!"4&@$0F(0&$"`"`""4@@80%!H-$)2:!A"8F@80&``M -M"`'^($`8`@T0*``M"`'^($`H`@T0``"@'Q2`#0@``>!G@0(`(""!`"@`F@9@ -M``'@9X(EX"\`"``@`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@` -M`0!(!'X@8`"`H!____]_*``M"/__($`H`@T0``"@'Z"FWB<```!0((`/.`P` -M#0@`"()0#`@-$!`(#1`<"`T0(`@-$"#^'V`D``T0`'P?8+#:`@``?D`0`7Y@ -M0"`"`"`!_E]@`()!$`'^84`!?D%``'WA5P`!```&!``@`((@4``$`6`!>N!G -M`OO_)P`$`!@!_B!`H/W_)P".(!@`?#]@L-L"`"`"`"````!0`(@`$`3^($`! -M?@!`('K@5X7]_R<4"`T0&`@-$""`#S@H"`T0!#X.$(!IWB\``.!A`(*@80`$ -MP6$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@ -M'____W\X@"<(`(/F5PT6`"``@^97@@0`(`+^((``_"``L-L"``"#YU<"`@`@ -M3(`G""``30@``B%P(`(-$$B`)P@``@<0$``M"`"#YU=(F@<0@@P`(#B`)P@D -M`$T(`(7@5PV%YE<."@`@`GXA@`#\(`"PVP(`$`(-$```H!\H``T(``'@9P'N -MWR\`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@ -M'____W\@`0`@`)JF41C^OV$``*`?H''>)P":!F`$/@X0@$?>+P``X&$`@L!A -M(/K@5P`$H6'&.@`@#_Z_80"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@` -M`0!(``$`2`1^(&``@*`?____?SB`1P@`A`80/(`G"`"#X&>!`P`@.)P'$$B< -M!Q`!G#^`3(('$```H!^@+@`@`)JF42"`AP@`B>=7`'P_8+#;`@`A"0`@`GYA -M@`""00``A>=7`@,`(`""@4$`"`803(!'""``;0@`A$%P(`0-$"2`9P@D!@(0 -M((!'"""$`1`!G%^`3(0'$*`4`"``FJ91`)JF40""@4%,@$<('`!M"/^%GW`@ -M`$T(`(AA8``(06`@!`T0`9Q?@$R$!Q``CT$8'`8-$"$"`"``?@80`GQ!`+#: -M`@"`"@`@"/Y!B``/01@!`@`@`GQ!`+#:`@"@!P`@"'Y!0!#^08@`#T$8`0(` -M(`)\00"PV@(`(`0`(!!^04`8_D&(``]!&$$"`"`@_E]@`GQ!`+#:`@`8?D%` -M)`0-$!``30@`A>=7`@0`("0`30@@>N%7`0(`(`)^08```B$`(`$`(!`"#1`0 -M&@T02)H'$`/^/V`\@@<0*``M"#B)P":!F`$/@X0``;> -M+P``P&$`FJ91`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!( -M!'X@8`"`H!____]_*``M"$0`1PC__R!`*`(-$``%X6<\`"<(@0,`(`'ZX%<" -M_>!7`@````$<`"``@B!0H`0`($0"!Q``@^!G@1D`($``1P@`!>%G`((@4`$" -M`"!``@<0`_X_8"`6`"`\`@<0.`!'"#P"!Q`"?F&``'R?8+#;`@``B"$``(/@ -M9P$#`"`D@$`((!P!$"2<`!`D!`<0(`\`("`"!Q``B(%``!P"$$P`)P@<`&T( -M`(8@:!``;0@@'`<0`(?A9QP"#1`B`@`@)!P'$!`<#1`@"``@)`0-$"0`+0@` -M`^%7!@8`($B`@0@`">%7)`0-$`8$`"`X@"$(``/B5P$"`"!,@"$((`!-"`"$ -M(&@@`@T0$!P-$```H!\0``T(#``M"``#X%!`0`@```- -M"``!X&!`0`@3(`G"``"(7`@`@T0$``M"`"#YU<"-@`@)``M"`+^((``FB``(#0` -M(!`"#1````T(``'@9X*_W2<`)``@`)J!04R`)P@<`&T(_X,_<"``C0@`@F%@ -M``GB9QP"A`0`@``H&$`"(@&`@"`T0`(\A&`(@R&'""@`@`J!@``C^(8@` -MCR`8`0(`(``@R&$"H"``(`<`(`C^8$`0_B&(`(\@&`$"`"``(,AA`J`@`*`# -M`"`0_F!`&/XAB`"/(!B!$0`@`J`@```@R&$8_F!`)`8-$!``+0@`@^=7@AT` -M(`+^(8``FB````GB9Q`"#1`!&P`@`7XA0"@"#1```*`?`*`?"``!`$@``0!( -M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_*``M""``30C_ -M_R!`*`(-$``/(1@!!``@(`L`(`*<(``@_C]@)`(-$!`*#1```*`?@`W?+P": -MW2<(?B&(`(\@&($!`"`"G"``(`4`(`C^($`0?B&(`(\@&($!`"`"G"``(`(` -M(!#^($`8?B&(`IP@`!C^($`"_B"``)I@`"0`+0A(@($(`(G@5P4"`"!,@"$( -M$`8-$``"(7`@`@T0``"@'Q``#0@,`"T(``/@5P&+W2>`R?\G!#X.$(!=W2\, -M`*T)`!S'40"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^ -M(&``@*`?____?SR`)@@`@^!G@@P`(!R`)@@8@@80*``M"`"#X&<"?#]@`0`` -M`$()`"`8@@80((!F"`"'YE=G@5S=)R`"!S@`F@9@`%O=)P0^#A"` -M+=TO`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"` -MH!____]_+`"M"0``H!^@4=TG`)H&8`0^#A"`)-TO``"@80"@'P@``0!(``$` -M2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?P"`1@@`!>%G -M`1``(!B`)@@`@^!G@@X`("!ZX5!!``@$(!&"`"%YE>" -M!``@`(!@"`"'YE<`!$%0@@``(`"$`!`8A`80``"@'R`HW2<```!0%(`F"!0" -M`1`0@&8($(8`$!B`)@@`@$`(`(7F5X(!`"`8@@$0$(!&"`"$`!`@^/\G``1! -M4`0^#A"@]-PO`((@4`A^CE,`FJ91+!H-$#`:#1`T&@T01!H-$`!\7V`PW`(` -M(`(`(``$`6``&@`0!'X`0`'^($`@^N!7A?W_)S@$#1!`!`T0@'X!0#P`#1`` -M?!]@L-P"``!\/V#XI@(``'Q?8']&``!(`(T(3`"M"%``S0@0&@X0%!H.$`!\ -M?V!-251!(#;^+P`,XV!4&@T06!H-$`A^CD.`#-TG!#X.$"#RW"\X_I]A`'W@ -M5TU)5$&A`0`@`)[G42`9W2IG(@(*.`*>!V``H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$` -M2``!`$@$?B!@`("@'____W\8@"D(``/G5X$*`"```*`?`*`?"``!`$@``0!( -M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]__(%M"@"GZ6>" -MX/\G1``M"`"#X&!7`0,`(`"^#V``?%]@P,T"`"!O$R@/?BI`@/__)P`GX%<`G@80 -M@@4`(`"?YV<"`P`@`+X/8`!\7V#`S0(`H&D3*!=^*D"`__\G`/P':````!`` -M@`80`*()$"`9!B@```!0H$?=+P`'Q"DF`(` -M`)X'8`":)F"@(_$O__]-0``!X&!V"@>``H -M`)HF8"`?_"\!_A]@`'Q?8G##`@``10D(``'@9P$#`"``O@]@`'Q?8,3.`@`@ -M.A,H*GXJ0(#__R! -M!``@`'Q?8'#.`@`#?H"`''YA0`C^'V`#_C]@`(AA0"#Q#2@`"()0H"?B+P8$ -M!P@`"`@(,!])$``GX%97`@````']YU<+`````7P?8(3.`@`!!$%0P<,- -M*`C^/V"`BPDH`@D)"```GQ!VL`(`!'X`@```GQ!XL`(`H!86*`C^'X``F^9G -M`7P?8(#.`@`!!$%00;P-*`+^/V"`;>0O`$4)"`%ZX% -MIV&@,MPG`)H&8`0^#A``-@X0`#AN8QA^CE,0&@X0%!P.$```H&$`_`!@_S\` -M```0P!D`_`9@_S\````0H!D0_@:``'P_8"(`(`B`S=PO`/P&0`"````0?@"` -M`'P_8"(`(`B`RMPO`'P'0`!````0?@"``'P_8"(`(`B`Q]PO`'P'0`#````0 -M?@"``'P_8"(`(`B`Q-PO````4`!\/V`B`"`(@,+<+Q``K@D4`,X)!(#M"R"` -M#S@8$&X+`'Q?8)C,`@```2$(`(``0""`#S@``0$0```?")C+`@``@`\X!#X. -M$"#EVR\4_I]AH`(`*/S_#4#\@0T("GX`B"`DW"<4_I]A!#X.$"#HVR\@_I]A -M(*_<+P``X&$@]_\O``"@80``P&$!_A]@(-<'*/S_+4#\@0T(_X$?4``<`$`` -M@`<0H*O<+P":!F`@&=PG(/Z?800^#A``-@X0`#AN8Q!^CE,`"]XO`7K@5X(` -M`""`"]XO!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC%'Z.4Q`:#A``?+]A`!$P -M``"!Z"^`G=PO`(`F"`#\(&@```@(`/P@8/_W__\`@@80@)S<+P```%`#_C]@ -M`/'_+Q``K@D$@.T+((`/.!00;@L$/@X0H-3;+R1^X$``FJ91``1!4`@(``D` -MGN=1`'KD5P`(@E`L`@`@'`"@"`(((`@``^17"P,`(`"^#V``?%]@<-@"`*"M -M$BB<_C]@@/__)UB`P@@@!``@`(9A4`"&(4``@B)`=(@@"`"(($``D(`8`?XA -M0`".8!@`C>%7A?O_)P`1Y&-G`@,`(`"^ -M#V``?%]@<-@"`*"5$BBU_C]@@/__)P"695%<@,()=(A""0`09&``"")A#OKF -M5XH(`"`.>N%7B@H`(`/^)H``@H-!``1&$`""(T(!GD@0!)P($``'Y5<`(`A2 -M+`D`(``D25(!_E]B``;'00`&)5`@#0`@`)!`&0"^#V``?%]@<-@"`*"&$BB] -M_C]@@/__)P"^#V``?%]@<-@"`*"#$BB^_C]@@/__)P`'Y5>"`0`@`?Y?8J`$ -M`"`!_A]B`?X?8@*4B!``E"%0`)!@&``4(E``D(`8`?XG0`".X!D!>NE7`@8` -M(`*&B!`!A"@(0/X@:`&"2!``!B)0`)&`&`)\(4`!`````HY`&`*>YU$"$&1@ -M`@@B80%ZZ%<"!0`@`?XE0`".8!D`C>57!@,`(`+^)8``@B)`7(#`"0"6)4`` -M@B)`=(A`"0'^)D``">)G`(Z@&0+;_R<#_B:``()C0/F%(0C`_B!H^8-!$`EZ -MX5<@!(`0"P,`(`"^#V``?%]@<-@"`"!G$BC\_C]@@/__)PL$(`@`DB!``'KA -M5R("@!`)`P`@`+X/8`!\7V!PV`(`H&$2*/_^/V"`__\G`W[AIP/^/$``FH!` -M`'Q@0"`"``#"A2$(`(/@9\&)01`A`@`@``ZB&``$(D#!@T$0`(Z@&`L$``@: -M>N!7@IO;)P"$`D"@FMLGP8%!$`0^#A"@:-LO)'Z@0`!\OV$``@``"`A`"`"& -M85``!>%G"P0`"2$%`"`<`"`)`@@@"``#X5<*`P`@`+X/8`!\7V!PV`(`($X2 -M*%/^/V"`__\G6(!$"09ZY5<-`0`@`!7E9P(#`"``O@]@`'Q?8'#8`@"@2!(H -M5?X_8(#__R<`CN-0H`$`(``,PU`!_B-``([@&`"5XU<&$@`@`(XC0`"")$!T -MB$`(`OXC@`"")$!<@(`(``0D0*`"`"``D``9`H2`$``$05`!_B%``(Y@&`!Z -MX5>,]O\G#OKA5XH&`"`#_B&``(*"00`,1A``@B)`!(@`$``;X5N!7#/[`00P!`"`0_A]@`0%!$``$'PAPY`(``7K@ -M5P)]X%<"````@0,`(`!\7V!PV`(``'P_8%T!```@'1(H`+X/8(#__R<9`$<0 -MH,L1*``!GV`\``*)>[R\" -MF@9@((@&"!.$)@@`@>!7`@(`(````%`<`(<0(`0`("*(!@@!?@!0`('@5T$! -M`"`BB`8("(@&"!P`AQ`(B`8(H$S;)P(`AQ`$/@X0`"';+P``P&$<`"`("_X? -M8`R`0!``?%]@ULP"``$%`0@-@$`0#GX`0`$!01``#@`8<7K@5PS^H$$,`0`@ -M$/X?8`$!01``!!\(<.0"``%ZX%<"?>!7`@````$#`"``O@]@`'Q?8'#8`@`@ -M_Q$HR?X_0(#__R<9@$80H*T1*`":!F``!!\(U*P"`(!ZX&!GV`\``($"`"`%A`8(``0_"+RQ`@```@!H!8!&$"`(!P@3!"<(`('@ -M5P("`"````!0'("&$"`$`"`B"`<(`7X`4`"!X%=!`0`@(@@'"`@(!P@<@(80 -M"`@'"*`LVR<"@(80!#X.$"#_VB\D_I]A``'@9X(#`"``?%]@F,T"``!\/V`? -M`0``(.@1*`"^#V"`__\G!``@"/2##1```"`(\(,-$`""(%#\@PT0"`@@"*"` -M%2CP_PU```"@8?B!#1``?%]@!-D"`/#_#4`@SQ0H^/\M0`":!F`@,-LG)/Z? -M80`^#A``\=HOC_[?01"`C1`!?@=`H.0,*%=^)T"`N=LO``"@8:`%"B@"_A]@ -M`'P?8";2```"_C]@$/Y-0*`]#"@`AF%0`'P?8+2L`@"@+^TO`((@4""UVR\` -MF@9@D/X?0"#;#"AM?B=`@,7<)P0^#A"`X=HO`'R_8;2L`@`"A"8(`X!&$`'^ -M(&@"@D80`)H&8"`G[2\`@B!0`H0&"/Q_`&`@!]LG`H!&$`!\7V!8L0(`7`$A -M"``#X%?&`@`@`OX?8&`!(0@``^!7`?X?8`4``%````!```0`0""`#S@,"0`( -M```_"*CC`@``B"`(`(/@9P*`#S@``>!G`8`/.``$/PCWK`(``OK@5X(!`"`` -M"#\(U+`"```"`"`!^N!7`H`/.``(/PC6L`(```/@5P!\7V!4Y`(`C`$`(``( -M'PA6Y`(```$`(``('PA8Y`(`((`/.```@1`$/@X0H,3:+P""(%``!!\(]ZP" -M```!X&<`?+]A6+$"`,$!`"`(@X80(HL&"`B!AA``"!\(BP8((,K_+P`0`!B`Y-HG!#X.$*"ZVB\` -M@B!0`!S'40!\OV%8L0(`G)V&$)Z=AA"@_P9`H&?<+R#^7V"9G480(-_:)YB= -M1A`$/@X0(+':+P""(%``?+]A6+$"`"S_!D`@8MPO"/Y?8````%`J@480(-C: -M)S2!AA``?)]@M*P"`!\$`@@`?%]@6+$"`!P%(0C\?V!@`OK@5P"&`6"B!0`@ -M'P9"$#@+(0@T"Z$(`(/B5\D#`"`#_@%H`((_4`"#XE<*`@`@(`$`(`'^`6@` -MA@!H'P!"$"4%(0@`@^!G`0(`("0%(0@`@`!H'P!"$``.`!@#?@!@`7K@5T$$ -M`"!""0$(`WK@5T0)(0A!@`\X!`.!$$()`0@``^!7#((`8""`#S@$`8$0!#X. -M$`"3VB^`O>PO`7K@5P(!`""``0`H@+W:)X`X`"B`O-HG!#X.$("3VB\`?+]A -M6+$"`':))@@``%\(8+("``""`$``&@!`:`6`$`'^`$``$"`8!_K@5P`(&&$``$'PCWK`(``7K@5P("`"!*B08(3H&& -M$"`#`"!,B08(`GK@5X("`"!&B08(3H&&$$B)!@@@`@`@4(&&$`"^#V"@PA$H -MV?X_0`B+!@@ZBR8(``(`0`B!AA``#"`8/(4&"``!X&+#0`@5HD&"`%^ -M`$`@#``@5H&&$%")!@@`!>!7"0H`(`'^`$``#"`8H`@`(`B!AA!2B08(!HE& -M"``!X5>J`P`@`?X`0&2%!@@`!%\(JJL"```!X5>,`0`@__\`0``,(!@(@880 -M6(D&"`%^`$!8@880(HL&"`"!X%?+`P`@"(&&$%2)1@@`A>!7"0P!&$D!`"`( -MA880`((`8":))@@``^!7`8C:)R"G`"@F@880@(;:)P`(7PARP@(``'P_8%BQ -M`@",%@`@!(D`"`IZX%<*%0`@@(E@"#+ZX5<*$@`@`?KA -M5P1^`8`A`0`@`0R`&""+@`@!_@%`@(&`$`5^`5``>N!7"1!@&`R&85"*AX`0 -M!7X!0``0P!B&@8`0GHN@"):)0`B0BP`(`(7B5PD(`$`,``)0``P`&`1^0X`` -M!>!7"@P!&`3^08``!>!7"PP!&""!@!`(?@!`!'Y`D``,`1@>A8`0`7Y`0"`= -M`""$A8`0A(L`"*`;`"`>@8`0``H?"%KD`@",>N!7BP$`(*5ZX%?,!P`@$?Y? -M8(!ZX%>+`0`@A'K@5TP%`"`2_E]@*'K@5PL!`"`L>N!7#`$`(&AZX%<"`0`@ -M(`$`(!;^7V`5_E]@C(6`$(B)``@``'\(7+("```&`$``$*`8AH&`$)2)8`B2 -MB8`(``?B5R"+``@L`@`@BH6`$(Z+8`@@`P`@`(`!0`2)8`@&^N%7B@$`((Z+ -M8`@`!@!0``P`&`3^8H``!^!7"HP!&`1^08``!>!7"PP!&""!@!`(?@!`!'Y` -MD``,`1@>A8`0@HM`"``%X%N!7`@4`(`'^ -M'V"@"PPH9?X_8,B?1A`&B28(H'L,*`+^'V`!_A]@R/X_8(`'#"@6""<(`(W@ -M'X,!`"`>"$<(``WA'P0$`"`IA08(/)]&$`%^`$``#B`8!/K@5RF!1A"*5_\O -M@!``(`'^'V`\@480*9]&$`!\`6#_?___`!!`&$2!AA``!!\(]ZP"``#\(&#_ -M?___`GK@5T*#AA`B`P`@`)!@&%J%!@@``>!G`@$`($2#AA``AD%@-(L&"`"$ -M8%`JA48(``:`0``$`4``&B!`+(L`""R'@!````)0-(&&$`%^`4`#?@!@*H%& -M$`0(1PB8A08(DH6&$```?PA`$**%@!`!?@!`"'K@5XO\_R>8 -MB480F87&"`""(%`"?@.``!H`0*`'@!"B!8`0(`4`(````%``&F!`H(M!"`"% -MXE<)!*%@HHM!"``%XE<)!(%@`?X@0`1^`$`(^N!7B_K_)YZ)AA"N=7^H&-$*$#`"`3_@9```@?"'+"`@``&@!``'K@5PD0`!@, -M``!0_(&-$`'^!T"@S`LHF/X_0("AVB\!>N=7``"@88()`""@[`@H`?X?8`!\ -M'V`;A0```OX_8/[_34"@)`LH`(9A4/Z)#0AL>N!7`@$`(&O^'V#Z@8T0`'P? -M8!R%```"_C]@^O]-0"`?"R@`AF%0(.,(*`+^'V``?!]@)M(```+^/V#\_TU` -M(!L+*`"&85#\B0T(`'Q?8%BQ`@````!`!'P@`,S.`@``?!]@M*P"`%'ZX%<: -M!&`(#`4`(,`%(0@`@^!G@@,`(!P%(0@"^N!7`@(`(`'^/V!:`T$0(`(`("#^ -M(6@`@B!06@-!$-__(6`:`D`0H`'L+P""(%`@A]HO`)H&8)#^'T`@K0LH3_XG -M0"#SV2N!7;/Z?8"(1`"``D*`8 -M$_X&0``0(!AL^N)7`'R_8;2L`@`"A`8(`7R?8&L````#?@!H`H!&$`""`$`$ -M?```S,X"``!\7V!8L0(`47K@5QJ$9@@,!0`@P`4!"``!X&>"`P`@'`4!"`)Z -MX%<"`@`@`?X?8%H!01`@`@`@(/X!:````%!:`4$0W_\!8"`&`"`:@$80``@? -M"'+"`@``&@!``'K@5PD0(!@`?+]AM*P"``*$!@@,@B!0`7X`:`*`1A`#@D80 -M%HI&$!>(1A``F@9@H.#K+P""(%`"A`8(_'\`8*#`V2<"@$80`#X.$*"IV2\H -M?N"G`(HB8@``P&(`@J!B``2!8@"&86(`_!Q`G,P"`"0```@`"$)B&'[@IP#R -MW&$`?+]A5*H"`*!9VB\`\N9!````8@B`!P@!?B!`%(@'"`"!X%>%`@`@(%C: -M+P`@"&``O@]@(,\0*&;^/V``G`8`$("G"`1^P(``+`M@`*HJ8``H2F``IFE@ -M`"2)8"!3`"@`C*)``)P&``"%`@`@($#:+P":!F``O@]@(+<0*&#^/V````<($``G"`1^0(``(`A@ -M($4`*`"$($````<(`GX@@`P`!P@``B!``)X`$`@`!P@!?@!`"``'$```!P@! -M?B!`%`@'"``"!Q`!?@!0``(`8```!Q`@,]HO`)H&8`!'VR<$/@X0H'+9+RC^ -MX:<``(!B`()@8@`$06(`_!Q`G,P"`"0```@`AB%B&'[@IP#RO&$`?/]A5*H" -M`"`HVB\`\L=!````8@@`!P@!?B!`%`@'"`"!X%>%`@`@H";:+P`@"&``O@]@ -MH)T0*+?^/V``F@<`$`!'"`1^8(``*`I@`*8I8``&04`@,``H`*)H8`":!P`` -MFH=!`GX@@`P`!P@``B!``*0`$`@`!P@!?@!`"``'$`":!P`!?B!`%`@'"``" -M!A`!?@!0``(`8`":IT$`@`80H!?:+P`@"&``>=DG`#X.$"!4V2\H_N&G``0! -M8@``0&(`_!Q`G,P"`"0```@`@B!B&'[@IP#\_$%4J@(`H`W:+P"&P6$``*!A -M"(`'"!2()P@!?@!```/@5P4#`"`@#-HO`)H&8`"^#V`@@Q`H;?X_8!2()P@$ -M@`<(`7Y`4`'^`%``!&!B!/YI@!"`1P@`)`E@`*(H8``&04"@$P`H`!QG8`R` -M!P@"_BF```(@0`"@`!`(@`<(!*8'$`%^`$`(@`<0H/_9+P":!F"`%MLG*'[@ -MIP!\WV"`"$87@,A@(0 -M"(0"$`2"`A`@@`\X`(`"$```7P@8S0(`"(``$`!\86@``@``!(!`"``&07@` -M`$%X#(0`$""`#S@`A@`0!#X.$"`EV2\H_N&G``#@80`$H6$`_!Q`G,P"``0` -M``B@Q@(H``+`:0B`!A``'B=X`(``>`R`!A`$G@80H$;9)P"YU$`'@%``(``8`1^((`0@`8((/#_+P`"`$`!_N=!%(@&"``? -MYU(%`4 -M"`<(``(`0``>(%``@@80"``'"`"!X%>.```@`/X&$"`PV2<@_I]A``!`"`P` -M``@`?$%@_S\```!\`&#_/P`````!4""`#S@`@``0!#X.$"#NV"\8?N"G`/R\ -M052J`@`@M]DO`(+`802`)@@`G$!`%(@F"`'^(%``A"!@!/Y`@!"`)@@`A&!` -M`(0@``/ZX(<#`@`@#(`A"!+ZX(`$``#N`9!/YG@!"`1@@`I@E@`"0I8``&04"@L_\O`OY_ -M8`R`!@@"_B>```(@0`"<`!`!?@A"`?X'0`"AZ%<-^/\GH)_9+P`H"F"`M]HG -M!#X.$*#2V"\8?N"G`(+@80#\W$%4J@(`H)C9+P`$H6$$`"<(`)Y`0!0()P@! -M_B!0`(0@8`+^0(`,`"<(`(0@`""6V2\`@@80@/+8)P0^#A"@T-@O&'[@IP`` -MP&$`@D!B`/R\052J`@"@CMDO``0A8@```&($@.8)`!P'8"#2_R\`@B!0`7K@ -M5P"`2!`"`@`@#(`&"`+^)X```@`````)$""*V2\`(`A@@.G8)P`^#A`@NM@O -M&'[@IP#\O$%4J@(`H(/9+P""P&$4B"8(`?Y`4`2`)@@`A"!@`OY`@`R`)@@` -MA$!`H('9+P`<`1"`D]HG!#X.$*"YV"\H?N"G`/P<0)S,`@`D`"`*`(*@81C^ -MZ*<`_!Q"5*H"`*!XV2\`!.%A``#`800`"`@"?B"`#``("``"````F^9G`(`' -M$`$#`"`$``@(!'X@@!``"`@``@!`(+/_+P":)F``H@A@H)/_+P'^/V"@<=DO -M`!P'8`#0V"<$/@X0`*S8+Z!LV2\```!B``!`8AA^Z*<`?!]@5*H"``!RH$$` -MHBA2`'*`00!^!A`$H@80"*(&$````0H!@`#@`8````0`!\`$#LO0(`!`D@"`C^`I````!``'P` -M0.R_`@`$"0`(``(@>`""87@`D`$8W`>"$`""8&`(>N%7A?3_)^R)#0@@!@`@ -M!_X_8```0$`/?@"0``0`:``08!@`@@!``(!-0-P)`0C__R!``(!A0`"0`1C< -M!X$0`(/@9X+Y_R<`!`<(`(!&$`$$!P@!@$80`@0'"`*`1A`@!0`@`_X_8`'^ -M`&`#?D"`_O\`8`"`#4#<"0`(`(*&00`$`)```$80`?X@0!#ZX%>%^O\GH$?8 -M)T3^GV$@`P`@``B"4`((8```B(!!``9&$`%^8D``CH$8``GA5PR`#S@`_/\G -M!#X.$(`*V"\```!B`(*@82#/V"\`!.%A``#`82#YVR\3_A]@`'R?8"2R`@"0 -M"2((`'Q?8`"(`@``A&!`'?X?8`"$0$``(>AG``!!$($#`"``?%]@P,T"``!\ -M/V!5!P``(.4.*`"^#V"`__\G`J!!$"`#`"````!0`(1&"`"`(4`#A$`0`?ZF -M00%^`$`#>N!7A?S_)Y0%`@@3_C]@`8!!$!W^'V`!_E]@H-H-*`">9V"@O=@O -M`!P'8``;V"<$/@X0`.[7+Z"XV"\``,!A``"@8:#BVR\"_A]@`'R?8"2R`@"0 -M"0((`'P_8`"(`@`%_E]@``*`00`$1A"4!4((``)@0`&$01`"`@```OX_8`'^ -M7V"@S0TH`!QG8*"PV"\`F@9@``S8)P0(0`@$B&`(`(7A5X($`"`""$`(`HA@ -M"`"%X5>"`@`@``@`"`"((`@`@>!7(8`/.`'^'V`@@`\X````4``$0`@`!>%G -M@@D`(`"$0`@`!>%G`@@`(`&$8`@!!$`(``?A5P(&`"``!>%G`00`(``$8$`! -MA($(`(1@0`&$80@`!^)7`@(`(*#[_R?_?T%`((`/.`'^'V`@@`\X````4`0^ -M#A"@R-%G``Q@&($``"```($0``0? -M"'RR`@```@!`((`/.``&`%`$/@X0H*S7+P+^'V``?+]A=.0"``"`1@@`@B!0 -M@/Y_0*`'%"@`"()0!(!&"`/^'V``@B!0@/Y_0*`$%"@`"()0@-#7)_^1/Q@` -M`H`0`@*`$""`#S@$`H`0`'Q_8!``(`"@`@`@``1!4``$(4`$`B```7Y!0`"" -M@10`?>%7``$```:`#S@`_/\G!#X.$("@UR\``,!A`'S_81``(`"@"P`@`)JF -M40":)D``R`<(``(G0`"`@!#___]_____?____W____]_____?____W____]_ -M____?____W____]_____?____W____]_____?____W____]_____?P'^ID$` -M_>97``$```:ZUR<`\_\G!#X.$*"(UR\`"()0``,`(`)^`H``?`!`=.0"`*#E -M_R\(```(`7Z"0"!ZXE>&L-!G`"!(8`+Y_R<`O@]@`'Q?8'37`@`@9@XH%/XG0(#__R<` -M`-\)\.8"```#`"`"_B:``(1`0"#8_R\```$0"`#'"0'^ID$`'>=G`08`("+Z -MYE<&!0`@#``'"``!X&<`($A@`OG_)P"^#V``?%]@=-<"`*!:#B@A_B=`@/__ -M)X!_`2B@`P`@``#`80+^)H``A$!`H,S_+P```1`(`,<)`?ZF02+ZYE<&"0`@ -M`!WG9P`@2&"!!``@#``'"``!X&<"^?\G`+X/8`!\7V!TUP(`($\.*"_^)T"` -M__\G`+X/8`!\7V!TUP(`($P.*"[^)T"`__\G(OKF5P&+UR<`O@]@`'Q?8'37 -M`@`@2`XH-OXG0(#__R<$/@X0@%W7+P``OPGTY@(``)OF9__^_T$"`P`@`+X/ -M8`!\7V!TUP(`H$$.*`?^)T"`__\G#(`&"``!X&<"`P`@`+X/8`!\7V!TUP(` -M(#T.*`C^)T"`__\G`'S?873D`@````<0`OX?8`""(%"`_E]`H`$-*`7^?V`, -M@`8(`((@4`!_`%`$``<0`_X?8(#^7T"@_0PH!?Y_8`B`!@@``>!G@G+7)P"^ -M#V``?%]@=-<"`*`P#B@5_B=`@/__)P0^#A"`0]N!7BP,`(`!\7V!TUP(``'P_8.L!```@)PXH -M`+X/8(#__R<#!$<(``7A9P%\7T"``````GX`@`!\(`!TY`(`('H)*`1^!T`` -MA`8(`7X`0"!?UR<`@$80``A`"`"$@!`""$`(`H2`$`0(``@@@`\X!("`$`0^ -M#A``/]L`@"`1/LO@`,`(``B"4`0 -M@`80`*0(0`$$``@"?@!``"0`0``00!H`I>E7#!L`(`*D"``&>N!7@0D`((D1 -M`"`%>N!7C?G_)P-\@`%D2`$``'R&01E2``````8X[`+N!>X(````(@E`(/7_ -M)Q2`!A``(@E`H//_)QB`!A``(@E`(/+_)R"`!A``(@E`H/#_)QR`!A``(@E` -M(.__)R2`!A``(@E`H.W_)RB`!A`#^N=7"NS_)P`B"4"@6/$O`)XG8`%^`$"@ -MZ?\G``[@&25^`%`->N!7C>?_)P-\@`'T2`$``'R&03U2``````8X!,K*\,KJ -MRLK*RLK*RNT``*``X2\`(@E`@.'_)P/ZYU<+G@=@*WSQ+PN"(%`@@$8(``7A -M9P$0`"`#?@B0`!!@&`0$`0C^?P!@`(`A4`"!X5<`D"`8"P8`(`$$`0@#?@!0 -M`!``&`"!X%>)`P`@``(!0`4$(`@'?@A@`8`?@``"@&(@`0`@+*A&$"R<1A`` -M*>IG@0(`(`!\/V#@EP(``(``"`%^`$``@``0!`0!"`%^`&`@'M!G`0,`(`"^#V``?%]@ -MP,T"`"#,#2@Y_BA`@/__)Y5%!P@``>!G`0,`(`"^#V``?%]@P,T"`*#'#2@Z -M_BA`@/__)P'ZYV'`P4`(+3^'V"@Q@@H3OXH -M0(#1\2^`_A]`"(`&%"!Q\2\```!0(%(%*$+^/V`6^N>'`P0`(+3^'V"@P`@H -M6/XH0`#*[R\(H@84@#[O+R!-!2@<_C]@0/KG9X$&`""]_A]@H+L(*`">)V!` -M_A]@"(`&%`S`!@B_?P!@#(`&%#!%)PB@MP@HO?X?8`'^'V`P`4<4"/KG9P$) -M`"````!0_X%-$`C^'V((H`84(*'S+___#4```>!A`0(`(*!FYB\,@`<(((OS -M+P">!V"610<(``'@9P+Z_R?_A0T(``'@9X+X_R>@\=8G*/Z?800^#A``Q-8O -M``"`8@""8&(`!*%A`(;A80`(0F(`BB)B"/X!0"!\UR\`#L`9````8B"FVB\` -M'`=@`'R?8"2R`@"0"2((`'Q?8`"(`@``A&!`(?X?8`"$0$```$$0````4`*` -M@1`$GD$0!:1!$`:H01`'ID$0"/XA0"`#`"``!$%0`(0&"`%^04``@$`0`?X@ -M0`'^ID$`A>=7B?S_)Y0%`@@`'"=@`8!!$`"$`0@!_E]@((D,*`"B:&`@;-YU$'_A]BB_X?8"U^*4``@`@H$/\&0"";]R\`("A@``$@8H$"`"`-^NA7 -M`@P`("`$!P@!>N!7@@H`((S^'V`@>@@H"7XI0(O^'V"@>`@H`"`H8"`$!P@` -M`>!G`1T`(#B%!@H`(>AG@@<`((S^'V`@=`@H$GXI0*`%$"CX_PU``(XH&"#T -M#RCX_PU```4`(`"^#V``?%]@F,T"`*!D#2@'?BE`@/__)SB?1A",_A]@(&P( -M*!M^*4",_A]@H&H(*!]^*4"`I=@O```@8*!H""B+_A]@@*/8+P=ZX%<"?>!7 -M!@```('C_R!X?\G"'K@5X("`"````<(^($-$`0`!PB@ -M`0`@_($-$"#R#RCX_PU`^/\-0"`"#R@`@B!0````8HO^'V`@7`@H`"`H8`)Z -MZ%<-?`A2`@```(#9_R?__Q]B.)]&$(O^'V`@U_\G2'XI0`1^`(``?"!`:,T" -M``R```@`?$!H``P```2```@`!``4`(`/.`1^`(``?`!`:,T"``@```@````( -M((`/.`"``!``?!]@!``@``"`#S@`?!]@!``@``"`#S@$?@"``'P`0&C-`@`$ -M```(`$``"`%^`&`@@`\X`(``$`1^`(``?$!`:,T"``0`(0@`P``(`GK@9P*` -M#S@,``$(`'P`:``"````@``4`(`/.`0^#A"@3-8O'/Z?82`6UR\``,!A``"@ -M80```'P@0&C-`@`,@``(`'Q`:``0```$@``(``0`%(!>UB<$/@X0@"[6 -M+P#AXB\%!"`(!`0`"`C^((```@!H`'P_8`#$`@``?>!7)$(``*)6UB<`@8`0 -M`/V`$"-"``"`5-8G!#X.$(`FUB\`V>(OY`0@".4$``@``E\0Y>8"``]^`&`` -M`%\0Y.8"``!/UB<$/@X0@"C6+P``H&$`@N!AH-+B+P`$P6$``>!G@@,`(`!\ -M7V`\UP(``'P_8$$*``"@"PTH`+X/8(#__R<"&B```!H`0`$$8`@`?%]@!,0" -M``"*`1C0`X$0T@=!$`"#X&!G`8(@4`$``%``@H<0H$/6)P``1Q`$/@X0 -M@!36+R`L^B\``*!AH#[6)PB`!A`$/@X0`!G6+P``P&$`(`A2`'S_812S`@`@ -M`0`@`)JF40'^ID$`A0<(`('F5XH'`"`&_N:G!/\'0`!R`$`@*_XO`!PG8`%Z -MX%>"^O\G`?X?8@!\/V"0!P``H/X'*#+^'V`R_A]@(/T'*`":)F`@,]8G`"`( -M8``!X&<"`P`@`'P?8$SE`@``@`\X`'P?8$[E`@``@`\X`7K@5X']_R<@@`\X -M__\?8``!X&<"`P`@`'P?8"3E`@```P`@`'P?8#CE`@"``0`@`7K@5X']_R?_ -M_Q]@`(`/.``!X&<"`P`@`'P?8%CE`@``@`\X`'P?8%GE`@``@`\X`7K@5X'] -M_R<@@`\X__\?8``!X&<"`P`@`'P?8%#E`@``@`\X`'P?8%3E`@``@`\X`7K@ -M5X']_R<@@`\X__\?8`0^#A"@]=4O*/Z?823^/X(`GN=1`"`(4@!\OV&XQ`(` -M(`(`(``"!``@"(``"``!X&>!]O\G`+X/8`!\ -M7V!TUP(`(,D,*"?^*$"`__\G`+X/8`!\7V!TUP(`(,8,*";^*$"`__\G!(`` -M"``!X&<(`@@0@@0`(`B```@``>!G@>W_)P"^#V``?%]@=-<"`*"_#"@N_BA` -M@/__)P"^#V``?%]@=-<"`*"\#"@M_BA`@/__)P">!V"@"M8G*/Z?800^#A`` -MSM4O``@@"`"#X&<``*!AH@D`(*+^WX$@W/PO````4``!X&!\-4G`+X/8*`+#2@=?B=`@.[5)P"(!@@!?@!`(.W5 -M)P"`AA`2_A]@H+8'*"=^)T``_/\G!#X.$``V#A``.&YC$'Z.4P``(&#__Q]@ -M``<`*`2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,``"!@`'P?8````!"` -M`0`H!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC&'Z.4Q`:#A`4'`X0``"@80"" -MP&$`F@9@`*X`*```!Q``>N!7`0(`(`":!F``?#]@```@"(!^UB\0`*X)%`#. -M"02`[0L@@`\X&!!N"P0^#A``-@X0`#AN8Q!^CE,``"!@`88?&(#Q_R\$@.T+ -M((`/.!`0;@L$/@X0`#8.$``X;F,0?HY3```@8(#^'T"`[/\O!(#M"R"`#S@0 -M$&X+!#X.$``V#A``.&YC$'Z.4P``(&``?!]@````(`#G_R\$@.T+((`/.!`0 -M;@L$/@X0`#8.$``X;F,0?HY3`GY`@`!\`4!0SP(```$`"`#A_R\$@.T+((`/ -M.!`0;@L$/@X0`#8.$``X;F,0?HY3`'P_8`(`(`@`8]8O!(#M"R"`#S@0$&X+ -M!#X.$``V#A``.&YC&'Z.4Q`:#A`4'`X0``#`80!\OV$$`#``@%;6+P"`)@C[ -M_R!@`)P@<`""!A"`5M8O$`"N"10`S@D$@.T+((`/.!@0;@L`?#]@!``P``"` -M(`@`@`!@`(`/.`0^#A``-@X0`#AN8Q1^CE,0&@X0`'R_800`,```2]8O`(`F -M"/O_(&`!_B!H`((&$`!+UB\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC -M%'Z.4Q`:#A``?+]A!``P`(!"UB\`P"8(^O\@8`""!A0`0]8O$`"N"02`[0L@ -M@`\X%!!N"P0^#A``-@X0`#AN8QA^CE,0&@X0%!P.$```P&$`?+]A!``P`(`Y -MUB\`@"8(^_\@8`"<(&@`@@80@#G6+Q``K@D4`,X)!(#M"R"`#S@8$&X+!#X. -M$``V#A``.&YC%'Z.4Q`:#A```*!A`'P?8`$`(`@`-=8O`!H`<`!\/V`!`"`( -M`#36+Q``K@D$@.T+((`/.!00;@L$/@X0`#8.$``X;F,0?HY3`'P?8````"`` -M]/\O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC$'Z.4P5ZX%>&`@`@`GX@@`#\ -M`$!0SP(```$`"`#M_R\$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,4?HY3$!H. -M$`!\OV$8`#```!S6+P"`)@@`_"!@_W___P""!A``'-8O$`"N"02`[0L@@`\X -M%!!N"P0^#A``-@X0`#AN8Q1^CE,0&@X0`'R_81@`,`"`$]8O`(`F"`+^(&@` -M@@80`!36+Q``K@D$@.T+((`/.!00;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\ -MOV$8`#``@`O6+P"`)@@!_B!H`((&$``,UB\0`*X)!(#M"R"`#S@4$&X+!#X. -M$``V#A``.&YC$'Z.4P!\'V`````0@`$`*`2`[0L@@`\X$!!N"P0^#A``-@X0 -M`#AN8Q1^CE,0&@X0``"@80!\'V`!`"`(``/6+P`:`&@`?#]@`0`@"``"UB\0 -M`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC$'Z.4P&&'QB`]/\O!(#M"R"` -M#S@0$&X+!#X.$``V#A``.&YC$'Z.4X#^'T``\/\O!(#M"R"`#S@0$&X+!#X. -M$``V#A``.&YC$'Z.4P!\'V`````@`.O_+P2`[0L@@`\X$!!N"P0^#A``-@X0 -M`#AN8Q!^CE,%>N!7A@(`(`)^((``_`!`4,\"```!``@`Y/\O!(#M"R"`#S@0 -M$&X+!#X.$``V#A``.&YC%'Z.4Q`:#A``?+]A&``P``#AU2\`@"8(`/P@:`"` -M````@@80`.'5+Q``K@D$@.T+((`/.!00;@L`?!]@$``P``!\7V`8`#`````` -M"`!\(&`/SP`````!"``"(&``@A]0``(`:!]^`(@`@`\X`'P?8!``,``````( -M`GX@8`""'U```@!H'WX`B`"`#S@`?!]@$``P``````@$?B!@`((?4``"`&@? -M?@"(`(`/.`0^#A``-@X0`#AN8Q1^CE,0&@X0``"@80!\'V`0`#``````"`%^ -M(&``@A]0``(`:!]^`(@`>N!7@0,`(`!\'V```"`(`,K5+P`:(&``@A]0``(` -M:!]^`(@0`*X)!(#M"R"`#S@4$&X+`'P?8!``,``````(`'P@8`"`````@A]0 -M``(`:!]^`(@`@`\X!#X.$``V#A``.&YC$'Z.4P!\'V#HP@(```4`"`1ZX%>- -M`P`@``4`("#^'V``6_\O``@`(!#^'V"`6?\O@`8`(`"^#V"E_C]``"X,*(`$ -M`"`"?H"!`'R&`>Q9`0````8X<%8``&U6``!P5@``;58``(!6```$@.T+((`/ -M.!`0;@L$/@X0`#8.$``X;F,8?HY3$!H.$/S_#4``^/@O_(%-"`!\/V#HP@(` -M"($`"````5``?>!7`*`/`(4Y`"``?!]@H)@"````0`@`?!]@&/<"``````@` -M!$!``'P?8'SW`@`````(``2@002!``@`@`90`'W@5P`"```%`P`@`'P_8`"0 -M`0``?!]@U.8"```"`!``+``@`'W@5P`!```%`P`@`'P_8``@`P``?!]@U.8" -M```"`!"`)P`@0'K@5P4#`"``?#]@`+`$``!\'V#4Y@(```(`$(`C`"`0>N!7 -M!0,`(`!\/V``0`8``'P?8-3F`@```@`0@!\`(`!ZX%>!`@`@,OX_F`!\'V#4 -MY@(```(`$``<`"``?%]@`$`?``!\'V#4Y@(```0`$`"%``@#>N!7@A$`(`1Z -MX%>-`P`@@`4`("#^'V``1?\O@`@`(!#^'V"`0_\O``<`(`"^#V``?#]@(P$` -M`(#Z"RB`!``@`GZ`@0!\A@&(6P$````&.-96``#35@``UE8``--6``#G5@`` -M`?X?8``+`"`@_A]@`!W_+P`)`"`0_A]@@!O_+X`'`"``O@]@I?X_0`#P"RB` -M!0`@!'K@5PW]_R<"?H"!`'R&`>1;`0````8X[%8``.E6``#L5@``Z58``/Y6 -M``````!0@'8`*`!\/V#HP@(`!)L`$/R!30@(A0`0$`"N"02`[0L@@`\X&!!N -M"P0^#A``-@X0`#AN8Q!^CE,`?!]@Z,("```%``@!>N!7`0,`($#^'V"`"/\O -M`((@4`!\'V#FXP(```)`$`2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,` -M?!]@Z,("```%``@!>N!7`0,`($#^'V"`'/\O`?X_8`!\'V#FXP(```)`$`2` -M[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,`..$O2@0`"`!\/V#HP@(``(%` -M$`1ZX%>!$@`@!'K@5XT#`"``!0`@(/X?8`#T_B\`"``@$/X?8(#R_B^`!@`@ -M`+X/8*7^/T``QPLH@`0`(`)^@($`?(8!)%T!````!C@^5P``.U<``#Y7```[ -M5P``3E<``"#^'V"`ZOXO`'P_8.C"`@``A0`(`7K@5P$#`"!`_A]@`.?^+P"" -M(%``?!]@YN,"```"0!````!0`$@`*`!\/V``D`$``'P?8-CF`@```@`0`'P_ -M8`!`'P``?!]@U.8"```"`!``?#]@`#`J``!\'V#@Y@(```(`$`!\/V``L`0` -M`'P?8-SF`@```@`0!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC''Z.4Q`:#A`4 -M'`X0`'S?8=3F`@````<(`'W@5P!`'P"""P`@`'R_8>C"`@``A08(`WK@5X(Q -M`"#\_PU`@'GX+_R!+0@0@P80`'P?8-#F`@``!``(`'K@5P(!`"````<(@`$` -M(`!\'V#8Y@(`````"`!\OV'HP@(`%($&$(`H`"#\_PU`@'#X+_R!+0@`?+]A -MZ,("`!"!!@@`@`!0#($&$!2!)@@`@>!7"2``(`!\'V#0Y@(```0`"`%ZX%<" -M#@`@```'"!2!!A``A08(!'K@5XT#`"``!0`@(/X?8`"[_B\`"``@$/X?8("Y -M_B^`!@`@`+X/8*7^/T``C@LH@`0`(`)^@($`?(8![%X!````!CBP5P``K5<` -M`+!7``"M5P``P%<``````%"`%0`H@!``(`!\'V#8Y@(`````"!2!!A``A08( -M!'K@5XT#`""`!0`@(/X?8`#)_B^`"``@$/X?8(#'_B\`!P`@`+X/8`!\/V`C -M`0``@'X+*(`$`"`"?H"!`'R&`6A?`0````8XSE<``,M7``#.5P``RU<``-]7 -M```!_A]@``8`*``!`"``@`!0%($&$/R!+0@`?+]AZ,("`!"#!A`0`*X)%`#. -M"02`[0L@@`\X'!!N"P!\/V#0Y@(``(!`$`"`#S@`?#]@$``P``!\'V`8IP(` -M#`$`"`"``!``@`\X!#X.$``V#A``.&YC$'Z.4P!\'V#`:P"``'P_8$,```F` -M\]0O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC%'Z.4Q`:#A```*!A!?KF5X$% -M`""`Y]0O!?Y&@`!\/V`8IP(```)!0`0!(0@,`6$(`,!`"``&07``A``4`.74 -M+Q``K@D$@.T+((`/.!00;@L$/@X0`#8.$``X;F,4?HY3$!H.$```H&$%^N97 -M@04`(`#N=7@@$`(`#\IFD` -M``"`@`,`(`1ZYU>"`@`@`OX&@'W^/V"`4]4O`'R@:0```(`%?B>``/P`0!BG -M`@```0`(`!H`%`1ZYU>"`P`@!7XG@`#\`$`8IP(```$`"`!```@`@>97@OS_ -M)P5ZYUN!7`@<`(``(PF`% -M?J"``'Q_8!BG`@``AJ)``(%B"`#`@0@!?F-0``?B5P$"`"``?*)@____?P#Z -MXE<"^?\G!7Z@@`!\?V`8IP(``(:B0!"!P@@`@6((`(P!%`-ZX%>"`0`@`'SB -M8/___W\`"@`@!'K@5X((`"``?*)@____?P7^8H``BF%0`OYA@`"*84`"_N&( -M!7Z@@`!\?V`8IP(``(:B0`"!8@@`P($($('""``-XE>"^_\G@```(``(XF`` -MCB!0``(!$`#ZX%>"!``@!7Z@@`!\?V`8IP(``(:B0!R!8@@`A&$8`((A0``" -M`1"``P`@!7Z@@`!\?V`8IP(``(:B0!R!8@@`@B%```(!$("=_R\$@.T+((`/ -M.!`0;@L`?)]@$``P``5ZX%>!!P`@!7Y`@`!\'V`8IP(```!A0`R!`0@``$(( -M``!!8`"$'U``!`!H'WX`B`"``!``>N!7`0$`(`R!`0@```(0`(`/.`!\'V`( -M`#``````"`"`#SB@`0`@``1!4`%^(4``CD`8`WKA5XH#`"`"A']0`@8@``'^ -M($``C^`?``9@0"'[_R<`@D$0`(`/.```(&"@`0`@````4`%^`$``#@`8`WK@ -M5PJ`#S@``&!`!(9```%^04``$>$?`(9@0"*`#S@`A($0`/K_)P`(@E``!$%0 -M`'S_8("T`@`@!P`@8(7#"`9^((``CF!`DHDA"`&$OX``B^!G@0(`(``)XF<" -M`0`@E85!$`'^GV"4A4$0`7XA0`".0!@`#>%7"H`/.`#X_R<$/@X0(*'3+S#^ -MGV$`?/]A3-D"`!2!!P@`?#]B:+,"`/B!#1`8A0<(`'S?85SG`@#\@4T0`'P? -M8`#]`@`<'``0`'P'$%[E`@``?+]AU,8"`#S_!D`$``<0%'P'$/3``@`!_A]@ -M`?X_8*!#Z"___TU`_X4-"`!\'V*4F0(``WX`@```"$`#>N!G"``'$"$#`""8 -M_E]"`+X/8-)^*4"@;@HH`/]'0(#__RN%7"_W_)TZ$``A0^N)7.(%&$(Q'`"!@A@`(`/Q`0``" -M`````*!```8$!`@!?L-`#WX`8````$``@`)0$(%#$`&%!`@! -M?N5`!'X`D````$````)0`(;C0`"!0Q#F!`0(!'X`D````$``@`)0$(%#$`=Z -MXU>+\?\G````4/R'K0CXART)^8<-"?J'[0C[A\T(H`,`(``(@E``EF51``9% -M0"`701`!?@!``GZ"0`'^($`3>N!7"B``(.V$0`@/?D%@`'KB5P`$04"+`0`@ -M!GKB5ZP*`"`,A$11"'KB5XL!`"`/>N)7+`@`(`P$1%$0>N)7BP$`(!-ZXE>L -M!0`@#(1#411ZXE>+`0`@'GKB5RP#`"`,!$-1'WKB5XL"`"`D>N)7B0$`(`"$ -M0E$`!D)`(!5!$`%^0D$'>N57@>O_)R5ZY5>!#@`@[89`"`1^09``>N57``1! -M0(L!`"`&>N57K.?_)PR$9%$(>N57BP$`(`]ZY5+`0`@ -M$WKE5ZSB_R<,A&-1%'KE5XL!`"`>>N57+.#_)PP$8U$?>N57B]__)R1ZY5>) -MWO\G(-W_)P"$8E$@AT$((`,`(````%`@AR$(``/A5PN"0&`!?@!``?YA0"5Z -MX%>+_/\G$85&$``"`1@#?@!0$H%&$`"+X"^@7-,G,/Z?800^#A"@*M,O`([C -M4```7PAHLP(``'Q?8@`"``"0!F$)D09!"6`&`0B2!B$)````00`(@E`%_A]@ -M`'S?8%3&`@`4`8,0`'P_8"3G`@``?!]@`/T"`!P"`!``?+]@Q-H"``#_`D`` -M@``0$/\"0`2``!`@_P)`"(``$!3\`!!>Y0(`&'\#0!B``!!0_P)`#(``$$#_ -M`D`<_``0<)@"`"#\`!!TF`(```1_"&6S`@`D_``0D)@"``/ZX5N!7C`,`(&`&`0@```!```K@&`-\`0```0`` -M````0``*@!@`FJ91(`<`(`""(%`"_@=``(`#4$`!1Q``)`%``!H`0`$%``@$ -M?@"0````0`)^`$````)04`%'$`'^ID$"_B!`!_KF5XHM`"``&N%!H83'"0!\ -M'V+EY@(`#WX'8`AZYV<"?`!H\`````(*`!@`$L!!`(H@02"=1!":A"<*#_X( -M8`CZZ&<"?`!H\`````(*`!@`%$!!`)5$$).$)PH/_@A@"/KH9P)\`&CP```` -M`@H`&``$"`H`%F!!`7KH5Q"71!`,#``@YH0'"`]^`&`#^N%7```@0@((`"`` -M!!\(9+,"``!ZX%<,!@`@`OX(0`"``U!`@400`"0!0``:`$`!!0`(#WX`8``` -M`$`"?@!````"4"`#`"!0@400`OX(0"`!`"````10(/X?8#"!1!"AA@<(`?X@ -M0@1^`)``'`!```H@&0"*R$$@`4<0FH8'"`1^`)``%`!```I`&0`!1Q"3A@<( -M!'X`D``6`$`!>NA7$`%'$*P&`"``"F`9YH0'"`1^`)`#^N%7``#@00("`"`` -M!!\(9+,"``!ZX%<)SO\G`OX'0"`!`"````10(/X?8"#1_R,!0`@H`,`(`""(%``)`%```(`0`@'8`@`C`!`&`=` -M$`'^($`.^N!7BO+2)X#[_R>@`@`@`((@4*@&80@`C`!`&`=`$`'^($`.^N!7 -M"N[2)X#\_R<$/@X0H+G2+P``P&`@O?PO`((`8```H&"@M?PO`((`8```0&`@ -MQOPO`((`8```8&"@OOPO`((`8```@&#_^^)7`OWA5_____\"?>%7_____P)] -MXE?_____@@,`(`!\7V#(S0(``'P_8&\$``"@G`DH`+X/8(#__R<`#`-@H)3V -M+P"*(F"`UM(G`'P?8!29`@``@`\X!#X.$""GTB^W_A]@`'P_8$T%````GP0H -M`'P?8'\9````@B!0H"/5+P3^7V``S](G!#X.$""ATB^W_A]@`'P_8%0%```` -MF00H`'P?8%09````@B!0H!W5+PC^7V``R=(G!#X.$*";TB\4_I]A`'P?8"#V -M`@`````(@'K@9P(.`""`PN0O``!@8`!\GV!PPP(`,`4""`".(1@@4^N!7"1``&`P``%`"`8(0(,S2)Q3^GV$$ -M/@X0`(W2+Z!7TR\``,!A``"@8:"!UB\"_A]@`'R?8"2R`@"0"0((`'P_8`"( -M`@`4_E]@``*`00`$1A"4!4((``)@0`&$01`"`@```OX_8`'^7V"@;`@H`!QG -M8*!/TR\`F@9@`*O2)P0^#A``BM(OC?X_0@``X&$`?+]A)+("``!\'V(``"`` -M,$`H"#2!Q@DT@P80('`$*`'^"$`P0"@(-(,&$"!N!"@!_@A`-($F"``#YU?P -M_U^"#@,`(``"!U``)>!7A0D`(#B!!@@@`P`@`7X`0`"<`%``)>!7A08`(#B! -M!@C_?P!`.($&$`'^"$"@9`0H`!PG8#2!)@@@8P0H`?X(0#B!)@B@800H`?X( -M0#2!)@@`@@<0.($&"""8TB<$@`<0!#X.$*!HTB\"_A]@H'\!*&G^WX$`?+]A -MS-4"`#Q^!T`"_C]@A/]&0""W`R@`AF%0/7X'0`+^/V""_T9`H+0#*`"&85"@ -M>`$H`?X?8`!\'V`+@@```OX_8(C_1D"@L`,H`(9A4`!\'V`,@@```OX_8(;_ -M1D"@K0,H`(9A4("#TB<$/@X0@&?2+P``@&(`!!\(<>0"``%ZX%<`@F!B@872 -M)R`@TR\?_A]B``!`8B!*UB\\_A]@`'P_8B2R`@"0B>@)`'R_80"(`@``FL=! -M`)J'00`@1A``*`I@`!PG8*"0!"@\_E]@`)J'092%"`@`($80`0!'$`*:!P`\ -M_C]@`?Y?8*`R""@`IFE@H!73+P`D"6``=](G!#X.$*!+TB\D_I]A````8@"" -MX&$@#],O``2A80``P&'\_PU``((@4*`2"2@!_E]@`(Y&&/S_#4`@X/DO@/X_ -M8/R!30@`(`A@`)XG8"`1\B\!_G]@H`G3+P`(G!#X.$`!$TB\``,!A -M`((@8@`$`6*@+N0O`)[G40`('P@`PP(``?Y?8@!]X%<@0@``(@(`(!5^J8$8 -M_`84$!`````!`"`8_`84,C(```'ZZ%AG -M`@<`("`S^B\#_A]@`'P?8/S#`@`@,?,O#_X_8``!(&`!!0`@(!,$*"[^'V`` -MO@]@H&()*+#^/V```@`@("SZ+P```%"@!PPH"7X)@`!$'PAN=7@@L`(""K^R\!_A]@ -M`/X&%$#^'V``@`84```_"+C$`@````!0%H(_4"!$[2\`!$%0``'@9P``'Q#P -MY@(``@,`(`"^#V``?%]@=-<"`"#O""C7_C]@@/__)Z!Z^B\`G@=@`+<&*`7^ -M'V"@^_4O`((@4````%`@^O4O`((@4`'^'V"@^/4O`((@4`%ZYU<"`0`@@(T& -M*(```""`=OPO````4"`=]B\#_C]@@";2)P0^#A"`\M$O``0`"`5ZX%<"?>!7 -M!`````)]X%<0````@0,`(`!\7V!TUP(``'P_8,\!``"@W`@H`+X/8(#__R<` -M@^!G`;X/8$$U"2CI_C]``'P?8/S#`@"`(?,O``'@9P$4TB<`O@]@`'Q?8'37 -M`@`@U0@HZ_X_0(#__R<$/@X0`.C1+Z"RTB\``,!A``"@8:#N!7`?Y_8J(3 -M`"`N_A]@(,@#*"G^/V`@<`8H`)[G40'^'V`@<_LO_/\M0/R!+0@`@``(`'P` -M8/___^\`@``0((#[+P'^'V```0`@____?P'^YT$\^N=7!?[_)Q7^"8(`?@@4 -M`$`H"""]`R@N_A]@0/X?8```"!2@-_HO`*(H4@``'PCPY@(`($/M+P">YU$` -M`0`@____?P'^YT$\^N=7!@8`((#]_R<@M0,H*OX_8*!#_"\`GN=1``$`(/__ -M_W\!_N=!//KG5P7^_R<`HBA2%?X)@H!H!B@,(@@4`"((%(#^'V````@4__\? -M8`@`"!0(_A]@#``(%`%ZYU>!!``@(,S_+P```%`!?E\44[$"``"8XB^`E.,O -MH)\+*'W^'Y@`-``@`(0&"`%ZX%>"!P`@+OX?8*"C`R@K_C]@@'C2+R#]^2\` -M`,!A```?"/3F`@``*NTO`*)&$"[^'V"@G@,H`7XI0"!VTB\`'`=@`$0?"%SD -M`@```>!G`'R_8?S$`@"!$P`@`'P_8`@`$@0`(]($-$`B!``CX@0T0#($` -M".R!#1`0@0`(\($-$"[^'V`@E`,H+/X_8""U_R\```!0(+?U+^S_#4`<@08( -M[($M"`"``%#T@0T0`'P?8*S9`@#T_RU`(%X+*.S_34``0#\(8.0"``!`7PAD -MY`(`[/\-0`'^?V`0_I]@(-?<+P/^OV`N_A]@H(<#*`M^*4"``@`@+OX?8*"% -M`R@M_C]@H*;_+P/^'V"`<^(O+OX?8*""`R@N_C]@`7Y?%%.Q`@"`;>,O@/3B -M+P!>XB\`?-]A!,,"`"!1V2\```<(H"79+P```%````<(`_X_8``.`!B@"`$H -M``('$"[^'V`@>0,H!?X_8`#_!D"@D_(O#_X_8``!(&"!`@`@H'4#*"[^'V`` -MO@]@(,4(*-[^/T`N_A]@H'(#*`;^/V"@MM$G0/Z?800^#A`@B-$O,/Z?80`` -M8&(`@N!A``@?"`JM`@`#_M]A"GY`@@"EZ5<`?+]A)+("`*4$`"``HBA20OKG -M5T$!`"",HT80C:-&$````%`@=^,O`)XG8(`:`""`.](O````8B!FU2\+_A]@ -MD(DF"`!\7V``B`(``(1@0"'^'V``A$!```!!$`*B@1`$G$$0@OX?8`6`01`& -MHD$0!YY!$`C^04``)BE0_(--$`C^`(C]@4T0$/X`B/Z!31"@`P`@`((@4`"" -M#4#\!0`(``!!$`%^04`!_@!```X@&``#YU<)_/\GE(4&"`O^/V`!@$$0`(0! -M"`'^7V"@1@4!0((`*(H8`&`01``A`$(`?Y?8*#3!B@`(&A@H+;1+P">!V``%M$G -M!#X.$`#GT"\``,!A`'R_8;C.`@`!>N!7`GWG5P(````!`P`@`+X/8`!\/V#I -M`@``H,P'*`C_1D"`__\G`?X?8`__)D`@VO\O``1!4`)ZYU<```!0(@4`(`_^ -M/V``_T9``OY_8(/^GV"@)/HO`(JB4````%`;_C]@H`0`(`+_1D`$_T9``OY_ -M8(/^GV`@(/HO`(JB4````%`;_C]@!O]&0`+^?V"#_I]@H!SZ+P"*HE"`^]`G -M!#X.$(#?T"\``(!BH)K1+P""8&(``$!BH,34+Q3^'V``?#]B)+("`)")Z`D` -M?+]A`(@"``":QT$(_A]B`)J'00`@1A``*`I@`!PG8*`*`R@4_E]@`)J'092% -M"`@`($80`0!'$`*:!P`4_C]@`?Y?8*"L!B@`IFE@H(_1+P`D"6``\=`G!#X. -M$`#`T"\`>N!7`(:A8:P!`"##_M^!"'K@5PP#`"``O@]@`'Q?8,#-`@`@I@N!7`@P`(```?PAXY`(```0!8`"" -M(4`@\@(H$/Y?8`";YF>!U]`G`OX&@`!\`$`DL@(```%`"``%X6<"`P`@`+X/ -M8`!\7V#`S0(`H),'*!!^)T"`__\G````4"`"`3@!_C]@@,_0)P3^'V`0_G]@ -M`OZ?8*#M^2\`FJ9@@,S0)P0^#A``I-`OQ?[_00``P&$"!``(`(*@83!Z(&`" -M_>!7(`````$#`"``O@]@`'Q?8,#-`@"@A@^!G`0,`(`"^ -M#V``?%]@P,T"`*""!R@#_B=`@/__)P,$!P@%>N!7`GW@5PT````"`>!G`GW@ -M5Q`````!`P`@`+X/8`!\7V#`S0(`H'L'*,G^/T"`__\G`,72+P]ZX(>$`P`@ -MP/X?8"""`BC+_C]``!P'8""Z_R\`FB9@@+70)P($!P@#?J!AP/X?8*!]`B@3 -M_B=`%/[FIP````(&``!!\(H,("`(`"]"<$/@X0H'_0+RC^GV$``>!AY?X?0@(#`"``O@]@ -M`'Q?8'#8`@`@80!G#/[`00(&`"`!_A]@"H!&$``$ -M05`3A$80((2&$`O^'V`,@$`0*(2`$"*(!@@8?@!`H`,`(`Z`@!`'A`8(``'@ -M9X$!`"`QA``("'X`:#&`0!``?#]@ULP"``"%``@!`$<0`7X`0``.0!@/>N%7 -M`(%`$`P!`"````!0`(%`$``$'PAPY`(``7K@5P)]X%<"`````0,`(`"^#V`` -M?%]@<-@"`"!%!R@C?BA`@/__)QD`1Q"@\P8H`!P'8/S_#4`!_C]@("<'*`'^ -M7V`!!`<(@/X_8/V!31``!`<(_H%-$/S_#4"@Z_%7"@$`((`!`"B`6-`G@)H`*(!7T"<$ -M/@X0($+0+SS^GV$``"!B0_X?8*`@`B@`HBA@`*/H9Z+^WX("`P`@`+X/8`!\ -M7V!PV`(`H!('*`)^*T"`__\G"(`("``!X&!G,'Y(0@("`"`!_A]@"H!'$""]!B@`G@=@H-/T+P">!V`@B`<($X2G"0"! -MYE<,`P`@`+X/8`!\7V!PV`(`H/H&*!]^*T"`__\G`00)"/M_(&`!`DD0((@' -M"`"!YE<*`0`@!/X`:`$`21"@`0`@`"B*4@%^"D``#H`:`WX*@`"`QT$D!`<( -M`('F5P$$`"`.>NI7B_O_)P"^#V``?%]@<-@"`"#N!B@L?BM`@/__)P#\9T(` -M`@``XH4)"`/^/V```>!G"X2G"@)\/V`$````&OKJ5P'^`$`!#B`8X85)"`"H -M!D``!>!7"P,`(`"^#V``?%]@<-@"`*#C!B@\?BM`@/__)P":X*<`J!Q````! -M4``.0!@@B`<(`('F5_]_`4`!#D`8!X0'"`!ZX%>,#``@`)OF9X$%`"`6"`D( -M`'P`8/#_````&@!H%@")$""(!P@`@>97@@$`(-V%"0C[?P!@W8%)$``$"0C< -M@4D0`00)"`A^`&C=@4D0`@@)"-Z!B1`$?DE"!/X*4``.H!H!?@%```Y`&/S_ -M#4"@M08H`?X_8!R`!PB`_C]@#00`"/V!31`<@`<(#`0`"/Z!31#\_PU`('GW -M+P"B2&`#_@I`_'\`8``.(!KBA0D(``'@9QR`9P@!%0`@$H0!"`QZ`&`"`P`@ -M`+X/8`!\7V!PV`(`(,,&*'5^*T"`__\G`)OF9P$%`"`(>N!7`@0`("0$!P@` -MI"A`)'[@IP#R!T"P?@!`(!4"*`C^7V`<@&<(`"@*8`">)V``I$A`(-D+*!3^ -M84#BA4D('(`G"``B`4``#B`:#H@`"``$`$`.@(`0'(!G""B((0@`@^!G`1`` -M(.*%"0@`@`!`*("!$"`.`"`<@&<(%(0!"``!X&!G`1<`(`YZZE<*#0`@ -M)@@G"`"#X&>!#@`@*``'"``$05`@?N\O`?Y_8`%^"D``#H`:`WX*@`"`QT$= -M!`<(0'K@9P'X_R<@B`<(`('F5XH-`"`.>NI7B@D`(``H"F"@I`4H`)XG8``. -M@!H!_@9`H/K_)P`.H!D`O@]@`'Q?8'#8`@`@B08HJWXK0(#__R<`O@]@`'Q? -M8'#8`@`@A@8HK'XK0(#__R<`O@]@`'Q?8'#8`@`@@P8HO'XK0(#__R<]_A]@ -M((L!*,)^*T"@S<\G//Z?800^#A"@F\\O*/Z?80``H&%#_A]@H(8!*`":)F`` -MF^9G`'P_8@`"```"`P`@`+X/8`!\7V!PV`(`('@&*!'^*$"`__\G"(`&"``! -MX&!G`@,`(`"^#V``?%]@<-@"`*!E!B@9 -M_BA`@/__)PH$!P@``>!G@@(`(`'^'V`*`$<0(#,&*``"`0`@$@0'"`-ZX%>"`0`@,80`"`A^`&@Q@$`0H$[T+P`N!G`@,`(`"^#V``?%]@<-@"`"!,!BA(_BA`@/__)PS^04````!0`!PG8``: -M04"@9PLH%/YA0.(%2`@<`"<(`!H!0``0H!D.B``(``0`0`Z`@!`@#@`@'`!G -M"!2$`0@``>!G`0,`(`"^#V``?%]@<-@"`"!`!BA1_BA`@/__)Q6$`0@``>!G -M`0,`(`"^#V``?%]@<-@"`*`[!BA2_BA`@/__)Q:$`0@``>!G`0,`(`"^#V`` -M?%]@<-@"`"`W!BA3_BA`@/__)_R!30@,_@%``)HF8"`=[R\"_G]@`_X'@``` -M1T`.^N=7B@D`("8((0@`@^!G`0L`("@``0@`!$%0H!?O+P'^?V`!_@=``!#@ -M&0/^!X```$=`'00!"$!ZX&N!7#0`?4``!````@(@0`GX'@`!\ -M_V$$Q`(``!X`0)0!``C8_R=`(/'X+]K_1T``'`=``!X`0+@+``@`'L=!R`=' -M".B!AQ``BB@(ZH6'$`"``%``!."G!/YA8<0``0`0`!\7V!:Y0(` -M(OK@5P``@1`K`@`@``Q@&$#ZX%?,$``@!'X`4$#ZX%<,`@`@C/K@5PH!`"!T -M^N!7`@D`('3ZX%=!#``@]W\`0(SZX%?!"@`@#GX`0)'ZX%<"_>!7E0```$$( -M`"`*?@!`F?K@5P+]X%>;````P04`(`)^`$"=^N!7`@$`("`$`"``!H$0H?K@ -M5T$"`"#^?P!`I?K@5P(!`"#\?P!```"!$`#+UB\%?N"G`/(?4`1^`)```)\0 -M7.4"``!\'V(4F@(``'\(0!3_)T`@O=`O@/Y?8`"**`B,^N!7BP4`(*7ZX%>) -M!``@E?K@5X$#`"!:_A]@)@&($"@!B!!9_A]@*@&($%C^'V`L`8@0E?K@5X(# -M`"!N_A]@)@&($"@!B!!9_A]@*@&($%C^'V`L`8@0@/K@5XL$`""$^N!7B0,` -M(%K^'V`F`8@0*`&($%G^'V`J`8@06/X?8"P!B!`H^N!7BP0`("SZX%>)`P`@ -M;OX?8"8!B!`H`8@0;?X?8"H!B!!L_A]@+`&($&CZX%>"`P`@;OX?8"8!B!`H -M`8@0;?X?8"H!B!!L_A]@+`&($-R%)P@`@^!G`HH`&$(!`"#:@T<0VH<'""#- -MT"\#_C]@"7X`0``*0!@__C]@(`<`(+`%9P@`F@U`_`4`"``$`$``"D`8`((` -M0``@`$``!8`0`?X&0``.H!D#^N97`9JF4?__`$``#B`8`(?@5PL!`"`?>N%7 -MC/?_)WX)"`C=@4<0(`7/)RC^GV$$/@X0`-K.+SO^OYH``(!B`()@8J"1SR\` -M!`%B``#@8:"[TB\8_A]@`'R_822R`@"0B28*`'Q?8@"(`@``I,A!$/X?8`"D -MB$$``$80`?KI5S3_!D``*"I@H@(`(```0&"`@@@HCOX?0"`"`"`@_BI`@)4( -M*([^'T`G_BI`@*X`*#2!)@B@K0`HCOX?0#B!)@@@K``HCOX?0```"@@!^NE7 -M!``'$`0`"@@8_C]@"``'$`'^'V`!``!0`GX`0`(`1Q"4A08(`?Y?8`$`1Q`" -MI`@`H)@$*``@:&"@>\\O`)X'8`#>SB<`/@X0`+/.+Q"`C1``@L!A``2A80"& -M`6(%_@!`('3/+P`.(!H``.!A()[2+P"B"&``?)]@)+("`)`)(@@`?%]@`(@" -M``"$8$`9_A]@`(1`0```01`0A`T(!)Q!$`.`01`1A`T(!?XA0`*`01`@`P`@ -M``1!4`"$!@@!?D%``(!`$`'^($`!_J9!``7G5XG\_R>4!0((`*(H8`&`01`` -MA`$(`?Y?8*"!!"@`(&A@H&3/+P">!V"`>=`G`#X.$("9SB\0@(T0`(*@80`$ -M`6(@7L\O`(;A80``P&$@B-(O"/X?8`!\?V`DL@(`D(E!"`!\GV``B`(```@A -M0!G^'V`#^N9G`X!`$($#`"``?%]@P,T"``!\/V`I!P``H'0%*`"^#V"`__\G -M````4``(@4`!@$`0"'X`B`*`0!`0A`T(`'Y"$`:`0!`1A`T(!YI`$`6`0!"4 -MA0$(`OY?8`2`0!`9_A]@"/X_8*!I!"@`GF=@`"`(8`":)F``!$%0H%'N+P+^ -M?V`@2L\O`!P'8`!>T"<$/@X0`'W.+P``X&&@1,\O`(+`80``H&&@;M(O!OX? -M8`!\GV`DL@(`D`E""`!\?V``B`(```8A0!O^'V``!H%!``!&$`'^'V`"@$`0 -M`'P?8"\!```#@$`0"'X`B`2`0!"4!0((!9Y`$`&`0!`"!@$`!OX_8`'^7V"@ -M500H`!QG8*`XSR\`F@9@`)7.)P0^#A`@<\XO`_[@IP``H&$`@L!A``0!8@/^ -M'$`@,<\O``X@&@``X&$@6](O`*((8`!\OV`DL@(`D(DB"`!\7V``B`(``(2` -M0!O^'V``A$!``7KG9P``01"A`P`@\OY?0@"^#V``?%]@P,T"`"!'!2C8?BE` -M@/__)P)ZYU<#?@)`"@,`(`"^#V``?%]@P,T"`*!"!2C;?BE`@/__)P(<0A`@ -M!0`@``1!4`("0!`#!D`0"/YAB`0&0!``A"9``80@"`)^04`%`D`0!GX`0``% -MYU<,!P`@`7XI0``"0!`(_B"(`0)`$`*$)@"`^N!G\_Y_0(+V_R<`O@]@`'Q? -M8,#-`@"@-`4HX7XI0(#__R>4A0((`*(H8`$`0A``!`((`?Y?8"`O!"@`(&A@ -M(!+/+P">!V"`<!7!H0`4`4$ -M`%``@`$0((`/.````%`$/@X0@/C-+P``P&$`@@!B``2A8:"\SB\``.$)`*`G -M0``#YU<.G"!0H+S.+P""!A`@&LXG````4"`!`"``@B!0`?X@0`7ZX%>&!0`@ -M&/[@IP#\7$"HJ@(`*``!"```8`@D``$(````"`"!X5!G@0$`(`"^#V!G_C]@`!T%*`'^YT$8_J9!!'['007ZYU>&`,XG -M`'P_8*BJ`@```@=`$```"``!X&<`@@9"@>__)R@`"`@``"`()``("``"`!`P -M`@@0+`(($#@`"`@````(``'@9P&^#V#!$04H3OX_8#0`"`@``"`()``("``` -M``@``^!7A0(`(`"^#V`@#04H4OX_8#0`"`@``"`(*``("`````@``^!7A>S_ -M)P"^#V`@Z_\G5OX_8"`#`"``"()0``1@"`%^@D``AD`0`?X@0`%^`$``">%7 -MC?S_)P"`#S@"?H&((`,`(`"&85```$`(`?YA0`"$`!`$_B!`!'X`0``'XE<. -M@`\X`/S_)P!\/V"HJ@(`"(``"`"`0`@````((,#_)P'^/V`8?N"G`/Q<0*BJ -M`@`T``$(`()@8"@`(0@````(`(`@"""X_RGD80GYQ&$`A^QXD@6LXOH)Q&$/B!#0C\ -M@2T(H%?<+PQ^`$"@QN!7BFD`*(!0 -MSB\``*!A(-+B+PG^'V``B>(OH%#.+P":!F`@D-\O`?X?8-+^'V"@=?\O^/X_ -M0("HS2<$/@X0('K-+QC^GV$`!!\(YN,"```!X&>"W?@O@-0%*`%ZX%>.`@`@ -M`-/Z+P```%``@B!0H#W[+P'^7V"`"0(H@"P"*(`A^"\```!0(#7W+_C_+4`` -M``!0__\_8*"-^2_\_TU`````4""U^2_X_RU``OX?8/__/V`@BODO_/]-0`+^ -M'V"@L?DO^/\M0`;^'V#__S]@H(;Y+_S_34`&_A]@(*[Y+_C_+4`#_A]@__\_ -M8""#^2_\_TU``_X?8*"J^2_X_RU`!/X?8/__/V"@?_DO_/]-0`3^'V`@I_DO -M^/\M0`7^'V#__S]@('SY+_S_34`%_A]@H*/Y+_C_+4`*_A]@(%KQ+P'^/V`+ -M_A]@H%CQ+P""(%```!\(Y+P"``!]X%<````"`GW@5P````2!`P`@`'Q?8/#- -M`@``?#]@,`(``"!"!"@`O@]@@/__)P#`]R\`'N%7!)!@"($! +M`"`$!``1(/W_)P0&`!$`?#]@U.\"``3^($!(`@T0`'Q?8``"``!,!`T0`/Z? +M8%`(#1``A"!`!/X@0/S_(&`$`@T0`(`/.```'SAK`0`````?.&\!`````!\X +MN!7@?[_)P2`OQ____]_#``-$`0`8`@8`(`(`?YA0`0&`!`( +M`(`+,`@-$```+@@`^N!7`@D`(`0`[@L(`&X+#`!."Q``+@L4``X+&`#N"AP` +MS@H@`*X*)`"."B@`;@HL`$X*,``N"C0`#@HX`.X)/`#."4``K@D@@0\X1'Z. +M0P0`#@@"@!\2"``N"`."'Q(,`(X/$`#N"Q0`K@L8`&X+'`!."R``+@LD``X+ +M*`#N"BP`S@HP`*X*-`"."C@`;@H\`$X*0``N"D0`#@I(`.X)3`#."5``K@E4 +M`(X)6`!N"8@`#@@!?N"O7`!."6``+@ED``X):`#N"&P`S@AP`*X(=`"."'@` +M;@A\`$X(@``N"(P`#@@2@!\2A``."""!#CBH?HY#`/SO8_____L`@0\X`/SO +M:P````0`@0\X`/P/8`````0`_.]C____^P"!#S@`@.]K`($/.`#\#V`````$ +M`($/.""`#S@`(``(((`/.`"``!*``@X0A``.$```#0AX!@X0`'K@5WP$#A`A +M"@`@`7X`0```#1!4&`X06!8.$%P4#A!@$@X09!`.$&@.#A!L#`X0<`H.$'0( +M#A`"H%\)`Z`_"0QX#A`$%`X0"!(.$(AR#A",=@X0((`/.!0Z#A````T0#``M +M"%08#A``^N!76!8.$`$)`"!<%`X08!(.$&00#A!H#@X0;`P.$'`*#A!T"`X0 +M`J!?"0.@/PD,>`X0!!0.$`@2#A"(<@X0C'8.$!0Z#A`(N``0((`/.`@`C0L@ +M@`\XJ'Z.0P2`OQ____]_```-"`%Z`%````T0`0T`(`0`#@@"@!\2"``N"`." +M'Q(,`(X/$`#N"Q0`K@M4`(X)6`!N"8@`#@@!?N"O7`!."6``+@ED``X):`#N +M"&P`S@AP`*X(=`"."'@`;@A\`$X(@``N"(P`#@@2@!\2A``."""!#CBH?HY# +M#``-"`!ZX%"#0`@"`"`"P0`#@@" +M@!\2"``N"`."'Q(,`(X/$`#N"Q0`K@M4`(X)6`!N"8@`#@@!?N"O7`!."6`` +M+@ED``X):`#N"&P`S@AP`*X(=`"."'@`;@A\`$X(@``N"(P`#@@2@!\2A``. +M"""!#CBH?HY#"`#@"`'^WV``C`,0&+8#$!RT`Q`@L@,0)+`#$"BN`Q`LK`,0 +M,*H#$#2H`Q`XI@,0/*0#$$"B`Q!$H`,02)X#$$R<`Q!0F@,0,`!-"`!ZX5<` +M_O]@`0$`(!@$`!`P#@T0#`X-$`"'_R>090``@+J,`0@$#A`L``T(,`!-"`%^ +M`$``>N%7+``-$`P`#A`0`@X0%`0.$!@&#A`<"`X0(`H.$"0,#A`H#@X0+!`. +M$#`2#A`T%`X0.!8.$#P8#A!`>`X0`J!?"0.@/PD`H!\)1!0.$$@2#A!,$`X0 +M4'(.$%1V#A!8/@X0$'Z.4X`$-R@0?HY#4``."`%^X*]$`$X)2``N"4P`#@D" +ME!\2`Y(?$AE^Y(@`@*,?$``N"!0`3@@8`&X(5``."!*`'Q(<`(X((`"N""0` +MS@@H`.X(+``."3``+@DT`$X).`!N"3P`C@E``(X/#``."%@`[@LA`P`@`/X_ +M8`%Z05`P!`T0`@$`(`'^/V`T`@T00``-"```0`@`>N%7@0$`(`'^/V`@!``@ +M1`(-$#P`30@$?@!```7@5T``#1`"`0`@.`!-"$`$#1``^N!7`0\`(```#@@$ +M`"X("`!."!`^#A"`BO\O1`!-"`!ZX5N!7@@$` +M(`P`#0@8`$`(,`0-$#1\#1``````@)C_)P``#@@$`"X("`!."""!#CBH?HY# +M````0````$````!``'P`%```'S@$`@`4`%4`(`0^#A``-@X0`#AN8P```$`` +M``!`````0`!\`!0``!\X!`(`%"!0`"@0?HY3!(#M"R"`#S@0$&X+`(-`8`#^ +M/V`"!``@`!\`(`"#0&``_C]@@1T`("04`"```>!'____?X41`"`/>N!7`?[? +M8`T+`"`'>N!7!/Z?9PT$`"`#>N!7`_Z?9PT#`"`!>N!7`OZ?9PT"`"`@`@`@ +M`?Z?9P`&`!@`!@`8``8`&``&`!B``@`P``$`0`""($@`A>!7!@P`0`:$(%`` +M@0\X``'@9R#^OV"!`@`@!`(`(``!`$`!_J)00___)P`!`$`@^/\G`(J"9Z`! +M`"``_A]A`?X?80"$0%``$`1)!8$`4`'^WV`@_I]G@`(`,``!`$``@B!(`(7@ +M5P8,`$`&A"!0`/[_8`-ZY%<"@`-0`7KD9P*"(U``@0\X_X4?&""!#S@`_C]@ +M$`!@"/S_86"X_F%0`/P!$`$`````_K]@!(H!$`B*`1`,B@$0$(H!$`#\P&@` +M```,%(P!$!B*`1`N%7``"` +M8`!ZX5?_?T%``8`/.``"0A``>N%7_W]!0"&`#S@!?H)`H/W_)P`"0A`````` +M``6!9P`"@&@!@0\X`WKB9P`$@1B"$0`@``2"&``$@A@`!8(?!/X@4`1^8%`" +M!``P!)"`"`20H`@$D,`(!)#@"`2(`1$$B@$1!(P!$02.`1&E!0`@!'KA9___ +M_W\B!P`@`WJ!9P/^($`!@0\X`_YA0``!`#`!E(`(`8A!$0"!#S@$D(`(!)"@ +M"`2(`1$A^O\G!(H!$0-Z@6<$D(`(H/C_)P2(`1$!_B!0`7Y@4``!`#`!E(`( +M`8A!$0"!#S@@%0`@$/Z?8:`3`"`4_I]A(!(`(!C^GV&@$``@'/Z?82`/`"`@ +M_I]AH`T`("3^GV$@#``@*/Z?8:`*`"`L_I]A(`D`(##^GV&@!P`@-/Z?82`& +M`"`X_I]AH`0`(#S^GV$@`P`@0/Z?8:`!`"!$_I]A2/Z?840`3@M``"X+/``. +M"S@`[@HT`,X*,`"N"BP`C@HH`&X*)`!."B``+@H<``X*&`#N"10`S@D0`*X) +M!(#M"P@8;@,@@`\X!'Z.0P"#0&``_C]@@1,`("0(`"```>!'`?[?8(4%`"`& +M%*`8`?ZB0""*GE<`"@"`@@(`,``!`$``@B!(`(7@5P8,`$`&A"!0`($/.*`! +M`"``_A]A`?X?80"$0%``$`1)!8$`4/__OV`&%*`8`?ZB0""*GE<`"@"``?[? +M8(("`#```0!``((@2`"%X%<&#`!`!H0@4`#^WV`#>N17`@`#4`%ZY&<"`B-0 +M`($/.```(&`@@0\X__\?8``#X%?_?V%`#@(`(`"$@$``">!7____?X4&`"`` +M!>%G____?P&`#S@``(!@`(1`"``$0A`!?H)``/KA5___84`A@`\X`?X@0*#\ +M_R<`A$`(``7A9____W\!@`\X`H9````&@$$`^N%7__]A0"&`#S@`!$80(/W_ +M)P*&0`!$-`X00#(.$#PP#A`X+@X0-"P.$#`J#A`L*`X0*"8.$"0D#A`@(@X0 +M'"`.$!@>#A`4'`X0(($/.!`:#A!$`$X+0``N"SP`#@LX`.X*-`#."C``K@HL +M`(X**`!N"B0`3@H@`"X*'``."A@`[@D4`,X)(($/.!``K@D``!\(S+,"``"` +M#S@`?%]@Q+0"``@!(0@"_B"``(``0``$`$`0!0`(((`/.`@!`1```!\(R*L" +M`""`#S@`#@`8```?",BK`@``?`!@`/\``""`#S@(?@"(```?",BK`@``@`\X +M!#X.$(#"_2\`"!\(EL("``)ZX%>,[?TG`+X/8`!\7V#$S@(`H'@T*';^/V"` +M__\G%OZ?8`"(0!`@`0`@`(JB4`'^HD`E^N)7"@0`(`"*@D``?,)`-,L"`!0% +M@P@`">!7@OO_)Q4%@P@`B$`0#GK@5P%^`%`)``!0`(!!$""`#S@``$$0!#X. +M$`"W_2\``>!G@0$`(`"&0A`@W_TG``A#$`",H1D`?-]A-,L"`&0'AQ``#&(9 +M9@F'$``0!%%D"T<)9@LG"6H+!PAL"X<(H`0`(``0Y&``$(1@`!`$8``:0D$` +M#*49`!8@00",9!D!_N-``(SC&!GZXU>*"@`@"O[CIP"<'$!P!8`(``GA5XOX +M_R=Q!8`(``GA5PGW_R=R!8`(`(G@5XOU_R=S!8`(`(G@5PGT_R=T!8`(``GB +M9P*)X5<"\O\G=@N`""#R_R=X"P`(;`F'$&H!AQ!H#X<09A.'$&05AQ``FD(0 +M(,7])P`60Q```$!@````4`!\7V$TRP(```S#4`!\?V`TQP(`$X4A"22!`0D@ +M#0`@`(JB4`#\@D`TR0(`5`1B"``'X5<+"0`@501B"``'X5>)!P`@5@1B"`"' +MX%<+!@`@5P1B"`"'X%>)!``@6`IB"``,Y!@`C^%7B0(`(%H*8@@`A^-7"0$` +M(%P`8@@`@`%``7[#0`S^HD``$^-7B_+_)R"`#SA@`040``(`4``"`!@@@`\X +M``!!$`0^#A"@D/TO-/Z?80```&(`@N!A``2A80"B*%*@!#@H_*,-$``!X&<` +M',=1H@<`()W^?YJ`2/XOH,,>*```P&$`@B!0(-<>*/S_34```>!G`0,`(`"^ +M#V``?%]@(,X"`"`M-"@C_BE`@/__)P```%"@-20H^/\M0`CZYE>!`0`@^($- +M"``!X&>!#@`@`'Q?8E"R`@"510D(``'@9P$#`"``O@]@`'Q?8"#.`@"@(S0H +M*_XI0(#__R!G@@0`("``'"@`F@9@`$`-*``@"&`@ +M\!@H`)XG8*"S#2@`F@9@@`$`(``@"&`@[1@H`)XG8)4C210`Z#*/S_34```>!G`0,`(`"^#V``?%]@(,X" +M`"`2-"A&_BE`@/__)_R!#0@``>!G`0,`(`"^#V``?%]@(,X"`*`--"A(_BE` +M@/__)R"1_2!G +M`6G])X"O$R@`:/TG``4<(`"`#S@$/@X0@#O]+P!\/V"XK`(`H,LE*```H&$` +M`#\(K-T"``":!F`@R24H"OX@0```/PBPW0(``)H&8*#&)2@*_B!``'P_8-R8 +M`@"@Q"4H`)H&8(!=_2<`?#]@-*X"``$$0`@@.2\@`GY!0`0^#A`@+/TO*/Y? +M8`!\/V`0L`(`@#4O*`!\'V`````0`+<**`!5_2>`\00@!#X.$(`F_2\````( +M``'@9P$"`"``?!]@`````H#%%"@`4/TG@$8J**!T$B@```!0`$[])P!\/V"X +MK@(``01`"*`J+R`"?D%``'P_8+"M`@`!!$`(("@O(`)^04```$`(!`@@"``$ +M`6"@H"H@!OY?8`````@`?#]@"/<"`/Q[`&`A@`\X`(``$`!]X%<``0``!H`/ +M.(#^'T`@@`\X`(``$`0^#A"`$OTO`-`2*(`Y-2@`/OTG!#X.$``0_2\!!(`) +M``0@"`A^AH$`F"!H`@2`"1!^AH$`F"!H`P2`"1A^AH$`F"!H(%,6*`".`!@` +M?!]@``"```"7"B@`-?TG``0@"`!\?V!`L@(``()!$``$(`@&_N"G`/)<8`1^ +M`$`@#R\@!/XA0`!\/V"TK@(``01`"*`,+R`"?D%`@``4(`0^#A`@__PO8/Y? +M8`!\/V`0IP(`@`@O*``$'P@XKP(``'K@5P'^'V"@OQ(H`@``4(`O_R\%>N!7 +MA27])P`S_R\/>N"'!"3])P!\'V"TK`(`H#\/*`""(%"`(?TG`'P_8,RM`@`! +M!$`((/XN(`)^04`$/@X0`/;\+P``H&$!!``(`'S?8;2L`@`C`$<0`(0&"*`C +M_R\B`$<0!7K@5X4"`""`)O\O#WK@AP,,```@`@9'$`"((F@$`D$0`GY@@!J$!@@` +M``!```8`0`.`/X`(!`$(``(@<`@"01`:A`8(````0``&8$`"A`8(``8`@``" +M`&@(`$$0`(0&"`Q^)T`&?N"G!OY<4!3^!D`@424H`(0@0`"$!@@:A"8(!/Y& +M0"#'*R@`AF%0H`0`(`($9P@!_B%0`(Y@&`("1Q`"?@"`#X`_@`@$`0@``@!P +M"`!!$`"'X6_B\!>N!7`0$`(`5ZX%>"U/PG`'P_8(2P`@``B``(`8`? +M<`"`@!``?!]@```!```Q"B@`T/PG!#X.$("C_"\``*!A(#(2*````%`@N!,H +M`)H&8`"`!@@!?@!@``"?$(2P`@``TOXO`7K@5P$!`"`%>N!7`LC\)P!\'V`` +M``$``"<**`#&_"<$/@X0@)G\+P``H&$@U#@H````"`"]-"@!>N!7`L+\)P`` +M`%``FB9@H%0D*``$05"`O_PG!#X.$`"3_"\``*!AH'HA*``(``@`B"8(``"? +M$(RP`@```A\0!/@"````GQ!TIP(``+G\)P0^#A"`D?PO``"@80`$``@(?B"` +M`H0&"``"`&@`?>!7``$``"$%`"``',=1B1X`(``!X&>"!P`@`'S?852M`@`` +M"0`@`'S?892M`@"`!P`@`'S?862M`@``!@`@`'S?872M`@"`!``@`'S?882M +M`@```P`@`7K@5P'Y_R<`?#]@7@(``""/,R@`O@]@`)[G40""(%`@`0`@`81F +M"`'^($``A^!7B@,`(`""!D`$!$`(``('0`($``@``>%7@?O_)P'^_V$!!D<0 +M`81&"`3^!D`@?"XH`GXG0("E_B\%>N!7A9[\)P!8$R@`G^=G`FX0*`!\OV&T +MK`(`;(@&"*"[$"@`@B!0``X(*("D_B\/>N"'A)C\)P":!F"@L0XH`((@4("6 +M_"<`?>!7`0$```'G_R<`?>!7``(```'D_R<`?>!7`0(```'D_R<`YO\G!#X. +M$(!E_"\)!"`(`OK@5P!\WV&TK`(`H@(`(```H&$```!0'P!'$"`!`"``@B!0 +M'P)'$`F$!@@``%\0H+`"`&`$!P@``>!G`0$`(`3^`&@?`$<0`X0F"!D$!P@` +M@^!G`GP`:`$```!"`@`@&0!'$/Y_`&`9`$<0``X`&`2$)@@`@^!G`GP`:`(` +M```!?`!@_?___QD`1Q``#B`8`X0&"``!X&!G!/X`:`'\`&#[____&0!'$``.(!@&A`8(``'@9PC^`&@!_`!@ +M]____QD`1Q`'A"8(&@0'"`"#X&<"?`!H`0```$("`"`:`$<0_G\`8!H`1Q`` +M#@`8"(0F"`"#X&<"?`!H`@````%\`&#]____&@!'$`J$)@@@!`<(`(/@9P)\ +M`&@$````0@(`("``1Q#[?P!@(`!'$``.`!@+A"8(`(/@9P)\`&@(`````7P` +M8/?___\@`$<0`H0&"'(`1Q`"A`8((&?^+W(`1Q`%>N!7A0(`(`!J_B\/>N"' +M`QP'8*-W#B@#@B!0`(0&"`A^7Q#@L0(```!?$`RG`@`.A`8(``!?$`VG`@`- +MA`8(``!?$%RR`@`/A`8(``"?$+3=`@"`5/PG!#X.$``G_"\``*!A`@0`"`!\ +M?V!,M`(`!GY`@`&$!@@`A"%`(X!`$!2`!@@`A$%````!$!B`!@@$@``0`X0& +M""2`0!``A`8((H!`$`3^!D`(_B!`("LN*!#^7V`!A`8(#'K@5X)&_"<@82LH +M`H0&"`!%_"<$/@X0`!;\+X!+_B\%>N!7AD'\)P"$"2B`0/PG!#X.$*`2_"\` +M`"!@``0`"`&$0`@@4`0H`OX@0(`W-"@#>N!7@CO\)P!)_B\/>N"'!#K\)X!> +M!"@`.?PGH#8K(`""(%``?#]@6*\"``$$0`B@%"X@`GY!0```0`@$`(`(``1" +M4!=^X:<(`&`(`/*\8`"(05`/?N&G#```"`#R7&``!@!0"W[@IP`*`4``<@!` +M`(``$""`#S@```!0!#X.$*`!_"_\?X!@`'Q?8%"R`@"2"2$(`'R_80`$```` +M`@)`!'Y@0`"0`1@`&^!7D@>!$*L#`""0`X$0````4)`!@1``@B!0!'YB0`"0 +M`1B2!X$0`)O@5PL#`"``O@]@`'Q?8"#.`@"@K#(HO?X_0(#__R<`&^!7BQ[\ +M)P!\7V`@S@(``'P_8'L!```@J#(H`+X/8(#__R<$/@X0H.S[+Q3^GV&`>N!7 +M"P,`(`"^#V``?%]@Y-<"`*"B,BB,_C]@@/__)P```$``#@`8`7X`:/Z!C1!I +M_A^``OX_8/[_34`@!"TH`(9A4````%"@)/PG%/Z?800^#A`@Z_LO+/Z?80`` +MH&$`@N!A```@"`0```@``B!`"(`&"``"($`,@`8(``(@0!"`!@@`@"!0%(`& +M"`"`(%`8@`8(`(`@4!R`!@@`@`!0`'P_8,JT!G`?X?8""`#S@"``!0!#X.$"#'^R\'_A]@H!,? +M*`'^/V``!!\(T+,"``%ZX%<`?+]A(/8"``("`"``@`8(*WX`:*#L^R<`@`80 +M`$X#**#?`B@!_A]@``@?"&##`@``?>!7(T(``(("`"`D_A]@(`D?*`""(%"@ +MV@(H````4("8`RB`]O\G!#X.$*#'^R]L_I]A]OY_0@``X&&`_C]B`'R_82#& +M`@`%HT80!*-&$`>C1A`&HT80":-&$`BC1A`@`0`@`!S'40%^QT$$>N=7"@\` +M(``:!T`4!0`(`GX'@@J!1A#`_TU`!/\&0`""(%`@K@`H`"!!0``!X&?@_TU" +M`@8`(`3_!D`!_C]@H*H`*``@24```>!G@?7_)P"^#V``?%]@/-@"`"!<,B@% +M_BE`@/__)P"^#V``?%]@/-@"`"!9,B@!_BE`@/__)Y[^'V`%@480!(%&$`>! +M1A`&@480":-&$`BC1A`@`0`@!/[?80%^QT$(>N=7"@\`(``:!T`0!0`(`GX' +M@@J!1A#`_TU`!/\&0`""(%`@F0`H`"!!0``!X&?@_RU"`@8`(`3_!D`!_C]@ +MH)4`*`"@2$```>!G@?7_)P"^#V``?%]@/-@"`"!',B@5_BE`@/__)P"^#V`` +M?%]@/-@"`"!$,B@1_BE`@/__)\#_#4``GB=@(#<`*"#_1D```>!G`0,`(`"^ +M#V``?%]@/-@"`"`^,B@9_BE`@/__)P```%`@P?LG;/Z?800^#A`@D/LO:/Z? +M84/^7X(``,!A@/X?8`!\_V$@Q@(`"8%'$`B!1Q`@`0`@`)JF40'^ID$$^N97 +M"@\`(`">!D`8!0`(`OX&@@J!1Q#`_TU`!/\'0`""(%`@>P`H`"!!0``!X&?@ +M_RU"`@8`(`3_!T`!_C]@H'<`*`"@2$```>!G@?7_)P"^#V``?%]@/-@"`"`I +M,B@*?BE`@/__)P"^#V``?%]@/-@"`"`F,B@&?BE`@/__)Y[^'V`)@4<0"(%' +M$"`!`"`$_K]A`?ZF00CZYE<*#P`@`)X&0!0%``@"_@:""H%'$,#_34`$_P=` +M`((@4"!H`"@`($%```'@9^#_+4("!@`@!/\'0`'^/V"@9``H`*!(0``!X&>! +M]?\G`+X/8`!\7V`\V`(`(!8R*!I^*4"`__\G`+X/8`!\7V`\V`(`(!,R*!9^ +M*4"`__\GP/\-0``<)V`@!@`H*/]'0``!X&!G@0,`(`!\7V`\V`(``'P_8),!```@`S(H`+X/8(#__R<@ +M_@=`_/\M0"!E_R\$_D9```'@9P$#`"``O@]@`'Q?8#S8`@`@_3$HS/X_0(#_ +M_R?X@2T(``)'$/R!+0@!`D<0H(#[)R3^GV$$/@X0H$C[+R3^GV$`?!]B``(` +M```!P&$`?!]@(/8"``)]YUN!G@B@`(!]_"$"@]BPH='XH0*`8*B@"_A]@($\`*``!G`0,`(`"^#V``?%]@/-@"`*#H,2AZ?BA`@/__)P!\_V$@Q@(`#/V'$``$ +M````?!]@&9````+^/V`,_T=`H$DL*`"&85"@`1A`F@$80(`0`(`""(%``_!Q`XN4"``("0```G@!`!`5`$`'^`$`` +M#B`8!/K@5XO[_R<,H8<0`'P?8!F0```"_C]@#/]'0"`W+"@`AF%0()3_+_[_ +M#4```>!G`0,`(`"^#V``?%]@/-@"`"#,,2B:?BA`@/__)_Z%#0@H@$80_X4- +M""F`1A`@`P`H`!P'8)#^'T"@SRPHHGXH0*!,^R!G`0``4`)\'V`"`````H%&$`!\7V`LV`(``OX?8`/^/V`" +M_V9`H(TL*``(@E`7?@=``OX_8!+_1D"@(2PH`(9A4*3^'V"@42PH`((@4`!\ +M7V#*SP(`3'X'0`+^/V`@'2PH`(9A4(!?*"@`*OLG`#X.$"#^^B\D_I]A$(*- +M$```8&``!*%A`'S?8239`@`'_A]@`_X_8`!_1T`@?RPH``B"4`!\'V`]T@`` +M`OX_8!#^34"@$BPH`(9A4"`$_R\&_A]@``'@9X$"`"``O@]@^?X_8""H,2@8 +M?T=`@/__)Z`M`BCT_PU```'@9X$"`"``O@]@_?X_8*"C,2@8?T=`@/__)_R) +M+0B`^N!G`OP@:`#_```!CB`8$/Y`@/J)+0@`A"!``((&$*#;_"!G`'R_82#&`@"B`@`@:?[_@87^'V`<@480(`(`(!3^/V`E_A]@ +M'(%&$!;^/V``@T80("TL*`""(%``?%]@R,\"`$S^!T`"_C]@H/@K*`"&85`` +M?-]A)-D"``Q_!T`,_C]@H#@L*``$05`"_A]@`_X_8`A_1T``_V9`(%PL*``( +M@E`"_@=``OX_8`[_1D`@\"LH`(9A4!?^!T`"_C]@$/]&0*#M*R@`AF%0(/SZ +M)P```%`$/@X0@,_Z+P!\7V`DV0(```'@9P)]X%YU$"_>A7`0````$#`"``O@]@`'Q?8%38`@`@:C$H +MXOX_8(#__R<````(`GK@9P)2`"`9?@E`(&\L*.G^/V`@D2DH`OX?8*!6`B@` +MH@A@H+S^+PG^'V```>!G`'S?84C9`@"!`@`@`+X/8//^/V"@7S$H#']'0(#_ +M_R<@Y0$H]/\-0``!X&>!`@`@`+X/8/?^/V`@6S$H#']'0(#__R?XB4T(``X! +M&!!^((#TB0T(``(`0`A^`(@`#"`8"'X!D!!^0(#VB0T(`(+@IP`$`$`(?@"( +M``P`&`#R/&```."G`((<0*"C$BCL_RU```'@9X$"`"``O@]@`7XI0"!.,2@, +M?T=`@/__)^R!#0@`?!]B4,8"``-^X*<`\AQ@(/;[+P7^/V#L@0T0"_X?8/*! +MC1`#_@E``OX_8/+_34"@K"LH`(9A4"`$`"``FJ91Z($-".R!+0@`@>!7A@`` +M(``%Z`D!_@9```Z@&0;ZYE>*&P`@!9H?4`&`'X``'@!``0%($``!2!`"_A]@ +M`_X_8`!_1T``?VA`(`LL*``(@E`@D_XO"?X?8``!X&<"#P`@(+\!*/3_#4`` +M`>!G@@\`(/B)30@`#@$8$'X@@/2)#0@``@!`"'X`B``,(!@(?@&0$'Y`@/:) +M#0@`@N"G``0`0`A^`(@`#``8`/(\8```X*<`@AQ`((`2*.C_+4```>!G@>?_ +M)P"^#V`G?BE`H"HQ*`Q_1T"`__\G`+X/8!-^*4`@*#$H#']'0(#__R<`O@]@ +M%WXI0*`E,2@,?T=`@/__)P$?2!``'T@0`*((0`!\`$"^Y0(`,1Y`$#`>0!`` +MH^AG`0``4`)\'V`"````"`%($`7^'V`#_C]@!']'0`A_:$`@["LH``B"4`!\ +M7V#*SP(`3/X)0`+^/V"@?RLH`(9A4`#")RB@!`(H````4)#^'T"@'BPHH?X_ +M0"":^B=$_I]A!#X.$(!C^B\`?/]A2-D"```!X&<"?>!7`0````$#`"``O@]@ +M`'P_8$\!``"@#C$H#/]'0(#__R<``*!!`'P?8K[E`@`P?LA!`OX?8`/^/V`` +M_T=``!IG0"#9*R@`"()0`OX?8`/^/V`"_T=``!IG0"#6*R@`"()0`*`&0#`$ +M``@``!\0;)@"``!Z^B<$/@X0($OZ+RS^GV$`@J!AH%G^+P`.`!@``>!G`0,` +M(`"^#V``?%]@:-@"`"#],"BZ_C]@@/__)Z""`2CT_PU```'@9P$#`"``O@]@ +M`'Q?8&C8`@`@^#`HOOX_8(#__R?XB4T(``X!&!!^((#TB0T(``(`0`AZX(<$ +M?`!H````_P5^`)``#"`8``/@5P$#`"``O@]@`'Q?8&C8`@`@[S`HR_X_8(#_ +M_R<(?@&0``X`&!!^0(#VB0T(``0`0`AZX(<$?`!H````_P5^0)``#`$8``'A +M5P$#`"``O@]@`'Q?8&C8`@`@YC`HU_X_8(#__R<`@N"G`/(\8```X*<`@AQ` +M(#42*`":)F```>!G`0,`(`"^#V``?%]@:-@"`"#?,"C@_C]@@/__)Z!E^B!G``HA"$$!`"`""@$(!`H!"`"!X%<)@`!0#`(`4""` +M#S@`$``8!#X.$(`>^B\`?!]@(/8"``````@$>N!GUOZ_00)'^B=S_P9`H-HK +M*(W^)D"@_"@H`OX?8``$'PC%LP(``WK@5P$!`"`1>N!7"P@`(*`&`"``BJ)0 +M`/P"0'#&`@``!0`(`OY"@`!\?V#0Y0(`_O\A0`"$($"@!``H`(1!0`'^`D`` +M#J`8!?KB5POY_R>0_A]`(,TK**+^)D"`-_HG``"?",BS`@`"`&(````"0`$$ +M``@`A^%G``H`&`$!X&``(`-0.P#`!`!?L=!`)X?4``*X!D">N=7"A,`("J+!@@"_C]@`!X`0/Z! +MC1``?!]@!M(``/[_34"@^"HH`(9A4`!\'V`^D````OX_8.;_34"@]2HH`(9A +M4`'^'V"@BO\O^/\M0``!X&<"!@`@`OX?8""(_R_T_RU```$`8@'N_R<`?%]@ +M:-@"``!\/V`)`0``((:!C1``?!]@!M(```+^/V#F_TU`(-HJ*`"&85`@!0`@ +M`"`(4O2!#0CX@2T(`(`@4`)^"(``@`U`[`,`$`%^"$(`G!]0``S`&0)ZZ%<* +M$``@+HD&"`+^/V``'`!`_H&-$`!\'V`^D```_O]-0"#/*B@`AF%0`_X?8"!D +M_R_X_RU```'@9P(&`"`$_A]@H&'_+_3_+4```>!A`?'_)P!\7V!HV`(``'P_ +M8$4!``"@8#`H`+X/8(#__R<`O@]@`'Q?8&C8`@"@73`HH?X_0(#__R?P@2T( +M[(%-"`"$`$```R%0!WX`@$$'`"`!_O]A@)G[+Z"C$2CH_RU`Z($-""Z))@@` +M@`!0+H&&$`!\'V`^D````OX_8"[_1D"@N2HH`(9A4*#6_R<`G@=@!#X.$`"> +M^2^/_O]!``'`80!\'V`@]@(``GWG5P$````!`P`@`+X/8`!\7V!HV`(`($LP +M*,G^)T"`__\G````"`1ZX&>"OODG`?X'0"!0*RCW_C]`('(H*`+^'V``"!\( +M8,,"``'^/V``?>!7(T(```&"(%!]_A]@`_X@0*`D`"@`'$=@H`$`(`":IE$! +M_@9```Z@&0/ZYE<*"0`@@)O_+P`!X&>"!``@@,'_+P`!X&``'Q?8'#&`@`J"P$(`/P@0+[E`@`(@(`0+@D!"`J`@!"0_A]` +M(#!7 +M(T(```(#`"``?%]@2,X"``'^'V`"_C]@(&4J*`"&85`!_@A`#/X_8!#_1D"@ +M8BHH`(9A4!?^"$`$_C]@)/]&0"!@*B@`AF%0//X(0`3^/V`<_T9`H%TJ*`"& +M85`*_@A``OX_8"#_1D`@6RHH`(9A4"/^"$`"_C]@(O]&0*!8*B@`AF%0`'P? +M8!F0```"_C]@*/]&0*!5*B@`AF%0`&;Y)P0^#A``./DO``'@9P)]X%!7 +M(T(```3^'V`"?!]@`P````/^/V``_T9`"/]F0""A*B@`"()0`'P?8!?2```" +M_C]@%/]&0*`T*B@`AF%0:?X?@`+^/V`6_T9`(#(J*`"&85"`="8H`#[Y)P0^ +M#A"`%ODO`'R_86##`@``B"8(:?[_@0#]X%=G(/X?8`)\'V`B```` +M!(%&$`#]X%!7(T(``*)`_R\"F@9@ +M`+K^+X`$^2<$/@X0@-_X+P``P&$`?+]AQ+0"``B!!@@!>N!7_?X?0@(#^2>2 +M_A]`H),J*`%^*$"`K2PH"($&"`!\_V%DPP(``GX`@``:`$`2!0`("($&$*`T +M_R\`@`<(()?_+P"`!P@`?#]@ON4"``"*``@"@(`0```?$$B8`@`(@08(`GX` +M@``:`$`3!0`("($&$*#%&B@"_A]@`7KG5P%\'V"TK`(`(0P+*`&"(%``H2PH +M*W\(0*""*BA4?BA``/#X)P0^#A"`P/@O`'R_893%`@`<@28(`(/@9P()`"`< +M@080`'P?8`"0```,_C]@`?Y?8*!K)R@'_G]@`/\&0*"0&2C__S]@``'@9P$$ +M`"``O@]@`'Q?8.37`@"@;2\H8?X_8(#__R<@X/@G`?X?8````%"@WO@G'($& +M$`0^#A``K_@O`(/@9P!\OV"4Q0(`@0$`(""!(@@`@^!G`@,`(`"^#V``?%]@ +MY-<"`*!C+RC9_C]@@/__)P($0`B@9"`H`WX`0*"C&2@`_P)```'@9P'2^"<` +MO@]@`'Q?8.37`@`@72\HWOX_8(#__R<$/@X0`*'X+P"#X&<`?+]@E,4"`($! +M`"`<@2((`(/@9P(#`"``O@]@`'Q?8.37`@"@52\H=_X_8(#__R<"!$`(`GY! +M4``.01B@52`H!7X`0*"4&2@`_P)```'@9P'#^"<`O@]@`'Q?8.37`@`@3B\H +M?/X_8(#__R<$/@X0()7X+R#^GV$`@^!G@@,`(`!\7V#XUP(``'P_8!,`0`@@-``*`"*!@@$@(80 +MD_X?0"`_*BB>_C]`H+WX)R#^GV$$/@X0`(3X+X_^'T(``.!A`(+`80%^"$`@ +M.BHHIOX_0(!&^2\``*!A((7_+P">!V`@1_DO`)H&8`%ZYUN!7"_O_)R#^ +M'V`P@$$0,8!!$#*`01`@@`\X,X!!$``!X&<"?%]@0,X"``%\7V!$S@(``'P? +M8!?2```$_C]@('4I(`"&85`$/@X0(%OX+R#^GV%I_O^!__X_8/Z#C1``?+]A +M4,8"```!X&<<_A]@`GP?8!X````0@4803/X'0`+^/V#^_TU`(&PI*`"&85`` +M?-]A2-D"``7^'V`#_C]@!']'0!#_9D"@T2DH``B"4`'^!T`$_C]@!/]&0*!E +M*2@`AF%0`'P?8!F0```"_C]@'/]&0*!B*2@`AF%0//X'0`3^/V`8_T9`(&`I +M*`"&85"@Y?\O`?X?8"#^'V``@480`8%&$`+^'V`#_C]@`']'0`#_9D`@Q"DH +M``B"4`/^!T`"_C]@'O]&0"!8*2@`AF%0H'?X)R#^GV$$/@X0H#?X+\+^/T`` +M`*!A`'P?8"$!````]2DH`7Y?$,^S`@``?#]@ON4"``":!F`@.RHH:/Y?8(!< +M^"<$/@X0`##X+P``H&$@$BN!7 +M"P,`(`"^#V``?%]@D,X"`"#;+BB1_C]@@/__)P-\``"8Y@(`@$OX)P0^#A`@ +M(_@O)/Z?8:+^WX$`FJ91])L-$/3_#4#\_RU`H&P%*/C_34```>!G`KX/8$(M +M+R@6?B=`_($-"!3^/V`,`D`0:/X_8`X"@!``?!]@ON4"`/B!+0B@'BHH:/Y? +M8``('PA@PP(``'W@5R-"```"`P`@^($-"(#^/V`(&H`0"@*`$`P:@!`.`H`0 +MD?X?0*#.*2@I?B=`_($-"/2!+0@@T`8H#'X`0*!*^"N=7"H(@4/G[ +MX%<+?#]@^?___P?^`$``#@`8!7Y`@`/^!H``!`!``WX`0`"HIT$`J(="``!* +M$`+^`(````=0`H`_4`"*`!@1>N!7"0-)$`L#`"``?#]@:0$``*"Y*2@+_A]@ +M$/X?8`D!21``>N!7B@(`(`O^'V`@MBDHM_X_0````%`)`4D0`"H`0!`%``@! +M_BA"`8!&$`+^YT$%^NA7"A@`(`!\GV)4P0(``R+(`0!\7V*TQ@(``GKG5P!\ +MOV)TV0(`#`(`(`+^'V``(HA!``!&$`+^WV&U>^=7B@$`(+7_WV$`(HA!`!Q& +M$-A[YU>)W_\GR'OG5PP)`"``_`E`)-L"```'(`@0!P`(`GX`0`"``%``"L`: +M$'X'0``L`$``"L`9!?X?8""@*2@`HBA@!?X?8*">*2@`+"M@H-;_)P/^OV'" +M>^=7"9JF4:D!`"`>?@=``?Z_82Q^!T"@TO\G``K`&8```"B`#/@G!#X.$"#7 +M]R\0_A]@`'R_853"`@`4_C]@`/]&0`K^?V`"_I]@(.,@*`"*HE``A08(```? +M$'"8`@`!A08(```?$'28`@`"A08(```?$'B8`@`#A08(```?$'R8`@`$A08( +M```?$("8`@`%A08(```?$(28`@`&A08(```?$(B8`@`'A08(```?$(R8`@`( +MA08(```?$)"8`@`)A08(```?$)28`@"`[O)V`@!7($(```$Z`2``!!\(Q;,"`!)Z +MX%`Q?\G!#X.$("F]R\`?!]@(/8"``````@0>N!G`'P_8H3;`@"" +MR/!G`'R_ +M833'`@`"(@`@`)?E9T$!`"!J!`<(:P0'"````$``&@!`/`4`"'``!Q!T``<0 +M;`0'"``:`$"H!0`(>``'$#B%!@A*>N!71/YF0`+\9D`(`````(8!"`R'!A!\ +M``<0$(5&"`+ZY5<"_>57`0````($`"`,AB$($88!"(0`!Q`2A@$(@`('$(@` +M!Q"@$``@$X8!"%!ZX5>,"P`@:@0'"`Y^(%``C@`8!WK@5Y`"1Q"+`@`@'WK@ +M5XH!`"`!?B!``(X`&)`"1Q``(@!`(`<`"``"(!@2AP8(`('@5PD#`"``@B!0 +MC`('$(@"!Q"$`@<0(`8`((`"!Q`DAB$(*88!"(0`!Q`JA@$(@`('$(@`!Q`K +MA@$(H`$`((P`!Q"``"<($(5&"```?PC(LP(`BX0!"`A^@("*A`$(``A@:`", +M`1@`!I\0!.<"```*GPB^Y0(`%($&$!B)!A`E?N"G"/X^!7BP$`(-Q[X%=,+0`@ +M`?Y_8-U[X%>+`0`@X7O@5\PJ`"`"_G]@XGO@5XL!`"#F>^!73"@`(`/^?V#G +M>^!7BP$`(.M[X%?,)0`@!/Y_8.Q[X%>+`0`@\'O@5TPC`"`%_G]@\7O@5XL! +M`"#U>^!7S"``(`;^?V#V>^!7BP$`(/I[X%=,'@`@!_Y_8/M[X%>+`0`@!7K@ +M5\P;`"`(_G]@!GK@5XL!`"`*>N!73!D`(`G^?V`+>N!7BP$`(`]ZX%?,%@`@ +M"OY_8!!ZX%>+`0`@%'K@5TP4`"`+_G]@%7K@5XL!`"`9>N!7S!$`(`S^?V`: +M>N!7BP$`(!YZX%=,#P`@#?Y_8!]ZX%>+`0`@(WK@5\P,`"`._G]@)'K@5XL! +M`"`H>N!73`H`(`_^?V`I>N!7BP$`("UZX%?,!P`@$/Y_8"YZX%>+`0`@,GK@ +M5TP%`"`1_G]@,WK@5XL!`"`W>N!7S`(`(!+^?V`X>N!7*@$`(!/^?V``AF%0 +M`)?E9RB'!A`""0`@:@0'"`YZX%<+`0`@('K@5PP$`"`A>N!7BP$`("MZX%?, +M`P`@`?X?8"MZX%57 +M`@````'Z_R=0>N%7C"<`(`"7Y6<`!$%0@@<`(&H$9P@._@%0``X`&`=ZX%<` +MHHA@"P(`(!]ZX%<+?`!``0````L.`!@`"`!`(`<`")`&1Q`!?@!0D0!'$`'Z +MY5<"`P`@;`1G"`"B`4``!P`(D`9'$`%^`%"1`$<0`OKE5P($`"!K!&<(`*(! +M0!`'``@!?H!0``H"&)$(1Q"@`0`@D`9'$)`$9PB1!@<(`_R!`&#!`@"2"$<0 +M``G@5PL`8&`*"&)@``G@5Y0$!Q"A`@`@DP9'$``'XE<"`0`@``A`4)0$!Q"@ +MOA4HF'Z'0)$&!PB$`"<(E`!'"),&9PB@NQ4HG'Z'0)$&!PB(`"<(E`!'"),& +M9PB@N!4HH'Z'0)$&!PB,`"<(E`!'"),&9PB@M14HI'Z'0)$&!PA\`"<(E`!' +M"),&9PB@LA4HJ'Z'0(``)PAP``<*=``G"7@`QPA\`&<(A``'"8@`YPB,`$<) +M,(&F"`!\_V$TR0(``)?E9[C_1T`B!0`@-(&&"&H$!P@A>N!7BP$`("MZX%N!7#"D`((``9PA->N%7F``G +M"$D"`"!-_A]@`'KA5PH!`"````!0K``'$$UZY%=)`@`@3?X?8`!ZY%<*`0`@ +M````4+``!Q!-^N-720(`($W^'V``^N-7"@$`(````%"T``<03?KB5TD"`"!- +M_A]@`/KB5PH!`"````!0N``'$$UZXU=)`@`@3?X?8`!ZXU<*`0`@````4+P` +M!Q"1!@<(`'R?8)CF`@``AB!`("SY+P`(0F"1!@<(G``G"(0`1P@`A"!`("GY +M+P%^0D"1!@<(H``G"(@`1P@`A"!`(";Y+P)^0D"1!@<(I``G"(P`1P@`A"!` +M("/Y+P-^0D"1!@<(J``G"'P`1P@`A"!`("#Y+P1^0D"@`P`@`((@4`.(8``" +M_D"``'P!0/R8`@``!@`0`?X@0`7ZX%<+_/\GK`!'"+``!PFT`.<(N`"G"+P` +MQP@$@28)``2!0`*(9```?/]A5,$"``"&1Q``B(1``02""`B!!@@!B$<0`!!$ +M00*4!`%J!"<(`I!'$`"4!$$!!`0)``S#0`.01Q``C@-!`I#D``".!1H$CD<0 +M`)#D0`&$XP@%CD<0`(KB0`*.I``&BD<0`(ZD0`&$H@@'BD<0`@R@``B*1Q`` +M#`!``00`"`#_ID`)@$<0`"`(8"#3^"\!_\9``(4&"&H$)P@`@$<0`84&"+`` +M1P@!@$<0`H1G"`.$AP@`(`A@`/^F0"#-^"\!_\9``(4&"&H$)P@"@$<0`84& +M"+0`1P@#@$<0!(1G"`6$AP@`(`A@`/^F0"#'^"\!_\9``(4&"&H$)P@$@$<0 +M`84&"+@`1P@%@$<0!H1G"`>$AP@`(`A@`/^F0"#!^"\!_\9``(4&"`:`1Q`! +MA08(!X!'$,``!P@!?@!`H)K^+\``!Q``H?8G!#X.$"![]B\H_I]A`'P?8B3; +M`@``?!]@(/8"``````@`?+]AM,8"`!!ZX&"!P`@`"!"0"`'`0@``'\(R+,"`"!^`$``"B`8!X%&$``'`0@(@480BX0! +M"`A^0("*A`$(``0`:*`"`"``@(<0`+X/8"!B+2@=_BA`!X!G`'Q?8)CF`@`"#``@`(9A4*`%`"`'A\8(``J`&`"$@4$`C@!`,`<`"``( +M1A```>)7#`@"8`"$@4$``$80`?YA0`7ZX5<*%0`@`/P!0'39`@`(!0`(```# +M4`"!XE<`(.A@B?;_)Z#V_R<`BH)@````4`!\'V%TV0(`!X?F"*`$`"``H,!` +M`(IA&``$@$$`!D80`(GA5PR&@6``!(!!``A&$`%^`$``$&!`"(5A"`1ZX%<` +MAF-0B@(`(`"'XE=`!X,("?C_)R#X_R<`BF)@`(?B5PF*H1@`!(!!4`=C"``* +M1A``A^)7#(IB8``$@$$`!D80``H?"+[E`@``BF<(`(`A41"+!@@2BP8)`!+@ +MIQ2+Y@@`D!R0`(##0`6-1A``AF%0"(<&"*`#`"`>?J!``X0!`````T``"H!0 +M`)H!0``)0!`!_F%`!/KA5PO\_R<.BP8(`!+@IP"0')``#F!`"H<&"``*@$`` +MF@!`&`<`"``(@$`$!@$(`(`!0``(`%`.>N=7!(%&$*("`"`&AT80!(<&"":' +M9@@`!@!`!(%&$"`%`"``AF%0`X2!``+^H8`??@*(``@`0``"`!@`_()`_)@" +M`````A`!_F%`!?KA5XOZ_R<@`OXO`/\&0*!)]BN!G@C+V)X`+""@`>N!7"0,`(`"^#V``?%]@D,X"`""\+"B` +M_C]@@/__)X`I""B`6?XO@"SV)P0^#A```?8O`'R_81C$`@`#A08(`7K@5X(! +M`"``A08(`7K@5P'_$"@```!0`(%&$`.!1A"@)O8G!(%&$`0^#A`@^O4O'/Z? +M8?C_+4`@`2@H!?Y?8`!\'V`K`0``(+8G*%W^/V#\A4T(``7A9P!\OV$8Q`(` +M@@$`(`2%!@@!>N!7@0D`(`"%!@CZA2T(`('@5X$#`"`!^N!7`@$`(`#J$"B` +M```@`.\0*/R%30CZA2T(^X4-"`*%1A`!@480`(-&$`'^'V``!>%G`X%&$($% +M`"@```!0!(%&$"`F]B<<_I]A#``@"`#\`$#H`0``%`0`"``"`$"@Z/\G'GX` +M0`0^#A"@Y/4O'/Z?89;^'T`@H"""``@@*CV+P``P&$!A08((*8.*`""(%`!A08(``!?$/"L`@`` +M"!\(8,,"``!]X%N!7`N3U)P*%!@C_?P!```_@'R+B]2<"@480`-/_ +M+P'^'V`@X/4G!(%&$`0^#A`@MO4O'/Z?80``P&$```!0__K@5_R!#1`L!``@ +M`(*@80!\7V`,V`(``'P_8.,!``"@9"PH`+X/8(#__R<`CD88_/\-0"!(+"@" +M_C]@_/\-0"`&'2B`_C]@`'P?8`C%`@#\@4T(!/X_8``<9V"@B1PH`)J&8(`@ +M`"`$/@X0H*;U+QS^GV$``,!A`(*@80"`!@C^_RU`H($P*/W_34#^A2T(`OK@ +M5P*$!@@!`@`@%7K@5P(9`"`5>N=7`1@`(``!X&<"`0`@`OK@5P(3`"#]A2T( +MH$<<*````%````!0`)HF8*"5'"C__TU`_X4-"``!X&N!7`>C_)P"^#V``?%]@#-@" +M`*`_+"BC_C]@@/__)P"^#V``?%]@#-@"`*`\+"B%_C]@@/__)Z#"]2<<_I]A +M!#X.$*""]2\@_I]A``"@80`$(`@@0"""0`@````4`""(%`@;QPH_/]-0/R!#0B@SQPH@/X_8``! +MX&<""``@@$X/*``!X&<"O@]@PH!G`@,`(`"^#V``?%]@ +M#-@"`"`C+"C>_C]@@/__)_R!+0B@*2N!7!0,`(`"^#V``?%]@#-@"`"`:+"CK_C]@@/__)P)^ +M`(``?$``4+$"``"$!@@!_C]@`GK@5P&"(%``!>%G@0$`(`!]X5<`!`(`!0,` +M(`"^#V``?%]@#-@"`"`1+"CQ_C]@@/__)R`"`3@`F@9@_($-"/O_+4`@-S`H +M^O]-0/J%+0@@`QPH````4````%#\_RU`(%$<*/G_34#YA0T(``'@9X$%`"#\ +M@0T(H*8<*(#^/V```>!G`@,`((`E#R@``>!G`GP_8`D!```B7BPH`KX/8""* +M]2<@_I]A!#X.$*!3]2\X_I]A``"@80`$(`@@!RP!`(O7_)^R!#1"``P`@`+X/8`!\7V`,V`(`(.8K +M*`'^*$"`__\G[($-"``!X&<"`P`@`+X/8`!\7V`,V`(`H.$K*`_^*$"`__\G +M`(0&"*"#_R_\_RU``80&"/V%#0H``>A7#GXH0`D!`"```^!7"P,`(`"^#V`` +M?%]@#-@"`*#9*R@=_BA`@/__)_R!#0C[_RU`H``P*/K_34#[A0T(`7K@5P$# +M`"``O@]@`'Q?8`S8`@`@TRLHI/X_0(#__R<@:APH_($-"``!P&$"`P`@`+X/ +M8`!\7V`,V`(`(,XK**;^/T"`__\G#`#G"0"?YV<"`P`@`+X/8`!\7V`,V`(` +MH,DK**?^/T"`__\G`X0&"`:`1Q`"A`8(!8!'$`&$!@@`("!0$X0'"``"`$`3 +M@$<0"X0&"!&`1Q`+A`8(OW]`8`%ZX5>??B!@`0<`((+ZX%<+`0`@AOK@5PP% +M`""@>N!7`GW@5^`````!`P`@`+X/8`!\7V`,V`(`H+HK*+C^/T"`__\G`?K@ +M5X(3`"`9_A]@(,`F*+O^/T`@B`<($X0G"`"!X%!+@`@_($-""!)'"B`_C]@``'@9P(L +M`"``R`XH``'@9X$J`"``O@]@H!T`(&7^*$"`2`(H``'@9R("`"`!_A]@((,3 +M*`3^'V`"_A]@$(!'$/J%30C\_PU`H(4K*`/^/V#\@2T((/$;*````%"`'_"'0`@`"'H9P$!`"`" +M>NA7CA@`(`"^#V``?%]@#-@"`*"4*RBC_BA`@/__)PN$)@@@FR8H&OX?8/J% +M+0@@B!LH````4````%#\_RU`(-8;*//_34#SA0T(``'@9P$1`"#\@0T(H"L< +M*(#^/V```>!G@@X`(("J#B@``>!G`0T`(`"^#V"-_BA`@.(K*``+`"``(>AG +M`0$`(`)ZZ%<.`P`@`+X/8`!\7V`,V`(`((,K*-[^/T"`__\G^H4M""!X&R@` +M``!0`'P?8'@9``"@41`H`((@4``"`"#\@2T(^H5-""`C,"@`G@=@H`'U)SC^ +MGV$!>N!7@>;_)P)ZX%"`P`@!(`)"#@! +M"A``@`D(-`$*$([^'T`@"0`@#7XL0`+ZZE>"`P`@-'\*0`"F*6`@3BXH``!` +M8([^'T"@!``@%'XL0`/ZZE>"!@`@-'\*0`"F*6"@7BXH``!`8([^'T`;?BQ` +M@&$F*`"`*0B@8"8HCOX?0`2`*0@@7R8HCOX?0##^!V`#_BI@`(``:`*`1A`` +M$"<8H`0O*`"F"6``@"D(!((&$`2`*0@0^N=7"((&$`(+`"`*?B>``(``4``E +MZ6<`@B!0(00`(``$05``)"=0`OX@@`^$1A`0@D80"/X@B"`"`"`1@D80$81& +M$!""1A`/@D80#(1&$`)^)X`-@D80!GXGB*`"`"`.@D800/KG9P$!`"#_@1]P +M`7X`0`!\`&#__P\`_($-$/R%#0@8_C]@%8!&$/V%#0@!_E]@%H!&$/Z%#0@7 +M@$80E`4*"`&`1A`"(@@`(#DJ*``L:V"@4O4O`*X+8*"[]"=$_I]A!#X.$*"` +M]"\@_I]A_/\-0/C_+4`@S@$H]/]-0!3^/V#\@0T(H$GU+P`"@!```*!A_($- +M"```7PCDKP(`H`03*`K^/V`@2/4O`)H&8*"V]"<@_I]A!#X.$`!X]"\`"!\( +M8,,"``!\OV&TK`(``'W@5R-"``"B!``@/H0F"`"#X&<"_>!7`P````("`"`@ +MGO8O`?X?8""5^R\```!0@#KU+P``P&$^A`8(``'@9P('`""@!``@#/X?8$.$ +M!@@``>!G`@(`(``$'PA&Y`(``7K@5X&0'R@```!0@-D`*"`U]2\`'`=@@)#T +M)P)ZX%_BI`3`B("4H("`@0 +M?H:!```_"`#D`@``&`!H!(``$%`(B`E."`@($'Z&@0`8`&@`@``04@@("`S^ +MX$$*@(`05@@("`B`@!!>"`@(`(,&$`*`21`(?@"0`X!)$`3^`$`$@080"/X` +M0`B!!A`*_@!`#($&$!"?!A`!!$D(`"0)8`">)V`@/"8H`GY!0`$$"0@X`"@( +M`GX`0``.0!H`'DE`%(4&$$,$"`@@=2\H_/]M0/R!#0@`)`!```Y`&D,$"`@` +M`>!G`!Z)0@$,`"``@`@('_X_8"$"0!`(_B"(H*4I*"("0!`??B!@`(`("!X" +M@!`\!`@(`'P_8J2M`@`"@$@0&*D&$`&$2`@`H@A@`"@J8*`J)B@"?D%``80( +M"`)^`$``)`!```Y`&@`>B4(@&28H`)XH0/R! +M#0@`(@!```X@&D`("`@">N!G`0L`(`!\'V#,K0(``00@"`+^0$``!"`(_(4- +M$##ZX%<"_>!7W0````$#`"``O@]@`'Q?8`S.`@"@O2HHI/XJ0(#__R>@#28H +M`)XH0/R!#0@`(@!```X@&D`("`@!>N!G@0D`(`!\'V!8KP(``00@"`+^0$`` +M!"`(W?K@5_R%#1`!`P`@`+X/8`!\7V`,S@(`H+(J*+#^*D"`__\GH`(F*`"> +M*$#\@0T(`"(`0``.(!I#!`@(`GK@5X(3`"``?!]@K*T"``$$(`@"_D!```0@ +M""KZX%?\A0T0`0,`(`"^#V``?%]@#,X"`*"G*BB[_BI`@/__)P">*$`@]R4H +M)(,&$/R!#0@`(@!```X@&C@`"`@`GNA!`)XG8*`0+RC\_TU`_($-"``!X&>! +M`0`@*)\&$``B`$``#B`:#($&"``(``@@>N!G`@(`("2!)@@"A``(!'X`:`*` +M0!`B"`<(`"(`0"(`AQ`@'/0G./Z?80"#X&>"!0`@#?X_8!@"0!`&!"`(H`(` +M(/[_(&`*_C]@&`)`$`8$(`@!_B!H((`/.`8"0!`!^N!7`OW@5P(````!^_\G +M`+X/8"#I*B#,_C]@``1!4!,$0!`*!$`0!`1`$`/^/V`6`D`0$@1`$`;^/V`< +M```(((`/."P"0!`$/@X0H-?S+RC^GV$``,!A#```",/^'X(F?@!`(%X<*/C_ +M+4```!\(X.,"``P`IPD,```(`)HF8"#2)2B`_E]@*/[F01R>!A#X_PU`(%@< +M*#3^)T"@[_\O`)H&8`+^'V!4@$80(HA&"```'P@`Y`(`(,LE*$C^)T`YA`8( +M_GX`8(!^`&@Y@$804/X?8%B`1A````!068!&$'S^'V"@?"4H&'XH0`!\/V`, +ME@(``(``"`%^`$``@``0`!P'8"`.$B@`@B!0?/X?8"!W)2@;?BA`(/3S)RC^ +MGV$$/@X0H,/S+P"2)%$`',=1`)JF40`0!%$`EF51``'@9P".XU"B`P`@`!1% +M40"^#V``?%]@#,X"`*!E*BC[_C]@@/__)P"*HE``?)]@M*P"`*`$`"`!!.`) +M`(QE:`".81D`(>AG`HQD:`*.(1D"?-]A`0````'^HD``G^)7B@\`(&@$8@H@ +M`0`@``S#4`%^PT``)^-7BOO_)P`*8$`"A"$*`W[CIV0``@I__DAB`G)H```' +MZ5>"^O\G`8Q_@`"&8V@`D.$8`')H0`*$P0@!A&$(`OKA5X#^"&*![_\G``QE +M:`".01D`(>AG`@QD:`)\OV$!````H.__)P*.`1E#!`((`GK@5P$=YV%G@0(`(&P.@A`<$$(0&Q)"$!X40A`= +M%D(0`(/@9X&^\R<@OO,G`(Z`$`0^#A``B_,O#7K@5P``H&$%`P`@`+X/8`!\ +M7V`,S@(`(#\J*.7^/V"`__\G@%/T+P`:'Q#DKP(`@%3T+X"O\R<$/@X0`(/S +M+PUZX%<``*!A!0,`(`"^#V``?%]@#,X"`"`W*BC6_C]@@/__)X!+]"\`?%]@ +MJ+`"`#P!(0@`@^97A0``(#P;`1"`2O0O@*7S)P`^#A"@>O,O'/Z?8:/^WX$` +M`*!A$(`-$+?^'V`@-B4H4GXG0+?^'V"@-"4H`)HF8`":!F#__RU`H%,N*/[_ +M34#_A0T(``'@9P)]X%!G@?S_)P%ZX%<"?>!7 +M`@````'\_R<```!0H%KU)QS^GV$`/@X0(&7S+QS^GV&C_M^!``"@8;?^'V`@ +M(24H=GXG0+?^'V"@'R4H`)HF8`":!F#__RU`H#XN*/[_34#_A0T(``'@9P)] +MX%__)_Z%#0@@[O\G````4`!\'V`@^@(``(`/.`0^#A"@7?,O +M0/Z?80`!`&+T_E]"H@,`(`""X&$`O@]@`'Q?8"C.`@"@`RHHXOX_8(#__R<, +M`*@)($X%*`"DQD&@;P4H#(!&$!>$)@@``>!G_O\`8`+\`&@!````%X!&$!J( +M!@@`@`9`'`0@"!V$!@A`>N!G(A0`(`"B*%(#_@!@`WK@5P']X&!'0`@`$0?"+WD`@```>!G@1L`(/"! +M#0@`?#]@A+$"``"``!#T@0T(`?KH5P2``!""`@`@^/\-0`'^/V"@%"0H``1! +M4``5`"``?-]A*,\"``P!!PCH@0T0$`$'".R!#1``"`@(`(`&0/@!X`DP_A]@ +MH,PD*`">)V``"`@(`(`&0/P!``HP_A]@H,DD*``@*&`\B"8(('$M*/#_#4`\ +MB"8("OY`@```85``'@A```8`4!1Z`$`$``%``'K@5XH"`"``O@]@V/X_0""Y +M*2@`?T=`@/__)^B!#1#H_PU```1!4`"&85!@_I]@(#_^+P"*HE"@.?,G0/Z? +M80!\7V!DEP(``'Q_8$27`@`!^N!G`'R?8#27`@`"@`\X``0_"/>L`@`!^N!7 +M`@T`(!1ZX%>!`P`@"0D`(`IZX%<"@`\X```""`%^`$`@@`\X```"$`0``@@! +M?@!`((`/.`0``A`(``((`7X`0""`#S@(``(0#``""`%^`$`@@`\X#``"$#=Z +MX%N!7`A@`(!0``0@!?@!`((`/ +M.!0``1````$(`7X`0""`#S@```$0!``!"`%^`$`@@`\X!``!$`@``0@!?@!` +M((`/.`@``1`,``$(`7X`0""`#S@,``$0$``!"`%^`$`@@`\X$``!$!@``0@! +M?@!`((`/.!@``1`<``$(`7X`0""`#S@<``$0(``!"`%^`$`@@`\X(``!$"0` +M`0@!?@!`((`/."0``1`H``$(`7X`0""`#S@H``$0+``!"`%^`$`@@`\X+``! +M$#=ZX%-$0`@@%?S+P```&*@,!TH`)H&8`":!F``@B!0(`D,*/C_34`!>N!7 +M@?C_)Q3^YJ<`\MQA`'S_8:#F`@#X@0T(!```"``!X&<"^0TH`)P'0`3^/V`@ +MN"XH`?Y?8`":!F``@B!0(``,*/C_34`!>N!7`OG_)R!,\R\`(`A@`'P?8`L! +M```@.B0H`)HF8`#M_R<`1O,OH%XD*```H&$`?!]@`/````"I'"B@1?,O`)H& +M8*"R\B#!``@`'P_8,"T`@``@0`( +M`/Q&8/__Q_\`!`!H`($`$`#\IF$``#@``/WF9Q_W_Q>!EO(G`'P?8$2K`@`` +MFB9@H(<2*``$05"`D_(G!#X.$"!L\B\`!$%0``#@80""P&$!_A]@H)@-*`'^ +M/V```>!GP9#R)PC^'V`$``<0#`"@"1R`&@0@$`0`?X'4``*(!@6@$80__O@5P```%""AO(G +M((;R)Q:`1A`$/@X0(&3R+RS^GV$``,!A`((`8@"B*%(@(O,O_*,-$```H&&@ +M?@`H`"`(8`!\_V&(PP(```'@9P2!!Q!!$@`@`"('$`!\7V*(P0(``"0@0/^& +M(`@@SPLH_/]-0/R!+0@`@^!G@@(`(`BA1Q``O@]@(%PI*%[^/V#\@2T(!(`` +M"``!X&<"`@`@H-[_+P2!!PC\@0T(!```"```!Q#\@0T()B*`$```!P@``>!G +M`@(`(*`1\R\`F@9@H`,`(`'^/V($@0<(__\_8``D`$#_`D`0H`WS+P":!F`` +MH@A@('GR)RS^GV$$/@X0H#WR+R#^GV$``,!A`(*@80```%`@`P`@_($-$/__ +MID'\_PU`!/X_8*!M+B@!_E]@`)OF9P$*`"#\@2T(`!P'8*"T"RCX_TU`^($- +M"`0```@``>!G`00`(`P```@2!``(``'@9P)]X%<$`````GW@5P,```""]/\G +M_($M"`!\!T"(P0(`_P)`$````%`@:/(G(/Z?800^#A"`)_(O`'R_85SG`@`8 +MA`8(``'@9X%0\B<<@`8(``@@"`"#X&>"`0`@@&<&*```(&`<@`8('`!`"``" +M'Q!\YP(`$`0!"']_`&`@2O(G$`!!$`0^#A``'?(OH'D%*`""H&$`?%]@',8" +M```)(0@``^!7`'S_8!3;`@`!$``@``&!$*`"`"``BJ)0`'T#$)()```!_B)` +M`(Z@&`3ZXE>*"P`@#/[BIP#\G``,Y`(``OXB@``)XF<`CL!`@?G_)X+^7T"" +M_G]`(`0`(``'`Q`#?B"``(3@IQ#^/)``B>!7!01A8!1^(4``D$`8`'WA5Y() +M```,^_\G(//_)P`'`Q`"_@:```X`0``!``@@,O(G`!``&`0^#A``!?(O(-+R +M+P``H&$8A$8(`7KA9X$"`"``?']@6.<"``"((0@!_B!``(*!$`)ZX6<`?%]@ +M7.<"``$"`"`(`"$(``(!$`P`(0@$`@$0&``A"!`"`1`<`"$(%`(!$`""(%`@ +MR?(O&`)!$(`C\B<$/@X0(`3R+S#^GV&@P_(O``#`80``(&(!_A]@'`!'"/B! +M31`D!`$(`'S_85SG`@#Z@4T0%@8'"!"$)P@`#@`:^8%-$`"#X&?X@0T(@0$` +M(!B`!Q"@`0`@')P'$!"`!Q`4G`<0``@'"``!X&<9A*<)(@(`(!&$1PJ@+08H +M`!P'8!P`1P@`!#\('L4"``!\?V!\YP(``(/@9Q`$@0B!`P`@`(`A"`S^YJ<` +M@*!``/P\``SD`@``@^)7C00`(!B$)P@`@^!G`0,`(``;Z5<"`@`@&H0G"!*$ +MIP@`@^)7@0$`(`"``1"@`@`@?W\"8`"`(0@`@`!``(`!$(!^`F@0`$$0`"`( +M8"`2`"@`'"=@(*;R+P"B"&`@$O(G,/Z?800^#A"`V/$O____8:`+`"``FJ91 +M`?[&0:!F"R@`'`=@```@8""4_R\`'`=@`_P&`(C"`@#_>^!7@04`(/_[YU!T`$!````('@5XD``"``FN9A``JG&03Z +MYE<+]/\G(//Q)P'^!T`$/@X0@-7Q+P``P&$`?+]A7.<"``"`!@@<@"`("(`& +M$`2`!@@MA&`*+H2`"0R`!A`(?H:!`!Q'0@Q^YZ<`?!]B#.0"``"@/$($B&@( +M!!KI`0"&1U``#`$8`'K@5P"8:6I)`0`@*H2`$"J&@!"`-"!7"?3_)Z#U_R<``@%0(#+_)P'^'V`$/@X0 +MH*SQ+RC^GV$``,!A#```"`""H&$<```*%@8`"`%^`$``#N`9`!P'8"`!!2C_ +M_RU`_X4-"`%ZX%>""P`@^/\-0*!$_R\!_C]@^($-"`P`(`@<@``(`"'@5X(& +M`"`"B``("(A`"``!X5<)`0`@``7A9X(#`"`0A``(`7K@5P$"`"``_@80("(& +M*``!G`/3_``$2`"`*^N"'A`$` +M(`"$!P@``>!G`0$`(``J"2C\@2T("_K@AP,!`"``7`DH_($M"`SZX(<#`0`@ +M`#`)*/R!+0@(^N"'`P$`((","BC\@2T(#_K@AP,!`""`P`^N!G@14`("`#`"`!_C]B(#KR+P`D"6`@.?(O`"0)8`'^*$($^NA7#1$` +M(/R!#0@!HC^``('@9X'\_R<`,O(O``!`8@"B"&``@B!0H.0**/#_34`!>N!7 +M@??_)_"!#0@$```(``'@9PP`(`@!]?\G$H0@"`+ZX%<"_>!7`0````+]X%<% +M````@O'_)P#2#"B@?0LH`*((8`"B"&``@B!0(-H**/#_34`!>N!7@O7_)X#K +M_R<`(_(O```@8O3_#4`@_/XO`((@4`%ZX%<`@B!0@0$`(/2!#0@``>!G@@`` +M(`'^/V``C^`?`@<`(*#!G`0$`((`Q!2C\@2T(!OK@AP,#`"``6!8H`&T6*`": +M!F"@A@,H`((@4/R!+0@#^N"'`[G_)P"X_R<$/@X0@$#Q+P``X&$`@L!A`00` +M"`":IE%`>N!G`ARG88!ZX&!6O$G(`$`*``````'R&02`>``````8X]P("`OD```"@.?$G`?X?8`0^#A"`$O$O&O[_ +MF0``P&%W_A]@H,LB*#_^)T``?+]AJ+`"`#R!)@@@R2(H=_X?8``=YV<"`P`@ +M`+X/8`!\7V`,S@(`(+TG*$+^)T"`__\G/($&"`MZX%<&`0`@"GK@5P8!`"`@ +M+_$G`?X?8*!\_2\+_A]@.($&"``!X&97`@```(()`"`\`0<(`GK@5PT(`"`$B`@(``'@ +M9P/^'V`"?!]@!`````!:_2\@V!$H2'\'0``!X&>!+``@`+X/8`!\7V`,S@(` +MH)$G*"%^*4"`__\G`?KF5P(E`"`\`2<(!OK@5XTC`"`"B`@(`GK@5P(5`"`" +M^N!7C20`(#0?!Q!Q_A]@H)(B*"U^*4`$B`@(``'@9P`@"%("`P`@"N!7`0,`(`"^#V`` +M?%]@#,X"`*!T)RA*?BE`@/__)Z`W_2\&_A]@!(@("``!X&<'_A]@`GP?8`@` +M````-/TO(+(1*$A_!T```>!G@08`(`"^#V``?%]@#,X"`*!K)RA8?BE`@/__ +M)P'ZYE<"F^9G`OWF5P(````"O@]@PL(G*&-^*4"@W_`G`"`(8`0^#A`@N/`O +M*/Z?80``X&&@W_(O`((`8J#@\B\``,!A`GK@5[W^/YJ"`0`@($0.*``$"`B` +M-``@``0?"-SC`@`!>N!7@C(`(`!\OV%PK`(`!H4&"``!X&<",``@!7KG5P4O +M`"``?-]AM*P"`!!^"$`@A!@H"GXG0``!X&>!*P`@(/X?8/^!31`*?@A`(%$! +M*/__+4`!>N!7`@H`(/^%#0@@>N!7"P,`(`"^#V``?%]@^,T"`"!/)R@!_BA` +M@/__)P!\7V"XXP(````A"`&`?X``P``(``8`:`"``!0```$(`$`@"*!1(BB& +M_A]`H?X?8"!0(B@+_BA`@,+R+P``(&`@3B(HH?X?8"R!!@@``>!G`0,`(`"^ +M#V``?%]@^,T"`*!!)R@0_BA`@/__)QA^"$`,@"<(,($&$`#\8$#H`0``&HA` +M"!2$(0@LGP80``(A4`!\?V!LV0(`-(<&$`"0(!@@%QDH;@A'"/^%+0@@^N!7 +MB@4`(""U*R@T@08(-($&"*`-`"C_A2T(``_@'P(!V````!0H*[P)RC^GV$$/@X0(&WP +M+P``0&`@^N!7````4(L#`"``?%]@^,T"``!\/V!L!0``H"(G*`"^#V"`__\G +M``7A9X&3\"<`?+]@M*P"`$.$8@@"^N%7((2""(((`"`D`$$(``7A9P$"`"`" +M!"$(`OK@9X$%`""``P`@!OX@@`#\($!,M`(`)H@@"`#]X&?8#P``@@$`((!^ +M(F@@`0`@(()"$``((F```^)7@8;P)R"&\"N!7XO[?@8XE`"`"A"8( +M(!,B*+K^'V`#A"8(H!$B*+K^'V``??`G(`;[+P":!F"`>_`GN/X?8"`.(B@I +M?B=``'P_8%"R`@"6Q0`(`7K@5P$#`"``O@]@`'Q?8"#.`@"@`"!G`G+P)Z"3`"@$_A]@@'#P)[C^'V`@`R(H-7XG +M0`!\/V!0L@(`EL4`"`%ZX%"^/\G(%CP)R3^GV$$/@X0`"#P+QK^'YH``.!A>/X?8*#6(2A>?BA``'R_ +M8:BP`@`\@28((-0A*'C^'V``G^=G`!S'40(#`"``O@]@`'Q?8`S.`@"@QR8H +M8'XH0(#__R<\@08(#'K@5P((`"`@@?PO"?X?8'C^'V"@RR$H:7XH0`5^7Q#M +MK`(``'P?8````@"`E/TO/(%&"`">!V"@D@XH"OX_8``-#"B`!@`@>/X?8*#$ +M(2AU?BA`/($&"`EZX%<.`P`@`+X/8`!\7V`,S@(`(+@F*'9^*$"`__\G`?[? +M82`M\"<`'`=@!#X.$"`/\"\T_I]A`"`(4@P`X`D`FJ91`/P'0.@!```4!&`* +M'/['01J(!P@`G(E"`"8`4`-^`%#_@4T0`'P_8+ZL`@`@V1'$`>?@!``*0H0*"H\2\`IDE@`?X&0``.H!D` +M`$<0`*0)0``.0!H`)>A7#`8`(`"D"$`!!``(`GX`0`/ZYE<`#F`:B_;_)P"^ +M#V``?%]@@,X"`*"-)BC/_C]`@/__)Z#X!R@`F@9@H`_P)S3^GV$$/@X0@-[O +M+P``P&$,```(`'R_8;2L`@``?"!`Z`$``!Q^($(4A``(`"+@04"(!@@!>N!G +M`((@4`("`"``!!\(.;`"```!X&>!```@`?X_8`".0!J@^_$O`"`(4@`.`!@% +M>N!7BP8`(`3^"$`@J1EG@@$`('"$!@@!>N!7`@(`((#V +M\2\">N!7`GP?8@$`````#B@:`'P_8#"M`@`@J1!G@0,`(`&$!P@``>!G`@(`(`"$!P@``>!G@@``(`'^'V(`#@@8 +M`*/H9P(!X&!7!`````$#`"``O@]@`'Q?8"#.`@"@7B8H&'XG0(#__R<`?#]@```@ +M``#$``@$^N97`1H`<`)\`&#S____`(!`%"`=&2@```!0`,WO)P""(%`&`D`0 +M!0)`$!("0!`(`H`0"@)`$`L"0!`$`D`0$P)`$`P"`!`'`D`0$0)`$!`"0!`8 +M`D`0'``@"`!^@!`.B"`(`@*`$""`#S@```!0!#X.$("S[R\`?-]BZ.,"```` +M"P@:_C^;#``@"@!\OV&TK`(`'(`("`"JJE(,?D!"D/X?8%B`2!`*_@9`("`8 +M*&C^*$``?']B[.,"``"`"0@BJH@0`'X`%`!\_V&XXP(``(`'"`'^/V``?@`4 +M`'P?8_#C`@````P(``(`%$.$)@@@IOLO`"0)8"`!`"``*(I2`"I'%`"W\2\+ +M>N!7`C,`(`!\WV'TXP(``$0'"`&`/X```!\(^.,"``!```@``^!G`2L`(`!$ +M!P@!@#^``(`)"`!```@``^!G`B@`(`!$!P@!@#^``(`'"`!```@``^!G`B4` +M(`!$)P@@-R$H>OX?8""@^R\`H@A@`$0'"```OPG\XP(``WX`@@"@YD(`?#]@ +M<*L"`*!5%R@`K@M@``'@9P(%`"``K@M@H``8*%S^*$`"H`8``7K@9R$%`"`% +M!`D(?W\`8*`%`"`%`$D0`+X/8`!\7V#XS0(`H"`F*#'^+$"`__\G@'X`:`4` +M21`&_A]@(`!)$```"PB@N@TH`?X_8!&$*`B?_@!@`7K@5P()`"``1`<(`(`G +M"`&`7X``P``(``0`:`"``!0`@`<(`$`@""`>(2B&_A]``$0'"`"`*0@!@%^` +M`,``"``$`&@`@``4(`<`(`'^GV(#_@!@`WK@5X(#`"``1`<(`(`I"`&`7X`` +MP``(``0`:`"``!2``0`@>OX?8*`3(2A0_BQ``$0'"`%^`$```$<4`$0'""!Z +MX%<"S/\G`,O_)P%ZZE>!*2,H>_X?8*`-(2AA_BQ````,"``J`!0`@^\G!#X. +M$(!/[R\``,!A`(+@8:`!`"``FJ91`?X&0``.H!D@^N97B@4`(`/^1H```#\( +M_.,"```N"'@VGO)X`+"B@``>!G`FCO)P"; +MYFN!7`0<`("#`#B@`'`=@'``'""#5(2@P?@!`H(0> +M*`":!F"`_A]@$@!'$`Z%!P@!?@!```_@'Z$!`"`.@4<0H/7_)P2`I@D`?%]@ +MQ,X"``!\/V#?`0``H.0E*`"^#V"`__\G!#X.$"`K[R\N_A]@`'R_82S8`@`" +M_C]@7/]&0"!&("@`AF%0````4`3^/V!@_T9`H$,@*`"&85`<_A]@!/X_8&3_ +M1D`@02`H`(9A4"#^'V`$_C]@9/]&0*`^("@`AF%0)/X?8`3^/V!D_T9`(#P@ +M*`"&85`H_A]@!/X_8&3_1D"@.2`H`(9A4`!&[R<$/@X0H!GO+PC^'V``?+]A +M+-0"``""(%#X_T9`@/Y_8`+^GV"@)1@H`(JB4`C^'V#*_C]@>/Y&0`+^?V`" +M_I]@("(8*`"*HE`0_A]@`((@4'S^1D`2_G]@`OZ?8*`>&"@`BJ)0``0?"$3G +M`@``?%]@+-@"``5ZX%<"?>!7!````(($`"``"!\(8,,"``!]X%<@0@```@(` +M("#^'V`R_C]@(`(`(&I_04`@_A]@,OX_8&A_04`"_G]@`_Z?8*`2&"@`BJ)0 +M!?X?8"+^/V"0_D9`D/Y_8"`^*R@`"()0`'Q?8$S5`@`'_A]@`((@4&+^?V"@ +M.BLH``B"4(`F[R<$/@X0H/SN+P+^/V``?-]A5I````!\OV$LT`(`&GX'0(#_ +M1D`@%"`H`(9A4!]^!T`"_C]@@O]&0*`1("@`AF%0'GX'0`+^/V"$_T9`(`\@ +M*`"&85`B?@=``OX_8(;_1D"@#"`H`(9A4"%^!T`"_C]@B/]&0"`*("@`AF%0 +M`GX'0`+^/V"*_T9`H`<@*`"&85`#?@=``OX_8(S_1D`@!2`H`(9A4``_T9`H.`?*`"&85`,?@=``OX_8*#_1D`@WA\H`(9A4`U^!T`"_C]@ +MHO]&0*#;'R@`AF%0&'X'0`+^/V"D_T9`(-D?*`"&85``?!]@!I<```+^/V"F +M_T9`(-8?*`"&85``?!]@!($```+^/V"J_T9`(-,?*`"&85``?!]@!8$```+^ +M/V"L_T9`(-`?*`"&85``?!]@`9$``!K^/V"P_T9`(,T?*`"&85``?!]@`*$` +M`(#^/V`<_D9`(.$?*`"&85``?!]@0*$``(#^/V"<_D9`(-X?*`"&85`6?@=` +M`OX_8)C_1D"@Q!\H`(9A4`!\7V#.SP(``'P?8`"4```"_C]@(,$?*`"&85`@ +MX>XG'/Z?800^#A`@H^XO`OX_8`!\WV$`E````'Q?8,S/`@``'`=@(+L?*`"& +M85``?+]A+-0"``%^!T`0_C]@Z/]&0*#.'R@`AF%0#'X'0`+^/V"F_T9`(+4? +M*`"&85"`PNXG!#X.$*"2[B\"_A]@`'<=*(!&`"@`!``HH'4=*`'^'V``\/\O +M@+S_+P#R&RB@-/8O````4("Y[B<$/@X0`)/N+P!\_V$/D```H)'_+VG^WX$` +M?+]A+-8"`"[^!T`"_C]@BO]&0""G'R@`AF%0*7X'0`+^/V#T_T9`H*0?*`"& +M85`B?@=``OX_8/K_1D`@HA\H`(9A4#;^!T`"_C]@%OY&0*"?'R@`AF%0-_X' +M0`+^/V`8_D9`()T?*`"&85!?_@=``OX_8!K^1D"@FA\H`(9A4`U^!T`"_C]@ +MC/]&0""8'R@`AF%0#WX'0`+^/V"._T9`H)4?*`"&85`A?@=``OX_8.C_1D`@ +MDQ\H`(9A4"=^!T`"_C]@ZO]&0*"0'R@`AF%0*'X'0`+^/V#L_T9`((X?*`"& +M85`7?@=``OX_8/;_1D"@BQ\H`(9A4"5^!T`"_C]@^/]&0"")'R@`AF%0$7X' +M0`+^/V#\_T9`H(8?*`"&85!"?@=``OX_8/[_1D`@A!\H`(9A4$-^!T`"_C]@ +M`)I&8*"!'R@`AF%0('X'0`+^/V`&_D9`('\?*`"&85`S?@=``OX_8.;_1D"@ +M?!\H`(9A4#I^!T`"_C]@"/Y&0"!Z'R@`AF%0`)X'8`;^/V`,_D9`H'XG!#X.$``([B^@`P`@`)JF403_`4`0_C]@H&8?*``$05`! +M_@9```Z@&0_ZYE>)+NXG`'Q_8&3$`@``@B!0!_K@5XGY_R<#_@:```(`:(!^ +M0&@`@@!```8`0`0%0!`!_@!`(/O_)P`.(!@`!!\(`,,"``"`#SB`_G]`0OK@ +M5P'^/V`!@B!0"/X@@`"&0$`-_B&``'K@5PS```@!`@`@"(0`%````6@,@``4 +M@`$`(``$`'`,@``4"(0`%`"`#S@`?)]@``(```!\7V!0L@(```'@9PQ^(H`! +M$``@`?X?8(X!01`,P&`("(``%`'^`6@,@``4`$`?",3D`@```>!G@0(`(`S` +M8`@"_A]@"(``%`+^`6@,@``4C`4!"`%ZX%<"`P`@#,!@"(#^'T`(@``4`/P! +M:``!```,@``4C04!"`%ZX%>"!@`@#,``"`B(`!0`"`!H#(``%``$`"````!0 +MC@%!$`S```@`?`!@_/[__PR``!0(_``4`P$```"`#S@``!\(9,,"``"`#S@$ +M/@X0@-3M+X#-_R^`N/\O@#__+P"I_B^`#/(O```?"&3#`@``HO4O`/G_+Z!4 +M]2\`@B!0@#(;*`#[[2<$/@X0@,_M+P``'P@8Q0(`#'K@5P;Y[2>`FNXO(&8* +M*```H&&@F^XO`)H&8`#V[2<$/@X0@,GM+X"6[B\`?%]@7.4"````H0D`@B!0 +M``(?$&#E`@"@E>XO`'X!$`";YF>!`0`@H`DC*`":!F``[NTGH.WM)P```%`$ +M/@X0@,#M+X"-[B\`?%]@9.4"````H0D`@B!0``(?$&CE`@"@C.XO`'X!$`"; +MYF>!`0`@H``C*`":!F``Y>TGH.3M)P```%`$/@X0@-#M+P``H&$`@D!BH(/N +M+P">YU$``"!B`$0?"-#"`@`!>N!7X?[_0H(!`"`!_O]AH$(-*`'^'V`@?NXO +M!O[?8@```&*@K/$O./X?8`!\WV%0L@(`D`F'"@!\OV(`B`(``"IJ0@`JBD$` +M+$80`)H&8`"F*6`@MQ\H./Y?8``JJD(`K$H0&(0&"`1ZX%N!7,0%' +M$((!`"`!?E\0S^0"```"`"`#>N!7`@$`(`)^7Q#.Y`(```0?"/>L`@`">N!7 +M@@$`(*`B`2@@A`8(((0I"(\#1Q24!0<(./X_8`&`21``A`D(`?Y?8*`S(R@` +M)&E@($WN+P`@"&`!^N=7H0P-*`$``%"@2NXO`*((8`"O[2<$/@X0@'CM+P!\ +MOV%"H>TG```?"&3E`@```>!G@I_M)P!\'V!@L@(`H$D. +M*/__/V```>!G@?G_)P!\7V`HS@(``'P_8&('```@)B0H`+X/8(#__R<$/@X0 +M@'OM+P``8&(`@L!A``2A80"&06(`"")B(#?N+P">YU$```!B`$0?"-#"`@`! +M>N!7@@$`(`'^_V&@]@PH`?X?8``<'Q3`Y`(``!H?%,3D`@`!>NE7`?Y_8`*& +M85``I@E@`!PG8`":1F`0_I]@H*#X+P"BJ&`!^N=7H>X,*`$``%"@+.XO`"`( +M8`"-[2<$/@X0`%WM+P``H&$`@L!A8_X?8*`8'R@`FB9@``0?"`##`@``@>97 +M`0,`(``:7Q#5K`(``)H&8*"A$"@`'"=@@'_M)P"B]2^`?NTG!#X.$*!.[2\& +M?D"``'P_8$RT`@``A`!!-@0D"#@"1!`W!"0((`\`*#8"1!"@=NTG-P!$$`9^ +M((``?!]@3+0"```"H$`VA.((*(3""`&.'X``$$`8`(X#8``-X%<*!P`@``0A +M0`"00!@`"#\((*T"``%^`$``A(!@``@_"%"\`@`FB&((`(8@8`")X&<`#@`8 +M`H`/.`#X_R<@@`\X`(X#8`9^((``?!]@3+0"```"H$`VA.((*83""`&.'X`` +M$$`8`(X#8``-X%>,!@`@``1!&``(/P@@K0(`_W\`0`"$@&``"#\(4+P"`":( +M8@@`AB!@`(G@9P`.`!@"@`\X@/C_)R"`#S@`C@-@!#X.$*`M[2\&?D"``'P_ +M8$RT`@``A`!!-@0D"#<"1!`X!"0(H.#_+S8"1!"@5>TG.`!$$````%``?)]@ +MX+0"`"`$`"!@!4((`GX@@`"&85``B"!`,(<`$`"'`!`!?@!```X`&``%X%>+ +M^_\G`(`/.`9^((``?!]@3+0"```"0$````!0/`!!$#T`01`Z`$$0H`(`(`"" +M(%#__G]@``(!0"H&0!`!_B!`#/K@5PO]_R<`@`\X'`!@"`!\OV#@O`(`"(0A +M"!"`@@@&_D"``'P_8$RT`@``A$!`-@0A"`("(@`D@D$0-@0A"!P`8`@7`D`0 +M$H0A"/[_(&`2@D$0-@0A"!2`8@@"@D$`'``@"!*$``@```%H((`/.!*`0!`` +M?#]@M*P"`$.$@`@!>N)7``!_"/"\`@`A`@`@'`!`"""$(`B`^N!G`00`(`&$ +M(0@D`D$0`?X_8!<"0!`<`"`($H0`""`%`"`!?@!H`GKB5X($`"`(A"$()`)! +M$`C^/V`7`D`0'``@"!*$``C^?P!@((`/.!*`0!`$A"$()`)!$`3^/V`@@`\X +M%P)`$`0^#A"@#.TO!GX@@````&(`?!]@3+0"```"X$$]A$<(/(1G"``&`4`` +M#B`8`'R_8>"\`@!NA08(`('A5P"B*%*)`0`@;84&"``!X5>,).TG-X3'"3:$ +M9PHXA$<*````4#R`1Q`]@$<0(.?N+P=^`8`@@(8(``!@80(F`@``IH="`!;@ +MIT#^'$`'?@"(``X@&2H`2A``G`=`*@0@"`"D!T`J!``(__K@5P'^?V`"AF%0 +M_WK@5P'^7V`"!$%0`)/D9P(!`"``G>E7@A$`(`"EZ5>"!``@`(?A9P$"`"`" +M'`(``('D5XH.`""`#0`@`(/D5PH-`"``#``@`)WI5P$&`"``A^%G`00`(``% +MX6<"!0`@`('D5XKX_R>``P`@`('D5PH'`"```@`@`(/D5PP"`"``!>%G@?S_ +M)R`$`"`!_C]B`(/D5XH"`"``!>%G`@$`(`"!Y%>,^/\G`OX_8@"CZ&>!#P`@ +M`?KH5X(-`"`@G?\O`"`(8``-`"``?-]AM*P"`$,$)P@"^N!7`OW@5P$````" +M!0`@;X4&"`"!Y5>&`P`@``@?"+3D`@``@>E7C`$`(*!S_R\`(`A@0P0G"`"# +MX&>"`P`@;X4&"`"!Y5N%7!X0F""$"`"`(A`<*`?X`0``. +M(!@'@$80G_X!8`%ZX%<"?>%7H`````)\GV`!````$80'"`AZX&="`0`@!H1& +M"`6$1@@`A`!`!X!&$``(`4``#@`8%X1&""#6_R\`("A@$80&")]^`&`!>N!7 +M`1``(``$7P@0L@(`!X0&"``%X%*``<)V"`&0`@`OX? +M8!*`1A``_D@0-(0'"""()@@!>@!@`?X@0`"08!@7A"8(H00`(`+^0(``?)]@ +M?/<"````(@@`AB!```("$```GP@(O0(`@`,`(`!\GV`8]P(````B"`"&($`` +M`@(0``"?"`2]`@``!"(``(8@0``$0D```@$0!X0F"`!\7V#@]P(``?Y@4``` +M(0@`AB!```(!$`!\7V``^`(````A"`*(9@@`AB!```(!$!&$)PB`^N!G`@$` +M(``!X&>"`0`@%X0F"*"W_R\`(`A@H&7_+P`@"&``D.PG`(`/.```/P@(Y`(` +M`(@@"`"#X&<"@`\X@'K@9P!\/V#@O`(``0(`('#]@!"G#P``(`(`(,C_`$!P +M_8`0YP\``+S_`$`@@`\X((``$`0^#A"`6.PO`'S^+Z#7\R\!_C]@`'R_86S# +M`@``"A\(ON4"``C]AA!8`@``)7[@IPC^')"4?B!`&X4&"`3]!A``AY,#`('@ +M5Q2#!A`+"``@&(7&"1F%!@@:A28(H$/N+P%^`$``'>=G`(X`&`("`"`!_A]@ +M&(%&$"`&`"`9@T80``'@9QF#1A`"`@`@@`,`(````%`8@480&8%&$*`=\B\` +M``!0&WK@5PP!`"```@`H`&WL)R!O[B\```!0@&OL)P0^#A"@.^PO````4``( +M/PA@PP(``/W@5R-"``#!;_`O!/X?8``!X&%8NPGH&;N +M+P'^'V``?!]@```$`(#!^2^`7^PG!#X.$``T["\`;.XO`'R_8>BR`@`IA28( +M`?X@0`]ZX(N!7`5KL)X"K!"@#>N!7@5CL)RF%!@@` +M@/Y7!E?L)Z!E&2@"_A]@````4```'Q!(M`(````?$$2T`@`@4^PG*8%&$`0^ +M#A"@(^PO`OX?8(!?&2@`?!]@]+$"`*#Z#"A]_C^8`'P_8%#%`@`(@0`(`($@ +M""#D^B\,?@!`($KL)P```%```%\0>,("``"`#S@$/@X0(!WL+QC^GV$`3^XO +M!7K@5X8(`"`@^@\H_/\-0`!\OV%LPP(``($&"/R!+0@`@"!0!($&"`"!X%>. +M`P`@`'P?8`````$`H/DO`?X?8!"!1A#\@0T(`($&$"!1["<8_I]A!#X.$``0 +M["\`/>XO`7K@5X'/_R^`0>XO!7K@5P!\OV%LPP(`A08`(`Z)!@@!?@!``!`@ +M&`Z!AA`(B08(`('@5P(&`"``L?\OH.L`@`` +M?-]AX+0"``!\7V#@O`(``'Q_8+;D`@```>!G`'R?8+CD`@`B#``@`)[G40C^ +M/V!@`T<0C'\A0!`"`1"4?R%`%`(!$)Q_(4`8`@$0?'\A0!P"`1`D?`$0+/<" +M`"A\`1"0]P(`+'P!$$26`@`P?`$0L)8"`!7^OV%T?R%`(`(!$*`8`"`$_C]@ +M`7K@5X(+`"`$_C]@8`-'$+!_(4`0`@$0M'\A0!0"`1"X?R%`&`(!$*A_(4`< +M`@$0)'P!$!SW`@`H?`$0@/<"`"Q\`1`TE@(`,'P!$*"6`@`#_K]AI'\A0"`" +M`1`@#``@`_X_8`S^/V!@`T<0['\A0!`"`1#X?R%`%`(!$`1^(4`8`@$0U'\A +M0!P"`1`D?`$03/<"`"A\`1"P]P(`+'P!$&26`@`P?`$0T)8"``!\OV%O`0`` +MO'\A0"`"`1`(_C]@`(*!$*`V(B@`'H(0H`4`(``@"%(&?@B``!P`0*(?0!`` +MF@9@H!\`*``@*&"@K?XO`"`(8`%^"$``#@`:('KH5POZ_R<`H_XO`GY?$.ZQ +M`@"`^NLG'`#@"`!\'V'@O`(`"(0C"`;^0(``?#]@3+0"``"$@$`V!$((*03" +M"`&$/X``D&`8(`(`(!0`I`@`A&$8_W\A0`".0!@`#>%7#`,`("8((@@`A^!G +M`?S_)P*$(@`!^N!7@OK_)Q``)`@"A"``)()#$!P`(`@7!$`0$H0`"`%^`&@@ +M@`\X$H!`$!P`(`@(A"`(!OX@@`#\($#@M`(`HH4@"`""0$```#\(_+P"``2$ +M(``#_D"``@@@"`"$X*<0_ER0`!`A&``$@!`@@`\X`((`8`0^#A"@KNLO```` +M80""(&$&_B"``'P?8$RT`@```F!!```?"`CD`@``"``(``'@9P(``&$FD(40 +MH-`7*`"2!&`VA$4(`80?@``1X&>""0`@*80E"``#X5>+`0`@*(0E"``#X5<, +M`0`@(`(`(#:"11"@4?XO`)($8#:$)0@``!\(\+P"``("`````!\0!/<"`*!\ +M_B\`D@1@`!``(``$'PCWK`(```1_"&NO`@``@>%7`0T`(`!\/V#@O`(``?KA +M5P%]X%<"````@@,`(#2```@!?@!``WKA5S2``!""!P`@H`0`(`7^'V`"^N%7 +M`7W@5P$````"`P`@.(``"`%^`$`X@``0`_X?8"`"`"`V@$40/(``"`%^`$`\ +M@``0(%#^+P"2!&`W@$40($'^+P"2!&`@MNLG.(!%$`0^#A``C^LO``#@8:## +M&"@!_A]@`'P?8/2Q`@`@7@PH??X_F``(&`<@`8(`'S_8>BR`@`J`H`0$00'""R!)PCU?T!@$01'$`*(9@@` +M@^%7``0!8(X"`"``A2<(`OK@5P$!`"`(?@%H$0!'$(!ZX&!`0`@H#?^+P":!F```0`@ +M($/^+P":!F`*A`8(``'@9P$#`"`0!`<(?W\`8!``1Q`D!`<(``'H5P(C^2\( +MA4<(!X0&""B%)P@``&%``(/A5PP#`"```^!7"@``4`N``%`+?`!0`0```(`` +M`"`!?@%0('/K)RP`1Q``@^!G`BP`(/!ZX%<+!P`@_'K@5PD&`"#P>@!0!'P` +M0`,````"?@"0("8`(`Y^`$``>N!7#"@`(`YZX%<))P`@(",`(`%^`%`(>N!7 +M"P0`(!!ZX%<)`P`@"'H`4`1\`$`#`````GX`D"`>`"`2?@!`(GK@5PL$`"`P +M>N!7"0,`(")^(%`?_@"(``(`0``"`!@@&0`@%7X`0#1ZX%<+!``@0'K@5PD# +M`"`T>@!0!'P`0`,````"?@"0(!0`(!U^`$!D>N!7"P0`((QZX%<)`P`@9'H` +M4`1\`$`#`````GX`D"`/`"`A?@!`D7K@5PL$`""9>N!7"0,`()%Z`%`$?`!` +M`P````)^`)`@"@`@+'X`0)MZX%<+!``@G7K@5PD#`"";?B!0'_X`B``"`$`` +M`@`8(`4`("]^`$"A>N!7"P<`(*5ZX%<)!@`@H7H`4`1\`$`#`````GX`D#%^ +M`$```$$0((`/.````%`!^N!7`OW@5P(````!U_\G((`/.`'^'V`$/@X0(!/K +M+XS^'V``?#]@FP0``"#1'"@%_K]A`'P_8'"L`@`YA0`(`7K@5X(!`"````!0 +M.8%`$`;^OV&@-^LG`(X&&`0^#A"`%.LO1/X_@@!\OV&\XP(`H*$%*``@"%(` +M?>!7__\``"$$`"``GN=1@),%*```P&$@L20H`)HF8`)ZX%=!`0`@`?X?8@": +MQF&,_A]@(,$<*$7^*$`0@`8(``'@9X(!`"`4@`8(``'@9X$$`"",_A]@H+P< +M*$G^*$``'`=@H&`C*``@*&`">N!7`G[@406>YU$@*.LG`)X'8`0^#A``]^HO +M`,3K+P!^7Q!VJP(`('(D*```H&$``>!G@0(`(`!\/V!@!```(+(<*(S^'V"` +M&10HH,#K+P":!F``&^LG!#X.$"#TZB\D_I]A??[_F8S^'V"@K!PH"OXG0``A +M[2\!>N!7@00`((`=[2\(>N!7`0,`(`!F`R@">N!7@0$`((!D`R@#>N!7`@\` +M((S^'V`@I1PH%_XG0`!\OV&\XP(`$(`&"``!X&>"`0`@%(`&"``!X&>!"0`@ +M@*WK+P``P&$!?E\0=:L"`!#^!D``FB9@()@D*/C_34`">N!7`@(`(`"`!@@0 +M@`80!(`&"!2`!A"``10HH*CK+P`!G@@,`(`!\7V#XS0(` +M`'P_8+$$```@@"$H`+X/8(#__R<@BP\H`"`(4EX(!PCTH0T0"GX`@/"!#1`` +M?/]A9-D"`/#_#4``GB=@(&@D*/C_34#\@0T(]*$-$$H`AQ`0?@"(3`"'$/B! +M#0@`?!]BO.,"`$X`AQ`0?@"(4`"'$%8(!P@`GB=@"GX`@/"!#1#P_PU`(%\D +M*!!^2$``?!]@J*\"``!2'2A6""<("OX@@`"`X*?P\PT0\/\-0`">)V"@620H +M`"!(8!Q\"!#&<0``H('K+P":!F"@[NHG,/Z?800^#A`@P^HOOOX_0````&*@ +M;1PH5/X?8"!ZZR\`HBA2``!`8@!\OV'(K`(``($&"`!\OV(````!``[`&0!\ +M@&(`__[_"W[GIP"@'$``&@!`"7KH5QP%X`FB!@`@`*9I4@IZYU<"?>=7"``` +M``($`"!4_A]@(&$<*,?^/T``C/\O``#@85/^'V"@7APH`)XG8`'^!U`)>N!7 +MC0@`(``2`"`!_C]B`?Y_8@!^7Q!WJP(``"HJ:`".!QB@!@`@``(`:`!\*F#_ +M___^`(X'&`"``&@`?`!H```!`H`#`"`!_C]B`'PJ8/____X`C@<8`(``:`!\ +M`&@````"`($&$"!@ZR\`)`E@"_KG5X()`"`+>N=7@0@`(``('P@2K0(```'@ +M9X$%`"`@%_@O`OX*D``%`"`#?(`!R*P```!\AD$R*P`````&..;?W]_7V^?? +MW]\``*#5_R\*_A]@`?KH5P((`"``?#]@3+`"``"$``@``>!G`@4`(`"!!@@` +M?`!@`/\```A^`(@!>N!7`GW@5P,```#!"?@O"/X*D(```"``_D`0`*?I9X$" +M`""`814H@-D5**`%^"^`_A]`@#C[+U'^'V"@-QPH`!PG8%+^'V`@-APH`"`H +M8%/^'V"@-!PH`)XG8`SZYU>"INHG`'P_8/\!```@A"$H`+X/8`"DZB<$/@X0 +M@'3J+P``X&$`?#]@/0$``*`M'"A8_A]@`#KK+P!\?V#(K`(``(%!"`!\(6`` +M_P``"/[`B09^YZ<`GCQ``(8@0`2%H`D`?$%@_P#__PC^)H``A"!H(#7K+P"# +M`1!5_A]@H",<*``<)V!6_A]@("(<*`">)V!7_A]@H"`<*`":)F`$^N97@HSJ +M)P"^#V"@<"$HMOX_0("*ZB<$_C]@&`)`$`+^7V`9!$`0#_Y_8!P&0!!__C]@ +M&P)`$"(&0!`C!D`0*`1`$"T$0!`R!$`0-P1`$`""(%`D`H`0`(*`82D80!`( +M?H:)*AA`$"X"@!`S`D`0"/X@B#0"0!``?#]@_P,``"8"@!``@H!A*QA`$`A^ +MAHDL&$`0,`*`$#4"0!`(_B"(((`/.#8"0!`$/@X0@$?J+P!\GV!HK0(`H.O_ +M+TQ_`D`'_C]@B`-"$`'^'V```A\0I)@"`*!OZB>/`4(0!#X.$*!#ZB\```!0 +M@)+_+P!\OV%HK0(`B(4&""#E_"^/A28(3/\&0*"&_"\`@B!0`'H5*`!IZB<` +M`>!G`@``4`5^`(``?&!`$*<"``!\OV`,Y`(`H`D`(`""(%``@H!``(@!0!@( +MP`@,_N"G`(J<00`,!A`("``(`(I<0`@`@1`$B`$`!@"!$`""@4`0!`((!`"! +M$!0$`@@*`$$0`?X`0``.(!@$^N!7"_;_)P"``@@`?#]@:*T"`'"!@!`(B`(( +M8%`$!B``@AZ@8`0((@""'R!@!`!G +M`4'J)P"^#V``?%]@!,X"`"#+("@4_B9`@/__)P0^#A"`$>HOH$3L+QK^OYD+ +M>N!7`0,`(`"^#V``?%]@^,T"`"#%("@%_B9`@/__)X`G%RB@6_\O"OX?8'O^ +M'V`@RALH"/XF0(`TZB<$/@X0@!3J+P`$'P@QK0(```'@9R3^7X("`P`@`+X/ +M8`!\7V`,S@(`(+L@*"9^*4"`__\G`'R_8;2L`@`\A`8(``'@9P(#`"``O@]@ +M`'Q?8`S.`@"@M2`H)WXI0(#__R=N_A]@(+P;*"E^*4``?-]AJ+`"`#P!)PB@ +MN1LH;OX?8(`W!"@`$`(H@/7S+X`O["\/>N"'`P,`(`"^#V``?%]@#,X"`*"K +M("B]?BE`@/__)SZ$!@@$>N!7@@D`(#P!!P@,>N!7`0,`(`"^#V``?%]@#,X" +M`*"E("C"?BE`@/__)P"ZZB^@C?4O``#@80":!F`@,OPO`((@4*"YZB\`G@=@ +MH"8`(`">YU$@]OLO````4"`(%R@`GN=1/(0&"*")_"]#A"8(`+\=*`"%]2]# +MA`8(``'@9P!\/V",L`(`@@$`(`">@!`@`0`@````4`"*``B`P0\H@&?U+SP! +M!P@,>N!7@@L`(```'PBLW0(`$'X`0"!L$B@*_B9`(-C]+P'^'V(9A`8(<'X` +M:!F`1A"@`?\O`?X_8EZ(!@@``>!G`@(`(```'PBXXP(`__\_8``"`!1#A`8( +M``'@9X$$%2B`"@`@``'@9P$#`"``O@]@`'Q?8`S.`@"@A2`H]7XI0(#__R<9 +MA`8(SW\`8!F`1A`?A`8(^W\`8!^`1A`@IQTH`*(H4J"?%"@"_A]BH&,5*``` +M`%"`Q`XH`)H&8"`-_"\$_C]@`'$)**`#(R@`H@A@(!/_+P`@"&``0?4O`!X? +M$`CX`@``'A\0#/@"`&[^'V`@?QLH!_X_@#P!)PB@?1LH;OX?8`#MZ2<$/@X0 +MH+OI+P```%```#\(2.0"``!\OV&PW0(`((!`$"#^'V`%@$`0`(`&"$#^/V`` +M`D`0(-01*!!^`$``@`8(H-(1*`1^`$"`WNDG!#X.$*"TZ2^!_A]@HO[?@:!P +M&R@U?B=```0?"*[D`@```>!G`@8`(``K`B@">N!7@00`((`I`B@#>N!7`0,` +M(`#=\R\!>N!7@0$`((`U!"@`>N!7C`4`(('^'V`@9QLH0WXG0``$OPELL`(` +M`#P'*"`T_R\#_A]@H$T'*`":!F``S^DG@-7K+P%ZX%>"`@`@`-;K+P%ZX%<" +M`0`@`*<'*`#+Z2>`T>LO!7K@5X+)Z2<`TNLO`7K@5P+(Z2<`?%]@M*P"`%X( +M(0@`@^!G@0$`('$$`0@``>!G`L3I)P"#X&>"`0`@<`0!"`%ZX%>!P>DG@?X? +M8"!4&RAA?B=`@*/^+P%ZX%>"ONDG@?X?8"!1&RAG?B=`@,X&*`%^7Q!+L`(` +M`+OI)P0^#A"`C>DO@,+K+P`!X&>!M^DG`'P_8`(#``"@2ALH@?X?8`!\OV%, +ML0(`((,**`3_!D`D@08(`7Y?$*WD`@`!?@!`)($&$`!\'V````$``!#W+P"O +MZ2<$/@X0@(SI+P```&*@'1PH`(+`80"YZR\'>N"'@P$`(`!/!"@``>!G@0(` +M(`'^'V````<07?X?8*`<`""I_C]@`'P_8I3#`@`"B0@(`GK@5XL"`"`!_A]@ +M```'$%W^'V"@%P`@L/X_8`P`J`D<@"8("(3@"2#ZYU<+`P`@`+X/8`!\7V#$ +MS@(`H"D@*+K^/V"`__\G```?"/SC`@`#_D>```0`0*!2$2@T_B!```'@9P(& +M`"``?#]@G)8"``"```@!?@!``(``$`7^'V`2@$80`'X'$"#:]R\`(`A@H`<` +M(%[^'V```!\(N.,"``&>/X``0``(``/@9P'^7V`"!0`@`'P_8)26`@``@``( +M`7X`0`"``!``!`<07_X?8`">)V``'QLH`([I)R#G""@`F@9@`HD("`%^`$`" +M@8@0H&/W+P":!F"@VQ@H`"`(8(#^'V`2@$80((CI)P!^!Q``?%]@:*\"`-`% +M(0@``^!7`8`/.-`!01```>!G`@``4`%\'V`!`````!7_)P0^#A"`5NDO`'S? +M8:BP`@!H!0<(``'@9^+^_X$"`P`@`+X/8`!\7V`,S@(`(`0@*"?^)T"`__\G +M:@4G"`'ZX%<"!``@D`4'"`%ZX%>"`@`@(+$<*`'^'V````!0D`%'$&H%)P@` +M?+]AK-T"``'ZX%<`@$8(`@,`('!_!T`@U!$H!'XA0(1_!T"@`0`@0'\G0(1_ +M!T`$?B%`@-`1*`"`)@AP?P=`(,\1*!#^($``?+]AM*P"`$.$!@@\_B9```!? +M$&NO`@!H?P=`($(;*"C^7V!#A`8(``'@9P(1`"`@A`8(C`4G"%Y_`&!`?@!H +M((!&$!^$!@@`@^!G`GP`:`0````!?`!@^____Z`.`"`?@$80((0&"#]^`&`@ +M"``@(7X`:""$!@A??B!@4H@&"!5ZX(<#!``@0?X`:""`1A``O@]@`'Q?8`S. +M`@"@X!\H=_XG0(#__R>__@!@`7X`:"`$`"`@@$80`7K@5X'T_R<">N!7@?7_ +M)P"^#V"@-2`H?_XG0(`)`"@X@`8(;/XF0"!K]2\!_E]@,`$'"``!X&<"`P`@ +M`+X/8`!\7V`,S@(`(-0?*(7^)T"`__\G(#OU+T.$)@@`?!]@```"``"E]B\` +M1NDG!#X.$(`7Z2\`?+]AM*P"`$.$!@@``>!G`@L`(`!\'V!4K0(`.(`&$&3\ +M!A!HK`(`(`<`(`C^/V``?!]@9*T"`#B`!A!D_`80@*P"`*`#`"`$_C]@`'P? +M8'2M`@`X@`809/P&$(RL`@`,_C]@(`4`(&B"1A`!>N!7@??_)P)ZX%DG!#X.$(#^Z"\````(!7K@5PXJZ2<`?%]@4,X"``!\/V`S`0``H+0?*`"^ +M#V"`__\G`'R_8$SD`@`@`P`@`(9A4/#^(&```B%H.@)"$`'^(4``CF`8``8@ +M0`.$(`@`@^!G`(I!0`$&`"`$`D$0`(0A&`"*@$`!^N%G.@0B""+X_R<`!$`( +M#_X@8`1^08```B%HH/;_)P".(!@`@B!0!`)!$``$(`@"!(`)`()`0`$$(`@( +M?H:!`)@@:``*`4`@@`\X5@*`$`!\/V!,Y`(`(/$:(&#^7V`$/@X0H.;H+XS^ +M'V``?#]@1@8``("D&BB`X",HH#/^+P3^'V``?+]AM*P"`%Z(!@@``>!G`KX< +M*````%`@$^LO<(!&$`MZX%>!`@`@`/D5*```'PC@XP(`H#$'*`""(%"`(`@H +M`7Y?$':K`@"`W?HOH,(,*$.$)@B``^DG!#X.$(#CZ"\``,!A`'S_893#`@`" +MB0<(``'@9P""(&*A`0`@@OY?0@)ZX%>,!``@#H4'"``!X&<"`P`@`+X/8`!\ +M7V#$S@(`((8?*`%^*4"`__\G#`"G"6+^'V`<@`8*H(L:*``<)V`P!`@(#'H@ +M8($!`"#\?@!@2'K@5P(J`"`.A0<(``'@9P(#`"``O@]@`'Q?8,3.`@`@?!\H +M#WXI0(#__R?_?P!`#H%'$`'^'V``@`@0$80&"*!^`&"@>N!7`0D`(*`]""@` +M'`=@#(`&"``!X&"`P`@ +M??X?8"!M&BB@_C]`H",$*``"!P`@$80&")]^`&`! +M>N!7@@4`(`""'"@`?#]@$)8"``"```@!?E\0(ZT"``%^`$"@^APH`(``$#`$ +M"`CP?B!@4/K@5X+1Z"=\_A]@(&`:*%%^*4"@%@0H`!P'8(#.Z"<(^N!7`0,` +M(`"^#V``?%]@Q,X"`*!2'RA9?BE`@/__)P`!G +M@0,`(`":!F`@D/8O`((@4`*)!PC_?P!`H,3H)P*!AQ`2A`8(!'K@5P$#`"`` +MO@]@`'Q?8,3.`@"@1Q\HL_X_0(#__R>`_A]@H+[H)Q*`1A`$/@X0@);H+P`` +MH&$`?/]AE,,"``*)!P@``>!GN_X_0@$!`"`">N!7C`0`(`Z%!P@``>!G`@,` +M(`"^#V``?%]@Q,X"`"`\'R@!_BA`@/__)PR`Q@EB_A]@'``'"J!!&B@`FB9@ +M,`0("`QZ(&"!`0`@_'X`8$AZX%>"$P`@#H4'"``!X&<"`P`@`+X/8`!\7V#$ +MS@(`(#(?*`W^*$"`__\G_W\`0`Z!1Q`#_A]@$@!'$*#U!R@`F@9@#``'"``! +MX&>!!0`@`&\)*``!X&N"'HO[?@80#`"`$@08(`'W@5P````("!@`@`'\@ +M*`-ZX%>"!``@+_X?8*`7&B@@?B=``?X?8`B!1A``?!]@```@`(#@]2^`@.@G +M+_X?8"`3&B@H?B=`@)T:*`!^Z"<$/@X0`$[H+X"#ZB\*>N!7`GW@5PD````" +M?>!7!`````)]X%<#````@@,`(`-ZX%<"?>!7"0```$&:_2\(_A]@(#D6*``` +M`%"`DQHH`'+H)P0^#A`@3.@O(/Z?82!YZB^G_O]!"'K@5X$$`"``=^HO`GK@ +M5P$#`"``O@]@`'Q?8%#.`@`@^!XH`?XG0(#__R?4_A]@H/X9*`/^)T``?-]A +M+.8"```$!P@#>N!7JO$:*`'^OV$`;NHO"'K@5P*:IE$`F^9G@04`(*!&^B\` +M``!0@$?]+P`!H&$"`P`@`+X/8`!\7V!0S@(`H.L>*!/^)T"`__\G`%05*`"; +MYF!7__\```$"`"#\@0T(`('@ +M5X8``"#\@PT0@`@:*/R!+0@)^N!7!0$`(``!X&<"`P`@`&H:*`!\'V"TK`(` +M(&[Z+P""(%``!P`@``0'"`'^/V`$>N!7"X(@4`5ZX%N!7@00`((!-ZB\$>N!7`0,`(`"^#V``?%]@4,X"`*#.'B@!_BA`@/__ +M)]7^'V`@U1DH`_XH0"`$%B@!_A]@H$;J+P'^'V(*>N!7`B`(4@!\'V"TK`(` +MH%?Z+P""(%"@!P`@`)JF413^YJ<`?/]AC+$"``*>'````>!G`/+<88$"`"`` +MG`=`H`,7*`""(%``'N=!`/Y'$`'^!D``#J`9!/KF5POX_R<`(>AG@04`((#2 +MZ"^@#/TO``"@8:!3_2\)_A]@H-+H+P":!F`@$/HO`?X?8(`*`R@``0`@H$_] +M+PG^'V#5_A]@(+X9*.K^/T"`+.@G`'K@5P"`7U#+`0`@`(0`$`"``!```$!@ +M0'Y!0`=^09``>N!7`(0`$`H!`"``A!]0`(``$`"`#S@$/@X0H/?G+P`$05`` +M@J!A`'P_8`"````/_I]@``"@8``$84``@F%``(AA@/]_@D``B^%7#H1`0`Z& +MHE``A2`8@OO_)P=^P8$`!.&G`',`4`(%X6<'?@"`(D[I+P($(4`"',!!`)P& +M$"`5Z"<```!0!#X.$`#GYR\`9``H``'@9P$1Z"?__Q]@H#,6*!S^/V``80`H +M`WK@5Z'J_"\`FJ91`'P?8)3"`@`$&P`0"!M`$``;0!``&E\0=ZL"`"`+`R@! +M&T`0`!H?$$3F`@"`!^@G!#X.$"#>YR\@_I]A``!@8`!\7V"@SP(```$!"`"" +M(%#X@0T0!`$!""!4`"C\@0T0``'@9X(1`"`@'`$H`?X?8`!\OV$PY@(```$` +M(`'^`$``#B`8&/[@IP":7$`A!`$(``'@9P$!`"``@^%7B?O_)P!\WV&4P@(` +M``-'$`_^'V`?`$$0'OX&0`!R`$`&?@!`('8A*/C_+4```>!G`@$`((#C!BB` +M`P`@``4'"`!\/V!Y/@``&'[@IR3^!D"@508H`'(`0"`"Z"<@_I]A!#X.$"#" +MYR\L_I]AZ/\-0`""(%`@<^DO&/Y?8-#^'V#H@4T0````4.F!31``?+]AOJP" +M``":!F"@3!`H[/\M0`!\'V#C_#4`` +M@B!0H&/I+QC^7V#0_A]@Z(%-$````%#I@4T0`'R_8;ZL`@``F@9@(#T0*.S_ +M+4``?!]@W)@"`"`[$"CR_RU``)H&8*`Y$"CX_RU``'P?8I7!`@``!`@(``'@ +M9[3_S4$"`P`@`+X/8`!\7V"`S@(`(%H>*.'^/V"`__\G`*(H4@!\_V$PY@(` +M(`<`(``?BE`'P0)"`)^`$`` +M&J!!`?X(0``.(!H`!`@(`('H5XOX_R<:A"<(`)P&4``.8!CH_PU`H&@`*``< +M1V`@T>"`0`@^($M"``#YU<&`@`@````4!"`!A"@P?\G__\?8!"`!@@` +M@`!`H+__)Q"`!A```!\(F,$"``"`#S@$/@X0((#G+P```%"@>``H`((@4(#[ +M_R\#>N!7`@,`(``$'PCPK`(`($@`*`""(%"`?`(H`(+\+P!\OV&4P@(``(4& +M"!A^X*<`_!Q`,.8"`"X$``@(>N!G!/X?8*"\`"@!``!0(%7[+P'^'V``P/\O +M`%`;*````%`@G>!T`!!``(`(1&"`)^`$``#F`: +M`)X)0``.X!D`A>=7B@,`(`"J"F``G"=`(&CI+P`>05``I@=0`(1&"``.X!D` +M)@%0`(!&$``.`!@`@>=7BA\`(`"N!7`@0`(`#$_R\``>!G +M@@$`(`.B2A`@!``@`"0I8*`"`"`$_C]@`ZA*$*`!`"``*"I@`OX_8`."2A`` +M'@=``00`"`)^`$``'@!``(/@9P"$1@@BU_\G``[@&0'^9T(`G`E``)PG0*!) +MZ2\`'D%0#_X?8`&`2A`0_A]@`![G00"`1Q``A`8(`7X`0`"`1A`@U?\G`([I +M&0```%"@;^@O&/Y?8!P`*0@1A``(('X`:!&`0!`<`"D( +M$H0`"/-_`&`2@$`0`WX'0"(`B1`&_A]@5`!)$`?^'V!5`$D0"'X`B""1'"A6 +M`$D0!WX`8%(`B1"@_A]@.0!)$`">!V`@,/,O`((@4````%`X`$D0"`")$$B` +M21`!_A]@28!)$$JB21!+_@E``"`H8"#4Z"\`'$=@`)H&8*!>!2@`@B!0@#KG +M)P``'PA$Y@(`````.`0^#A`@"^!`P`@``4'"!A^X*<`_#Q`,.8"`"Z$``@( +M?@!H+H!`$`";YF`&P`H@/SF)P-\@`&(R@```'R&0:(R```` +M``8X[??Y`0`[_R^`^.8G`/CF)P0^#A"@S^8O)/Z?80``P&'\_PU`^/\M0"`: +M]"_T_TU`_($M"!3^'V``@(`0^(&M"0`=YV<5_A]@`7P?8!8````,@$80`(@` +M"!!^`%`.@(80H/X?8`V`1A`0_@9``((@4*!TZ"\$_E]@``0?")3!`@#\@2T( +M&'[@IP#\'$`PY@(`(P0`"!"`1A#X@0T(('_U+PQ^`$"@^>8G)/Z?80``7Q"< +MP0(``(`/.```'Q"8P0(``(`/.`0^#A"`N.8O`'S?893"`@``!0<(&'[@IP#\ +MO$%.Y@(``"3]+R"3^B\```!0`(P:*"#K$R@+_A]@%'\'0""&!RA]_C^8@"O_ +M+P-ZX%>"`@`@`+W[+P"H`2@%A`8(H'?_+P""(%"@W/\O`?X?8(#5YB<$/@X0 +M`*CF+P"#X&<`?+]A,.8"`('1YB<&""`(`/K@5P!\?V"4P@(`#`,`(`"%(0@8 +M_N"G`)I<0"X$(0@!_B!H+@)!$`@((`@""$`(``/A5X$#`"``A2$(&/[@IP": +M7$`N!"$(`OX@:"X"01`""$`(#@@`"``%X%IV$`HLAA`!WG9X$2`"`, +M`(<*``C'"OS_#4``@B!0(*8-*`"F26`(`"<*`*/H9X(+`"``!`D(`WK@5P'^ +MOV*"!@`@"OX?8/R!31`,``<(#00`""!ZX&<"`@`@(`(`(````%`,_A]@_(%- +M$`'^'V"@Z_\G_8%-$`EZX%@Z?\G`)KF80`(!P@`&N!! +M!/X?8*#F_R?\@4T0!'X(0"#^/V`@;2(H`?Y?8`0`"`@`@"L(`('@5X+8_R>` +MU_\GH`'G+P"R#&`@:N8G2/Z?800^#A"@+^8O&/Z?80``H&$`F@9@($08*/S_ +M+4#\@2T(`(/@9P$"`""@>04H`)H&8`%ZX%<"^_\G(&CF)QC^GV$$/@X0("_F +M+RC^GV$@!``@`"`(4J!#&"@`G@=@````8J!6$"@(_A^`H/+_+P">!V````!0 +M_/\M0"`?#2C[_TU`^X4-"``!X&T)`'S?8:#F`@`4_N>G`)P<0`0` +MH`D$?@=`_H5-"`!R`$`@3"(H!/X_8/Z%+0B@-!@H`)X'8`"?YV<```!B@@@` +M(``@"%+^A2T(``/H5P;I_R<`H`9`!WX@@`P`!P@``B!`!/X`0*"4&B@(_B!` +M`!P'8`3^/V"@02(H`?Y?8*#X_R-]O\G`WR``!7!0(`(`2A!A"@]P\H"($&"`BA!A`@D_\O`!P'8`">!V"@ +M_^4G)/Z?800^#A"@PN4O__\?8"`.%"A"_C]@`!S'40!\OV$@Q`(`H.D`*"R= +M!A``G480````4*`O`"@!_C]@`.;E)P0^#A"@P.4O*/Z?80``X&$`@L!A^/\M +M0""_%R@(_E]@`!WG9P!\OV$@Q`(`@7\`*`-^)X``F@!""@4("`%ZX%>,!P`@ +M(!<`*``+ +M]_\G`!P'8"#HY2"!@`@^X4-"``!X&?_?P=`(?O_)P$. +MP!D$_T9``OX'0``"(4"@K!`8$0`?X?8`H!2!`@`0`H +M`!P'8(#N_R<"?@"``'P_8"#$`@```D!```@?"`JM`@`<"6$(``;@IQX)`0@` +M<@!``!``&!1ZX%<4?@!0"1!`&#")``@,!$%0``'A5PJ`#S@PA8`0`!`!&`I^ +M`(`T@0`0````4#B!`!``?!]@..8"`#3_($"@,1\@`()`8`0^#A"`C.4O``&@ +M8:$!`"``@L!A`!WG9P$#`"``4P`H``(`(````%`*@4`0`?X&0``.H!D#^N97 +M"K#E)P/^!H``?"!`(,0"``J%``@!>N!7#/K_)P`=YV<"^?\G!'K@5ROE_R\+ +MF@9@`/C_)P``8&"@`@`@````4`""85``D&$8`7X`0``0`!@`@^%7"OW_)R"` +M#S@`!H$0``B!"``)X%>*`@`@`'R?8"#$`@`L!P(0*`-"$```@1``@`\X``0? +M""##`@``@`\X!#X.$*!QY2\<_I]AH+<2*/C_#4``?+]A(,0"`/C_#4`@&A\H +M-/\F0`%ZX%>!`0`@`)[O+P%ZX%<"`@`@^($-"#2!!A#\@0T(.($&$#3_!D`@ +MI^4G'/Z?80`('PA0PP(``(`/.`0^#A`@;^4O*/Z?8=#^/T(``*!A``@?"`JM +M`@"@+0`H_H&-$*`&`"``',=1(,;_+P```!X`0!X)``@`?']@6SX` +M```<)V"@X_\O_O]-0`%^!T``#L`9`WKG5PHC`"`#?@>``'S_82#$`@``'D!` +M"@4!"`1ZX%<.&0`@`+X/8*`=`"`9_BA``)OF9P$5`"`"?@>``!X@0!R)``C_ +M?P!``!'@'R(2`"`<@8`0`OX?8`H!01``A0<(`'Q_8%L^```!?@!``(%'$"`, +M`"`>B0`(`GX'@``>`$(`F^9G'`D("($&`"```>!G`@0`()3^'T"@!A"0@( +M`'Q_8!$^````'"=@_O]-0`#&_R\@I/\O`!P'8(#A_R<#?(`!--<```!\AD'- +M-0`````&.+[,M-X"`````?KF5P+=_R<`O@]@VOX_0`!)'"@`V_\G_HD-"`I^ +M`(`@4O)/Z?81"`#1`4@@T0`WX!@`!\?V`@Q`(` +M``8`0A2(#0@&"2@(`('@5P("`"`6B`T("`DH"`"!X%=G@1``(`H% +M"`@#>N!7!06H"8(-`"`("0@(!@DH"``"`$``$``8``@_"`JM`@`@G/\O_O]- +M0*`(`"``@`90@-<6*`@)"`@&"2@(``(`0``0`!@`"#\("JT"`*"6_R_^_TU` +M'(DG"``"`%``'>=G`!"@&8$!`"`%!0@(`!H`4``0H!D`G>97`@,`(`'^'V"` +M..!G@B+E)Z"#\B^` +M_A]`@+;U+X`@Y2<$/@X0(/CD+S3^GV&@.Q(H^/\-0`!\WV$XY@(`^/\-0``< +M)V`@K!XH\/]-0/"!#0@`"#\("JT"``I^`(@`$``8('#_+^;_34```*!A```` +M4.R!#1#FB0T(Z/\M0.B!#1#P_PU`(*0>*/#_34``'`=@\/\M0""-'B@`'$=@ +M(`T`(`""(%`#_@"``'R_8"#$`@``"H!`"@5""`!ZX5<,"``@!'KA5PH'`"`" +M_@"```I@0!R)`0@`&@!0'(&!$``1X!\!?>%7`0```(("`"`"_A]@"@%"$`"% +M`@@!?@!``(%"$`'^`$``#B`8`_K@5XOR_R<@@(Q,H0OX_8*`2Y2AG`HK`40$=G@0H`(``(@E`$@`8*`((@4*`"`"``($A@"`!A +M"`'^($``!(%@`(9!8`"=X%<%_?\G"(@F"`">Z$$`G"!0"(*&$``*)T``@H<0 +M`((@4`@"`A`@`0`@!(0&$``@"%*`AN4OH.7D)P`@"&`,`"`(`'Z`$`#\(&`` +M_O__((`/.`P"`!`$/@X0(*_D+P``8&``@H!@(`0`(`!^`1"@^?\O`(8!8``` +M`0@!?@!````!$``&`A`(@&$(`(?A9X'5Y"<`^_\GH```(````%`$/@X0@*CD +M+Z!UY2\``*!A````80!\?V"`IP(`,(`!"``!X&<"`0`@,/P!$``$`@``^N97 +M`?[_8`*.XU``"()0``S#4*`%`"``AD%@%`@!"`":H$$``@!`%`"!$`"``0@! +M?H)```(`0`"``1`$?L-`#'Y!0`-ZXE<*$``@`(X#0``,`$``?*!`#*<"``X( +M`0@`B2((``(`0`X`@1``CB89`(X`&``:`$``@>17AO/_)P3^)(``AD!!-Q)% +M$#8(11`P@`$("?YD@0"`!4!```40-/X!0``"8$&@V/\O`)8%8!```0@0%@$0 +M/``%$`'^!$``#B`9(/7_)P")(@B@6>4O`!`$8`"TY"<$/@X0()+D+RS^GV$` +M`"!B````4`*$R`GX@0T0#'[GIP#R'&(`?+]AC*<"``#RYD$`H@A@^/\M0*#. +M_R_\_TU`@$WE+_B!+0@$@$<("(0`$`B()PC\@4T(`(0@0`B"AQ`$H"8`!*(' +M$`"$(%``H`9"($KE+P`"B!``'>=G`@$`(("G]B^````@`%7S+R"TY"!G@?/_ +M)_R!#0CU_RU`H$0?*/3_34#TA>T)$?X?8*`A%B@`GB=@]84M"`/ZX%>"`0`@ +M(!\6*!+^'V"`\?\G_($-""`"!S@`FB9@````8A'^'V`@&Q8H`"`H8`"?YV"`P`@()T+*/R!#0B`_C]@#`!`"*"]^R\1`D$0]84-"``!X&>"W/\G +M()P+*/R!#0@``>!G@=K_)P)^`(``?$``4+$"```%X6>!`0`@`'WA5P`$`@`% +MU?\G`+X/8`!\7V`,V`(`H/@:*$[^*$"`__\G$?X?8"#_%2A7_BA`H'OD)S#^ +MGV$$/@X0H#KD+Q3^GV$`"#\(O-<"`/R#C1``"#\(8,,"``#]X%N!7@@4`(`!\/V#\S`(``($`"`%^`$``@0`0"GK@5P4$ +M`"``?!]@````!`#%^R\``@`@````4`!\/V#\S`(``($`$`2`[0L@@`\X$!!N +M"P0^#A``-@X0`#AN8R!^CE,0&@X0%!P.$!@>#A`<(`X0``#@80""`&(`!,%A +M`)JF40!ZYU>,!@`@@`\`*`%ZX%>"`@`@`'P_8/S,`@`$@0`(`7X`0`2!`!`` +MG@=@@.,=*`'^ID$`&^=7B?G_)P!\/V#\S`(`!($`"``!Z%>-`@`@`'P?8``` +M``2`K_LO`?X?8``!`"````!0!($`$!``K@D4`,X)&`#N"1P`#@H$@.T+((`/ +M."`0;@L$/@X0`#8.$``X;F,4?HY3`'P?8`P`(`B`V>0O`'P_8``1,`#\@PT4 +M`'Q`8````0`#?B!@_,$-"`````@`?`!@`````0!ZX5<"`@`@`/K@5P(!`"`` +M>N!7`0,`(`%ZX5<"`P`@`?K@5P("`"``>N!7`@$`(`'^'V"````@````4`2` +M[0L@@`\X%!!N"P0^#A`@^.,O````4`!\OV%`LP(`+(`&$#"`!A`T@`80H(D& +M*#B`!A"@B`8H1(`&$$B`!A",_P9``((@4*"DY2]0_E]@W/\&0`""(%"@HN4O +M4/Y?8`'^'V"@@@8H6(`&$&"`!A`!_A]@7(!&$%V`1A`@%N0G7H!&$`0^#A"@ +M[N,O1/Z?80!\WV%`LP(`6``G"```H&$!^N!7-``'"(('`"``AF%06`8'$*`# +M`"``AD%@`!H`0`)^(8``G"!`C)L`$-R;`!`!?D%`%'KA5P7\_R. +M"@`@.``'"#P`9P@P`$<(`("!0`)^`8``'"!`W($`"-R'`!````)0.``'$`%^ +M`4`@,.4O%/X_8*!@!B@P`@<02``'$#@`!P@@+>4O%/X_8"`!`"!```<00``' +M"`"!YE>.!P`@``B"4`/^9E``"$)@(`,`(``(`F``@`%``GXA@`"<($#%_/\G.``'$$`&!Q`P"`<0/``'"```'Q`0^`(`?`$'"$P`!Q!< +M!`<(``'@9P$$`""`3P8H8``G"``"`%``?>!7W`4```X!`"````!07`!'$%T$ +M!P@``>!G@04`(`!*!BB(`2<(/`!'"``"`%``?>!7,'4``"X#`"!,`(<(```` +M4*`!`"!=`$<0/`!'"$P`APA>!&<(`(?A9X$$`"!D`"<(!?X`4``!X5<%`0`@ +M`(/@9X(!`"````!07@!'$`"&85``">%7A`$'"(8/`"!" +M#0`@`(?A9X$!`"!=!"<(`(/@9P(+`"``@B!0V(,-$-R;#1!```<(X(4-$.2! +M#1#H@PT0[(D-$/2##1#P@PT0^(,-$/R##1!D!`<0(!,"*-C_#4!0``<(`7X` +M0""A_R]0``<0`"X&*(0!!Q"(`0<0``'@9X$-`""`*P8HA`$G"``"`%``?>!7 +MB!,``(X*`"`!_A]@V($-$#P`!PC!G`)JF +M40$1`"`#_A]@^/\M0""5"BCT_TU``'P_8!C&`@``@0`(``'@9P(#`"``O@]@ +M`'Q?8!C8`@"@-!HHHOX_8(#__R?T@:T)_W\`0`";YF<`@0`0`0<`(````%`$ +M@`80"(`&$/B!#0@`?>!7``(```X#`"``O@]@`'Q?8!C8`@"@*QHHK/X_8(#_ +M_R<`@(80`)H&8""QXR<@_I]A!#X.$*!MXR\``"!@````4`#^@!`$@``0(+H) +M*`R```@`?#]@&,8"``"!``@!?@!``($`$*#?#"@!_A]@@)/C)P``'P@8Q0(` +M!GK@5P:`#S@````@!#X.$*!EXR\```!0```_"!C%`@`,@C]0()?^+P'^7V"` +M`@`@"`"@"0""(%"@[_\O"`(`$`":!F```>!G`8KC)P#\_R<$/@X0@'/C+P!\ +MOV)@Y0(```'`8?3^WT*B`P`@7?Z?F@"^#V``?%]@*,X"`*`/&BB5?RI`@/__ +M)P!^1Q``?+]A=.4"``"(!@@``>!G`)[G40(F`""`RO\O``$`8H$^`"`,`"@* +M`'Q_8GCE`@``H@D0`(0("`EZX%<"?>!7#@````)\'V`!````PCD`(```1Q`. +M>N!7`A,`(`!\/V!`LP(`/($`"`(>2!`!?@!`/($`$``("`@``>!G#("($`(# +M`"``O@]@`'Q?8"C.`@"@^QDHM'\J0(#__R<`?>!7``(```P#`"``O@]@`'Q? +M8"C.`@`@]QDHM7\J0(#__R<`B`8(`"`?$&SE`@```>!G`"`?$'#E`@`!$``@ +M`+X/8`!\7V`HS@(`H/`9*+A_*D"`__\G&H@("!U^`$"@.O4O`!!`&@R`2!`` +M(!\0<.4"```("`@`(!\0;.4"```!Z5<`@"D*#`8`(```*5``D``8(`4`(`"" +MAA``A`!0`("&$"`#`"``$``8`'Q_8GCE`@`@`0`@`(`I"@"(!@@``>!G`0D` +M(`"$"`@.>N!7`1(`(("?_R\``>!G@1,`(`!\7V!PY0(````A"````1`(@``0 +M``A`"`"()@@`A>!7`(`I"HGR_R<``H`0`)Z&$`"$"`@.>N!7`'P?8FSE`@`! +M20`@'(1("@QZ"6#\?JEA@D0`(#'^'V"@VQ0H97XJ0`"`"0@,(0`@`"``(`"^#V``?%]@*,X"`"#,&2CO?RI`@/__ +M)P">!V(@1^,G`"`(8#+^'V`@T10H*WXJ0`"`"0@N!7`@8`(`"%!@@``>!G@00`(""$"`@!>N!7`@,`(*"W#"@@_@A```'@9Z(! +M`"````@(``L`(```"`@`?%]@7.4"````(0@`@^!G`JI*8,(R`"``@"H(```! +M$"#W`R@@_P9```'@9P$#`"``O@]@`'Q?8"C.`@"@L!DH5WXJ0(#__R<`JDI@ +M("P`(```"`B`;?XO`"L`(`!\7V!DY0(````A"`"#X&>!`@`@`'Q?8&CE`@`` +M`"$((`@`(`2``!````$0`'P?8&"R`@``Z0,H``'@9P$#`"``O@]@`'Q?8"C. +M`@`@HQDH&_X_F(#__R<```@(`'Q?8&CE`@````$0`(`)"""8#"@`+`!`@/KF +M5P+]YE=0````@AH`(```"`B@DN\O`"0I8(`8`"`Q_A]@(*(4*(M^*D``@`D( +M'`0@"""@%"@Q_A]@Y/KF5P+]YE?T````@@(`(```'PA\Y0(```'@9P("`#B` +MS?\G`+X/8`!\7V`HS@(`H)`9*+1^*D"`__\G!'K@5P'T_R<(>N!7`<3_)X#Z +M_R!G@0D`(`"`*@@$@``(``'@ +M9P"J2F`!`P`@`+X/8`!\7V`HS@(`H(09*,-^*D"`__\G```("`2``!````$0 +M(&'_+P`>"!`!_A]@(+7_)P``1Q````@(`(``$`!\'V!@L@(``,`#*``!X&>! +MS/\G`+X/8`!\7V`HS@(`('H9*,M^*D"`__\G!#X.$*#9XB\```!0(,[T+___ +MWV(``ODO`'P?8K2L`@`@!&@*'P1("AD$*`H```!0&0!($"!*^"\!_A]@H&'Y +M+P```%``?#]@)0(``*!W%"B"_A]@`'S?84RQ`@`@!2<(-OK@5XHE`"``?/]A +M3.0"``">`$`$!&`(`(?A9X$B`"`C!4<(``7A9P(1`"`B!0<(`7X`0"(!1Q`& +M_@&0(0%'$#__`6``#D`8(P%'$`'^`$``#B`8H`L`("`!1Q`@!0<(`"C*8@`> +M`$`$!"`(H&<4*(?^'V`@!0<((04G"``>`$``@$H(!`0`"``081B@*``H`)I& +M8"`%!P@!?@!```X@&"`!1Q`C!0<(_W\`0``.0!@C`4<0``7A9P$.`"``?+]B +ML.0"``!\_V*NY`(``(0`&``>`$`!^N!G.@0`"*(!`"`/?J!A\'X`8`1^H)$` +MF@9``!X`0%8(``B@BOI7#0(`(`"` +M"@@$?@!```'J5XWF_R0" +M``":1Q`@ZO8O`)H&8`)ZYU<"?>=7`P```*%"`"@!#@<8!'KG5P("`""@0``H +M`OX?8*`_`"@#_A]@`?X?8`!\OV&LY`(``(!&$`!\'V!0L`(`H$(#*``@*&`` +M_D80($/V+P"$!PB`E^(G````4`!\/V!,L0(`((%`$"*!0!`C@4`0`_X?8""` +M#S@A@4`0!#X.$`!FXB\`?+]A3+$"`""%)@@`A``8`'P`0$SD`@`!^N!G.@0` +M",(!`"`/?@!@\'X`8`1^`)``?-]AK.0"```$)P@`@^!G@8?B)P`!X&>"AN(G +M`'P_8*<"``"@&!0HAOX?8"!2`R@$_P9`((/B)P!^1Q`$/@X0(%CB+R3^GV$` +M`,!A`)JF4?R;#1#\_PU`^/\M0*"A[R_T_TU```'@9P($`"#X@2T(#?X?8`R` +M0!`$_A]@#H"`$/2!#0B@`@`@`1Q`$`!\/V`G`0``(%T9*`"^#V``?#]@KN0" +M``"$``@``>!G`@\`((#$^B\">N!7@04`(`##^B\#>N!7`00`((!V["\!>N!7 +M@0(`(`#/_"\`>N!7]($M"(P$`""````@]($M"`!\7V#\]P(````!"`%^`$`` +M``$0H`,`(`/^'V``?%]@]/<"`````0@!?@!````!$`'^'V"@!``@`H!`$`": +M0!``?#]@^/<"``"```@!?@!``(``$/2!#0@"?D`0A?X?8*#S$RBC_C]`^($- +M"/R!+0@@]?`O#'X`0*!OXBEG`'P_8DCD`@`!"@`@`'R? +M8H2M`@`"_A]@`"@J8`":24`@8!TH__]M0/^%#0@`)@!```Y`&@`H"F``&BE` +MH#P=*/__34#_A0T(`"0`0``.H!D`@`@((`8`(`'^/V``?#]@E*T"`````%`` +MFDE`H%8=*/__;4#_A0T(`((@4``F`$``#J`9`(`("(`L[B\<``<((AJ'$"P@ +M0!``@`<(H%\`*`'^/V`1!`<(GWX`8`%ZX%>"`@`@`'P_8`B6`@``@``(`7X` +M0`"``!"@0.(G-/Z?800^#A"`!>(O`(*@8:"F]"\`!,%A`'Q?8+2L`@``F^9G +M`!PG0(("`"!`_A]@(`!!$`7\``"#_)R!T^"\!_A]@``H?"(RP`@`@K0N!7`O3A)P#J#"@`\^$G!#X.$*#!X2\D_I]A``#`8?S_#4#X_RU` +M(`SO+_3_34```>!G@0,`(`!\7V#XS0(``'P_8`4!``"@;Q@H`+X/8(#__R?\ +M@0T(&/X_8``"@!#X@:T)$?X_8`R"1A``"``($'X`4`Z`AA"@_A]@('_B+PV` +M1A```"<($((&$`0$)P@4@D80!00G""!^XB\5@D80^($-"/R!+0B@;_`O#'X` +M0"#JX2N!7%/[?80)\WV%D````@```(`RD!A"`6_(O`*/H9Z$0 +M`"``(`A@@&GB+P!\OV&4PP(`&/\&0*!N`B@`'"=@``'@9X'(X2==_A]@(%43 +M*`)^*D``A08(``'@9X&N#BA=_A]@(%(3*`A^*D`8_P9`H&<"*/__/V```>!G +M`0,`(`"^#V``?%]@Q,X"`*!$&"@+?BI`@/__)UW^'V`@2Q,H#'XJ0("\X2>` +M6>(O@+OA)P0^#A"@C>$O*/Z?80``X&'\_PU`^/\M0*#5[B_T_TU```'@9P$# +M`"``O@]@`'Q?8/C-`@"@.1@HY?X_8(#__R?\@0T(./X_8``"@!#X@:T)*/X_ +M8`R"1A``"``($'X`4`Z`AA"@_A]@($GB+PV`1A```,!A$/X&0`">)V"@0N,O +M*/Y?8"!(XB\`'`=@^($-"/R!+0B@.?`O#'X`0*"SX2$O````8@QZ`&``?#]B``0```(#`"``O@]@`'Q?8"#.`@`@&A@H +M`*(H8(#__R<(>N!7`GW@5P0````!`P`@`+X/8`!\7V`@S@(`(!48*`3^*$"` +M__\G`'S?85"R`@"610<(``'@9X*)X2!G`@(`(`C`)@A`^N!G`?W_)P#W_R>X_A]@ +MH`L3*`?^/V````!0,`%'%`#`!@@,>N!G`0,`(`"^#V``?%]@(,X"`"#^%R@C +M_BA`@/__)Y8?1Q2W_A]@(`03*``@*&"`<@0H"'KH5Z("`""__A]@(`$3*"W^ +M*$`@`@`@C/X?8"#_$B@R_BA`A/X?8`"`!A2`;.$G`'KA5PP#`"```@!0`('A +M5PL"`5`*``!0((`/.````A`@@`\X``0"$`0^#A`@0>$O`?X_8````&(```!0 +M(&G\+P`$05```:!A@@,`(`!\7V"`S@(``'P_8)T"``"@Z!(O@/Y?8"A^!T`<``<0#'[@0:!5[2\`'`=@'``G"J`" +MZ2\```!0'0!($``@"&`P_BA`H#`3*"#^7V`<`"<($80`""!^`&@1@$`0'``G +M"!*$``CS?P!@$H!`$`?^/V`B`H<0!OX?8%0`1Q!5`D<0"/X@B""=%BA6`D<0 +M!WX`8%(`AQ"@_A]@.0!'$`">!V`@/.TO`((@4````%`X`$<0"`"'$`":!F"@ +M;O\O`((@4(!'X2<$/@X0H!?A+QC^GV$``*!A`'P_8#L!``"@U!(HE?X?0(`5 +M_"\#_@:`!/X_8`!\OV`@Q`(```J`0`"%`@@*`T(0_W\`0`"!0A`%!0((``'@ +M9X$+`"`&"0((``@_"`JM`@`@COLO_O]-0`4%(@@`@$!0`OX&@``*($`("0(( +M'(6`$!Z!@!``O +M'/Z?88K^WT$``*!A%7X'0*"O$B@!?B=`@.K[+P/^!H`#_C]@`'R?8"#$`@`` +M"`!`"@-`$`8)(`@("0`(``(`0``0`!@`"#\("JT"`*!J^R_^_TU``OXF@`"( +M($`<@8`0_HD-"!Z!@!"@(^$G'/Z?800^#A`@YN`O*/Z?80!\/V!PSP(``($` +M"/"!#1`$@0`(]($-$``$'PB4P0(`&'[@IP#\O$%.Y@(`("0.*/C_#4`@6?DO +M__[?00%ZX%>!`0`@`%?Y+P`!X&<"'0`@``0?"/"L`@`%A"8(`('@5P+^'V`" +M?!]@`P`````<^B^*_A]@H),2*`=^)T`'A(8)!H0F"`A^AH$`F"!H"(2&"0J$ +M!@@0?H:!`)@@:`F$A@D8?H:!`)@@:`N$A@D`@^!G"'Z&@0`8`&@,A(8)$'Z& +M@0`8`&@-A(8)&'Z&@0`8`&@!`>!G`0$`(/B##1#\@0T0#X2&"0Z$!@@(?H:! +M`!@`:`I^`(#P@0T0^/\-0/#_+4`@:!HH``!`8(K^'V"@@!(H%'XG0`!\/V!! +M/@``(%#_+_C_#4"@`_HO`_X?8`!\'V```(``@$?N+R#ZX"!_?\GH`$/*$+^/V"`].HO@-O@)P0^#A"@O^`O./Z?80``(&(`@F!B +M`"1)4O2E#1`4?N"G`'S_8:#F`@``GKQ!"(`&"`#R'&+\@0T0$(`F"/S_#4"@ +MX!PH`?Y?8/R!+0@`'@@``('@5XX``"`0@`8(``+`40`=YV>B`0`@`*((8(`/ +M"R@`!0`@@$D+*`"=Z5<.ILEA"(`&"!"`)@@`@`!0``'G5PT`P&$`'>=G`@$` +M("`/`"`!_A]@^*5-$/FC31#ZG4T0`*((8"#%$BCT_RU`"(`&"`R`9@H'?D"" +M^/\-0"#T!R@`@B!0]($M"`=^9X#X@:T(````4``F24"@P@8H`?Z?8"`("B@` +M``!0"/X'0!"`)@@`(`!`(,@<*``<1V``H@A@(+42*``<)V`@RN`G./Z?800^ +M#A"`B>`O``'@9P(#`"``O@]@`'Q?8,3.`@"@0!!G@9/@)P"^#V``?%]@#-@"`*`>%RA-_C]@@/__)P0^#A"` +M;.`O````8@""X&$`!*%AH);B+P"&P6$)>N!7`@,`(`"^#V``?%]@#-@"`"`7 +M%RA9_C]@@/__)X"1XB\#>N!7`@,`(`"^#V``?%]@#-@"`*`2%RA:_C]@@/__ +M)P`@"&``GB=@`)I&8*"Y!B@`'&=@H,P)*````%"`A.`G!#X.$(!2X"^`)OPO +MH'[@)P```%`$/@X0(%#@+\C^/V``?!]@<*\"`(`G`2@``>!G`7K@)P!\7V`$ +MS@(``'P_8"$"``"@!!`#@"0``H&$`H!\(``$`2``!`$@``0!(``$` +M2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W]T@"8(`(/@9P*?YV"!0`@!_X_8)"" +M!A`H`"T(`?X@0"@"#1```*`?(.\!*`":!F```>!G`M#A+X```"```*`?<(`& +M"``!X&>!`0`@(.0"*%C^!D"````@6)P&$`"@'P@``0!(``$`2``!`$@``0!( +M``$`2``!`$@``0!(``$`2`1^(&``@*`?____?P``H!^`4.`G!#X.$``BX"\` +M`*!A!`(`$````%`(@`80$(`&$!2`!A`,@`80`*`?"``!`$@``0!(``$`2``! +M`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_;``M"`"#X&<`_`803D16 +M1`$#`"`<@$`(')H`$!@:`1`"`@`@``$`(``%X6!Q`!_B!`*`(- +M$```H!__^^=70H8"*%A^!T"@_`$H`!P'8*`!`""0`,<)!_[?80``H!^@%.`G +M`!P'8````%!L``T0((`/.'``#1`$/@X0`/+?+P``@&(`@J!A``3!80"@'P@` +M`0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?P@` +M*@@">N=G`IH@8$(;`"`(`@H0$`#J"0":P&D`G^=G%``*"B%?`"`('`H0`7KH +M5X(7`"",@"<(A(!'"`+ZX&"`@`@``$`(`"#X&!`0`@H'D"*%C^!T"````@6)H'$)":!Q"@?0$H`)X'8``!X&YU$`'^%7@`!A"`&"X&&` +MA@`0?``A"'R"`1`4`"H(__\@0!0""A``I^EGD"(!$*("`"!T(@$0?"(!$``$ +M06(@`@`@``1A8GP$"1!\(@$0``1!8O]["$*"VO\G$!X*$```H!^`"@`@($@" +M*%C^"4``H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@ +M`("@'____W\H`"T(`?X@0"@"#1```*`?H$4!*`"F"6``FF9B`*?I9P$#`"!P +M@`D(``'@9WR`J0F"\O\G(//_)UBB"1``H!\(``$`2``!`$@``0!(``$`2``! +M`$@``0!(``$`2``!`$@$?B!@`("@'____W\H`"T(__\@0"@"#1```*`?$``- +M"`P`+0@`@>!7@0$`(```#0@``>!G`;G_)R"HWR<```!0`"'H9P&X_R<,`"H( +M`?X@0*"V_R<,`@H0!#X.$(!NWR^`N@`H`#X"*`!H`"@`"P`H`(O_+P`B_R^` +M(_\O@)??)P0^#A``;-\O```-"`!\OV'P\/#P`'W@5_'P\/"!`0`@(.C?+P`: +M#1"`]?\O`!H-$*#*'R@$``T(````4"`*X"\```T0@(_?)P```%!D``T0((`/ +M.&@`#1`$/@X0`&;?+W@`X`D``*!A`*`?"``!`$@``0!(``$`2``!`$@``0!( +M``$`2``!`$@``0!(!'X@8`"`H!____]_=(`F"`"#X&<"G^=G`1H`(`"`)P@` +M_>!704U%4P(8`"!\@"8(`!S'40"#YE=TG`8000,`(`R!G +M@0$`("#^`2A8_@9`@```(%B)P&$`P`)P@`@^!G +M@00`('R"!A"`@"`(@((&$`P`)PB`@"`(?)H`$`P`)P@@`@`@@)H`$`P:!Q!\ +MF@80@)H&$!``)P@!_B!`$`('$`;^/V`\@@80`?X_8$2"!A`H`"T(6)X&$`'^ +M($`H`@T0``"@'__[YU="J@$H6/X&0*`@`2@`F@9@H`$`()"`I@D-_K]A``"@ +M'Z`UWR<`F@9@````4%P`#1`@@`\X8``-$`0^#A"`"=\O``#`80"@'P@``0!( +M``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?PP`IPD` +MF^9G`)[G40$/`"!\@"8(`(/F5T$#`"`,'@<0#`('$("`1@B`A``0?(`F"'P" +M`1`0`"<(__\@0!`"!Q`H`"T(=)X&$`'^($`H`@T0``"@'W"`!@@``>!G@0$` +M(""J`2A8_@9`@```(%B>!A"0G@80(*X`*`":!F```>!G`H_@+P`"`"`(`"<( +M`?X@0`@"!Q```*`?(!C?)P```%`$/@X0`.G>+P``H&$T`@`04`0`$%0&`!`` +M@B!0"`(`$`P(`!`4"@`0`?X"4``(`$`0@`80'WY#8!_^`V!(@`80$(`-"#B$ +M!A`8@`80'(`&$`2"!A`#_A]@/(`&$$""!A!$@@808/P&$#]%``!DF@80<((& +M$%R"!A!T@@80>((&$'R"!A"`@@80`80?@$R`!A`H@@80+((&$#""!A``?#]@ +M'40``"!;X"\`F@9@`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@` +M`0!(!'X@8`"`H!____]_%``M"`"#X&<`_`801%)(5`$#`""8@$`(F)H`$)0: +M`1"8A`80(`(`()2"!A`4&@T0E)H&$)B:!A`8`"T(`?X@0!@"#1`H`"T(`?X@ +M0"@"#1```*`?%(`-"``!X&>!`@`@(($`*`":!F```>!G`F+@+P`(`"``H!\( +M``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W\H +M`"T(__\@0"@"#1```*`?(./>)P```%`@@`\X#``-"``(@E`,"`T0$`@-$!P( +M#1`@"`T0(/X?8"0`#1``?!]@$-L"``!^0!`!?F!`(`(`(`'^7V``@D$0`?YA +M0`%^04``?>%7``$```8$`"``@B!0``0!8`%ZX&<"^_\G``0`&`'^($"@_?\G +M`(X@&`!\/V`0W`(`(`(`(````%``B``0!/X@0`%^`$`@>N!7A?W_)Q0(#1`8 +M"`T0((`/."@(#1`$/@X0`*;>+P``X&$`@J!A``3!80"@'P@``0!(``$`2``! +M`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?SB`)P@`@^97#18` +M(`"#YE>"!``@`OX@@`#\(``0W`(``(/G5P("`"!,@"<((`!-"``"(7`@`@T0 +M2(`G"``"!Q`0`"T(`(/G5TB:!Q""#``@.(`G""0`30@`A>!7#87F5PX*`"`" +M?B&``/P@`!#<`@`0`@T0``"@'R@`#0@``>!G@2K@+P"@'P@``0!(``$`2``! +M`$@``0!(``$`2``!`$@``0!(``$`2`1^(&``@*`?____?R`!`"``FJ91&/Z_ +M80``H!\@KMXG`)H&8`0^#A``A-XO``#@80""P&$@^N!7``2A8<8Z`"`/_K]A +M`*`?"``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!__ +M__]_.(!'"`"$!A`\@"<(`(/@9X$#`"`XG`<02)P'$`&!&0`@0`!'"``%X6<`@B!0`0(`($`"!Q`#_C]@(!8`(#P" +M!Q`X`$<(/`('$`)^88``?)]@$-P"``"((0``@^!G`0,`("2`0`@@'`$0))P` +M$"0$!Q`@#P`@(`('$`"(@4``'`(03``G"!P`;0@`AB!H$`!M""`)P":!F`$/@X0@`[> +M+PP`+0A4@``(4(`@"`""`#@,``T(,``@"`"#X&<"@@`X`*`?"``!`$@``0!( +M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_#``M"`'^7V`\ +MA``01(0`$"@`+0@!_B!`*`(-$```H!\@&``H#``-"``LWB<$/@X0``/>+PP` +M+0@``*!A`(/@9P)\'V`0W0(``H'@5X$!`"````T(``'@9P$!`""@#P`@$_[? +M80";YF<`',=1@0T`(`"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!( +M``$`2`1^(&``@*`?____?PP`30@$_C]@/`(!$`'^/V!$`@$0*``M"`'^($`H +M`@T0``"@'PP`#0A8&@`0((L`*%A^`$"@`0`H#``-"*`7WB<`'`=@!#X.$`#Q +MW2\`?!]B$-L"````X&$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$` +M2``!`$@$?B!@`("@'____W\H`"T(__]`0$2`)P@`@^!G*`0-$(%#`"``BJ)0 +M1(H'$""`AP@X@"<(`(GG5P!\OV$0W`(`(0X`(`+^8(`D@"<()`("$""`1P@@ +MA``0`)HA``"#YU>".P`@`)J!00`$!A`@`$T(``7A9X$!`"!,@"<(``(A<"`" +M#1`0`"T(`(/G5P(V`"`D`"T(`OX@@`":(``@-``@$`(-$```#0@``>!G`OS= +M)P`D`"``FH%!3(`G"!P`;0C_@S]P(`"-"`""86``">)G'`8-$*$!`"``"@80 +M`(B`8"`(#1``CR$8`B#(8<(*`"`"H&``"/XAB`"/(!@!`@`@`"#(80*@(``@ +M!P`@"/Y@0!#^(8@`CR`8`0(`(``@R&$"H"``H`,`(!#^8$`8_B&(`(\@&($1 +M`"`"H"```"#(81C^8$`D!@T0$``M"`"#YU>"'0`@`OXA@`":(```">)G$`(- +M$`$;`"`!?B%`*`(-$```H!\`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!( +M``$`2``!`$@$?B!@`("@'____W\H`"T((`!-"/__($`H`@T0``\A&`$$`"`@ +M"P`@`IP@`"#^/V`D`@T0$`H-$```H!\`2M\O@-;=)PA^(8@`CR`8@0$`(`*< +M(``@!0`@"/X@0!!^(8@`CR`8@0$`(`*<(``@`@`@$/X@0!A^(8@"G"``&/X@ +M0`+^((``FF``)``M"$B`@0@`B>!7!0(`($R`(0@0!@T0``(A<"`"#1```*`? +M$``-"`P`+0@``^!7@"#``@'(`F"!B"!A`H`"T(`(/@9P)\/V`!````0@D`(!B"!A`@@&8(`(?F +M5P$'`"!(@"8(.(!&"``#X5<"!0`@`GXA@`!\7V`0W`(``(2`020`+0@`!@80 +M`OX@@`"$(``!_M]A$`(-$```H!\@KMTG`!P'8`0^#A"`@MTO``"@83P```@$ +M>N!7@@D`(`"@'P@``0!(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2`1^ +M(&``@*`?____?R@`+0@!_B!`*`(-$```H!^@-/\O`)H&8`"AW2<`H!\(``$` +M2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@`("@'____W]T@,8) +M``"@'P`=YV"#@`@ +M('KA5Q_^/V`.?"%0`0````+^0(!``"T(`(1`0#P`+0@``^%7!0(`(``"(5#\ +M_T!@.``M"`"$0$```"$(`(/@9P$$`"`0@@80%(`@"!2"!A`0F@`0```A"!2: +M`!"@`@`@&(0&$!":!A`4F@80&(0&$``:`1```*`?H'/=)P```%`$/@X0@$;= +M+P``H&$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``!`$@$?B!@ +M`("@'____W\8@"8(`(/@9X$$`"`0@$8(`(7F5X($`"``@&`(`(?F5P`$05"" +M```@`(0`$!B$!A```*`?H&3=)P```%`4@"8(%`(!$!"`9@@0A@`0&(`F"`"` +M0`@`A>97@@$`(!B"`1`0@$8(`(0`$"#X_R<`!$%0!#X.$"`QW2\`@B!0"'Z. +M4P":IE$L&@T0,!H-$#0:#1!$&@T0`'Q?8)#<`@`@`@`@``0!8``:`!`$?@!` +M`?X@0"#ZX%>%_?\G.`0-$$`$#1"`?@%`/``-$`!\'V`0W0(``'P_8/BF`@`` +M?%]@!D8``$@`C0A,`*T(4`#-"!`:#A`4&@X0`'Q_8$U)5$$@-OXO``SC8%0: +M#1!8&@T0"'Z.0P!)W2<$/@X0H"[=+SC^GV$`?>!734E40:$!`"``GN=1H%7= +M)SC^GV$`FJ91^)L-$/S_34+X_\U!`_X_8B`%`"`!_A]B#``M"#RB`!!$H``0 +M*``M"`'^($`H`@T0``"@'R`G_R\,``T(`*`?"``!`$@``0!(``$`2``!`$@` +M`0!(``$`2``!`$@``0!(!'X@8`"`H!____]_0`!-"```(0@`@^!G_(,-$($` +M`"`8I``0`!H!$$``+0@$_D!`/``M"``#X5=`!`T0`@$`(#@`+0A``@T0(!@` +M($0:#1`0@"D(`(/I5T$$`"#\FPT0%(!)"!2$`!`0@"D($`(!$!BD`!`0@"D( +M_(,-$`"`*0@@^N!7#@(`("#^(%``@@D0H`,`(``HBE($@"D("(")"@"#X&<` +M@@D0(0(`(`R`Z0D8G`D0(`$`(!"F"1`8F@D0``"@'P`IZF!G`?W_)]``"0@`&^!7`B?@5P(AX%!A""!0`@`)_G9P(#`"``O@]@ +M`'Q?8"#.`@`@"!P`@`'P?8-C.`@`"_C]@H/D-*``$ +M05`%!"<(`_K@5P!\'V```"``B0$`(!A\`!0B,@````$`(!A\`!0",@```)OF +M9P%\'V#!G`0,`(`"^#V``?%]@),\"`*!`$R@J?BI`@/__)P'^'V`` +M`4D4!P0G""!M%R@`F@9@`P0'"``(*`B`?@!H#P%)$`$$!P@)`4D0``0'"`4"```X^"\`"`@(`"?@5P(&`"`%!`<("7K@5X$$`"``?%]@T,X"``-^@(`< +M?F%`"/X?8`/^/V``B&%`(/8-*``(@E"@:.(O!@0'"``("`@P'TD0`"?@5P'] +MYE<"`````?WG5PL````!?!]@Y,X"``$$05#!R`TH"/X_8`"."2@""0D(``"? +M$**P`@`$?@"```"?$*2P`@`@,18H"/X?@`";YF)V!C_A]@H!8.*``<)V"@D=PG-/Z?800^ +M#A``7MPO``"@80""(&(`!.%A`(;!82"'WB\`"`)B`GK@5P$0`"``!`@(``'@ +M9P"()PB!!0`@```'"````$`$@`@``(``4``:($``D``8`(*'$*!"WB\*_C]@ +M(`(`(``0X!D`F@!``("'$`":YF$```<(````0`"`"$``&H`0```'"`%^`$`@ +MI]TO"OX_8`"#X&<``@<0`@$`(`'^'V```$@0`)ZG82!OW"<`F@9@!#X.$``V +M#A``.&YC&'Z.4Q`:#A`4'`X0``"@80#\`&#_/P```!#`&0#\!F#_/P```!"@ +M&1#^!H``?#]@(@`@"``*W2\`_`9``(```!!^`(``?#]@(@`@"``'W2\`?`=` +M`$```!!^`(``?#]@(@`@"``$W2\`?`=``,```!!^`(``?#]@(@`@"``!W2\` +M``!0`'P_8"(`(`@`_]PO$`"N"10`S@D$@.T+((`/.!@0;@L`?%]@^,P"```! +M(0@`@`!`((`/.``!`1```!\(^,L"``"`#S@$/@X0H"'<+Q3^GV&@`@`H_/\- +M0/R!#0@*?@"(H&#<)Q3^GV$$/@X0H"3<+R#^GV&@Z]PO``#@82#W_R\``*!A +M``#`80'^'V"@V0N!7@@``(`!(WB\$@.T+((`/.!`0 +M;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$`$3```+KH+P#:W"\`@"8(`/P@ +M:```"`@`_"!@__?__P""!A``V=PO````4`/^/V``\?\O$`"N"02`[0L@@`\X +M%!!N"P0^#A`@$=PO)'[@0`":IE$`!$%0"`@`"0">YU$`>N17``B"4"P"`"`< +M`*`(`@@@"``#Y%<+`P`@`+X/8`!\7V#0V`(`(+02*)S^/V"`__\G6(#"""`$ +M`"``AF%0`(8A0`""(D!TB"`(`(@@0`"0@!@!_B%``(Y@&`"-X5>%^_\G`!'D +M9R$,`"`!"`)A`'WD5RH)``")`0`@`'WD5P`!```*`P`@`+X/8`!\7V#0V`(` +MH*82**[^/V"`__\G`7KD9P$#`"``O@]@`'Q?8-#8`@"@HA(HK_X_8(#__R<+ +M!"`(``(D4`"0`!D&>N-7#0$`(``-XV<"`P`@`+X/8`!\7V#0V`(`()P2*+7^ +M/V"`__\G`)9E45R`P@ETB$()`!!D8``((F$.^N97B@@`(`YZX5>*"@`@`_XF +M@`""@T$`!$80`((C0@&>2!`$G`@0``?E5P`@"%(L"0`@`"1)4@'^7V(`!L=! +M``8E4"`-`"``D$`9`+X/8`!\7V#0V`(`((T2*+W^/V"`__\G`+X/8`!\7V#0 +MV`(`((H2*+[^/V"`__\G``?E5X(!`"`!_E]BH`0`(`'^'V(!_A]B`I2($`"4 +M(5``D&`8`!0B4`"0@!@!_B=``([@&0%ZZ5<"!@`@`H:($`&$*`A`_B!H`8)( +M$``&(E``D8`8`GPA0`$````"CD`8`I[G40(09&`""")A`7KH5P(%`"`!_B5` +M`(Y@&0"-Y5<&`P`@`OXE@`""(D!<@,`)`)8E0`""(D!TB$`)`?XF0``)XF<` +MCJ`9`MO_)P/^)H``@F-`^84A",#^(&CY@T$0"7KA5R`$@!`+`P`@`+X/8`!\ +M7V#0V`(`H&T2*/S^/V"`__\G"P0@"`"2($``>N%7(@*`$`D#`"``O@]@`'Q? +M8-#8`@`@:!(H__X_8(#__R<#?N&G`_X\0`":@$``?&!`(`(``,*%(0@`@^!G +MP8E!$"$"`"``#J(8``0B0,``CJ`8"P0`"!IZX%<"V-LG`(0"0"#7VR?! +M@4$0!#X.$""EVR\D?J!``'R_80`"```("$`(`(9A4``%X6<+!``)(04`(!P` +M(`D"""`(``/A5PH#`"``O@]@`'Q?8-#8`@"@5!(H4_X_8(#__R=8@$0)!GKE +M5PT!`"``%>5G`@,`(`"^#V``?%]@T-@"`"!/$BA5_C]@@/__)P".XU"@`0`@ +M``S#4`'^(T``CN`8`)7C5P82`"``CB-``((D0'2(0`@"_B.``((D0%R`@`@` +M!"1`H`(`(`"0`!D"A(`0``1!4`'^(4``CF`8`'KA5XSV_R<.^N%7B@8`(`/^ +M(8``@H)!``Q&$`""(D`$B``0`!OA5P&,0!`,^/\G`IJ`$``:(5``D$`8(/?_ +M)P`:@D``O@]@`'Q?8-#8`@"@.1(H8_X_8(#__R<#_B&``()"0/D%(0C`_B!H +M^0-!$"`,@!`B$(`0`?XA0`!\`$`@`@``P0-`$*"FVR?``T`0!#X.$`!\VR\` +M`*!A'``@"`O^'V`,@$`0`'Q?8#;-`@`!!0$(#8!`$`Y^`$`!`4$0``X`&'%Z +MX%<,_L!!#`$`(!#^'V`!`4$0``0?"-#D`@`!>N!7`GW@5P(```"!`P`@`'Q? +M8-#8`@``?#]@70$``*`C$B@`O@]@@/__)QD`1Q`@TA$H`!P'8``$'PC4K`(` +M@'K@9P$#`"`7A`8(`8`?@`!]X&?8#P``(IGO+P*:!F`@B`8($X0F"`"!X%<" +M`@`@````4!P`AQ`@!``@(H@&"`%^`%``@>!700$`("*(!@@(B`8('`"'$`B( +M!@@@B=LG`@"'$`0^#A"`7=LO``#`81P`(`@+_A]@#(!`$`!\7V`VS0(``04! +M"`V`0!`.?@!``0%!$``.`!AQ>N!7#/Z@00P!`"`0_A]@`0%!$``$'PC0Y`(` +M`7K@5P)]X%<"`````0,`(`"^#V``?%]@T-@"`*`%$BC)_C]`@/__)QF`1A`@ +MM!$H`)H&8``$'PC4K`(`@'K@9P$%`"`7!`<(`8`?@`!]X&?8#P``@0(`(`6$ +M!@@`!#\(Z+$"```"`&@%@$80(`@'"!,$)P@`@>!7`@(`(````%`<@(80(`0` +M("((!P@!?@!0`('@5T$!`"`B"`<("`@'"!R`AA`("`<((&G;)P*`AA`$/@X0 +MH#O;+R3^GV$``>!G@@,`(`!\7V#XS0(``'P_8"$!``"@[A$H`+X/8(#__R<$ +M`"`(](,-$```(`CP@PT0`((@4/R##1`(""`(()L5*/#_#4```*!A^($-$`!\ +M7V!DV0(`\/\-0*#I%"CX_RU``)H&8*!LVRVR\`?+]AM*P"``*$)@@#@$80`?X@:`*"1A``F@9@H&'M+P"" +M(%`"A`8(_'\`8*!#VR<"@$80`'Q?8(2Q`@!<`2$(``/@5\8"`"`"_A]@8`$A +M"``#X%L`@`"^N!7@@$`(``(/P@`L0(```(`(`'ZX%<" +M@`\X``@_"`*Q`@```^!7`'Q?8+3D`@",`0`@``@?"+;D`@```0`@``@?"+CD +M`@`@@`\X``"!$`0^#A`@`=LO`((@4``$'PCWK`(```'@9P!\OV&$L0(`P0$` +M(`B#AA`BBP8("(&&$``('PC2P@(`'H&&$`1^`(`@@880H`,`*("#AA`@VP`H +M"(L&"!Z+!@@@RO\O`!``&``AVR<$/@X0(/?:+P""(%``',=1`'R_882Q`@"< +MG880GIV&$*#_!D`@I-PO(/Y?8)F=1A"@&]LGF)U&$`0^#A"@[=HO`((@4`!\ +MOV&$L0(`+/\&0*">W"\(_E]@````4"J!1A"@%-LG-(&&$`!\GV"TK`(`'P0" +M"`!\7V"$L0(`'`4A"/Q_8&`"^N!7`(8!8*(%`"`?!D(0.`LA"#0+H0@`@^)7 +MR0,`(`/^`6@`@C]0`(/B5PH"`"`@`0`@`?X!:`"&`&@?`$(0)04A"`"#X&N!7000`($()`0@#>N!71`DA"$&` +M#S@$`X$00@D!"``#X%<,@@!@((`/.`0!@1`$/@X0@,_:+P#X["\!>N!7`@$` +M((`!`"@`^MHG@#@`*`#YVB<$/@X0`-#:+P!\OV&$L0(`=HDF"```7PB,L@(` +M`((`0``:`$!H!8`0`?X`0``0(!@'^N!7`!S'42(!`"!V@880=IV&$`"&85`` +M!$%0H`,`(``L`@`!>N!7`@(`($J)!@A.@880(`,`($R)!@@">N!7@@(` +M($:)!@A.@8802(D&""`"`"!0@880`+X/8"#)$2C9_C]`"(L&"#J+)@@``@!` +M"(&&$``,(!@\A08(``'@9SJ=AA`!"P`@3HD&"`2)1@@`!>!7BP4`(/__`$`` +M#"`8"(&&$%*)!@@&B48(``'A5XL-`"!6B08(`7X`0"`,`"!6@8804(D&"``% +MX%<)"@`@`?X`0``,(!B@"``@"(&&$%*)!@@&B48(``'A5ZH#`"`!_@!`9(4& +M"``$7PBJJP(```'A5XP!`"#__P!```P@&`B!AA!8B08(`7X`0%B!AA`BBP8( +M`('@5\L#`"`(@8805(E&"`"%X%<)#`$820$`(`B%AA``@@!@)HDF"``#X%>! +MQ-HG(*<`*":!AA``P]HG``A?"-+"`@``?#]@A+$"`)R+``@&?F%``('A5XP6 +M`"`$B0`("GK@5PH5`""`B6`(,OKA5PH2`"`!^N%7!'X!@"$!`"`!#(`8((N` +M"`'^`4"`@8`0!7X!4`!ZX%<)$&`8#(9A4(J'@!`%?@%``!#`&(:!@!">BZ`( +MEHE`")"+``@`A>)7"0@`0`P``E``#``8!'Y#@``%X%<*#`$8!/Y!@``%X%<+ +M#`$8((&`$`A^`$`$?D"0``P!&!Z%@!`!?D!`(!T`((2%@!"$BP`(H!L`(!Z! +M@!``"A\(NN0"`(QZX%>+`0`@I7K@5\P'`"`1_E]@@'K@5XL!`""$>N!73`4` +M(!+^7V`H>N!7"P$`("QZX%<,`0`@:'K@5P(!`"`@`0`@%OY?8!7^7V",A8`0 +MB(D`"```?PB(L@(```8`0``0H!B&@8`0E(E@")*)@`@`!^)7((L`""P"`""* +MA8`0CHM@""`#`"``@`%`!(E@"`;ZX5>*`0`@CHM@"``&`%``#``8!/YB@``' +MX%<*C`$8!'Y!@``%X%<+#`$8((&`$`A^`$`$?D"0``P!&!Z%@!""BT`(``7@ +M5P&`#SB"@8`0H#__)P`0`!@$/@X0`&+:+P``P&$8"``(``@_"+3=`@``?+]A +MA+$"```#X%<`GN=1K`4`(`:!AA`!_A]@(!<,*`""(%`!_A]@R(%&$""'#"@& +MB28(`?X?8*`&`"!D_C]@R(4&"`%ZX%<"!0`@`?X?8*`0#"AE_C]@R)]&$`:) +M)@B@@`PH`OX?8`'^'V#(_C]@@`P,*!8()P@`C>`?@P$`(!X(1P@`#>$?!`0` +M("F%!@@\GT80`7X`0``.(!@$^N!7*8%&$(I7_R^`$``@`?X?8#R!1A`IGT80 +M`'P!8/]___\`$$`81(&&$``$'PCWK`(``/P@8/]___\">N!70H.&$"(#`"`` +MD&`86H4&"``!X&<"`0`@1(.&$`"&06`TBP8(`(1@4"J%1@@`!H!```0!0``: +M($`LBP`(+(>`$````E`T@880`7X!0`-^`&`J@480!`A'")B%!@B2A880``!_ +M"(BR`@```>!G``R!&*('`"``C*$8`?Z?8"`#`"````!0`GX@@`":($"@AX`0 +MHH6`$`%^`$`(>N!7B_S_)YR'AA">A880H%?:)YB)1A"9A<8(`((@4`)^`X`` +M&@!`H`>`$*(%@!`@!0`@````4``:8$"@BT$(`(7B5PD$H6"BBT$(``7B5PD$ +M@6`!_B!`!'X`0`CZX%>+^O\GGHF&$)R+AA`!?@-`!WX`8"!+VB>9@480!#X. +M$*`AVB\D_I]AC_[_02!!["\``*!A``#`872:'U#^@8T0;/X?8`%ZYU?Z@8T0 +MH0,`(!/^!D``"!\(TL("```:`$``>N!7"1``&`P``%#\@8T0`?X'0*#1"RB8 +M_C]``-[:+P%ZYU<``*!A@@D`(*#Q""@!_A]@`'P?8!N%```"_C]@_O]-0*`I +M"R@`AF%0_HD-"&QZX%<"`0`@:_X?8/J!C1``?!]@'(4```+^/V#Z_TU`("0+ +M*`"&85`@Z`@H`OX?8`!\'V`FT@```OX_8/S_34`@(`LH`(9A4/R)#0@`?%]@ +MA+$"`````$`$?"``+,\"``!\'V"TK`(`4?K@5QH$8`@,!0`@P`4A"`"#X&>" +M`P`@'`4A"`+ZX%<"`@`@`?X_8%H#01`@`@`@(/XA:`""(%!:`T$0W_\A8!H" +M0!`@/.PO`((@4*##VB\`F@9@D/X?0""R"RA/_B=`H"_:)R3^GV$$/@X0@._9 +M+Z`5["\``*!A=)H_4`%ZX%=L_I]@(A$`(`"0H!@3_@9``!`@&&SZXE<`?+]A +MM*P"``*$!@@!?)]@:P````-^`&@"@$80`((`0`1\```LSP(``'Q?8(2Q`@!1 +M>N!7&H1F"`P%`"#`!0$(``'@9X(#`"`N!7"1`@ +M&`!\OV&TK`(``H0&"`R"(%`!?@!H`H!&$`."1A`6BD80%XA&$`":!F`@&^PO +M`((@4`*$!@C\?P!@(/W9)P*`1A``/@X0(.;9+RA^X*<`BB)B``#`8@""H&(` +M!(%B`(9A8@#\'$#\S`(`)```"``(0F(8?N"G`/+<80!\OV%4J@(`();:+P#R +MYD$```!B"(`'"`%^($`4B`<(`('@5X4"`""@E-HO`"`(8`"^#V"@U1`H9OX_ +M8`")G`(P< +M0$(!`"``C!P`!```"``&`&@``F!X`(1A>`R&`A`(A`(0!(("$""`#S@`@`(0 +M``!?"'C-`@`(@``0`'QA:``"```$@$`(``9!>```07@,A``0((`/.`"&`!`$ +M/@X0H&'9+RC^X:<``.!A``2A80#\'$#\S`(`!```""#)`B@``L!I"(`&$``> +M)W@`@`!X#(`&$`2>!A`@@]DG`)P&$""`#S@`?@`0!#X.$(!0V2\`(-HO`"+: +M+P!\V2<$/@X0@%79+P``X&$@'=HO`(+`80``H&$`G@=@(`(`*``<)V"@'-HO +M`)H&8`!YV2<$/@X0H$_9+QA^X*<`@L!A`/R\052J`@`@!``@`)[G40`>`4`` +M@`!@!'X@@!"`!@@@\/\O``(`0`'^YT$4B`8(`!_G5P%^(%"M^O\G!(!&"`B` +M!@@`'`!0"(`&$``<`4``@`!@(&S9)P2`!A`8?N"G`/P<0%2J`@`(```(((`/ +M.`"``!`$/@X0H#_9+R#^GV$`@J!A&'[@IP#\W$%4J@(`!`#G":"A`BC\_RU` +M_($-"!``)P@``@!0!'X@B`"?X%`$(!&"`"F"6``)"E@``9!0*"S_R\"_G]@#(`&"`+^)X```B!``)P` +M$`%^"$(!_@=``*'H5PWX_R<@W-DO`"@*8`#TVB<$/@X0(`_9+QA^X*<`@N!A +M`/S<052J`@`@U=DO``2A800`)P@`GD!`%`@G"`'^(%``A"!@`OY`@`P`)P@` +MA"``H-+9+P""!A``+]DG!#X.$"`-V2\8?N"G``#`80""0&(`_+Q!5*H"`"#+ +MV2\`!"%B````8@2`Y@D`'`=@(-+_+P""(%`!>N!7`(!($`("`"`,@`8(`OXG +M@``"``````D0H,;9+P`@"&``)MDG`#X.$*#VV"\8?N"G`/R\052J`@`@P-DO +M`(+`812()@@!_D!0!(`F"`"$(&`"_D"`#(`F"`"$0$`@OMDO`!P!$`#0VB<$ +M/@X0(/;8+RA^X*<`_!Q`_,P"`"0`(`H`@J!A&/[HIP#\'$)4J@(`(+79+P`$ +MX6$``,!A!``("`)^((`,``@(``(```";YF<`@`<0`0,`(`0`"`@$?B"`$``( +M"``"`$`@L_\O`)HF8`"B"&"@D_\O`?X_8""NV2\`'`=@@`S9)P0^#A"`Z-@O +M(*G9+P```&(``$!B&'[HIP!\'V!4J@(``'*@00"B*%(`@$$!>NA7`"(&$`("`"``0`(H$(`F"`"> +M($`$@``0`7['01#^YT$4B`8(``'G5POY_R<@G=DO`"0)8(#\V"<8?N"G`/Q< +M0%2J`@`$``$(!'Y@@!```0@`!@!`((`/.`"``!`$/@X0H,G8+QS^GV$`?-]A +M5*H"`*!P_R\```!0`)'9+P``H&$```!0((?_+_S_+4``"()0!`"G"*`'`"#\ +M@>T(``(!```"84``?,!@____[P`"(4`$@`$(`(P`$``,('@(@`$(`7Z"0``" +M`'@,@`$0`?X"0``.H!@`#^)7$`!'"*7W_R<$_B*```(!```"@4$`?`!@____ +M[P``!A`0`$<(``(!```"(4``@``0H('9+P":!F"@[]@G'/Z?80`^#A``K-@O +M$(`-$!.$#0B@W_,O?WX`8("-VB<$?HY3`#8.$``X;F,0@`T0$X0-""`%`"!_ +M?@!@!'Z.4P`V#A``.&YC$(`-$!.$#0B`?@!@`('@5P'^'V`"``!0`!!N"R"` +M#S@$?HY#`P1`"']_06```B%H((`/.`,"0!`$/@X0H)_8+P`$86"@^_\O``"@ +M80.$!@B`?P!@`X!&$"#-\R\`A@%@`X0F"``"`&B@Q=@G`X!&$`0^#A`@EM@O +M``!@8*#T_R\`!(%@`X0!"(!_`&``"`!HH+_8)P.`01``?#]@,```":!FV2<` +M``!0`'P_8#````F@9-DG````4`0^#A"`C]@OH/K_+P``H&$$_A]@H.;9+P": +M)F``^O\O@+?8)P0^#A``B]@O(/;_+P``H&$"_A]@H.79+P":)F"`]?\O`+/8 +M)P0^#A"`AM@OH/'_+P``H&$!_A]@(.'9+P":)F``\?\O@*[8)P0^#A``@M@O +M(.W_+P``H&$(_A]@H-S9+P":)F"`[/\O`*K8)P0^#A"`?=@OH.C_+P``H&$# +M_A]@H-39+P":)F``Z/\O@*78)P0^#A``>=@O(.3_+P``H&$```!0H-/9+P": +M)F"`X_\O`*'8)P0^#A"@?-@O1/Z?80``H&$`@N!A``0!8@"&P6'L_PU``((@ +M4"`DVB\0_E]@H`4`(`""(%`!_@!@`WY`@`*"!P``!&"`_O\`8`"`34#L"0$( +M`?X@0``&`&CL`8$0$/K@5P7Z_R<`!`<("'Y(@`A^((`!!`<(``(`0`($)P@` +M$``8`(0@:`"08!@@"P`@``1!4``$(4``@HU`[`DB"`%^04``@`!X`!"@&``. +M`!@```!``'P`0$R^`@`$"2`("/X"D````$``?`!`3,`"``0)``@``B!X`()A +M>`"0`1C%]/\G[(D-""`&`"`'_C]@``!`0`]^`)``!`!H +M`!!@&`""`$``@$U`W`D!"/__($``@&%``)`!&-P'@1``@^!G@OG_)P`$!P@` +M@$80`00'"`&`1A`"!`<(`H!&$"`%`"`#_C]@`?X`8`-^0(#^_P!@`(`-0-P) +M``@`@H9!``0`D```1A`!_B!`$/K@5X7Z_R<@A-@G1/Z?82`#`"``"()0`@A@ +M``"(@$$`!D80`7YB0`".@1@`">%7#(`/.`#\_R<$/@X0`$?8+P```&(`@J!A +MH`O9+P`$X6$``,!A(#K<+Q/^'V``?)]@4+("`)`)(@@`?%]@`(@"``"$8$`= +M_A]@`(1`0``AZ&<``$$0@0,`(`!\7V`@S@(``'P_8&$'``"@ZPXH`+X/8(#_ +M_R<"H$$0(`,`(````%``A$8(`(`A0`.$0!`!_J9!`7X`0`-ZX%>%_/\GE`4" +M"!/^/V`!@$$0'?X?8`'^7V"@X`TH`)YG8"#ZV"\`'`=@@%?8)P0^#A"`*M@O +M(/78+P``P&$``*!AH"/<+P+^'V``?)]@4+("`)`)`@@`?#]@`(@"``7^7V`` +M`H!!``1&$)0%0@@``F!``81!$`("```"_C]@`?Y?8*#3#2@`'&=@(.W8+P": +M!F"`2-@G!`A`"`2(8`@`A>%7@@0`(`((0`@"B&`(`(7A5X("`"``"``(`(@@ +M"`"!X%""0`@`(1`"``%X6<""``@ +M`81@"`$$0`@`!^%7`@8`(``%X6%7C`,`(`!\7V`HS@(``'P_8-0#```@M`XH`+X/8(#__R>@)=@G +M``8`4!]^8&``@H$8``:B0$!^8&`&_F&0`8:?4``&?P@^Q`(`('X`8`""81@/ +M_F%``(CAIP#R8E`%?@"0%'[@IP`*'PBZY0(``(:<0``"8!@`"A\(O.4"```" +M`!@`!@!```@`0``%X6<`#&`8@0``(```@1``!!\(J+("```"`$`@@`\X``8` +M4`0^#A`@Z=`^_\G!#X.$(#(UR]#_O^!`'P?8M3D`@```,!AH`,`(`+^OV$"_B:``(1` +M0*#C_R\```$0"`#'"0'^ID$`'>=G`08`("+ZYE<&!0`@#``'"``!X&<`($A@ +M`OG_)P"^#V``?%]@U-<"`*!L#B@4_B=`@/__)P``WPE0YP(```,`(`+^)H`` +MA$!`(-C_+P```1`(`,<)`?ZF00`=YV=G`"!(8($$`"`,``<( +M``'@9P+Y_R<`O@]@`'Q?8-37`@"@50XH+_XG0(#__R<`O@]@`'Q?8-37`@"@ +M4@XH+OXG0(#__R+`P`@`'Q?8-37`@``?#]@ZP$``*`M#B@`O@]@@/__)P,$1P@`!>%G +M`7Q?0(`````"?@"``'P@`-3D`@`@?PDH!'X'0`"$!@@!?@!`H)O7)P"`1A`` +M"$`(`(2`$`((0`@"A(`0!`@`"""`#S@$@(`0!#X.$(![UR\``"!B`()@8@`$ +M`6(`AJ%A#/Y?8@">YU$`@`$0!'X`0`2``1`(_@A`"(`!$`K^"$`,@`$0`!S' +M41B<`1`!G*)P!$(&C]B\''4H0 +M(&'I+P`HBE(`!#\(]ZP"`(!$^R^``P`@`"()0!"`!A``I`A``00`"`)^`$`` +M)`!``!!`&@"EZ5<,&P`@`J0(``9ZX%>!"0`@B1$`(`5ZX%>-^?\G`WR``8!& +M`0``?(9!H%$`````!CCL`NX%[@@````B"4`@]?\G%(`&$``B"4"@\_\G&(`& +M$``B"4`@\O\G((`&$``B"4"@\/\G'(`&$``B"4`@[_\G)(`&$``B"4"@[?\G +M*(`&$`/ZYU<*[/\G`"()0""+\2\`GB=@`7X`0*#I_R<`#N`9)7X`4`UZX%>- +MY_\G`WR``1!'`0``?(9!Q%$`````!C@$RLKPRNK*RLK*RLK*[0``H$'A+P`B +M"4"`X?\G`_KG5PN>!V"KKO$O"X(@4""`1@@`!>%G`1``(`-^")``$&`8!`0! +M"/Y_`&``@"%0`('A5P"0(!@+!@`@`00!"`-^`%``$``8`('@5XD#`"```@%` +M!00@"`=^"&`!@!^```*`8B`!`"`LJ$80+)Q&$``IZF>!`@`@`'P_8."7`@`` +M@``(`7X`0`"``!`$!`$(`7X`8*!:UR\O +M(%(%*!S^/V!`^N=G@08`(+W^'V"@P`@H`)XG8$#^'V`(@`84#,`&"+]_`&`, +M@`84,$4G"*"\""B]_A]@`?X?8#`!1Q0(^N=G`0D`(````%#_@4T0"/X?8@B@ +M!A2@F?,O__\-0``!X&$!`@`@H)KF+PR`!PB@@_,O`)X'8)9%!P@``>!G`OK_ +M)_^%#0@``>!G@OC_)R`NUR01`%I$$0!JA!$`>F +M01`(_B%`(`,`(``$05``A`8(`7Y!0`"`0!`!_B!``?ZF00"%YU>)_/\GE`4" +M"``<)V`!@$$0`(0!"`'^7V`@CPPH`*)H8*"HUR\`(`A@``K7)P0^#A"`UM8O +M@*/7+P``H&$!_C]@`'P?8'"L`@`X`T`0H,WW+Q!_`$```>!G`0,`(`"^#V`` +M?%]@^,T"`""'#2CB_C^`@/__)R">UR\`F@9@@/C6)P0^#A`@V=8O,/Z?8>+^ +M7X+__Q]B`'R_87"L`@``?-]AO.,"`*`"`"``GN=1!_X?8HO^'V`W?BE`@(4( +M*!#_!D"@F_`"`X +MA08*`"'H9X('`"",_A]@('@(*!Q^*4"@'Q`H^/\-0`".*!@@#A`H^/\-0``% +M`"``O@]@`'Q?8/C-`@`@:@TH$'XI0(#__RN!7`GW@5P8````!XO\G +M.84F"`'ZX%AG`>#_)PAZX%>"`@`@```'"/B!#1`$``<(H`$`(/R!#1`@ +M#!`H^/\-0(O^'V`@8@@H17XI0/C_#4`@!@\H`((@4````&*+_A]@H%X(*``@ +M*&`">NA7#7P(4@(```"`UO\G__\?8CB?1A"+_A]@(-3_)U-^*4`$?@"``'P@ +M0,C-`@`,@``(`'Q`:``,```$@``(``0`%`"`#S@$?@"``'P`0,C-`@`(```( +M````"""`#S@`@``0`'P?8`0`(```@`\X`'P?8`0`(```@`\X!'X`@`!\`$#( +MS0(`!```"`!```@!?@!@((`/.`"``!`$?@"``'Q`0,C-`@`$`"$(`,``"`)Z +MX&<"@`\X#``!"`!\`&@``@```(``%`"`#S@$/@X0H(;6+QS^GV$@4-``'Q?8,C-`@``!"!```1``/R!#0@```$0 +M#(``"`!\0&@``0``!(``"``$`!2@2=!_?\G`(`&"``! +MX&*!P`@!O[FIP3_!T``<@!`H"C^+P`< +M)V`!>N!7@OK_)P'^'V(`?#]@E`<``"`!""@R_A]@,OX?8*#_!R@`FB9@(&W6 +M)P`@"&```>!G`@,`(`!\'V"LY0(``(`/.`!\'V"NY0(``(`/.`%ZX%>!_?\G +M((`/./__'V```>!G`@,`(`!\'V"$Y0(```,`(`!\'V"8Y0(`@`$`(`%ZX%>! +M_?\G__\?8`"`#S@``>!G`@,`(`!\'V"XY0(``(`/.`!\'V"YY0(``(`/.`%Z +MX%>!_?\G((`/./__'V```>!G`@,`(`!\'V"PY0(``(`/.`!\'V"TY0(``(`/ +M.`%ZX%>!_?\G((`/./__'V`$/@X0H"_6+RC^GV$D_C^"`)[G40`@"%(`?+]A +M&,4"`"`"`"``',=1`(+@80%^QT$`@@!B`(`&"``!YU<&%@`@`?X?8``<)V"@ +M$?TO_/]-0`"?YV?\@2T(`@D`(`2```@``>!G@@0`(`B```@``>!G@?;_)P"^ +M#V``?%]@U-<"`"#-#"@G_BA`@/__)P"^#V``?%]@U-<"`"#*#"@F_BA`@/__ +M)P2```@``>!G"`(($(($`"`(@``(``'@9X'M_R<`O@]@`'Q?8-37`@"@PPPH +M+OXH0(#__R<`O@]@`'Q?8-37`@"@P`PH+?XH0(#__R<`G@=@H$36)RC^GV$$ +M/@X0``C6+P`((`@`@^!G``"@8:()`""B_M^!H-G\+P```%```>!G`04`(!+^ +M'V`@P`!G@2K6)P"^#V"@#PTH(7XG0(`HUB<`B`8(`7X` +M0"`GUB<`@(80$OX?8""Y!R@K?B=``/S_)P0^#A``-@X0`#AN8Q!^CE,``"!@ +M__\?8``'`"@$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,0?HY3```@8`!\'V`` +M```0@`$`*`2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8QA^CE,0&@X0%!P.$``` +MH&$`@L!A`)H&8`"N`"@```<0`'K@5P$"`"``F@9@`'P_8```(`B`N-8O$`"N +M"10`S@D$@.T+((`/.!@0;@L$/@X0`#8.$``X;F,0?HY3```@8`&&'QB`\?\O +M!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC$'Z.4P``(&"`_A]`@.S_+P2`[0L@ +M@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,``"!@`'P?8````"``Y_\O!(#M"R"` +M#S@0$&X+!#X.$``V#A``.&YC$'Z.4P)^0(``?`%`L,\"```!``@`X?\O!(#M +M"R"`#S@0$&X+!#X.$``V#A``.&YC$'Z.4P!\/V`"`"`(`)W6+P2`[0L@@`\X +M$!!N"P0^#A``-@X0`#AN8QA^CE,0&@X0%!P.$```P&$`?+]A!``P`("0UB\` +M@"8(^_\@8`"<('``@@80@)#6+Q``K@D4`,X)!(#M"R"`#S@8$&X+`'P_8`0` +M,```@"`(`(``8`"`#S@$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$$`#```(76 +M+P"`)@C[_R!@`?X@:`""!A``A=8O$`"N"02`[0L@@`\X%!!N"P0^#A``-@X0 +M`#AN8Q1^CE,0&@X0`'R_800`,`"`?-8O`,`F"/K_(&``@@84`'W6+Q``K@D$ +M@.T+((`/.!00;@L$/@X0`#8.$``X;F,8?HY3$!H.$!0<#A```,!A`'R_800` +M,`"`<]8O`(`F"/O_(&``G"!H`((&$(!SUB\0`*X)%`#."02`[0L@@`\X&!!N +M"P0^#A``-@X0`#AN8Q1^CE,0&@X0``"@80!\'V`!`"`(`&_6+P`:`'``?#]@ +M`0`@"`!NUB\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC$'Z.4P!\'V`` +M```@`/3_+P2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,%>N!7A@(`(`)^ +M((``_`!`L,\"```!``@`[?\O!(#M"R"`#S@0$&X+!#X.$``V#A``.&YC%'Z. +M4Q`:#A``?+]A&``P``!6UB\`@"8(`/P@8/]___\`@@80`%;6+Q``K@D$@.T+ +M((`/.!00;@L$/@X0`#8.$``X;F,4?HY3$!H.$`!\OV$8`#``@$W6+P"`)@@" +M_B!H`((&$`!.UB\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC%'Z.4Q`: +M#A``?+]A&``P`(!%UB\`@"8(`?X@:`""!A``1M8O$`"N"02`[0L@@`\X%!!N +M"P0^#A``-@X0`#AN8Q!^CE,`?!]@````$(`!`"@$@.T+((`/.!`0;@L$/@X0 +M`#8.$``X;F,4?HY3$!H.$```H&$`?!]@`0`@"``]UB\`&@!H`'P_8`$`(`@` +M/-8O$`"N"02`[0L@@`\X%!!N"P0^#A``-@X0`#AN8Q!^CE,!AA\8@/3_+P2` +M[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE.`_A]``/#_+P2`[0L@@`\X$!!N +M"P0^#A``-@X0`#AN8Q!^CE,`?!]@````(`#K_R\$@.T+((`/.!`0;@L$/@X0 +M`#8.$``X;F,0?HY3!7K@5X8"`"`"?B"``/P`0+#/`@```0`(`.3_+P2`[0L@ +M@`\X$!!N"P0^#A``-@X0`#AN8Q1^CE,0&@X0`'R_81@`,```&]8O`(`F"`#\ +M(&@`@````((&$``;UB\0`*X)!(#M"R"`#S@4$&X+`'P?8!``,```?%]@&``P +M``````@`?"!@#\\``````0@``B!@`((?4``"`&@??@"(`(`/.`!\'V`0`#`` +M````"`)^(&``@A]0``(`:!]^`(@`@`\X`'P?8!``,``````(!'X@8`""'U`` +M`@!H'WX`B`"`#S@$/@X0`#8.$``X;F,4?HY3$!H.$```H&$`?!]@$``P```` +M``@!?B!@`((?4``"`&@??@"(`'K@5X$#`"``?!]@```@"``$UB\`&B!@`((? +M4``"`&@??@"($`"N"02`[0L@@`\X%!!N"P!\'V`0`#``````"`!\(&``@``` +M`((?4``"`&@??@"(`(`/.`0^#A``-@X0`#AN8Q!^CE,`?!]@2,,"```%``@$ +M>N!7C0,`(``%`"`@_A]@`%O_+P`(`"`0_A]@@%G_+X`&`"``O@]@I?X_0``R +M#"B`!``@`GZ`@0!\A@$<6`$````&./Q5``#Y50``_%4``/E5```,5@``!(#M +M"R"`#S@0$&X+!#X.$``V#A``.&YC&'Z.4Q`:#A#\_PU`@/7X+_R!30@`?#]@ +M2,,"``B!``@```%0`'W@5P"@#P"%.0`@`'P?8*"8`@```$`(`'P?8!CW`@`` +M```(``1`0`!\'V!\]P(`````"``$H$$$@0`(`(`&4`!]X%<``@``!0,`(`!\ +M/V``D`$``'P?8#3G`@```@`0`"P`(`!]X%<``0``!0,`(`!\/V``(`,``'P? +M8#3G`@```@`0@"<`($!ZX%<%`P`@`'P_8`"P!```?!]@-.<"```"`!"`(P`@ +M$'K@5P4#`"``?#]@`$`&``!\'V`TYP(```(`$(`?`"``>N!7@0(`(#+^/Y@` +M?!]@-.<"```"`!``'``@`'Q?8`!`'P``?!]@-.<"```$`!``A0`(`WK@5X(1 +M`"`$>N!7C0,`((`%`"`@_A]@`$7_+X`(`"`0_A]@@$/_+P`'`"``O@]@`'P_ +M8",!``"`_@LH@`0`(`)^@($`?(8!N%D!````!CAB5@``7U8``&)6``!?5@`` +M%8``'56 +M``"*5@``````4(!V`"@`?#]@2,,"``2;`!#\@4T("(4`$!``K@D$@.T+((`/ +M.!@0;@L$/@X0`#8.$``X;F,0?HY3`'P?8$C#`@``!0`(`7K@5P$#`"!`_A]@ +M@`C_+P""(%``?!]@1N0"```"0!`$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,0 +M?HY3`'P?8$C#`@``!0`(`7K@5P$#`"!`_A]@@!S_+P'^/V``?!]@1N0"```" +M0!`$@.T+((`/.!`0;@L$/@X0`#8.$``X;F,0?HY3@&[A+TH$``@`?#]@2,," +M``"!0!`$>N!7@1(`(`1ZX%>-`P`@``4`("#^'V``]/XO``@`(!#^'V"`\OXO +M@`8`(`"^#V"E_C]``,L+*(`$`"`"?H"!`'R&`51;`0````8XRE8``,=6``#* +M5@``QU8``-I6```@_A]@@.K^+P!\/V!(PP(``(4`"`%ZX%",0`@_/\-0`!W^"_\@2T($(,&$`!\'V`PYP(```0`"`!ZX%<"`0`@```' +M"(`!`"``?!]@..<"``````@`?+]A2,,"`!2!!A"`*``@_/\-0`!N^"_\@2T( +M`'R_84C#`@`0@08(`(``4`R!!A`4@28(`('@5PD@`"``?!]@,.<"```$``@! +M>N!7`@X`(```!P@4@080`(4&"`1ZX%>-`P`@``4`("#^'V``N_XO``@`(!#^ +M'V"`N?XO@`8`(`"^#V"E_C]``)(+*(`$`"`"?H"!`'R&`1Q=`0````8X/%<` +M`#E7```\5P``.5<``$Q7``````!0@!4`*(`0`"``?!]@..<"``````@4@080 +M`(4&"`1ZX%>-`P`@@`4`("#^'V``R?XO@`@`(!#^'V"`Q_XO``<`(`"^#V`` +M?#]@(P$``("""RB`!``@`GZ`@0!\A@&870$````&.%I7``!75P``6E<``%=7 +M``!K5P```?X?8``&`"@``0`@`(``4!2!!A#\@2T(`'R_84C#`@`0@P80$`"N +M"10`S@D$@.T+((`/.!P0;@L`?#]@,.<"``"`0!``@`\X`'P_8!``,```?!]@ +M&*<"``P!``@`@``0`(`/.`0^#A``-@X0`#AN8Q!^CE,`?!]@P&L`@`!\/V!# +M```)@"W5+P2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q1^CE,0&@X0``"@807Z +MYE>!!0`@@"'5+P7^1H``?#]@&*<"```"04`$`2$(#`%A"`#`0`@`!D%P`(0` +M%``?U2\0`*X)!(#M"R"`#S@4$&X+!#X.$``V#A``.&YC%'Z.4Q`:#A```*!A +M!?KF5X$%`"``%M4O!?Y&@`!\/V`8IP(```)!0`0!(0@,`6$(`,!`"``&06@` +MA``4@!/5+Q``K@D$@.T+((`/.!00;@L%?F"``/Q!0!BG`@```4$(`$!!"`-Z +MX%<"`@`@`'Q!8/___W\`A``0``8`(`1ZX%>"!``@`'Q!8/___W\%?@&```0` +M4`)^`(``!`!``GX`B`"``!"````@`(0`$`"`#S@$/@X0`#8.$``X;F,8?HY3 +M$!H.$!0<#A```,!A`(*@805^)X``_`!`&*<"``@!``@`A/XO`WKG5X(!`"`` +M_*9I````@(`#`"`$>N=7@@(`(`+^!H!]_C]@@(W5+P!\H&D```"`!7XG@`#\ +M`$`8IP(```$`"``:`!0$>N=7@@,`(`5^)X``_`!`&*<"```!``@`0``(`('F +M5X+\_R<%>N=7`0$`(``N!7@@$` +M(`!\XF#___]_``H`(`1ZX%>""``@`'RB8/___W\%_F*``(IA4`+^88``BF%` +M`O[AB`5^H(``?']@&*<"``"&HD``@6((`,"!"!"!P@@`#>)7@OO_)X```"`` +M".)@`(X@4``"`1``^N!7@@0`(`5^H(``?']@&*<"``"&HD`<@6((`(1A&`"" +M(4```@$0@`,`(`5^H(``?']@&*<"``"&HD`<@6((`((A0``"`1"`G?\O!(#M +M"R"`#S@0$&X+`'R?8!``,``%>N!7@0<`(`5^0(``?!]@&*<"````84`,@0$( +M``!""```06``A!]0``0`:!]^`(@`@``0`'K@5P$!`"`,@0$(```"$`"`#S@` +M?!]@"``P``````@`@`\XH`$`(``$05`!?B%``(Y`&`-ZX5>*`P`@`H1_4`(& +M(``!_B!``(_@'P`&8$`A^_\G`()!$`"`#S@``"!@H`$`(````%`!?@!```X` +M&`-ZX%<*@`\X``!@0`2&0``!?D%``!'A'P"&8$`B@`\X`(2!$`#Z_R<`"()0 +M``1!4`!\_V#@M`(`(`<`(&"%PP@&?B"``(Y@0)*)(0@!A+^``(O@9X$"`"`` +M">)G`@$`()6%01`!_I]@E(5!$`%^(4``CD`8``WA5PJ`#S@`^/\G!#X.$"#; +MTR\P_I]A`'S_8:S9`@`4@0<(`'P_8LBS`@#X@0T0&(4'"`!\WV&\YP(`_(%- +M$`!\'V``_0(`'!P`$`!\!Q"^Y0(``'R_833'`@`\_P9`!``'$!1\!Q!4P0(` +M`?X?8`'^/V"@?>@O__]-0/^%#0@`?!]BE)D"``-^`(````A``WK@9P@`!Q`A +M`P`@F/Y?0@"^#V#2?BE`H'(**`#_1T"`__\G)/X?8`""(%"@=.@O__]-0/^% +M#0@#?@"````(0`-ZX&<,``<0@0(`(`"^#V#6?BE`(&L**`#_1T"`__\G9/X? +M8`""(%`@;>@O__]-0/^%#0@#?@"````(0`-ZX&<0``<0@0(`(`"^#V#:?BE` +MH&,**`#_1T"`__\G`(`H"$F$H`@0BT804/KB5P#_@%`)I(!`H`(`(``$05`" +M!&(``!H!0#P'0!`!?D%`>GKA5PO]_R=.A``(4/KB5SB!1A",1P`@8(8`"`#\ +M0$```@````"@0``'`0@``(!`H`,`(`"&85``A@!`808`"```P$``A@U`^`U` +M$`'^84`%^N%7"_S_)P!\?V"$VP(`(`X`(``,PU``#"%!`84$"``,0T$/?@!@ +M````0````E``!N5``(%#$`",`$'F!`0(`7[#0`]^`&````!``(`"4!"!0Q`! +MA00(`7[E0`1^`)````!````"4`"&XT``@4,0Y@0$"`1^`)````!``(`"4!"! +M0Q`'>N-7B_'_)P```%#\AZT(^(L"@`@#(1$40AZXE>+`0`@#WKB5RP(`"`,!$11$'KB5XL!`"`3 +M>N)7K`4`(`R$0U$4>N)7BP$`(!YZXE+`@`@)'KB5XD! +M`"``A$)1``9"0"`501`!?D)!!WKE5X'K_RN57@0X`(.V&0`@$?D&0`'KE +M5P`$04"+`0`@!GKE5ZSG_R<,A&11"'KE5XL!`"`/>N57+.7_)PP$9%$0>N57 +MBP$`(!-ZY5>LXO\G#(1C411ZY5>+`0`@'GKE5RS@_R<,!&-1'WKE5XO?_RN57B=[_)R#=_R<`A&)1((=!""`#`"````!0((N!7B_S_)Q&%1A```@$8`WX`4!*!1A``M^`OH);3)S#^GV$$/@X0H&33 +M+P".XU```%\(R+,"``!\7V(``@``D`9A"9$&00E@!@$(D@8A"0```$$`"()0 +M!?X?8`!\WV"TQ@(`%`&#$`!\/V"$YP(``'P?8`#]`@`<`@`0`'R_8"3;`@`` +M_P)``(``$!#_`D`$@``0(/\"0`B``!`4_``0ON4"`!A_`T`8@``04/\"0`R` +M`!!`_P)`'/P`$'"8`@`@_``0=)@"```$?PC%LP(`)/P`$)"8`@`#^N%7*/P` +M$)28`@`B!@`@$(``$``$'PC$LP(``'K@5XP#`"!@!@$(````0``*X!@#?`$` +M``$``````$``"H`8`)JF42`'`"``@B!0`OX'0`"``U!``4<0`"0!0``:`$`! +M!0`(!'X`D````$`"?@!````"4%`!1Q`!_J9!`OX@0`?ZYE>*+0`@`!KA0:&$ +MQPD`?!]B1><"``]^!V`(>N=G`GP`:/`````""@`8`!+`00"*($$@G400FH0G +M"@_^"&`(^NAG`GP`:/`````""@`8`!1`00"51!"3A"<*#_X(8`CZZ&<"?`!H +M\`````(*`!@`!`@*`!9@00%ZZ%<0ET00#`P`(.:$!P@/?@!@`_KA5P``($(" +M"``@``0?",2S`@``>N!7#`8`(`+^"$``@`-00(%$$``D`4``&@!``04`"`]^ +M`&````!``GX`0````E`@`P`@4(%$$`+^"$`@`0`@```$4"#^'V`P@400H88' +M"`'^($($?@"0`!P`0``*(!D`BLA!(`%'$)J&!P@$?@"0`!0`0``*0!D``4<0 +MDX8'"`1^`)``%@!``7KH5Q`!1Q"L!@`@``I@&>:$!P@$?@"0`_KA5P``X$$" +M`@`@``0?",2S`@``>N!7"<[_)P+^!T`@`0`@```$4"#^'V`@T?\G,`%'$`/Z +MX5>"!P`@``0?",2S`@``>N!7C`4`(*`#`"``@B!0`"0!0``"`$`(!V`(`(P` +M0!@'0!`!_B!`#OK@5XHLTR>`^_\GH`(`(`""(%"H!F$(`(P`0!@'0!`!_B!` +M#OK@5PHHTR>`_/\G!#X.$*#STB\``,!@(+W\+P""`&```*!@H+7\+P""`&`` +M`$!@(,;\+P""`&```&!@H+[\+P""`&```(!@__OB5P+]X5?_____`GWA5___ +M__\"?>)7_____X(#`"``?%]@*,X"``!\/V!U!```H*`)*`"^#V"`__\G``P# +M8""2]B\`BB)@@!#3)P!\'V`4F0(``(`/.`0^#A`@X=(OM_X?8`!\/V!9!0`` +M@*$$*`!\'V!X&0```((@4*!=U2\$_E]@``G3)P0^#A`@V](OM_X?8`!\/V!@ +M!0``@)L$*`!\'V!-&0```((@4*!7U2\(_E]@``/3)P0^#A"@U=(O%/Z?80!\ +M'V`@]@(`````"(!ZX&<"#@`@@/KD+P``8&``?)]@T,,"`#`%`@@`CB$8((WG +M+___34#_A0T(`WX@@`!\'V"4F0(``(?A9P`"0$""!@`@``H?"+[E`@#[?^"G +M`/P<0)OW__\(?@"0!'X@0`0&`0@``@!``'K@5PD0`!@,``!0`@&"$"`&TR<4 +M_I]A!#X.$`#'TB^@D=,O``#`80``H&$@P-8O`OX?8`!\GV!0L@(`D`D""`!\ +M/V``B`(`%/Y?8``"@$$`!$80E`5""``"8$`!A$$0`@(```+^/V`!_E]@('`( +M*``<9V"@B=,O`)H&8`#ETB<$/@X0@,;2+XW^/T(``*!A`'S?85"R`@`T`><) +M`?X(0"!T!"@`GB=@`'P?8@``(``P0"@(\/]?@C0#!Q"@<`0H`?X(0#!`*`@T +M`P<0H&X$*`'^"$`T`0<(`('G5S@!)PBN!``@1/Y_@@"`!U``)>!7!00`(`'^ +M`$`X`0<0`?X(0*`%`"!#_BE``!X`4``EX%<&!0`@H&4$*`'^"$`T`0<(`(`& +M$#@!!PB@U-(G!(`&$`!B!"B@^_\G.`$G"/__`$`X`0<0`?X(0*#\_R=3_BE` +M!#X.$""@TB\"_A]@H'\!*&G^WX$`?+]A+-8"`#Q^!T`"_C]@A/]&0""W`R@` +MAF%0/7X'0`+^/V""_T9`H+0#*`"&85"@>`$H`?X?8`!\'V`+@@```OX_8(C_ +M1D"@L`,H`(9A4`!\'V`,@@```OX_8(;_1D"@K0,H`(9A4`"[TB<$/@X0`)_2 +M+P``@&(`!!\(T>0"``%ZX%<`@F!B`;W2)Z!7TR\?_A]B``!`8B"&UB\\_A]@ +M`'P_8E"R`@"0B>@)`'R_80"(`@``FL=!`)J'00`@1A``*`I@`!PG8*"0!"@\ +M_E]@`)J'092%"`@`($80`0!'$`*:!P`\_C]@`?Y?8*`S""@`IFE@($W3+P`D +M"6"`KM(G!#X.$""#TB\D_I]A````8@""X&&@1M,O``2A80``P&'\_PU``((@ +M4"`4"2@!_E]@`(Y&&/S_#4`@V_DO@/X_8/R!30@`(`A@`)XG8"`,\B\!_G]@ +M($'3+P`(G!#X.$(![TB\``,!A`((@8@`$`6(@9.0O`)[G40`('PA@ +MPP(``?Y?8@!]X%<@0@``(@(`(!5^J8$8_`84$!`````!`"`8_`84,C(```'Z +MZ%AG`@<`("`N^B\#_A]@`'P?8%S$`@`@ +M+/,O#_X_8``!(&`!!0`@(!,$*"[^'V``O@]@(&0)*+#^/V```@`@("?Z+P`` +M`%`@'0PH"7X)@`!$'PB\Y`(```'@9P$#`"``?!]@#-H"`("2_R\`?!]@>,0" +M`(`I]B\```!0H`GV+PI^*8`!_A]@(`CV+PI^*8`$_A]@H`;V+P""(%`%_A]@ +M(`7V+\#^/V`!>N=7@@L`(*"H^R\!_A]@`/X&%$#^'V``@`84```_"!C%`@`` +M``!0%H(_4*!Q[2\`!$%0``'@9P``'Q!0YP(``@,`(`"^#V``?%]@U-<"`*#P +M""C7_C]@@/__)Z!U^B\`G@=@`+@&*`7^'V"@]O4O`((@4````%`@]?4O`((@ +M4`'^'V"@\_4O`((@4`%ZYU<"`0`@@(X&*(```"``=/PO````4"`8]B\#_C]@ +M`%[2)P0^#A``*M(O``0`"`5ZX%<"?>!7!`````)]X%<0````@0,`(`!\7V#4 +MUP(``'P_8,\!```@W@@H`+X/8(#__R<`@^!G`;X/8,$V"2CI_C]``'P?8%S$ +M`@"`'/,O``'@9X%+TB<`O@]@`'Q?8-37`@"@U@@HZ_X_0(#__R<$/@X0@!_2 +M+R#JTB\``,!A``"@8:`8UB\#_A]@`'R?8%"R`@"0"2((`'Q_8`"(`@``AD!` +M!/X?8`"&@$$``$80````4`(`01"4!0((`0!!$`*&```#_C]@`?Y?8*#'!R@` +M'&=@(.'2+P":!F"`/-(G!#X.$*`>TB]`_I]A``#`82[^'V`@S0,H!/X_8`!\ +MOV'1Y`(``(0&"-?^7T(!>N!7`?Y_8J(3`"`N_A]@(,@#*"G^/V`@<08H`)[G +M40'^'V"@YU$``0`@____?P'^YT$\^N=7!@8`((#] +M_R<@M0,H*OX_8"!!_"\`GN=1``$`(/___W\!_N=!//KG5P7^_R<`HBA2%?X) +M@H!I!B@,(@@4`"((%(#^'V````@4__\?8`@`"!0(_A]@#``(%`%ZYU>!!``@ +M(,S_+P```%`!?E\4?[$"`(#-XB\`RN,O(+4+*'W^'Y@`-``@`(0&"`%ZX%>" +M!P`@+OX?8*"C`R@K_C]@`+#2+R#X^2\``,!A```?"%3G`@"`5^TO`*)&$"[^ +M'V"@G@,H`7XI0*"MTB\`'`=@`$0?"+SD`@```>!G`'R_85S%`@"!$P`@`'P_ +M8,#8`@`$@0`(]($-$`B!``CX@0T0#($`".R!#1`0@0`(\($-$"[^'V`@E`,H +M+/X_8""U_R\```!0(++U+^S_#4`<@08([($M"`"``%#T@0T0`'P?8`S:`@#T +M_RU`H',+*.S_34``0#\(P.0"``!`7PC$Y`(`[/\-0`'^?V`0_I]@H`K=+P/^ +MOV`N_A]@H(<#*`M^*4"``@`@+OX?8*"%`R@M_C]@H*;_+P/^'V``J>(O+OX? +M8*""`R@N_C]@`7Y?%'^Q`@``H^,O`"KC+X"3XB\`?-]A9,,"`""-V2\```<( +MH&'9+P```%````<(`_X_8``.`!B@"`$H``('$"[^'V`@>0,H!?X_8`#_!D"@ +MCO(O#_X_8``!(&"!`@`@H'4#*"[^'V``O@]@H,8(*-[^/T`N_A]@H'(#*`;^ +M/V`@[M$G0/Z?800^#A"@O]$O,/Z?80``8&(`@N!A``@?"`JM`@`#_M]A"GY` +M@@"EZ5<`?+]A4+("`*4$`"``HBA20OKG5T$!`"",HT80C:-&$````%"@K.,O +M`)XG8(`:`"``<](O````8B"BU2\+_A]@D(DF"`!\7V``B`(``(1@0"'^'V`` +MA$!```!!$`*B@1`$G$$0@OX?8`6`01`&HD$0!YY!$`C^04``)BE0_(--$`C^ +M`(C]@4T0$/X`B/Z!31"@`P`@`((@4`""#4#\!0`(``!!$`%^04`!_@!```X@ +M&``#YU<)_/\GE(4&"`O^/V`!@$$0`(0!"`'^7V"@1PM$G`(``$``^#A"`5=$O$("-$`""`&(`!.%A +M(!K2+P"&P6$``*!AH$C5+P;^'V``?']@4+("`)")00@`?)]@`(@"```((4`: +M_A]@``B!0```0A`0A`T($81-"`.`0!`"A$`0`?KG5P'^'V`"``!0!'X`@`)Z +MX5<%@$`0JP$`(`2@0!`!?@!H!8!`$)2%`0@!_E]@`8!`$!K^'V`&_C]@H/$& +M*``<9V`@"](O`)H&8``?TR<$/@X0@$71+_+^7T(``,!A`(*@80`$`6('?@!` +MH`/2+P`.(!H``.!A(#+5+P"B"&``?)]@4+("`)`)(@@`?%]@`(@"``"$8$`< +M_A]@`(1`0```01`"G$$0`7X)0`.`01`(?@"(!(!!$/3^'T`%@$$0"'X`B`:` +M01`'_@%`H`(`(`""(%``!$`0`7X`0`'^ID$!_B!```/G5XP$`"``A$8(@'KA +M9X'[_R<`O@]@`'Q?8"#.`@"@V@4!0((`*(H8`&`01``A`$( +M`?Y?8*#4!B@`(&A@(.[1+P">!V"`3=$G!#X.$(`>T2\``,!A`'R_81C/`@`! +M>N!7`GWG5P(````!`P`@`+X/8`!\/V#L`@``(,X'*`C_1D"`__\G`?X?8`__ +M)D`@VO\O``1!4`)ZYU<```!0(@4`(`_^/V``_T9``OY_8(/^GV"@'_HO`(JB +M4````%`;_C]@H`0`(`+_1D`$_T9``OY_8(/^GV`@&_HO`(JB4````%`;_C]@ +M!O]&0`+^?V"#_I]@H!?Z+P"*HE``,]$G!#X.$``7T2\``(!B(-+1+P""8&(` +M`$!BH`#5+Q3^'V``?#]B4+("`)")Z`D`?+]A`(@"``":QT$(_A]B`)J'00`@ +M1A``*`I@`!PG8*`*`R@4_E]@`)J'092%"`@`($80`0!'$`*:!P`4_C]@`?Y? +M8*"M!B@`IFE@(,?1+P`D"6"`*-$G!#X.$(#WT"\`>N!7`(:A8:P!`"##_M^! +M"'K@5PP#`"``O@]@`'Q?8"#.`@"@IPN!7`@P`(```?PC8Y`(```0!8`""(4`@\@(H$/Y?8`";YF!7(`````$#`"``O@]@`'Q?8"#. +M`@`@B`^!G`0,`(`"^#V``?%]@(,X"`""$!RC(_C]`@/__ +M)P,$!P@%>N!7`GW@5PT````"`>!G`GW@5Q`````!`P`@`+X/8`!\7V`@S@(` +M('T'*`'^)T"`__\G@/S2+P]ZX(>$`P`@P/X?8"""`B@%_B=``!P'8""Z_R\` +MFB9@`.W0)P($!P@#?J!AP/X?8*!]`BC0_C]`%/[FIP````(&``!!\(`,,"`(#]\R<$/@X0 +M(+?0+RC^GV$``>!AY?X?0@(#`"``O@]@`'Q?8-#8`@"@8@!G#/[`00(&`"`!_A]@"H!&$``$05`3A$80((2&$`O^'V`,@$`0*(2` +M$"*(!@@8?@!`H`,`(`Z`@!`'A`8(``'@9X$!`"`QA``("'X`:#&`0!``?#]@ +M-LT"``"%``@!`$<0`7X`0``.0!@/>N%7`(%`$`P!`"````!0`(%`$``$'PC0 +MY`(``7K@5P)]X%<"`````0,`(`"^#V``?%]@T-@"`*!&!R@C?BA`@/__)QD` +M1Q`@]08H`!P'8/S_#4`!_C]@H"@'*`'^7V`!!`<(@/X_8/V!31``!`<(_H%- +M$/S_#4"@YO%7"@$`((`!`"@`D-`G@)H`*`"/T"<$/@X0H'G0+SS^GV$``"!B0_X?8*`@ +M`B@`HBA@`*/H9Z+^WX("`P`@`+X/8`!\7V#0V`(`(!0'*`)^*T"`__\G"(`( +M"``!X&!G,'Y(0@("`"`!_A]@"H!'$*"^ +M!B@`G@=@H,[T+P">!V`@B`<($X2G"0"!YE<,`P`@`+X/8`!\7V#0V`(`(/P& +M*!]^*T"`__\G`00)"/M_(&`!`DD0((@'"`"!YE<*`0`@!/X`:`$`21"@`0`@ +M`"B*4@%^"D``#H`:`WX*@`"`QT$D!`<(`('F5P$$`"`.>NI7B_O_)P"^#V`` +M?%]@T-@"`*#O!B@L?BM`@/__)P#\9T(``@``XH4)"`/^/V```>!G"X2G"@)\ +M/V`$````&OKJ5P'^`$`!#B`8X85)"`"H!D``!>!7"P,`(`"^#V``?%]@T-@" +M`"#E!B@\?BM`@/__)P":X*<`J!Q````!4``.0!@@B`<(`('F5_]_`4`!#D`8 +M!X0'"`!ZX%>,#``@`)OF9X$%`"`6"`D(`'P`8/#_````&@!H%@")$""(!P@` +M@>97@@$`(-V%"0C[?P!@W8%)$``$"0C<@4D0`00)"`A^`&C=@4D0`@@)"-Z! +MB1`$?DE"!/X*4``.H!H!?@%```Y`&/S_#4`@MP8H`?X_8!R`!PB`_C]@#00` +M"/V!31`<@`<(#`0`"/Z!31#\_PU`('3W+P"B2&`#_@I`_'\`8``.(!KBA0D( +M``'@9QR`9P@!%0`@$H0!"`QZ`&`"`P`@`+X/8`!\7V#0V`(`H,0&*'5^*T"` +M__\G`)OF9P$%`"`(>N!7`@0`("0$!P@`I"A`)'[@IP#R!T"P?@!`(!4"*`C^ +M7V`<@&<(`"@*8`">)V``I$A`H/`+*!3^84#BA4D('(`G"``B`4``#B`:#H@` +M"``$`$`.@(`0'(!G""B((0@`@^!G`1``(.*%"0@`@`!`*("!$"`.`"`<@&<( +M%(0!"``!X&!G`1<`(`YZZE<*#0`@)@@G"`"#X&>!#@`@*``'"``$05`@ +M>>\O`?Y_8`%^"D``#H`:`WX*@`"`QT$=!`<(0'K@9P'X_R<@B`<(`('F5XH- +M`"`.>NI7B@D`(``H"F`@I@4H`)XG8``.@!H!_@9`H/K_)P`.H!D`O@]@`'Q? +M8-#8`@"@B@8HJWXK0(#__R<`O@]@`'Q?8-#8`@"@AP8HK'XK0(#__R<`O@]@ +M`'Q?8-#8`@"@A`8HO'XK0(#__R<]_A]@((L!*,)^*T`@!=`G//Z?800^#A`@ +MT\\O*/Z?80``H&%#_A]@H(8!*`":)F``F^9G`'P_8@`"```"`P`@`+X/8`!\ +M7V#0V`(`H'D&*!'^*$"`__\G"(`&"``!X&!G`@,`(`"^#V``?%]@T-@"`"!G!B@9_BA`@/__)PH$!P@``>!G@@(`(`'^ +M'V`*`$<0H#0&*``"`0`@$@0'"`-ZX%>"`0`@,80` +M"`A^`&@Q@$`0H$GT+P`N!G`@,`(`"^#V``?%]@T-@"`*!- +M!BA(_BA`@/__)PS^04````!0`!PG8``:04`@?PLH%/YA0.(%2`@<`"<(`!H! +M0``0H!D.B``(``0`0`Z`@!`@#@`@'`!G"!2$`0@``>!G`0,`(`"^#V``?%]@ +MT-@"`*!!!BA1_BA`@/__)Q6$`0@``>!G`0,`(`"^#V``?%]@T-@"`"`]!BA2 +M_BA`@/__)Q:$`0@``>!G`0,`(`"^#V``?%]@T-@"`*`X!BA3_BA`@/__)_R! +M30@,_@%``)HF8"`8[R\"_G]@`_X'@```1T`.^N=7B@D`("8((0@`@^!G`0L` +M("@``0@`!$%0H!+O+P'^?V`!_@=``!#@&0/^!X```$=`'00!"$!ZX&N!7#0`?4``!````@(@0`GX'@`!\_V%DQ`(``!X`0)0!``C8_R=`H.[X +M+]K_1T``'`=``!X`0+@+``@`'L=!R`='".B!AQ``BB@(ZH6'$`"``%``!."G +M!/YA8<0``0`0`!\7V"ZY0(`(OK@5P``@1`K`@`@``Q@&$#ZX%?, +M$``@!'X`4$#ZX%<,`@`@C/K@5PH!`"!T^N!7`@D`('3ZX%=!#``@]W\`0(SZ +MX%?!"@`@#GX`0)'ZX%<"_>!7E0```$$(`"`*?@!`F?K@5P+]X%>;````P04` +M(`)^`$"=^N!7`@$`("`$`"``!H$0H?K@5T$"`"#^?P!`I?K@5P(!`"#\?P!` +M``"!$``'UR\%?N"G`/(?4`1^`)```)\0O.4"``!\'V(4F@(``'\(0!3_)T"@ +M]-`O@/Y?8`"**`B,^N!7BP4`(*7ZX%>)!``@E?K@5X$#`"!:_A]@)@&($"@! +MB!!9_A]@*@&($%C^'V`L`8@0E?K@5X(#`"!N_A]@)@&($"@!B!!9_A]@*@&( +M$%C^'V`L`8@0@/K@5XL$`""$^N!7B0,`(%K^'V`F`8@0*`&($%G^'V`J`8@0 +M6/X?8"P!B!`H^N!7BP0`("SZX%>)`P`@;OX?8"8!B!`H`8@0;?X?8"H!B!!L +M_A]@+`&($&CZX%>"`P`@;OX?8"8!B!`H`8@0;?X?8"H!B!!L_A]@+`&($-R% +M)P@`@^!G`HH`&$(!`"#:@T<0VH<'"*`$T2\#_C]@"7X`0``*0!@__C]@(`<` +M(+`%9P@`F@U`_`4`"``$`$``"D`8`((`0``@`$``!8`0`?X&0``.H!D#^N97 +M`9JF4?__`$``#B`8`(?@5PL!`"`?>N%7C/?_)WX)"`C=@4<0H#S/)RC^GV$$ +M/@X0@!'/+SO^OYH``(!B`()@8B#)SR\`!`%B``#@8:#WTB\8_A]@`'R_85"R +M`@"0B28*`'Q?8@"(`@``I,A!$/X?8`"DB$$``$80`?KI5S3_!D``*"I@H@(` +M(```0&``F`@HCOX?0"`"`"`L_BI``*L(*([^'T`S_BI`@*X`*#2!)@B@K0`H +MCOX?0#B!)@@@K``HCOX?0```"@@!^NE7!``'$`0`"@@8_C]@"``'$`'^'V`! +M``!0`GX`0`(`1Q"4A08(`?Y?8`$`1Q`"I`@`H)D$*``@:&`@L\\O`)X'8(`5 +MSR<`/@X0@.K.+Q"`C1``@L!A``2A80"&`6(%_@!`H*O/+P`.(!H``.!A(-K2 +M+P"B"&``?)]@4+("`)`)(@@`?%]@`(@"``"$8$`9_A]@`(1`0```01`0A`T( +M!)Q!$`.`01`1A`T(!?XA0`*`01`@`P`@``1!4`"$!@@!?D%``(!`$`'^($`! +M_J9!``7G5XG\_R>4!0((`*(H8`&`01``A`$(`?Y?8*""!"@`(&A@()S/+P"> +M!V``L=`G`#X.$`#1SB\0@(T0`(*@80`$`6*@E<\O`(;A80``P&$@Q-(O"/X? +M8`!\?V!0L@(`D(E!"`!\GV``B`(```@A0!G^'V`#^N9G`X!`$($#`"``?%]@ +M(,X"``!\/V`U!P``('8%*`"^#V"`__\G````4``(@4`!@$`0"'X`B`*`0!`0 +MA`T(`'Y"$`:`0!`1A`T(!YI`$`6`0!"4A0$(`OY?8`2`0!`9_A]@"/X_8*!J +M!"@`GF=@`"`(8`":)F``!$%0H$SN+P+^?V"@@<\O`!P'8("5T"<$/@X0@+3. +M+P``X&$@?,\O`(+`80``H&&@JM(O!OX?8`!\GV!0L@(`D`E""`!\?V``B`(` +M``8A0!O^'V``!H%!``!&$`'^'V`"@$`0`'P?8"\!```#@$`0"'X`B`2`0!"4 +M!0((!9Y`$`&`0!`"!@$`!OX_8`'^7V"@5@0H`!QG8"!PSR\`F@9@@,S.)P0^ +M#A"@JLXO`_[@IP``H&$`@L!A``0!8@/^'$"@:,\O``X@&@``X&$@E](O`*(( +M8`!\OV!0L@(`D(DB"`!\7V``B`(``(2`0!O^'V``A$!``7KG9P``01"A`P`@ +M\OY?0@"^#V``?%]@(,X"`*!(!2C;?BE`@/__)P)ZYU<#?@)`"@,`(`"^#V`` +M?%]@(,X"`"!$!2C>?BE`@/__)P(<0A`@!0`@``1!4`("0!`#!D`0"/YAB`0& +M0!``A"9``80@"`)^04`%`D`0!GX`0``%YU<,!P`@`7XI0``"0!`(_B"(`0)` +M$`*$)@"`^N!G\_Y_0(+V_R<`O@]@`'Q?8"#.`@`@-@4HY'XI0(#__R>4A0(( +M`*(H8`$`0A``!`((`?Y?8"`P!"@`(&A@H$G/+P">!V``J!7!H0`4`4$`%``@`$0((`/.````%`$/@X0`##. +M+P``P&$`@@!B``2A82#TSB\``.$)`*`G0``#YU<.G"!0(/3.+P""!A"@4&!0`@&/[@IP#\7$"HJ@(`*``!"```8`@D +M``$(````"`"!X5!G@0$`(`"^#V!G_C]@ +M@!X%*`'^YT$8_J9!!'['007ZYU<&.,XG`'P_8*BJ`@```@=`$```"``!X&<` +M@@9"@>__)R@`"`@``"`()``("``"`!`P`@@0+`(($#@`"`@````(``'@9P&^ +M#V!!$P4H3OX_8#0`"`@``"`()``("`````@``^!7A0(`(`"^#V"@#@4H4OX_ +M8#0`"`@``"`(*``("`````@``^!7A>S_)P"^#V`@Z_\G5OX_8"`#`"``"()0 +M``1@"`%^@D``AD`0`?X@0`%^`$``">%7C?S_)P"`#S@"?H&((`,`(`"&85`` +M`$`(`?YA0`"$`!`$_B!`!'X`0``'XE<.@`\X`/S_)P!\/V"HJ@(`"(``"`"` +M0`@````((,#_)P'^/V`8?N"G`/Q<0*BJ`@`T``$(`()@8"@`(0@````(`(`@ +M"""X_R +MGD80GYQ&$`A^QXF@DN!7BFD`*`"(SB\``*!AH`GC+PG^'V"`P.(O((C. +M+P":!F"@Q=\O`?X?8-+^'V"@=?\O^OX_0`#@S2<$/@X0H+'-+QC^GV$`!!\( +M1N0"```!X&<"V_@O`-8%*`%ZX%>.`@`@@-#Z+P```%``@B!0H#W[+P'^7V"` +M"@(H@"T"*``?^"\```!0H#+W+_C_+4````!0__\_8""+^2_\_TU`````4*"R +M^2_X_RU``OX?8/__/V"@A_DO_/]-0`+^'V`@K_DO^/\M0`;^'V#__S]@((3Y +M+_S_34`&_A]@H*OY+_C_+4`#_A]@__\_8*"`^2_\_TU``_X?8""H^2_X_RU` +M!/X?8/__/V`@??DO_/]-0`3^'V"@I/DO^/\M0`7^'V#__S]@H'GY+_S_34`% +M_A]@(*'Y+_C_+4`*_A]@(%7Q+P'^/V`+_A]@H%/Q+P""(%```!\(1+T"``!] +MX%<````"`GW@5P````2!`P`@`'Q?8%#.`@``?#]@-`(``*!#!"@`O@]@@/__ +M)X"]]R^`5,XO____?____W____]_____?____W____]_____?____W____]_ M____?____W____]_____?____W____]_____?____W____]_____?____W__ M__]_____?____W____]_____?____W____]_____?____W____]_____?___ -M_W^`+``H@`3X+R`N!R@*_A^`('_W+_C_#4``?!]@!```]@#*]R____]_____ -M?____W____]_____?____W____]_____?____W____]_____?____W____]_ -M____?____W____]_____?____W____]_____?Z!W]R_X_PU`^($-"``!X&>! -MV_\G`?[_'P#__R<@@`\X`OX?8```'PC@O`(```'@9P&`#S@`?!]@2,4"`(!% -M\2<``#\(X+P"``"#X&!G`4S-)P!\'V!$Q0(`@#OQ+P2$!@@!>N!G -M`4G-)P&$!@@@>N!G`?X?8`$``%```!\00,4"`(!%S2<$/@X0(!?-+Q3^GV$` -M?!]@"@`@"(#IS2\`?#]@"@`@""#IS2_^?P!@(';W+_S_#4``M?!G'_?_!Z$#`"``LDH0T_X?8"#I_B^Y_C]@ -MH(K:+P``!P@`&@<0`"GJ9X("`"``)`E@_/\M0*"-`"CL_TU``(#I"?R!#0@` -M`>!G`1<`((`=SR\%>N!7@0$`(``N!7`A0`(("QS2\`;.XO`((@4""` -M[B](?TA`1`$($``D"6#\_RU`H(,`*.S_34#\@0T(``'@9X$(`"``A`H(`7K@ -M5PP'`"#1_A]@(-;^+]_^/V"@+>(O!OX?8`"$"@@">N!7"P(`(`!\'V````@` -M`'3:+P`!`"`@*>(O!_X?8`"DS2\`I!`0`@@`3/+P-ZX%>"```@`?X_8OBC -M#13XP0T(``'@9P$E`"``*>IG`B0`(("6S2\`4>XO`((@4"!E[B](?TA`1`$( -M$``D"6#\_RU`H&@`*$Q_2$``@`D(`('G5X$!`"#\FPT0(`$`(`":!F#\@0T( -M``'@9P$*`"#1_A]@H+G^+Y#^/T``A"H((+C^+]'^'V!,02@(H+;^+]'^'V!, -M00@(H-0`*/#_+4``A`H(`GX`@`!\($"\EP(`_($`"`%^`$`@#``@_($`$-+^ -M'V"@K_XOE?X_0`"$*@@@KOXOT?X?8$Q!*`B@K/XOT?X?8"`$XB\(_A]@^)L- -M%`"$"@@">N!7BP$`("!+VB\0_A^```$`(*#_X2\)_A]@`(`+"`%^`$``@`L0 -M`'G-+P!ZS2_H@0T4`#'N+TA!*`@@1>XO2'](0$0!"!#HP0T(@'C-+_C!#0@` -M`>!G`@,`(`!ZZ5>,'0`@```?",SF`@```>!G@1L`(`!\/V($`#``^,$-"`"` -MR`H``>!G`GP_8%4!``#"E_XOT?X?8(!IS2_P@0T(!'X`:``LP&K___]_____ -M?____W____]_____?____W____]_____?____W____]_____?____W____]_ -M____?____W____]_____?____W____]_____?P"L"!#___]_____?____W__ -M__]_____?____W____]_____?____W____]_____?____W____]_____?___ -M_W____]_____?____W____]_____?X!4S2_XP2T(`(/@9P&._R<`4!`@`@``KN+P""(%`@'NXO2'](0$0!"!#3_A]@('G^+]7^/T``A"H( -MH'?^+]/^'V``9?\O"OX?8`+^/V`@9N@O`_Y?8```(&(@#P`H]/\-0/2!+0@@ -M!G`00`(`"CZ&<"`P`@H*K.+P'^GV(%>N!7!77_)R!W -M_R?PFPT0\)L-$*##X2\(_A]@3$$("*"G`"@`*(I2`(0*"`)ZX%>*`0`@H+_A -M+PG^'V"`N!7`_X?8`I\'V`$````H*KX+_S_+4`` -MF^9G`((@4`$"`"#\@0T(``'@9P%\/V`!``````('$""?S"<<_I]A!#X.$*!U -MS"],_I]A`'S?8A_W_P<``2!B`(+@80`$`6(`FJ91\)L-$.R;#1#!:@`@`)H' -M$"!U\"_T_PU``'S?84#&`@`$`0<(]($M"`"`8%`"_DB``'P!0*#!`@#\`0`( -M`?Y_8@"!X5<(`0<(#J9I4@"`@%``?`%`M,$"`/P!``@!_C]B``'B5PP!!P@. -MHBA2`(`@4```'PC(P0(``?Z?8@"!X%<``0<(#BB*4@`!X&<`)$E2`0(`(``` -M'PC,P0(``('A5X4``"`!_E]B`'G.+P5ZX%<%`P`@`*JJ4@"GZ6<"H^AG`BGJ -M9P(EZ6>!```@`?Z_8@!\'V`)`"`((!+-+P'^?V(">N!G`:9I4@```%"@Z/4O -M_/\M0`+^'V`@Y_4O^/\M0"!NSB\`HBA2`7K@5X$$`"``;,XO!7K@5P$#`""` -M:LXO`WK@5X$!`"``:!`@`@```?"&"S`@``+>!G`7P_8@$`````H^AG@1T`(`!\'V!$ -MJP(``"PK8``$05#L_VU`H$SL+P`(@E```$!BUOX?8"`4_B\`)"E@`.G,+Z!. -MSB\``&!B!7K@5P!\WV'`Y@(`@@,`((`,X2_P@0T0`?X?8```!Q`@YLPO`*8) -M8(`'`""@Y,PO`*8)8/#_#4"@^`8H`?X_8""UYB\```<0`!`@&`#]X%?__P`` -M`0(`(/"!#0@``^!7C@``(/"##1`'>NE7``1!4((#`"````<(``'@9X$!`"#P -M@0T("WK@5XX``"`!_E]@`((@4`"CZ&<"!>%G`0(`(.R!#0@`+>!G`7P_8`$` -M````@B!B`*/H9P"B!Q`!$P`@\($-"``!X&>!$0`@`'Q?8,SE`@``!"$(!?K@ -M5X(#`"`1>N!7#7P`@`H````-?`!``,3__\T$`"````@0"GX`@`!\`$``U/__ -M```($`7ZX%!7``@```T"`"`"^N!7"7P_8`(````` -M`P`@`'W@5R`(```-`P`@`_K@5PE\/V`#````(`$`(``"01``&@@0H"G,)TS^ -MGV$`?A\04,4"``%^7Q`DK0(``(`/.`%^'Q!/Q0(``'Y?$"6M`@``@`\X!#X. -M$`#MRR\``*!A``0?",SE`@`!?@!0!'K@5P`!G@OO_)P`*`""@#O8O&?X(@-/^'V"@DOTOG/X_8"`6]B\9 -M_@B```'@9X+[_R<`'>=G`0,`(`/^'V``'"=@H++W+_C_34#X@0T("GZ@B0/^ -M'V`@V?"`@`@!?X?8`3^/Y@@F_!7``0```7\_R<`VO4O`!P'8``BS"\0`*X)%`#."02` -M[0L@@`\X(!!N"P0^#A``-@X0`#AN8Q!^CE,`?!]@0P``"8`>S"\`?`!H```` -M@`!\/V!#```)`!W,+P2`[0L@@`\X$!!N"P0^#A``-@X0`#AN8Q!^CE,`?!]@ -M0P``"0`7S"\`?`!@____?P!\/V!#```)@!7,+P2`[0L@@`\X$!!N"P0^#A"` -M/\LO`(*@80!\7V#@GP(`/`$A"`'^($`\`P$0``0@"`+^(%!8^N!7#6;+)P"" -M@$$%?(8!2*P,H`7K@5\$I`"`"_A]@@'D# -M*`1ZX%>"2,LG``+.+Z`F`"`#_A]@H++.+P":!F"`1SB\`FB9@`$++)X!Q`R@!>N!7@0$`(`!P`R@$>N!7`C_+)Z#6S2\` -MF@9@@#W+)R`*SB\`F@9@`#S+)R#]SB\`F@9@@#K+)R#BSB\`F@9@`#G+)Z!9 -MSB\`F@9@@#?+)Z!BSB\`F@9@`#;+)P#)S2\`-!`0`@@%L#*`1ZX%>"*LLGH-O-+P":!F``*!(@U@L@O,TO -M`)H&8``6RR>@4@E,TO`)H&8``3RR<@S\TO`)H&8(`1RR>@ -MV\TO`)H&8``0RR<@O,TO`)H&8(`.RR<@I@\,TO`)H&8``*RR>`"!G@@$`(`2$!@@!>N!G@0``(("K_B\@"``@`?[?82"&V2\`(`A@H'?9 -M+P`@"&``?#]@G)<"``"```@!?@!`(`,`(`"``!`0^N!7@"M_\G`+;_)Y#ZX%+^?\G`! -MW/\G4/K@5P'7_R>`]_\GL/K@5X'-_R>)`0`@H/K@5X''_R>`]/\GP/K@5P'/ -M_R?0^N!7@>S_)P#R_R<@PYU$@!``@`*(H -M4B"2UR\.A`8(!`"G"00D!Q"@_^4O`!P'8`":QF$`'>=G`2\`(`P`IPD`A`8( -M#GK@5P`D25*"`P`@`*/H9X(J`"``'.=A!`"G"00D!Q`@^?\G`!PG8AJ(!@@< -M_@9"'7X`0``0(!@@`@`@`!Q'8`"``%`(`$$(`!`@&``(`0@`@>!7"?W_)P#Z -MX%<,$``@#``!"``"@1```@!`_P4@"`P`!P@-`D`0`_X@8`/ZX%<"ZO\G``!? -M""#E`@``!>%G@0(`(``@"&`@`@$X`!PG8``!X&>!YO\G``0?"%6Q`@```>!G -M`'P_8'#D`@""!P`@%H0&"`-^`&`!>N!7`GW@5P(```""!``@H`0`(`"`0!`` -M?%]@R,T"``!\/V"I!@``($H!*`"^#V"`__\G`(0`"`%ZX%<"`P`@`'P_8*"7 -M`@``@``(`7X`0"`#`"``@``0`'P_8*27`@``@``(`7X`0`"``!``!`@(#'X` -M8`AZX%>"`@`@`'P_8*"8`@``@``(`7X`0`"``!``F@9@H/@%*``@*&"`U/\G -MH-7_)P2<"!`@?:0!`!@$`0(?X?8`C^/V`!_E]@(!0`*`">9V`@]\HO`!P' -M8(!7RB<$/@X0`"7*+R`!`"``FJ91@$7_+X!CW"\``>!G`O[_)P";YF<"`0`@ -M`%C<+P``H&$`F^9G`@$`(`"GW"^`^O\G#(`F"`"$``@.>N!70OC\+QS^`$!* -M_A]@(!+\+P":)F`@^M@O`)H&8""R]2\`FJ91`"[S+R"ZW2\```!0@/+_)P0^ -M#A"`$LHO`-_*+X#__R<$/@X0(!O*+RC^GV$```!B`'KA5P"&P6&I`P`@`(+@ -M80"^#V``?%]@P,T"`*#[`"BG_C]`@/__)_S_#4"@WP`H`((@4`!\OV$DL@(` -ME(4&"/ZA31#]@4T0``Y'&/S_#4"@JO$O@/X_8/J?C1"0B08(`'R?8`"(`@`` -M"`!`H%8%*/K_+4"0B08(^HDM"/R!30@`"`!`H-?I+P+^?V"4A08(`7X`0``. -M(!CO^N!7E(%&$`P!`""`_A]@E(%&$"`ZRB97`@(`("(("`B:@(`0H`0`()B&@!`!_F9` -M"`@("``'X5>:@(`000$`("(("`@("`@(F("`$`!\Z$$``@``XH4'"``!X&N!G`@,`(`"^#V``?%]@<-@"`"#!`"AH?BI`@/__)R0$ -M"0@`("A@)'[@IP!R2$``H@A@L'Y!0*#;!2@(?F=`!@@'".*%)P@`@`!`!`@G -M"`"#X&<&`(<0@0$`(.*%!P@``@!`!`"'$``Z2\"_G]@ -M(`@("`"!YE<"I@E@H@0`(!3^/V``?`A`V`$```3^/V``!$%0H)CI+P+^?V`$ -M_@E`$/X_8``$05`@ENDO`OY_8"0$"0@$_C]@)'[@IP!R"$"L?@!```1!4""2 -MZ2\"_G]@"P0("!IZX%<"`P`@'``("`3^/V!(?@!```1!4*"-Z2\"_G]@XH4G -M"`"#X&>!`P`@)`0)"``$05`D?N"G`'((0+!^`$"@B.DO`OY_8"8(*0@`@^!G -M@0<`("@`"0@`!$%0((7I+P'^?V`.^NA7B@<`(`'^"$``$"`:`_X(@```2$(= -M!`D(0'K@9P'X_R>@V\DG`*((8`"^#V``?%]@<-@"`""4`"BT?BI`@/__)P"^ -M#V``?%]@<-@"`""1`"A$_C^`@/__)P0^#A`@K,DO*/Z?86G^'X(``.!A(+KX -M+P+^'V``?-]AS,\"`$Q^"$`"_C]@G']'0*#Q^B\`AF%0`)_G9P!\OV',U0(` -MHA4`(&W^/V(,?@=`#/X_8"`P^R\`!$%0``H?"&"P`@#RB28(``(`0/Z!C1`0 -M?@A``OX_8)3_1D`@Z/HO`(9A4"9^"$`"_C]@_O]-0*#E^B\`AF%0#WX(0`+^ -M/V"0_T9`(./Z+P"&85`U?@A``OX_8`3^1D"@X/HO`(9A4&U^"$`"_C]@$OY& -M0"#>^B\`AF%0`'Q?8!29`@`)_@B`@/X_8"#R^B\`AF%0(!@`(````%``"!\( -M`,,"``!]X%!G@@,`(*`!`"#_ -MD1\8`'P?8.N!7@?O_)P)ZX%<"@`\X`/O_)P0^ -M#A"`7LDO&`0@"`KZX%!`P`@`'Q?8'#8`@``?#]@6`0``"!&`"@`O@]@@/__)P4$(`C[_R!@ -MH(#))P4"0!`$/@X0`%?)+QP`(`@``*!A,(0`"`Q^0&`(>N%7`!S'40("`"#P -M?@!@@'K@5RH!`"`"_A]@`!P'8!A^0$`QA``(`7K@9P)]X&<"````(@$`(`;^ -M'V``'`=@``0`0`N`1A`@@.TO`)H&8""()@@`_`9```(```"#X&?<'0`0`7+) -M)QR`1@@P!"$(V`-`$#$$(0C[_R!@V0-`$#(((0@@;LDGV@.`$`0^#A"`0LDO -M'``@"```H&$PA``(#'Y`8`AZX5<`',=1`@(`(/!^`&"`>N!7*@$`(`+^'V`` -M'`=@&'Y`0#&$``@!>N!G`GW@9P(````B`0`@!OX?8``"`P`@```?"/3#`@``'"=@`7X`0"#CRB\L_E]@@`(` -M(*#V[B\`'`=@@$/))P)ZX%>"0LDG`'P?8,BQ`@"`2^HO@$#))P!\'V#(L0(` -M@$GJ)P0^#A`@%,DO`(*@8`!\WV'___\``)QN8``)V`(@`8(`![@ -M00%^QT$@_J9!!GKG5P87R2>`^?\G!#X.$"#FR"\8_I]A`(*`8`5^0(``?']@ -MV,L"``"$(4"!G`AP`**`: -MR2<8_I]A!#X.$*#;R"\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'$!@"_X? -M8`+^((`"?D&``OYA@""Z^B\"?H*`,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@ -M(+;Z+P"*HE"P@"8(U(!&"+2`9@@``($("OX?8*"R^B\!_K]@4(`F","`1@A4 -M@&8(``"!"`K^'V`@K_HO`OZ_8*R`)@B\@$8(7(!F"`!\'V```"```$"`"`K^ -M'V"@JOHO`_Z_8"!C\B\```!0(&+R+P+^'V`@8?(O`?X?8(```"B`Z\@G!#X. -M$*"[R"\%_A]@H+KL+P""(%````!0(+GL+P""(%`!_A]@H+?L+P""(%`@)O,O -M!/X?F`"B_B\`XL@G!#X.$""YR"\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V`` -M'`!@`GY`@`!\'V`LG`(```4`$`0+`!`._A]@`OX@@`+^88"@E?HO`GZ"@##^ -MOX&@@"8(T(!&"*2`9@@``($("OX?8*"1^B\`BJ)0L(`F"-2`1@BT@&8(``"! -M"`K^'V`@COHO`?Z_8%"`)@C`@$8(5(!F"```@0@*_A]@H(KZ+P+^OV"L@"8( -MO(!&"%R`9@@`?!]@```@``!`@`@*_A]@((;Z+P/^OV"@/O(O````4*`]\B\" -M_A]@H#SR+P'^'V``W/\O`,?()P0^#A"@G,@O'/Z?82`\"2@``,!A``'@9P*^ -M#V!"W_\O:/X_8`!Q]"\`)`DH@*#_+X!$U2\@[P`H``"@80#N`"@!>N!7@@4` -M(```'PC@G@(`!GK@5X(#`"```!\(>-@"```!X&>"`0`@`(0&"``!X&>"`0`@ -M`+X/8*#3_R^`_C]@@)3_+P#O`"@``>!G`KX/8,+0_R^-_C]@@.D`*``!X&<" -MO@]@0L[_+Y/^/V``D?\O(.$`*`/^'V"`".HO'_X_8*`^ZB_\_TU```'@9P*^ -M#V#"R/\OJ_X_8"!R^R\`'`=@`+X/8"#&_R^P_C]@H+O()QS^GV%D?HY3$``. -M$!0"#A`8!`X0'`8.$"`(#A`D"@X0*`P.$"P.#A`P$`X0-!(.$#@4#A`\%@X0 -M0!@.$$0:#A!(-@X03#X.$%!R#A!4=@X06'@.$`*@GPE<&`X0`Z"?"6`8#A`` -M?+]A____``":;F``&H]@`)HO8`;^'V`"_B"```1!4`+^88`"?H*`H%'Z+RS^ -MOV"@JO\O9'YN0Q``#@@4`"X(&`!."!P`;@@@`(X()`"N""@`S@@L`.X(,``. -M"30`+@DX`$X)/`!N"40`K@E0`(X)3`#N"P%^YJ]4`(X)`/+\9Q*8'Q)<`(X) -M6`".#P*8'Q)@`(X)2`!N"P.8'Q)``(X)(`$/.&1^CD,$/@X0(%W(+QS^GV&` -M`0`@`+X/8(7^/V``H/\O`$CS+P`!X&!G(BCB -M+P*:!F`!_J9!!?KF5P7[_R<@H_(O_/\-0/R!#0@``>!G`@P`(````%"@"O(O -M_/\M0/R!#0@``>!G`@L`(`+^'V`@B_0O_/\M0/R!#0@``>!G@0P`((`IZ"\` -M`>!G@@D`(`!\/V``^@``($7T+P7^'V"`"``@`%;Q+P#G_R<`Y.$O`.;_)P!& -MXB\``>!G@>3_)X#B_R<`'>(O``'@9X'B_R<`O@]@(.'_)Y7^/V``O@]@((#_ -M+['^/V`&_A]@H'OT+_S_+4#\@0T(``'@9X$(`"``?-]A@,$"````!P@``>!G -M`=K_)P!\/V!\J`(``($`"`!\OV&$P0(``7X`>`"!`!"@FO(O`(`&"`!^!Q"@ -MU/\G`/X&$*",\B_\_PU`@-+_)Z!HR"<<_I]A9'Z.4Q``#A`4`@X0&`0.$!P& -M#A`@"`X0)`H.$"@,#A`L#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02#8. -M$$P^#A!0<@X05'8.$%AX#A`"H)\)7!@.$`.@GPE@&`X0`'R_8?___P``FFY@ -M`!J/8`":+V`&_A]@`OX@@``$05`"_F&``GZ"@*#^^2\A_K]@H%?_+V1^;D,0 -M``X(%``N"!@`3@@<`&X((`".""0`K@@H`,X(+`#N"#``#@DT`"X).`!."3P` -M;@E$`*X)4`"."4P`[@L!?N:O5`"."0#R_&<2F!\27`"."5@`C@\"F!\28`". -M"4@`;@L#F!\20`"."2`!#SAD?HY#<'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0 -M)`H.$"@,#A`L#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02!P.$$P>#A!0 -M(`X05#8.$%@^#A!<<@X08'8.$&1X#A`"H)\):!@.$`.@GPEL&`X0`'S?80@` -M(`@`?/]A____``C_'YH`GFY@`!Z/8`">+V`&_A]@`OX@@``$05`"_F&``GZ" -M@*#:^2\`BJ)0,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@H-;Y+P"*HE"P@"8( -MU(!&"+2`9@@``($("OX?8"#3^2\!_K]@4(`F","`1@A4@&8(``"!"`K^'V"@ -MS_DO`OZ_8*R`)@B\@$8(7(!F"!)^!X``0(`("OX?8*#+^2\#_K]@((3Q+P`` -M`%`@@_$O`OX?8"""\2\!_A]@(+/(+P-^"$```*!AH++(+P-^*$"@L,@O`!P' -M8`'ZYF=P?FY#@08`(`1ZX&!G"`````%]X&<"````@0,`(`!\'V``@`$` -M(*O(+QA^)T`!_A]@H*G(+SE^)T``%O\O$``."!0`+@@8`$X('`!N""``C@@D -M`*X(*`#.""P`[@@P``X)-``N"3@`3@D\`&X)1`"N"4@`S@E,`.X)4``."EP` -MC@E8`.X+`7[FKV``C@D`\OQG$I@?$F@`C@ED`(X/`I@?$FP`C@E4`&X+`Y@? -M$D``C@D@`0\X<'Z.0V1^CE,0``X0%`(.$!@$#A``X0`J"?"5P8#A`#H)\)8!@.$`!\OV'___\``)IN8``:CV``FB]@!OX?8`+^ -M((``!$%0`OYA@`)^@H`@F_DO%OZ_8"#T_B]D?FY#$``."!0`+@@8`$X('`!N -M""``C@@D`*X(*`#.""P`[@@P``X)-``N"3@`3@D\`&X)1`"N"5``C@E,`.X+ -M`7[FKU0`C@D`\OQG$I@?$EP`C@E8`(X/`I@?$F``C@E(`&X+`Y@?$D``C@D@ -M`0\X9'Z.0P``'PC!G"OZ@ -MB0$3`"``!!\(S.4"``1ZX%<+_"!@`/S__RL$`"`+@@%0````4"!W\R_X_RU` -M^($M"/R!#0@``@!0`"``0```!Q#:_A]@`'+Y+P'ZYE>."``@```_",#F`@`@ -M)@(H`)H&8-O^'V`@;ODO`)HF8`!\/V"TEP(``(``"``:`$``@``0`'P_8+"7 -M`@``@``(`7X`0`"``!`@"P`@`/X'$`"@`&````%``?KF5P``!Q`."``@`)H& -M8*`:`B@!_C]@V_X?8*!B^2\`FB9@`'P_8*R7`@``@``(`!H`0`"``!``?#]@ -MJ)<"``"```@!?@!``(``$""CQR=G@@$`((""T2\!>N!7`@$`("`#`"````!0`'P_8.D!``"@F?XO -M`+X/8/"!#0@*?@"((([')RC^GV$$/@X0($['+QS^GV$`?+]AM*P"`%:(1@@" -M?B&(``(A4`K^((```^!7C@8`((S^'V"@/_DOGOX_0````%#\@0T05H@&"`!\ -M/V`$V0(`"GX`@/B!#1#X_PU`(`L!*`""0&"@@<!G@0D`(`P```@`'L!!BOX?8*`L^2^Q -M_R=`#@0'"``!X&>"`@`@H`L`*#"!!@@`A_0O(('<+P7^'V"@$-8O+($&"``` -M`%`L@080H%?<)S2!!A"*_A]@("3Y+\/_)T`@K?0O^/\-0```'PB@XP(`^($M -M"``"`!#\@2T((`$`*`0"`!"`4-PG!#X.$*`KQR\D_I]A@"7L+P#6_R\```!0 -M_($-$`!\_V&TK`(`5H@'"`!\/V!/`0``"GX`@/B!#1`@%_DOC/X?8`!\WV$$ -MV0(``'R_85SC`@#X_PU``!PG8*#C`"@0_D9````?"*2K`@``[/DO5H@G"`K^ -M((```N"G^/,-$/C_#4``'"=@(-X`*`":1F`<_`80&7(``(`]W"<$/@X0H!W' -M+S3^GV&B_A^"``#`80">YU'\GPT0BOX?8"`'^2\4?BA`#7KG5P/^/V("+``@ -M@-K'+R!`R2\``*!A``#`80=ZX%<"?>=7!@````(6`""*_A]@(`#Y+R!^*$`` -M?#]@V)<"``"```@`?/]A<*P"``%^`$``@``0`'P_8`SX`@``@``(`'S?85SC -M`@`!?@!``(``$#J%!P@0?B=``7X`0#J!1Q``"!\("JT"``I^`(#X@0T0^/\- -M0"#$`"@`'$=@```'"!``!Q`$``<(H`O[+Q0`!Q"@2-PO!?X?8*"1U"\8_@B` -M`?X?8/"!#1`ZA0<(]($-$"!SY2_P_PU`@!``((K^'V`@ZO@O0GXH0`5ZYU<" -M?>=7"`````)]YU<*`````0,`(`"^#V``?%]@F,T"`*#:_2]&?BA`@/__)P=Z -MYU<"`P`@`+X/8`!\7V"8S0(`H-;]+TA^*$"`__\GH#?<+P/^'V`*>N=7`GWG -M5P@````"`@`@"'KG5P%^7Q"HJP(`@3CT+Z"RQR\`F@9@`#\`((`4R2\``*!A -M!WK@5P+]YE<&`````OWF5PL````"`0`@`!$`*``.`"",_A]@(-/X+Y%^*$`` -M?#]@U)<"``"```@!?@!`(`S)+P"``!```"!@H,[X+XK^'V`*^N97`OWF5P4` -M```"_>97"`````+]YE<)`````0,`(`"^#V``?%]@F,T"`""^_2^8?BA`@/__ -M)Z"-_R\`'`=@`!Y?$*JK`@`@9]0O&/X(@(`I`"`$/@X0H-7&+S3^GV$`?+]A -M<*P"`"R!!@@`>N!7]/X_0B$F`""*_A]@(+[X+VG^*$`L@08(-('&"0P```@` -M(B!`````4#2!!A`.A``(``'@9X($`""@P>LO,($&"(!Q_R\`?#]@_-D"``B! -M``CP@0T0(`,`(`R!``@`?#]@7.,"`!"```CP@0T0%(``"/2!#1``[<@O!GK@ -M5X$!`""`Z\@O!WK@5X(1`"``ZL@O"WK@5P$0`"`@!=PO!?X?8*#IR"\`(`A2 -M`WK@5P!\_V%!G@0$`(`"$U2\```!0+($& -M$*#?QBN!7 -M`'R_85SC`@""#``@`?X?8""`1A``?%]@M*P"`%`(@0E."`$($'Z&@0`8`&CX -M@0T03`B!"4H(`0@0?H:!`!@`:/R!#1!6""$(7@A!"/C_#4`!_G]@H";9+P3^ -MGV``>N8O(*'8+P'^'V"`].\O@`4`(`!!G@@0`(`P`!P@``>!G`0,`((C^ -M'V`@!`P`@``+I00">!V"@.P`H`"`H8`)ZX%N!7`"`(4H$! -M`"#PH0T0(`$`(``@"&#P@0T("GZ@B8S^'V`@0O@O+_XH0/RA#1``?!]BM*P" -M`*`!`"!6"`@(`("F40%^QT$`@>97#?[_)P`=YV>!`P`@`OKF5XT"`"",_A]@ -M(#KX+SO^*$!6"`@(_W_'00`!V#X_RU`(!L`*`">1V`! -M>N!7`0,`(`"^#V``?%]@F,T"`"`H_2]#_BA`@/__)P`%7!7P`0`$`````!@$0((`/ -M.`0``1``@$`(``!@"`"%X5" -M`0`@``7A9P*'X697C?S_)Z!(QB<<_I]A``2`$!!^08@"!(`0`'Q_8+2L`@`%A$$("'Z! -M@`2$00@`"$%X!`2`$`>$00@(?H&`!H1!"``(07@&!(`0"81!"`A^@8`(A$$( -M``A!>`@$@!"@,0`@``S#4`%^8V``AN%`!(Y@``!\OV#LO0(``(1A>`".81@` -MAF%``(IA0`2)`0D$CF```'R?8.R_`@``A&%X"/YAD`".81@`AF%``(AA0`2) -M80@`D`%Y``A@"`"084``!H`0`)`A&03^`T$$D&```))A>`".81@`AF%``(IA -M0`2)00D$D&```))A>`C^89``AF%``(AA0`2)80@`E`%Y`@A@"`"084`"!H`0 -M`)`A&0C^`T$$D&```))A>`".81@`AF%``(IA0`2)00D$D&```))A>`C^89`` -MAF%``(AA0`2)80@`E`%Y!`A@"`"084`$!H`0`)`A&0S^`T$$D&```))A>`". -M81@`AF%``(IA0`2)00D$D&```))A>`C^89``AF%``(AA0`2)80@`E`%Y!@A@ -M"`"084`&!H`0`)`!&02.8```!F1X`(YA&`"&84``BF%`!(FA"`2.8```!F1X -M"/YAD`"&84``B&%`!(EA"`"*87@`A$%``!!!&``,04`(!(`0`!!!&`%^8T`` -MCL$8"'KC5PJ`#SB`S?\G!'[@0*`#`"``BJ)0`(K"0`0,@0``C,-```B#$`'^ -M@D``#J(8!?KB5PO\_R<("$$(``9!0``0@1@.!(`0`(A`"``(H7@`CD(8``2! -M0`!\7V#LO0(```2"0`0)P@@(_H*0``BB0`!\GV#LOP(``(BB0`2)H@@`C,)X -M!`B@"`",HD`$"H`0`)#"&`*(H`@`C,)X``ZC&`"*HD``A*)`!(GB"`A^HY`` -MBJ)``(BB0`2)H@@`CL)X!@B@"`",HD`&"H`0`)#"&`2(H`@`C,)X``ZC&`"* -MHD``A*)`!(GB"`A^HY``BJ)``(BB0`2)H@@`CL)X"`B@"`",HD`("H`0`)#" -M&`:(H`@`C,)X``ZC&`"*HD``A*)`!(GB"`A^HY``BJ)``(BB0`2)H@@`CL)X -M"@B@"`",HD`*"H`0`)#"&`B(H`@`C,)X``ZC&`"*HD``A*)`!(GB"`A^HY`` -MBJ)``(BB0`2)H@@`CL)X#`B@"`",HD`,"H`0`)#"&`J(H`@`C,)X``ZC&`"* -MHD``A$)`!`FA"`A^0Y``!$%```A!0`0)00@`"H%X#@A`"``$0D`.!(`0`!"! -M&`R(0`@`"$%X``*!&`%^06`/?D&```B!>`0(0`@`"$%`!`2`$``0@1@.B$`( -M`@9`$``(07@``H$8`7Y!8`]^08``"(%X!@A`"``(@4`&"(`0`!!"&``"H1@! -M?D)@#WY!@``*@7@("$`(``B!0`@(@!``$$(8``*A&`%^0F`/?D&```J!>`H( -M0`@`"(%`"@B`$``00A@``J$8`7Y"8`]^08``"H%X#`A`"``(@4`,"(`0`!!" -M&``"H1@!?D)@#WY!@``*@7@."$`(``1"0`X$@!`(_D&0``1`$']^06`@?D%H -M`01`$`"((`@."$`(`(0@>`""(!@@@`\X`P)`$`0^#A"`=L4O``#`80""H&$@ -MUL8O!```"```QPD0_B"`$'X'B``"`$`@T\8O`)HF8!#^((``$`<8``(`0*#0 -MQB\*_B:`H)C%)P""`&``/@X0`&K%+P/ZX&=#_K^!`0,`(`"^#V``?%]@K-<" -M`*!4_"\!_B9`@/__)P![X5<)`P`@`+X/8`!\7V"LUP(`H%#\+P/^)D"`__\G -M`'WA5P`!```+`P`@`+X/8`!\7V"LUP(`($S\+P3^)D"`__\G`'KA5PH"`"`` -MAD%@(!7L+P+^?V"`/,N!7`?X?8""`#S@!``!0!#X.$`!1Q2^`V.8O('W%)T@```@$/@X0@%C% -M+P``P&$`@@!B`?Z_80">YU$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!( -M``$`2``!`$@$?B!@`("@'____W\`(>AG`2@`($``K0@\`"T(`(/B5X4``"`X -M`*T(`("""``)XFYU$`H!\(``$`2``!`$@``0!(``$`2``!`$@``0!(``$`2``! -M`$@$?B!@`("@'____W\`>N=7`?X_8`&"(%``@C]2/`"M"$``C0@`"^)7A0`` -M(#@`C0@``&((`(?A9P$)`"`!_N=!`(9!8```(0@@^N!7(/X@4`V:($`.FB9@ -M`!WG9X$!`"``H^!7!@(`(``!`"``H^!7C@``(`""(&(0`$$(``?A5P+X_R97`@````$#`"``O@]@ -M`'Q?8#S7`@"@W?LOR?XG0(#__R>@A?LO`)H&8`#ZYEA -MR?4O`1P'8`!\WV$$Q`(```$'"`-ZX%!`P`@`'Q?8/S-`@``?#]@AP$``*"X^R\`O@]@@/__ -M)P"$8`@&?D&```9`$`&$8`@@?D%H`09`$`"&85`"!D`0`P1`$`*$0`@$!$`0 -M`X1`"`4$0!`$A$`(!@1`$`6$(`@@[,0G!P)`$`0^#A"`O<0O_'KA9P$#`"`` -MO@]@`'Q?8/S-`@"@JOLOW?X_0(#__R<`A&`(``9`$`&$8`@!!D`0`H0@"`(" -M0!`&?B&`H.+$)P,"0!`$/@X0`+[$+P""H&$!!"`(!/K@5P`$`6*L!0`@#``` -M4`3^X%$`CL<9!GX`0`+^)D"@\?8O`!Q'8#+^'V``@$80`9Y&$`)^!T"@W,0G -M``!($"`#`"``B$`(``2`00!^1A`!?F%``)!!&`"&@!`#>N%G@OS_)P"`#S@$ -M/@X0H*K$+QS^GV$@^N!7`(*@82L$`"```,!A`'Q?8)C-`@``?#]@`@<``""0 -M^R\`O@]@@/__)Q0`!PC^_RU`(.[0+P`$05`H``<(``'@9P$$`"#\_RU`(.O0 -M+P`$05#^B0T(_(DM"``"`&@@`0`@_H&-$/Z)#0@@Z=@O`)HF8"#7Q"<<_I]A -M!#X.$"">Q"\``(!@`((`8``$X6$">N)7`83`"2("`"``A@%B!'KG5PE\WV$$ -M`````GZG00">)V"@T/8O`)I&8`&<1Q`@O<0G`!I($`0^#A"`BL0O_/KA9P$# -M`"``O@]@`'Q?8/S-`@"@=_LOT?X_0(#__R<`A(`(``A`$`&$@`@!"$`0`H0@ -M"`("0!`&_B&`(/X@:`,"0!`"!"$(!`)`$`,$(0@%`D`0!`0A"`8"0!`%!"$( -M(*O$)P<"0!``/@X0@(C$+][^/YH0@@T0``"@81P`P`D`!`%B0_X?8"!S]B\' -M_BA`(%OI+P":!F`0_@U``?X_8"!,^R\`($A@#00'"`Q^YT$1@$T0#`0'"!*` -M31`+A`8(`OQF`.(!```G?@!`_'\`8`"'X6<<@$8((0@`(``.(!@2!`$(#'K@ -M9P(#`"``O@]@`'Q?8'#8`@`@6_LO%OXH0(#__R<`@@%```X@&`X(`0@`!@!` -M(`X`(`X`@1`4!`$(``'@9P$#`"``O@]@`'Q?8'#8`@"@4_LO'_XH0(#__R<5 -M!`$(``'@9P$#`"``O@]@`'Q?8'#8`@`@3_LO(/XH0(#__R<6!`$(``'@9P$# -M`"``O@]@`'Q?8'#8`@"@2OLO(?XH0(#__R<@B`8(``'@9X)`QB<0@&T(`)X' -M8*#M_B\`!$%0,00'"`A^`&@@/<8G,0!'$`0^#A``;,0O`'R_8A2S`@````!B -M`(0`"`""X&'\?J!A`'S?8;2L`@`0_@!`(''L+PI^)T`!>N!7`*(H4J($`""C -M_M^"#P0H"`"J2F(0!`@(-((*$#B`BA`@?^PO0/Y*0#P`"1`6!`@(!'K@9R$L -M`"`@?B!@`(/@9P-^`&"B`P`@`*I*8@"^#V``?%]@R,T"`*`Q^R]_?BM`@/__ -M)P%ZX%>""0`@#P0H"`($"`A0`XD05`&)$!`$"`@@<^PO4G])0``08!H#!`@( -M`@0H"*!P["]6?TE``!"`&@"F"6"@??$O`((@4```0&(@#0`@``!@8@)ZX%PO4G])0``08!H0!`@(#P0H""!C["]6?TE``!``&*!P\2\`@B!0``!` -M8@``@&*`^N97`@8`(`!@QB\">N!7@00`(!#^!T`@2>PO"GXG0`%ZX%<"`@`@ -M`":?$):P`@``*)\0F+`"``CZYE<"_>97@`````+]YE?0````@A<`(!#^!T"@ -M0>PO"GXG0`%ZX%<"%0`@@%3&+P)ZX%>!$P`@`"0?$`3X`@``$@`@`(/@9Q`$ -M2`H!`P`@#P0H"``D"6"@3>PO``1!4"`'`"``$``8`$#6+P%ZX%<`)$E`H@4` -M(`\$*`@$?$$`S,X"```D*6(`#@$8$`1($*!&["\`!$%0`!``&*`%`"``@B!0 -M!'Q!`!29`@``#@$8$`1($`!\7V!^L@(`($_L+P`D*6(`$``8`?X_8`!.\2\` -M`$!B"/KF5Q$D2!""!0`@!/X'0*`H["\$?B=``7K@5P(#`"``)!\0!/@"`(3^ -M'T`@_/4O`"0I8``*`""`^N97`@D`((`WQB\">N!7@0<`(!#^!T"@(.PO"GXG -M0`%ZX%<"!0`@`'R_803X`@``I`80`'P?8`D!```@\_4O`"0I8`"`)@A(HPH0 -M3(,*$!#^!T`@&>PO"GXG0`%ZX%>"*\0G`"S&+P)ZX%%7B07$)^!_06`!?@!```0`:`2`0!`@+?`O`)X'8"*$1P@`F@9@(`/_ -M+P">)V`(_@=``!PG8"`6]B\0_E]@`/[#)R.$!P@,>N!7`0,`(`"^#V``?%]@ -M_,T"`*"Y^B\I?BA`@/__)R2$!P@``>!G`0,`(`"^#V``?%]@_,T"`""U^B\J -M?BA`@/__)Z`>\"\`G@=@``'@9P$!`"`@0O,O"`0""`"`!P@(_B=``!!@&``< -M!V`@]OTO&/Y'0"*$9P@`F@9@`!PG8*`P_R\`GD=@`.S#)Z`.\"\`G@=@)(0' -M"`%ZX&>!!``@`)X'8``<)V`@^O4O`_Y?8`C^!T`#?B=`(/CU+PW^7V``!P`@ -M``'@9P$#`"``O@]@`'Q?8/S-`@`@H?HO37XH0(#__R9V`BA$<(`)H&8"#M_B\`GB=@@-O#)PAZX5NE7``!"$*D!`"`:_I^:`'KI5PD# -M`"``O@]@`'Q?8,#-`@`@@/HO5'XJ0(#__R<`^N97#`$`(`"GYE<,`P`@`+X/ -M8`!\7V#`S0(`('OZ+U5^*D"`__\G`*(&0``GX%<,`P`@`+X/8`!\7V#`S0(` -MH';Z+U9^*D"`__\G````4`"GYE<"@(`000$`(`2`0!`$FD`0`OX?8`6`0!`! -M?@E0`8`?@`:`0!"4A0$(!Z)`$`&`0!`A_A]@"/X_8`+^7V`@:_DO`)YG8``@ -M"&``FB9@``1!4"!3XR\"_G]@H$O$+P`!G`M_V+Z#Z]R\!_A]@`&S@+X#&OR<$/@X0@)B_+P!]X%<`\@(` -MB=KV+X```"@`P[\G!#X.$`"5OR^``P`H@"$`*``!X&<"O@]@PMWV+U#^/V"` -M(0`H`+Z_)P0^#A``D+\O`'P?8`#S`@"`?``0`/<"`(1\`!``E@(`B'P`$."> -M`@",?``0Z)@"``!\'V``]@(`$'P`$""?`@`4?``0!*`"`(`Y`B@`<[\O`#/G -M+P!\'V#+````@$7G+P!\'V#$`````#+G+P!\'V#4`````#[G+P!\'V#O```` -M@$7G+P!\'V`*`0``@#;G+P!\'V`E`0``@##G+P#Y`2@`&P(H(-[F+P'^'V`@ -MW>8O````4"#LO__\_8*!9 -MZR\!_A]@`'P_8!`G``"@>NLO!OX?8("?OR<$/@X0@'&_+P#N`2B@G;\G```` -M4````%"@B/8G`((@4`0^#A"`HO@`$`(*!!ZB\`F@9@`?ZF007ZYE>%_?\G`/_I+P`;ZB\`B;\G!#X. -M$`!9OR\`!``H`WK@5\&$OR<._A]@`7K@5R*#OR<,_A]@((*_)P```%`$/@X0 -M`%N_+P!\_V$<^@(`@`X`**`$S"\``,!!``"@80"`!P@``>!G`@0`((`A`"@! -M>N!7@GV_)P!\/V#DO`!7I+R!TORN!7!/X?8`%\'V`!````H'R_)Q3^GV$$/@X0(#Z_+QS^GV$` -M`,!A````4/Z!C1"@`P`@`)JF40":)D#^B4T(`/P`0"#Z`@``!(`0`?ZF00`; -MYU<.`P`@`)H&8"`4`"C^_RU``7K@5X'Y_R>````@`?X?8"!OOR<<_I]A!#X. -M$*`SOR\&_A]@`'R_8:3C`@``@`80`'S_8?S"`@``@`<(`'S?82#Z`@```$!` -M`!P'8"#N!7`0$`(*!1OR<` -M@`800GX'0*!M`"A?_C]@0`@G"``#X%<%_A]@`7P?8`$```"`^O\G!#X.$"`< -MOR\4_I]A``#@8`""`&$`"()0````4/R!#1``BJ)0`((@4*!5`"@`!$%0H%P` -M*`'^'V````!0`?X_8*!2`"@`!$%0H%D`*`'^'V`!_A]@`?X_8*!/`"@`!$%0 -MH%8`*`+^'V````!0`?X_8*!,`"@`!$%0H%,`*`'^'V````!0`?X_8*!)`"@! -M_E]@H%``*`'^'V`!_A]@`?X_8*!&`"@!_E]@H$T`*`+^'V````!0`?X_8*!# -M`"@!_E]@H$H`*`'^'V````!0`?X_8*!``"@!_E]@H$<`*`'^'V`!_A]@`?X_ -M8*`]`"@!_E]@H$0`*`+^'V````!0`?X_8*`Z`"@!_E]@H$$`*`'^'V````!0 -M`?X_8*`W`"@`!$%0H#X`*`'^'V`!_A]@`?X_8*`T`"@`!$%0H#L`*`+^'V"@ -M"0`@!_[?8(`Q`"@@.0`H`?X?8`",`X@!?H!@````4`'^/V`@+@`H``A"8"`U -M`"@!_A]@`?X?8`'^/V`@*P`H``A"8"`R`"@"_A]@_W_#0`!ZXU<```!0`?X_ -M8"KU_R<`"$)@`"8`**`M`"@!_A]@````4`'^/V"@(P`H``1!4"`G`"C\_PU` -M_($-"``!X&``0`!@`B>!7#H`/.`#\_R<$/@X0`*Z^+P`- -M`"@`@B!0`'X?$&CD`@``?A\0;.0"``!\'V`DL@(`D@.`$)`#@!"5`T`4E@-` -M%``"7Q1N!G@@(`(`"O -MXB\`'`!0`7K@5X[\_R>`^O\G`'Q_8#S:`@``_T%``((@4`#`!@@!>N!G`0,` -M(`3`!@@$_B!````!$!KZX%<$?D%`COO_)P"%`0@!>N!7`?W@5QP````!`@`@ -M`+X/8*#3]2^=_C]`@+:^)___'V`(@`84`HD!"!3_(4```!\0T)@"``!\'V#4 -MF`(`($_`+P7^7V``L;XG!#X.$""!OB\!_E]@`'P_8*S$`@`@@=\OX/\`0``! -MX&>!JKXG`+X/8`!\7V"LUP(`H&OU+W+^/V"`__\G!#X.$*!YOB\`!$%0`'P_ -M8*C"`@"@>=\OW/\`0``!X&!G@5>^)P"^#V`` -M?%]@9,X"`*`8]2]M_C]@@/__)P0^#A"@)KXO``1!4`!\/V"TJP(`H";?+\S_ -M`$```>!G`0,`(`"^#V``?%]@F,T"`"`1]2^;_C]@@/__)___/V``?!]@_-D" -M``0#`!```P`0H(#W+P```%``2;XG!#X.$*`=OB\`!$%0`'R_86BO`@`(_@9` -MH!K?+RC^)D```>!G`0,`(`"^#V``?%]@I,T"`"`%]2^U_C]`@/__)P```%`` -M?#]@:*T"`,B!0!`!_A]@[(%`$/R!0!#L_P!`(-__+X2!`!``Y_\O@`4`*``> -M`"B`Q-,O`$8`*`!\/V`<]@(`)/X&0```'Q"HXP(`H#>^)P"``!``@`\X!#X. -M$*`1OB\`!$%0`'P_8$RP`@"@!]\OV/\`0`!^7Q!,Y`(``'Y?$$[D`@`"_A]@ -M`?X_8"!"V2\`!$%0#`"@"0``'Q"(XP(`*/X&0!R`!A`P?B!``'P?8E#=`@`` -M`@@0#'X`0`!\WV'HXP(````'$`""(%"@K[\O)/Y?8```"`@`@B!0H*V_+QC^ -M7V````<(!_X_8"$"0!`(_B"((*OS+R("0!`'?B!@```'"`">YU$>`H`0")Z& -M$"`ARB\`F@9@@#'4+X`@OB<$/@X0H/V]+P`$05``?!]BJ+`"`$A_"$`@[MXO -M:'\H0``!X&0!````D( -M```?$(#C`@``@`@(```?$.#C`@`8?@!````?$*#C`@`P`0@(```?$(3C`@`& -M_A]@5`!'$`?^'V!5`$<0"'X`B*"#\R]6`$<0!WX`8%(`AQ"@_A]@.0!'$`": -M!F"@[\DO`((@4#@>1Q`('H<0H/?)+P`,]_\G`'Q? -M8`#U`@``?#]@`/("`$"$`!`@_A]@1(``$`!\/V"HY@(`#(``$`B$`!````,( -M`(``$`2``!``?!]@$/@"``!\/V``]P(```(`4`)^`)`!?@!0`(``$`!\'V"L -MF`(``'P_8`"6`@```@!0`GX`D`%^`%``@``0`'P?8!"9`@``?#]@Z)@"```" -M`%`"?@"0`7X`4`"``!`@@`\X````4*#FV"<._A]@!#X.$`",O2\`(`A2`)[G -M4:`,`"``',=1.(`&"`````@``>!G`KX/8,+(]"^,_C]@-(`&"`````@``>!G -M`@0`("2`!@@````(``'@9P("`"`H@`8(````"``!X&>!`0`@`+X/8)+^/V"` -MP/0O`7X(0AA^QT$$_N=!!7KH5P:DO2<`?#]@J*H"``""!T`0```(``'@9P`" -MIT&![_\G)(`&"`````@P@`80+(`&$#B`!@@````(``'@9P&^#V!!MO0O=/X_ -M8#2`!@@``"`()(`&"`````@``^!7A0(`(`"^#V"@L?0O>/X_8#2`!@@``"`( -M*(`&"`````@`@>!7C>W_)P"^#V`@[/\G?/X_8`0^#A``-@X0`#AN8Q!^CE,` -ML>DO`'P_8)B8`@``@``0"/X?F`#NYR^`Y>!V_\G`?[_'P#__R<@@`\X`OX?8``` +M'PA`O0(```'@9P&`#S@`?!]@J,4"`(!`\2<``#\(0+T"``"#X&!G +M@8/-)P!\'V"DQ0(`@#;Q+P2$!@@!>N!G@8#-)P&$!@@@>N!G`?X?8`$``%`` +M`!\0H,4"``!]S2<$/@X0H$[-+Q3^GV$`?!]@"@`@"``ASB\`?#]@"@`@"*`@ +MSB_^?P!@H'/W+_S_#4"`LO!G +M'_?_%Z$#`"``LDH0T_X?8"#I_B^Y_C]@(+3:+P``!P@`&@<0`"GJ9X("`"`` +M)`E@_/\M0"".`"CL_TU``(#I"?R!#0@``>!G`1<`(`!5SR\%>N!7@0$`((!3 +MSR\!>N!7`A0`(`#IS2\`9^XO`((@4"![[B](?TA`1`$($``D"6#\_RU`((0` +M*.S_34#\@0T(``'@9X$(`"``A`H(`7K@5PP'`"#1_A]@(-;^+]_^/V`@9>(O +M!OX?8`"$"@@">N!7"P(`(`!\'V````@`@)W:+P`!`""@8.(O!_X?8(#;S2^` +MW,TOZ($-%`!7[B](02@((&ON+TA_2$!$`0@0Z,$-"`#;S2\@/L\O`*(H4@EZ +MX%>!`0`@`#S/+P-ZX%>"```@`?X_8OBC#13XP0T(``'@9P$E`"``*>IG`B0` +M(`#.S2\`3.XO`((@4"!@[B](?TA`1`$($``D"6#\_RU`(&D`*$Q_2$``@`D( +M`('G5X$!`"#\FPT0(`$`(`":!F#\@0T(``'@9P$*`"#1_A]@H+G^+Y#^/T`` +MA"H((+C^+]'^'V!,02@(H+;^+]'^'V!,00@((-4`*/#_+4``A`H(`GX`@`!\ +M($"\EP(`_($`"`%^`$`@#``@_($`$-+^'V"@K_XOE?X_0`"$*@@@KOXOT?X? +M8$Q!*`B@K/XOT?X?8*`[XB\(_A]@^)L-%`"$"@@">N!7BP$`(*!TVB\0_A^` +M``$`("`WXB\)_A]@`(`+"`%^`$``@`L0@+#-+X"QS2_H@0T4`"SN+TA!*`@@ +M0.XO2'](0$0!"!#HP0T(`+#-+_C!#0@``>!G`@,`(`!ZZ5>,'0`@```?""SG +M`@```>!G@1L`(`!\/V($`#``^,$-"`"`R`H``>!G`GP_8%4!``#"E_XOT?X? +M8`"AS2_P@0T(!'X`:``LP&K___]_____?____W____]_____?____W____]_ +M____?____W____]_____?____W____]_____?____W____]_____?____W__ +M__]_____?P"L"!#___]_____?____W____]_____?____W____]_____?___ +M_W____]_____?____W____]_____?____W____]_____?____W____]_____ +M?P",S2_XP2T(`(/@9P&._R>`B,TO`$<'*``!X&>!`@`@``7N+P""(%`@&>XO +M2'](0$0!"!#3_A]@('G^+]7^/T``A"H(H'?^+]/^'V``9?\O"OX?8`+^/V"@ +MD^@O`_Y?8```(&(@#P`H]/\-0/2!+0@@!G`00`(`"C +MZ&<"`P`@(.+.+P'^GV(%>N!7!77_)R!W_R?PFPT0\)L-$"#[X2\(_A]@3$$( +M"""H`"@`*(I2`(0*"`)ZX%>*`0`@(/?A+PG^'V"`N!7`_X?8`I\'V`$````(*CX+_S_+4``F^9G`((@4`$"`"#\@0T(``'@9P%\ +M/V`!``````('$*#6S"<<_I]A`(`/.`0^#A"@K,PO3/Z?80!\WV(?]_\7``$@ +M8@""X&$`!`%B`)JF4?";#1#LFPT0P6H`(`":!Q"@;_`O]/\-0`!\WV&@Q@(` +M!`$'"/2!+0@`@&!0`OY(@`!\`4``P@(`_`$`"`'^?V(`@>%7"`$'"`ZF:5(` +M@(!0`'P!0!3"`@#\`0`(`?X_8@`!XE<,`0<(#J(H4@"`(%```!\(*,("``'^ +MGV(`@>!7``$'"`XHBE(``>!G`"1)4@$"`"```!\(+,("``"!X5>%```@`?Y? +M8@"PSB\%>N!7!0,`(`"JJE(`I^EG`J/H9P(IZF<")>EG@0``(`'^OV(`?!]@ +M"0`@""!)S2\!_G]B`GK@9P&F:5(```!0H.7U+_S_+4`"_A]@(.3U+_C_+4`@ +MI!!``@`*/.+P5ZX%!`0`@`*#.+PEZ +MX%<"!0`@@*#.+P`!X&>"`P`@`.?D+P`!X&<"`@`@@)K6+P`!X&!!P`@ +M_($M"`"#X&!!``@```I"`"#X&<"`>!G@0(`(```'PC` +MLP(``"W@9P%\/V(!`````*/H9X$=`"``?!]@1*L"```L*V``!$%0[/]M0"!' +M["\`"()0``!`8M;^'V"@$_XO`"0I8``@S2^@A!7__\```$"`"#P@0T(``/@5XX``"#P +M@PT0!WKI5P`$05""`P`@```'"``!X&>!`0`@\($-"`MZX%>.```@`?Y?8`"" +M(%``H^AG`@7A9P$"`"#L@0T(`"W@9P%\/V`!`````((@8@"CZ&<`H@<0`1,` +M(/"!#0@``>!G@1$`(`!\7V`LY@(```0A"`7ZX%>"`P`@$7K@5PU\`(`*```` +M#7P`0`#$___-!``@```($`I^`(``?`!``-3__P``"!`%^N!7`7P_8`0````` +M`D$0`'W@5P`(```-`@`@`OK@5PE\/V`"``````,`(`!]X%<@"```#0,`(`/Z +MX%<)?#]@`P```"`!`"```D$0`!H($*!@S"=,_I]A`'X?$+#%`@`!?E\0)*T" +M``"`#S@!?A\0K\4"``!^7Q`EK0(``(`/.`0^#A``),PO``"@80`$'P@LY@(` +M`7X`4`1ZX%<`',=1KA8`(`""X&$`O@]@H"P#*(O^/V"`$``@`)OF9X$'`"`` +M?-]A).<"`````%"@U/N!7`)JF42XX`"`;_C]B`+X/8*`)`RBV_C]@`"P` +M(``=YV>!&@`@````4*"^]R\!_C]@`?X?8""Q]R_P_RU`!/X?8`">)V`@T_'X` +M0""V[R\``@!0T_X?8*"=_2]^_C]@^(%-"/"!+0C3_A]@()O]+P`"(5`$_A]@ +M(.7W+_S_+4"@$/8O&?X(@-/^'V`@E_TOBOX_8"`8]B\9_@B```'@9X+[_R<` +M"@`@H`OV+QG^"(#3_A]@()+]+YS^/V`@$_8O&?X(@``!X&>"^_\G`!WG9P$# +M`"`#_A]@`!PG8*"O]R_X_TU`^($-"`I^H(D#_A]@(-;W+_S_+4`!?A\0&^<" +M```9`"@`?!]@Q````(`V\R_3_A]@((;]+\3^/V#X@2T(H(3]+]/^'V``?#]@ +MN)<"``"```@`&@!``(``$"#^RR-G,LG`(*`005\A@&4I0$``'R& +M065I``````8X+0"R`+(`L@`X`#L`/@"R`+(`0@"R`+(`L@!B`&4`2P!.`%$` +M5`!<`%\`6@"&`)0`5P"R`+(`L@!K`'0`>@!]`(@`C@"+`'<`D0"R`+(`EP": +M`+(`L@"R`+(`L@"R`+(`L@!H`+(`L@"R`+(`L@"R`+(`G0"R`+(`L@"R`+(` +ML@"R`+(`L@"R`+(`L@"R`+(`L@"R`+(`L@"R`+(`H`"C`*8`J0"L`+(`L@"R +M`*\`L@"R`````$;O+P!\`R@!>N!7P2D`(`+^'V``>@,H!'K@5P)_RR<`/@1,LG`'(#*`%ZX%>!`0`@@'`#*`1ZX%>"=@L,XO`)H&8(!HRR<@8,XO +M`)H&8`!GRR<@'\XO`)H&8(!ERR<@1`70,H`7K@5X$!`"`` +M7`,H!'K@5P)ARR>@%LXO`)H&8(!?RR>@/,XO`)H&8`!>RR<@`,XO`)H&8(!< +MRR<@5LXO`)H&8`!;RR<`[LTOH`3.+P":!F``4P,H`7K@5P%8RR<$_A]@@%(# +M*(!6RR<`$<\O@%7+)R"/SB\`F@9@`%3+)R`'SB\`F@9@@%++)Z`0SR\`F@9@ +M`%'+)R#HS2\`F@9@@$_+)R`ASB\`F@9@`$[+)Z#WS2\`F@9@@$S+)Z",SB\` +MF@9@`$O+)R#+S2\`F@9@@$G+)R`*SB\`F@9@`$C+)Z`6SB\`F@9@@$;+)R#W +MS2\`F@9@`$7+)Z#;S2\`F@9@@$/+)R`*SR\`F@9@`$++)Z`KSB\`F@9@@$#+ +M)P!`RR<$/@X0H"#++RS^GV$``.!A2?X?8*#1_"\`GB=@H`$`(/3^7T(@A^8O +M`"`(8`"?!V(!4P`@!`#H"0```%`,`"@*!``($`"D*$`8_A]@%(!`$!R$"`C\ +M?B!@@/K@5P``"``@``0(!+;+P`@"&```,!A`'P_8`"7`@``@``( +M`7X`0"`:`"``@``0`'P_8"27`@``@``(`7X`0`"``!`*_@9`()+;+___+4`! +M>N!7`'S?8;#=`@`"!@`@_X4-"`!\?V"XXP(``(`A"`&`7X``P``(``0`:`"` +M`!0`@`$(`$`@"*"5_"^&_A]````G"`3^!D"@M_(O"OX@0``!X&>"`0`@!(0& +M"`%ZX&>!```@`*O^+R`(`"`!_M]AH+#9+P`@"&`@HMDO`"`(8`!\/V"!R?\G`+X/8*#:`2A3?RE``7KG5X*W_R<` +MMO\GD/K@5P'D_R<)!``@,/K@5XOY_RP^N!7@![/\G`/+_ +M)Z#WRBN!7`"1)4H(#`"`` +MH^AG@BH`(``!`@`@ +M`"`(8"`"`3@`'"=@``'@9X'F_R<`!!\(@;$"```!X&<`?#]@T.0"`(('`"`6 +MA`8(`WX`8`%ZX%<"?>!7`@```(($`""@!``@`(!`$`!\7V`HS@(``'P_8*T& +M``"@2@$H`+X/8(#__R<`A``(`7K@5P(#`"``?#]@H)<"``"```@!?@!`(`,` +M(`"``!``?#]@I)<"``"```@!?@!``(``$``$"`@,?@!@"'K@5X("`"``?#]@ +MH)@"``"```@!?@!``(``$`":!F`@#08H`"`H8(#4_R>@U?\G!)P($*"SRB<` +MG@=@`'P?8``0,``````(((`/.``0`!@$/@X0`([*+X#^7T(``"!B`(*@80`$ +M`6(@2LLO`(;A80``P&&@>,XO"/X?8`!\?V!0L@(`D(E!"`!\GV``B`(```@A +M0"'^'V``"(%`"/KH5P``0A"I`0`@&OY_F@#ZZ%<)`P`@`+X/8`!\7V`@S@(` +M("D!*![^*4"`__\G`'KH5PP!`"``)>A7#`,`(`"^#V``?%]@(,X"`"`D`2@? +M_BE`@/__)P`:"$``)>!7#`,`(`"^#V``?%]@(,X"`*`?`2@@_BE`@/__)P`` +M`%``)>A7`H"`$$$!`"`$@$`0!*!`$`6`0!`!_@A0`8`?@`:`0!"4A0$(!YI` +M$`&`0!`A_A]@"/X_8`'^7V`@%``H`)YG8*`MRR\`'`=@`([*)P0^#A"`6\HO +M(`$`(`":IE&`1?\O`)C<+P`!X&<"_O\G`)OF9P(!`""`C-PO``"@80";YF<" +M`0`@@-O<+X#Z_R<,@"8(`(0`"`YZX%="]_PO'/X`0$K^'V`@$?PO`)HF8*`D +MV2\`F@9@H*[U+P":IE$`*/,O(.W=+P```%"`\O\G!#X.$`!)RB^`%N%7`(;!82D$`"``@N!A`'Q?8"#.`@``?#]@ +M40$``*#[`"@`O@]@@/__)_S_#4"@WP`H`((@4`!\OV%0L@(`E(4&"/ZA31#] +M@4T0``Y'&/S_#4`@I/$O@/X_8/J?C1"0B08(`'R?8`"(`@``"`!`H&H%*/K_ +M+4"0B08(^HDM"/R!30@`"`!`(-'I+P+^?V"4A08(`7X`0``.(!CO^N!7E(%& +M$`P!`""`_A]@E(%&$"!PRB97`@(`("(("`B:@(`0H`0`()B&@!`!_F9`"`@("``'X5>: +M@(`000$`("(("`@("`@(F("`$`!\Z$$``@``XH4'"``!X&N!G`@,`(`"^#V``?%]@T-@"`"#!`"AH?BI`@/__)R0$"0@`("A@)'[@ +MIP!R2$``H@A@L'Y!0*#Q!2@(?F=`!@@'".*%)P@`@`!`!`@G"`"#X&<&`(<0 +M@0$`(.*%!P@``@!`!`"'$``!`P`@ +M)`0)"``$05`D?N"G`'((0+!^`$`@@NDO`OY_8"8(*0@`@^!G@0<`("@`"0@` +M!$%0H'[I+P'^?V`.^NA7B@<`(`'^"$``$"`:`_X(@```2$(=!`D(0'K@9P'X +M_R>@$!G@@,`(*`!`"#_D1\8`'P?8.N!7@?O_)P)ZX%<"@`\X`/O_)P0^#A"`E,DO&`0@ +M"`KZX%!`P`@ +M`'Q?8-#8`@``?#]@6`0``"!&`"@`O@]@@/__)P4$(`C[_R!@H+;))P4"0!`$ +M/@X0`(W)+QP`(`@``*!A,(0`"`Q^0&`(>N%7`!S'40("`"#P?@!@@'K@5RH! +M`"`"_A]@`!P'8!A^0$`QA``(`7K@9P)]X&<"````(@$`(`;^'V``'`=@``0` +M0`N`1A"@>>TO`)H&8""()@@`_`9```(```"#X&?<'0`0`:C))QR`1@@P!"$( +MV`-`$#$$(0C[_R!@V0-`$#(((0@@I,DGV@.`$`0^#A"`>,DO'``@"```H&$P +MA``(#'Y`8`AZX5<`',=1`@(`(/!^`&"`>N!7*@$`(`+^'V``'`=@&'Y`0#&$ +M``@!>N!G`GW@9P(````B`0`@!OX?8``"`P`@```?"%3$`@``'"=@`7X`0"`9RR\L_E]@@`(`("#P[B\`'`=@ +M@'G))P)ZX%>">,DG`'P?8/2Q`@``1>HO@';))P!\'V#TL0(``$/J)P0^#A`@ +M2LDO`(*@8`!\WV'___\``)QN8``)V`(@`8(`![@00%^QT$@_J9! +M!GKG5P9-R2>`^?\G!#X.$"`!G`AP`**!0R2<8_I]A!#X. +M$*`1R2\`@J!@`'S?8?___P``G&Y@`!R/8`"<+V``'$!@"_X?8`+^((`"?D&` +M`OYA@*"X^B\"?H*`,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@H+3Z+P"*HE"P +M@"8(U(!&"+2`9@@``($("OX?8""Q^B\!_K]@4(`F","`1@A4@&8(``"!"`K^ +M'V"@K?HO`OZ_8*R`)@B\@$8(7(!F"`!\'V```"```$"`"`K^'V`@J?HO`_Z_ +M8"!?\B\```!0(%[R+P+^'V`@7?(O`?X?8(```"B`(N!7@@4`(```'PC@G@(` +M!GK@5X(#`"```!\(V-@"```!X&>"`0`@`(0&"``!X&>"`0`@`+X/8*#3_R^` +M_C]@@)3_+P#O`"@``>!G`KX/8,+0_R^-_C]@@.D`*``!X&<"O@]@0L[_+Y/^ +M/V``D?\O(.$`*`/^'V```NHO'_X_8"`XZB_\_TU```'@9P*^#V#"R/\OJ_X_ +M8*!P^R\`'`=@`+X/8"#&_R^P_C]@H/'()QS^GV%D?HY3$``.$!0"#A`8!`X0 +M'`8.$"`(#A`D"@X0*`P.$"P.#A`P$`X0-!(.$#@4#A`\%@X00!@.$$0:#A!( +M-@X03#X.$%!R#A!4=@X06'@.$`*@GPE<&`X0`Z"?"6`8#A``?+]A____``": +M;F``&H]@`)HO8`;^'V`"_B"```1!4`+^88`"?H*`(%#Z+RS^OV"@JO\O9'YN +M0Q``#@@4`"X(&`!."!P`;@@@`(X()`"N""@`S@@L`.X(,``."30`+@DX`$X) +M/`!N"40`K@E0`(X)3`#N"P%^YJ]4`(X)`/+\9Q*8'Q)<`(X)6`".#P*8'Q)@ +M`(X)2`!N"P.8'Q)``(X)(`$/.&1^CD,$/@X0()/(+QS^GV&``0`@`+X/8(7^ +M/V``H/\O`$3S+P`!X&!G(E3B+P*:!F`!_J9! +M!?KF5P7[_R<@G_(O_/\-0/R!#0@``>!G`@P`(````%"@!O(O_/\M0/R!#0@` +M`>!G`@L`(`+^'V`@A_0O_/\M0/R!#0@``>!G@0P`(``CZ"\``>!G@@D`(`!\ +M/V``^@``($'T+P7^'V"`"``@@$_Q+P#G_R<`$.(O`.;_)P!RXB\``>!G@>3_ +M)X#B_R<`2>(O``'@9X'B_R<`O@]@(.'_)Y7^/V``O@]@((#_+['^/V`&_A]@ +MH'?T+_S_+4#\@0T(``'@9X$(`"``?-]AX,$"````!P@``>!G`=K_)P!\/V!\ +MJ`(``($`"`!\OV'DP0(``7X`>`"!`!"@EO(O`(`&"`!^!Q"@U/\G`/X&$*"( +M\B_\_PU`@-+_)Z">R"<<_I]A9'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H. +M$"@,#A`L#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02#8.$$P^#A!0<@X0 +M5'8.$%AX#A`"H)\)7!@.$`.@GPE@&`X0`'R_8?___P``FFY@`!J/8`":+V`& +M_A]@`OX@@``$05`"_F&``GZ"@"#]^2\A_K]@H%?_+V1^;D,0``X(%``N"!@` +M3@@<`&X((`".""0`K@@H`,X(+`#N"#``#@DT`"X).`!."3P`;@E$`*X)4`". +M"4P`[@L!?N:O5`"."0#R_&<2F!\27`"."5@`C@\"F!\28`"."4@`;@L#F!\2 +M0`"."2`!#SAD?HY#<'Z.4Q``#A`4`@X0&`0.$!P&#A`@"`X0)`H.$"@,#A`L +M#@X0,!`.$#02#A`X%`X0/!8.$$`8#A!$&@X02!P.$$P>#A!0(`X05#8.$%@^ +M#A!<<@X08'8.$&1X#A`"H)\):!@.$`.@GPEL&`X0`'S?80@`(`@`?/]A____ +M``C_'YH`GFY@`!Z/8`">+V`&_A]@`OX@@``$05`"_F&``GZ"@"#9^2\`BJ)0 +M,/Z_@:"`)@C0@$8(I(!F"```@0@*_A]@(-7Y+P"*HE"P@"8(U(!&"+2`9@@` +M`($("OX?8*#1^2\!_K]@4(`F","`1@A4@&8(``"!"`K^'V`@SODO`OZ_8*R` +M)@B\@$8(7(!F"!)^!X``0(`("OX?8"#*^2\#_K]@((#Q+P```%`@?_$O`OX? +M8"!^\2\!_A]@(.G(+P-^"$```*!AH.C(+P-^*$"@YL@O`!P'8`'ZYF=P?FY# +M@08`(`1ZX&!G"`````%]X&<"````@0,`(`!\'V``@`$`(.'(+QA^)T`! +M_A]@H-_(+SE^)T``%O\O$``."!0`+@@8`$X('`!N""``C@@D`*X(*`#.""P` +M[@@P``X)-``N"3@`3@D\`&X)1`"N"4@`S@E,`.X)4``."EP`C@E8`.X+`7[F +MKV``C@D`\OQG$I@?$F@`C@ED`(X/`I@?$FP`C@E4`&X+`Y@?$D``C@D@`0\X +M<'Z.0V1^CE,0``X0%`(.$!@$#A``X0`J"?"5P8 +M#A`#H)\)8!@.$`!\OV'___\``)IN8``:CV``FB]@!OX?8`+^((``!$%0`OYA +M@`)^@H"@F?DO%OZ_8"#T_B]D?FY#$``."!0`+@@8`$X('`!N""``C@@D`*X( +M*`#.""P`[@@P``X)-``N"3@`3@D\`&X)1`"N"5``C@E,`.X+`7[FKU0`C@D` +M\OQG$I@?$EP`C@E8`(X/`I@?$F``C@E(`&X+`Y@?$D``C@D@`0\X9'Z.0P`` +M'PC!G"OZ@B0$3`"``!!\( +M+.8"``1ZX%<+_"!@`/S__RL$`"`+@@%0````4"!S\R_X_RU`^($M"/R!#0@` +M`@!0`"``0```!Q#:_A]@@'#Y+P'ZYE>."``@```_""#G`@`@.@(H`)H&8-O^ +M'V"@;/DO`)HF8`!\/V"TEP(``(``"``:`$``@``0`'P_8+"7`@``@``(`7X` +M0`"``!`@"P`@`/X'$`"@`&````%``?KF5P``!Q`."``@`)H&8*`N`B@!_C]@ +MV_X?8"!A^2\`FB9@`'P_8*R7`@``@``(`!H`0`"``!``?#]@J)<"``"```@! +M?@!``(``$"#9QR=G@@$`(("UT2\!>N!7`@$`("`(`"````!0`'R_87"L +M`@`P@08(``'@9X$"`""-_A]@H#WY+R'^)T`@+``H,($&"(W^'V`@._DO^OX_ +M0`#X_R?P@0T("GX`B""WQR!G@@(`(*`+`"@P@08(@';T+Z"JW"\%_A]@("[6+RR!!@@` +M``!0+($&$""!W"N!7`OWF5P8```""'``@BOX?8"#R^"\K?BA` +M`'P_8-B7`@``@``(`'R_87"L`@`!?@!``(``$`!\/V`,^`(``(``"`%^`$`` +M@``0!H4&"``!X&<"`P`@.H4&"`%^`$`Z@480.X4&"`%^`$`[@480``@?"`JM +M`@``?/]AO.,"``I^`(#X@0T0^/\-0!#^)T"@R``H`)Y'8`"`!P@0@`<0!(`' +M""#[^B\4@`<0(&_<+P7^'V`@JM0O&/X(@#N%)@@%^N!7#!8`(`:%!@@``>!G +M@A0`(`'^'V#P@0T0.H4&"/6#31#T@4T0(%CE+_#_#4"`$``@BOX?8*#5^"]3 +M?BA`!?KF5P+]YE<(`````OWF5PH````!`P`@`+X/8`!\7V#XS0(`H,?]+U=^ +M*$"`__\G!_KF5P(#`"``O@]@`'Q?8/C-`@"@P_TO67XH0(#__R>@6MPO`_X? +M8`KZYE<"_>97"`````("`"`(^N97`7Y?$*BK`@"!(?0OH-7'+P`N!7`OWF5P8````"_>97"P````(!`""`$@`H``X`((S^'V"@ +MOO@OHGXH0`!\/V#4EP(``(``"`%^`$`@+\DO`(``$```(&`@NO@OBOX?8`KZ +MYE<"_>97!0````+]YE<(`````OWF5PD````!`P`@`+X/8`!\7V#XS0(`(*O] +M+ZE^*$"`__\G((?_+P`!G@@0`(*"F +MZR\P@08(@&G_+P!\/V!N!7@0$`(``-R2\'>N!7@A$`((`+R2\+>N!7 +M`1``(*`FW"\%_A]@(`O)+P`@"%(#>N!7`'S_8;SC`@#!8MPO!?X?8/RA#1"@ +M;/DO`!P'8`!\WV&TK`(`5@@G"`K^((``@."G^/,-$(K^'V`@C?@OG_XH0/C_ +M#4#P_RU`('$`*`">1V!6"`<(\/\M0`I^`(#X@0T0^/\-0*!M`"@0_D=`+($& +M"``!X&>!`0`@@)G5+P```%`L@080(`'')S3^GV&@@O@OA_XH0`!\WV&HKP(` +M`.+_)P0^#A"@PL8O(/Z?80%ZX%<`?+]AO.,"`((,`"`!_A]@((!&$`!\7V"T +MK`(`4`B!"4X(`0@0?H:!`!@`:/B!#1!,"($)2@@!"!!^AH$`&`!H_($-$%8( +M(0A>"$$(^/\-0`'^?V`@1MDO!/Z?8`!?YB^@P-@O`?X?8(#9[R^`!0`@@'W' +M+Z`%`"@``,!A````4!S\!A!K<0``H+O8+R"`1A"`U.\OH'O'+P`^!7`0<`(``"`4"@3``H`"`H8``! +MX&>"!``@#``'"``!X&!V(!FB9B`?X&0``.H!D"^N97"_C_)P+ZZ%<+`P`@`+X/8`!\ +M7V#XS0(`(#_]+QO^/YB`__\G!/X(@``D($``)``````'$`2```@@M,8G!``' +M$`0^#A"@C,8O//Z?88/^/X(`?/]AS.,"`"#'\R_H_PU`C/X?8"`^^"\2_BA` +MZ($M"*`\^"^-_A]@`(`G""`[^"^-_A]@Z($-"`">)V``?`!@`/S__^B!#1#H +M_PU`(#(`*/#_34#T@2T(`(/@9P`=G +M@0,`(`+ZYE>-`@`@C/X?8*`D^"\N_BA`5@@("/]_QT$`'."G"OX<@/B!#1`` +MG@=@^/\M0"`;`"@`GD=@`7K@5P$#`"``O@]@`'Q?8/C-`@`@%/TO-OXH0(#_ +M_R<`'`=@()C&)SS^GV$`@(`(``"@"`0`P`@$@``(``IB0``,`$``B^%7!HGA +M5P5\`$`!``````8!$""`#S@$``$0`(!`"```8`@`A>%7`?Z?8`((@E``A>%7 +M`?Y_8`Z&85`$@"`(!```"``#X%%G(H`/.`(``%```>!G@@$`(``%X6<"A^%G`0$`(""`#S@!_A]@((`/.`+^ +M'V`$/@X0H$'&+P```&$`@L!@(.__+P`$H6```>!@`@8`(````%``_@(0H`8` +M(`2``A``$`1@H`$`(``,(V``#`-@`!`D8"`$`"@`BD)@``(`(`'ZXU@:L8G'/Z?80`$@!`0?D&(`@2` +M$`!\?V"TK`(`!81!"`A^@8`$A$$(``A!>`0$@!`'A$$("'Z!@`:$00@`"$%X +M!@2`$`F$00@(?H&`"(1!"``(07@(!(`0H#$`(``,PU`!?F-@`(;A0`2.8``` +M?+]@3+X"``"$87@`CF$8`(9A0`"*84`$B0$)!(Y@``!\GV!,P`(``(1A>`C^ +M89``CF$8`(9A0`"(84`$B6$(`)`!>0`(8`@`D&%```:`$`"0(1D$_@-!!)!@ +M``"287@`CF$8`(9A0`"*84`$B4$)!)!@``"287@(_F&0`(9A0`"(84`$B6$( +M`)0!>0((8`@`D&%``@:`$`"0(1D(_@-!!)!@``"287@`CF$8`(9A0`"*84`$ +MB4$)!)!@``"287@(_F&0`(9A0`"(84`$B6$(`)0!>00(8`@`D&%`!`:`$`"0 +M(1D,_@-!!)!@``"287@`CF$8`(9A0`"*84`$B4$)!)!@``"287@(_F&0`(9A +M0`"(84`$B6$(`)0!>08(8`@`D&%`!@:`$`"0`1D$CF````9D>`".81@`AF%` +M`(IA0`2)H0@$CF````9D>`C^89``AF%``(AA0`2)80@`BF%X`(1!0``001@` +M#$%`"`2`$``001@!?F-``([!&`AZXU<*@`\X@,W_)P1^X$"@`P`@`(JB4`"* +MPD`$#($``(S#0``(@Q`!_H)```ZB&`7ZXE<+_/\G"`A!"``&04``$($8#@2` +M$`"(0`@`"*%X`(Y"&``$@4``?%]@3+X"```$@D`$"<(("/Z"D``(HD``?)]@ +M3,`"``"(HD`$B:((`(S">`0(H`@`C*)`!`J`$`"0PA@"B*`(`(S">``.HQ@` +MBJ)``(2B0`2)X@@(?J.0`(JB0`"(HD`$B:((`([">`8(H`@`C*)`!@J`$`"0 +MPA@$B*`(`(S">``.HQ@`BJ)``(2B0`2)X@@(?J.0`(JB0`"(HD`$B:((`([" +M>`@(H`@`C*)`"`J`$`"0PA@&B*`(`(S">``.HQ@`BJ)``(2B0`2)X@@(?J.0 +M`(JB0`"(HD`$B:((`([">`H(H`@`C*)`"@J`$`"0PA@(B*`(`(S">``.HQ@` +MBJ)``(2B0`2)X@@(?J.0`(JB0`"(HD`$B:((`([">`P(H`@`C*)`#`J`$`"0 +MPA@*B*`(`(S">``.HQ@`BJ)``(1"0`0)H0@(?D.0``1!0``(04`$"4$(``J! +M>`X(0`@`!$)`#@2`$``0@1@,B$`(``A!>``"@1@!?D%@#WY!@``(@7@$"$`( +M``A!0`0$@!``$($8#HA`"`(&0!``"$%X``*!&`%^06`/?D&```B!>`8(0`@` +M"(%`!@B`$``00A@``J$8`7Y"8`]^08``"H%X"`A`"``(@4`("(`0`!!"&``" +MH1@!?D)@#WY!@``*@7@*"$`(``B!0`H(@!``$$(8``*A&`%^0F`/?D&```J! +M>`P(0`@`"(%`#`B`$``00A@``J$8`7Y"8`]^08``"H%X#@A`"``$0D`.!(`0 +M"/Y!D``$0!!_?D%@('Y!:`$$0!``B"`(#@A`"`"$('@`@B`8((`/.`,"0!`$ +M/@X0@)C%+P``P&$`@J!A(/C&+P0```@``,<)$/X@@!!^!X@``@!`(/7&+P": +M)F`0_B"``!`'&``"`$"@\L8O"OXF@*"ZQ2<`@@!@`#X.$`",Q2\#^N!G0_Z_ +M@0$#`"``O@]@`'Q?8`S8`@"@0/PO!?XF0(#__R<`>^%7"0,`(`"^#V``?%]@ +M#-@"`*`\_"\'_B9`@/__)P!]X5<``0``"P,`(`"^#V``?%]@#-@"`"`X_"\( +M_B9`@/__)P!ZX5<*`@`@`(9!8*#ZZR\"_G]@@%[')P`0@1@`AD%@``AB8*!> +M["\!_I]@@%O')P``'PC8V`(``'K@5P'^'V`@@`\X`0``4`0^#A``<\4O`+[F +M+R"?Q2=(```(!#X.$(!ZQ2\``,!A`((`8@'^OV$`GN=1`*`?"``!`$@``0!( +M``$`2``!`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_`"'H9P$H`"!` +M`*T(/``M"`"#XE>%```@.`"M"`"`@@@`">)G`2(`(``$05```"(((/K@5R#^ +M(%`-FF!`#IIF8`"<(5``!^=7``("$"4!`"`!_N=!``0"$!@$`A``@&(($`"" +M"``'XE<"^/\G`)_G9X$8`"`8@"$(`(/@9Q"`P0B"%0`@``?C5___YT%!!P`@ +M`(0"$!2`(0@4`@,0$("!"!"(`!``@"((`(/A5P(#`"`8`"((`(/@9X$``"`8 +M"@(0$(`A"`""`A!``(T(`(`A"#P`[0@@_B!```_B5P""`1`%`@`@``XB4/S_ +M@&`X`"T(``*"0```(@@`@^!G`00`(!""`1`4@"`(%((!$!"&`!```"((%(8` +M$*`"`"`8B`$0$(8!$!2&`1`8B`$0``8"$"#G_R<`#&-@`?ZF02#ZYE<$_J)` +MCMC_)RP`+0@!?D=0`(0@0"P"#1`P`"T(`(/@9P$!`"``A"!0,`(-$```H!\` +M:\4G!#X.$(!%Q2\```!B`(+`80'^OV$`GN=1`*`?"``!`$@``0!(``$`2``! +M`$@``0!(``$`2``!`$@``0!(!'X@8`"`H!____]_`'KG5P'^/V`!@B!0`((_ +M4CP`K0A``(T(``OB5X4``"`X`(T(``!B"`"'X6!`0`@`*/@5P8"`"```0`@`*/@5XX``"`` +M@B!B$`!!"``'X5<"^/\G`?ZF02#ZYE<$?H)`#O+_)P``H!\`G^=G0@$`(``B +M"!``?@@0($_%)P">!V`$?HY3`#8.$``X;F,0@`T0$(1M"`/^`6``@$`0`OX! +MD```01``$&X+((`/.`1^CD,$/@X0`!W%+Z3^_X$``:!A`(+`80+]YEN!7`0$`(`"! +MYE" +M`@`@```_",RO`@`"A``(!'X`:`*`0!``!!\(U*P"`(!ZX&>!`@`@```_",RO +M`@`"A``(`WX`:`*`0!``@`\X!#X.$`#NQ"_\>N%G@0,`(`!\7V!1A`"?@=`H/[$)P``2!`@`P`@`(A`"``$@$$`?D80`7YA0`"001@` +MAH`0`WKA9X+\_R<`@`\X!#X.$*#,Q"\<_I]A(/K@5P""H&$K!``@``#`80!\ +M7V#XS0(``'P_8!4'```@?/LO`+X/8(#__R<4``<(_O\M0*`,T2\`!$%0*``' +M"``!X&_C^:$((-$```H&$< +M`,`)``0!8D/^'V"@7?8O!_XH0*!`Z2\`F@9@$/X-0`'^/V`@./LO`"!(8`T$ +M!P@,?N=!$8!-$`P$!P@2@$T0"X0&"`+\9@#B`0``)WX`0/Q_`&``A^%G'(!& +M""$(`"``#B`8$@0!"`QZX&<"`P`@`+X/8`!\7V#0V`(`($?[+Q;^*$"`__\G +M`((!0``.(!@."`$(``8`0"`.`"`.`($0%`0!"``!X&"8L8G$(!M"`">!V"@[?XO``1!4#$$!P@(?@!H(%_&)S$`1Q`$/@X0 +M`([$+P!\OV)`LP(`````8@"$``@`@N!A_'Z@80!^7Q"KJP(``'S?8;2L`@`0 +M_@!`H%7L+PI^)T`!>N!7`*(H4J($`""C_M^"#P0H"`"J2F(0!`@(:((*$&R` +MBA"@8^PO=/Y*0'``"1`6!`@(!'K@9R$L`"`@?B!@`(/@9P-^`&"B`P`@`*I* +M8@"^#V``?%]@*,X"`*`<^R^!?BM`@/__)P%ZX%>""0`@#P0H"`($"`A0`XD0 +M5`&)$!`$"`B@5^PO4G])0``08!H#!`@(`@0H""!5["]6?TE``!"`&@"F"6"@ +M9/$O`((@4```0&(@#0`@``!@8@)ZX%N!7 +M@00`(!#^!T"@+>PO"GXG0`%ZX%<"`@`@`":?$,*P`@``*)\0Q+`"``CZYE<" +M_>97@`````+]YE?0````@A<`(!#^!T`@)NPO"GXG0`%ZX%<"%0`@@'7&+P)Z +MX%>!$P`@`"0?$`3X`@``$@`@`(/@9Q`$2`H!`P`@#P0H"``D"6`@,NPO``1! +M4"`'`"``$``8`%_6+P%ZX%<`)$E`H@4`(`\$*`@$?$$`+,\"```D*6(`#@$8 +M$`1($"`K["\`!$%0`!``&*`%`"``@B!0!'Q!`!29`@``#@$8$`1($`!\7V"J +ML@(`H#/L+P`D*6(`$``8`?X_8``U\2\``$!B"/KF5Q$D2!""!0`@!/X'0"`- +M["\$?B=``7K@5P(#`"``)!\0!/@"`(3^'T"@Y?4O`"0I8``*`""`^N97`@D` +M((!8QB\">N!7@0<`(!#^!T`@!>PO"GXG0`%ZX%<"!0`@`'P?8@3X`@``)`@0 +M`'P?8`D!``"@W/4O`"0I8```*`A(HPH03(,*$!#^!T"@_>LO"GXG0`%ZX%>" +M3,0G`$W&+P)ZX%N%7@CL`(".$!P@$>N!7 +M@2D`(`"^#V``?%]@7,X"`*"\^B\[?BA`@/__)R.$1P@(>N%7`0,`(`"^#V`` +M?%]@7,X"`""X^B\-?BA`@/__)R2$1P@`!>%G`0,`(`"^#V``?%]@7,X"`*"S +M^B_\_C]`@/__)P2$0`@#?@"``(``0"0$``@??F%@#WX`8`"!X5>))<0GX']! +M8`%^`$``!`!H!(!`$"`3\"\`G@=@(H1'"`":!F`@`?\O`)XG8`C^!T``'"=@ +MH/[U+Q#^7V``'L0G(X0'"`QZX% +M!V```>!G`0$`(*`J\R\(!`((`(`'"`C^)T``$&`8`!P'8"#T_2\8_D=`(H1G +M"`":!F``'"=@H"[_+P">1V``#,0GH/3O+P">!V`DA`<(`7K@9X$$`"``G@=@ +M`!PG8*#B]2\#_E]@"/X'0`-^)T"@X/4O#?Y?8``'`"```>!G`0,`(`"^#V`` +M?%]@7,X"`""+^B]-?BA`@/__)S$$0@@`'`=@"/XG0`-^06"@6NLO`)YG8"*$ +M1P@`F@9@(.O^+P">)V"`^\,G"'KA5P'(_R<,>N%7@=O_)P"^#V``?%]@7,X" +M`*"`^B\D_C^`@/__)P``8`@!_B!0`(1!0`"$(&```@`0((`/.````%``?#]@ +M`!`P````'Q#$JP(`((`/.`"``!`$/@X0`-+#+X#^?T(``$!B`((@8@`$`6(` +MAJ%A((O$+P`(XF$``,!AH+G'+PC^'V``?']@4+("`)")00@`?)]@`(@"```( +M(4`A_A]@``B!0`AZZ5<``$(0J0$`(!K^GYH`>NE7"0,`(`"^#V``?%]@(,X" +M`"!J^B]@?BI`@/__)P#ZYE<,`0`@`*?F5PP#`"``O@]@`'Q?8"#.`@`@9?HO +M87XJ0(#__R<`H@9``"?@5PP#`"``O@]@`'Q?8"#.`@"@8/HO8GXJ0(#__R<` +M``!0`*?F5P*`@!!!`0`@!(!`$`2:0!`"_A]@!8!`$`%^"5`!@!^`!H!`$)2% +M`0@'HD`0`8!`$"'^'V`(_C]@`OY?8*!4^2\`GF=@`"`(8`":)F``!$%0H#;C +M+P+^?V"@:\0O`!P'8`#-PR<`!`(`C!(```0^#A``G;\O@,3W+P`!X&<"J?8O +MH,3W+P'^'V"`+^`O@,:_)P0^#A"`F+\O`'W@5P#R`@")I/8O@```*`##OR<$ +M/@X0`)6_+X`#`"B`(0`H``'@9P*^#V#"I_8O4/X_8(`A`"@`OK\G!#X.$`"0 +MOR\`?!]@`/,"`(!\`!``]P(`A'P`$`"6`@"(?``0X)X"`(Q\`!#HF`(``'P? +M8`#V`@`0?``0()\"`!1\`!`$H`(`@#D"*`!SOR^`]N8O`'P?8,L`````">8O`'P?8-0```"``>8O`?X?8*"@YB\```!0H)_F+P+^ +M'V``?#]@``0``"!%ZR\```!0`?X?8*!#ZR___S]@H!_K+P'^'V``?#]@$"<` +M`*!`ZR\&_A]@@)^_)P0^#A"`<;\O`.X!**"=OR<```!0````4*!2]B<`@B!0 +M!#X.$(!ROR^@+`$H??[?80!0`2@`NP$H@/S7+Z#HZ"\!_A]@H.?H+P+^'V"@ +MYN@O````4`#FZ2\`,0$H@%T!*`"R`2B`O0$H``'@9P*^#V!">?8O@OX_8`+^ +M'V"@+^LO"'XG@`7^'V`@+NLO"7XG@"`1ZB\`FJ91`/OI+P#_Z2^``0`@H`?J +M+P":!F`!_J9!!?KF5X7]_R<`Q>DO`.'I+P")OR<$/@X0`%F_+P`$`"@#>N!7 +MP82_)P[^'V`!>N!7(H._)PS^'V`@@K\G````4`0^#A``6[\O`'S_81SZ`@"` +M#@`H(`',+P``P$$``*!A`(`'"``!X&<"!``@@"$`*`%ZX%>"?;\G`'P_8-R8 +M`@!"_@9`(%?Q+P;^7V``?!]@`/H"`!@<`!`4&@`0;H@&"`!\/V"N!7@?G_)X```"`!_A]@(&^_)QS^GV$$/@X0H#._+P;^'V``?+]A +M!.0"``"`!A``?/]A7,,"``"`!P@`?-]A(/H"````0$``'`=@(-S`+P""(%`` +MX_\O`7K@5P("`"`@ZO\O`(`'"`%ZX%_B!@`H0@&`&"(%```@`0`(`/.`!\?V!``#```((@ +M0`"`(&@"?@&```(`:!=^`&`@@`\X`(`!$`!\/V!``#```(`@"`3^((@!_B!@ +M((`/.``"`!`$?HY3`'X.%#]^X*<`?@X4(`(`(`/^/(@`0`X(`7X`0```#A0` +M0`X(`('@5PW]_R<@@`\X!'Z.0P``0&````!0(`,`(``(@E``"&)`!`9A``%^ +M@D``@`%X`!``&`")X%<.@`\X`/S_)P0^#A``KKXO``T`*`""(%``?A\0R.0" +M``!^'Q#,Y`(``'P?8%"R`@"2`X`0D`.`$)4#0!26`T`4``)?%+SD`@```E\4 +MO>0"```"'Q3$Y`(```(?%,#D`@`T?P!``'R_80#V`@`@O.LO*(`&$*#,OB"`@`@@'+B+P`<`%`!>N!7COS_ +M)X#Z_R<`?']@G-H"``#_04``@B!0`,`&"`%ZX&!7'`````$"`"``O@]@H)WU+YW^/T"` +MMKXG__\?8`B`!A0"B0$(%/\A0```'Q#0F`(``'P?8-28`@`@3\`O!?Y?8`"Q +MOB<$/@X0((&^+P'^7V``?#]@#,4"`*!$WR_@_P!```'@9X&JOB<`O@]@`'Q? +M8`S8`@"@-?4O!7($(``*(!`"`!`T$0&7Z?$*.P`@``"``H`'B^)P0^#A`@2KXO +M``1!4`!\/V"XQ`(`H`W?+]S_`$```>!G@7.^)P"^#V``?%]@Y-<"`*#^]"\V +M_C]@@/__)P`('PA@PP(``'W@5R!"``"!ZNHG`'3J)P0^#A"`/[XO@,3_+X#, +M_R^`UO\O@+O_+X"0_R^`Y?\O`'P_8"#,`@#D_P!`(`#?+P`$05```>!G`6:^ +M)P"^#V``?%]@R-@"`"#Q]"]$_C]@@/__)P0^#A`@-;XO"/X_8`!\'V```"`` +M#`(`%`#`_R^@%NPO````4``9SR^`7;XG!#X.$*`OOB\```!0`'P_8)3#`@`" +M@8`0&/\`0#3_($"@\=XO``1!4``!X&>!5[XG`+X/8`!\7V#$S@(`H.+T+VW^ +M/V"`__\G!#X.$*`FOB\`!$%0`'P_8+2K`@`@ZMXOS/\`0``!X&+`"`"#+WB_8_P!``'Y?$*SD`@``?E\0KN0"``+^'V`!_C]@(#C9+P`$05`, +M`*`)```?$.CC`@`H_@9`'(`&$#!^($``?!]BL-T"```""!`,?@!``'S?84CD +M`@````<0`((@4*"OOR\D_E]@```("`""(%"@K;\O&/Y?8```!P@'_C]@(0)` +M$`C^((B@=/,O(@)`$`=^(&````<(`)[G41X"@!`(GH80H!W*+P":!F``-M0O +M@""^)P0^#A"@_;TO``1!4`!\'V*HL`(`2'\(0*"QWB^4?RA```'@9P$#`"`` +MO@]@`'Q?8`S.`@"@HO0OAOX_8(#__R<"_A]@`?X_8*`!G```)$`(#`"``O@]@`'Q?8`S.`@`@F_0OB?X_8(#__R<,`,`)`'P_ +M8JS=`@`H?@=`'``'$#!^($``@@@0#'Z@03`;"!``F@9@`((@4""0OR\D_E]@ +M`(`("`""(%`@CK\O&/Y?8!P`!P@`GN=1"!Y`$```"0@``!\0X.,"``"`"`@` +M`!\00.0"`!A^`$```!\0`.0"`#`!"`@``!\0Y.,"``;^'V!4`$<0!_X?8%4` +M1Q`(?@"(($WS+U8`1Q`'?@!@4@"'$*#^'V`Y`$<0`)H&8"#LR2\`@B!0.!Y' +M$`@>AQ`@],DO`!P'8(#YO2<$/@X0H,^]+P""(%``?!]@#/P"````'Q#\XP(` +M`'P?8OCC`@``?`@0#/T"``!\_V'LXP(``/P'$!#]`@``?-]AN.,"``!\!Q`4 +M_0(``'R_8?#C`@``_`80&/T"`*!POR^`_E]````("`""(%``?@`4`(`'"`!^ +M`!0```<(`'X`%`"`!@@`?@`4``)?%/3C`@``Y;TG`'P_8&2K`@`@DMTGX/\` +M0`!\'V!LP@(``)/A)P0^#A`@LKTO``1!4`!\OV'HL@(`#/\&0*!RWB]`_R9` +M```?"`SW`@`L@080`'P?8`#V`@`D?``03+0"`(#V_R\`UKTG`'S?8*#R`@`` +M?!]@`(P"``!\GV"@Y@(`#``"$`3^OV`0"@(0`(9A4`!^`A`$!@(0"`8"$"`( +M`"`!_C]@"?X`@`!\0$``_O__`'P?8`".`@``!$!`%/[@IP"('$`,!``0$`H` +M$`"(G$$`!@80!`8`$`@&`!`!_B!`!/K@5XSW_R<`?%]@`/4"``!\/V``\@(` +M0(0`$"#^'V!$@``0`'P_8`CG`@`,@``0"(0`$````P@`@``0!(``$`!\'V`4 +M^`(``'P_8`#W`@```@!0`GX`D`%^`%``@``0`'P?8*R8`@``?#]@`)8"```" +M`%`"?@"0`7X`4`"``!``?!]@$)D"``!\/V#HF`(```(`4`)^`)`!?@!0`(`` +M$""`#S@```!0H-S8)P[^'V`$/@X0`(R]+P`@"%(`GN=1H`P`(``!G`@(`("B`!@@````(``'@9X$!`"``O@]@DOX_8("*]"\!?@A"&'['003^ +MYT$%>NA7!J2])P!\/V"HJ@(``(('0!````@``>!G``*G08'O_R!G`;X/8$&`]"]T_C]@-(`&"```(`@D@`8( +M````"``#X%>%`@`@`+X/8*![]"]X_C]@-(`&"```(`@H@`8(````"`"!X%>- +M[?\G`+X/8"#L_R=\_C]@!#X.$``V#A``.&YC$'Z.4P!WZ2\`?#]@F)@"``"` +M`!`(_A^8`+3G+X"KYR^`!@`H"OX?8`'^/V"`'>$O"_X?8`'^/V``'.$O```` +M4`!\/V`*`"`(@"R^+P2`[0L@@`\X$!!N"P!\?V`D`#```'Q?8"0!,```?#]@ +M*`$P``!\'V``"`"``(`!$(.&'Q@```$0A88?&`"``!``@`\X@'X?$(2?`@`` +M@`\X`%@"```8```````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3715,8 +3711,8 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````````B`(`V&<````` M```````````````````````````````````````````````````````````` -M`````(@"`'AG```````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3810,22 +3806,22 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M```````````````````````````````````````$```````````````````` -M``````````!!0DP!Z`'H`>0!X`'@`=P!V`'8`=0!T`'0`;`D0`````!YQ"1``````'G8)$``````>>PD0`````!Z` -M"1$`````'H4)$0`````>B@D1`````!Z/"1$`````'I0)$0`````>F0D1```` -M`!Z>"1$`````'J,)$@`````>J`D2`````!ZT"1(`````#-@#`/T!`0`,W`,` -M_0$!``S@`P#]`0$`#.0#`/T!`0`,\`,`_0(!`0ST`P#]`@$!#/@#`/T"`0$, -M"@0`!P("`@P,!``'`@("#`X$``@"`@(,$`0`"@,"`@P2!``*`P("#!0$``D# -M`@(,%@0`"0,"`@P8!``)`P("#!P$``D#`@(,(`0`"0,"`PPD!``)`P(##"@$ -M``@#`@,,3`0`"`0#!`Q0!``'!`,$#%0$``8$`P0,6`0`!`0#!`Q@!Y`'@`>`!W`'8`=@!U`'0`=`!S`'(`<@!Q`'``<`!O`&X` +M;@!M`%@`6`!7`%8`5@!5`%0`5`!3`%(`4@!1`%``4`!/`$X`3@!-`$P`3`!+ +M`$H`%@`6`!4`%``4`!,`$@`2`!$`$``0``\`#@`-``P`"P`*``D`"``'`!YL +M"1``````'G$)$``````>=@D0`````!Y["1``````'H`)$0`````>A0D1```` +M`!Z*"1$`````'H\)$0`````>E`D1`````!Z9"1$`````'IX)$0`````>HPD2 +M`````!ZH"1(`````'K0)$@`````,V`,`_0$!``S<`P#]`0$`#.`#`/T!`0`, +MY`,`_0$!``SP`P#]`@$!#/0#`/T"`0$,^`,`_0(!`0P*!``'`@("#`P$``<" +M`@(,#@0`"`("`@P0!``*`P("#!($``H#`@(,%`0`"0,"`@P6!``)`P("#!@$ +M``D#`@(,'`0`"0,"`@P@!``)`P(##"0$``D#`@,,*`0`"`,"`PQ,!``(!`,$ +M#%`$``<$`P0,5`0`!@0#!`Q8!``$!`,$#%P$``0$`P0,8`0`"04#!0QD!``( +M!0,%#&@$``<%`P4,;`0`!@4#!0QP!``&!0,%#'0$``,%`P8,>00`!08$!@Q] +M!``%!@0&#($$!0,&!`8,@P0`!`8$!@R%!``$!@0&#(D$``0&!`8,C00``P8$ +M!@`````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3846,8 +3842,8 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M```````````````````````&`````````+"8`@`0``$`P)@"`!```0#0F`(` -M!``!`-28`@`%``$`W)@"``8``0"DV`(`!``!```````````````````````` +M``````8`````````L)@"`!```0#`F`(`$``!`-"8`@`$``$`U)@"``4``0#< +MF`(`!@`!``39`@`$``$````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -3886,15 +3882,15 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M```````````````````````````````````````````````````````````` -M```````````.``@`"@`$``0``@`P`#``%``P```"``"```````````$````` -M^@```0```#0`,``8`#````0````!````````Z`,``/____\!````.``P`!@` -M,```$`````(`````````!````/H```$````@`#``&``P``````!````````` -M```$``````!``0```"`!,``8`#```````"````````````0```````(@```` -M/``P`````````````````/____\0)P```(>3`P$````P`3``&``P```@```` -M!``````````$``#___]_`0```%-Y'-C:&5D7V4````````````` -M``````"($P`````````````````````````````````````````````````` -M`````````````````````&1I%1R9P`````````````````` -M`````@`'```````'`/W_``````````#]_P`````````````````````````` -M'``````````````````4`!L`"P`7```````!`!X`````````/@```"4````$ -M````````````````````````````-``Q`#$````````````(````%0`0``(` -M``!````````````````````````````````````````````````````````` -M```````````````````````9;@``_FT``%5<```&+```O5$``*(%``#O#@`` -M#0\``-,.```#,P``*S,```$````````````````````````````````````` M```````````````````````````````````````````````````````````` -M``````````````````````````````````"``````````/____\````````` -M``````````````````````````````````\`````````!00#`@$````!`0$! -M`@(``'=A:71?9&EN;U]S=&%T:7-T:6-S```````````````````````````` +M``````````````````````````````````````````````$```!R97-P;VYS +M95]T`````````#X````E````!``````````````````` +M`````````#0`,0`Q````````````"````!4`$``"````0``````````````` M```````````````````````````````````````````````````````````` -M````````````````````````````````````````````````````````F``` -M``````"X"P``*",``"@````*````,@`````````````````````````````` +M````K6T``))M``#F6P``!BP``$11``"B!0``^`X``!8/``#<#@``[S(``!=B -MM>9-FNQ%CYT?0(F'^A7OZ[+)C@O[[$%GL_U?ZD6_(_=3EN1;F\)U'.&N/6I, -M6FQ!?@+U3X-<:/11--$(^9/B5/%NW%AM>:56:4 -M$<^*$.D&!('^\*!$>+HEXTOSHOY=P("*!:T_O"%(<`3QWV/!=W6O8T(P(!KE -M#OUMOTR!%!@U)B_#X;ZB-JS(Y[HK,I7FH,"8&=&>?Z-F -M1'Y4JSN#"\J,*:?BO!T6=JT[VU9D3G0>%-N2"@QL2.2X79]NO>]# -MIL2H.:0Q-].+\C+50XM9;K?:C`%DL=*RWO\J-9M.BS&I?B$[IGVC?\- -MUKW>L9%48%`"`\ZI5GWG&;5B3>;LFH]%'YV)0/J'[Q6RZX[)^PM![+-G7_U% -MZB._4_?DEIM;=<+A'#VN3&IL6GY!]0*#3VA<4?31-/D(XI.K<1.7IO6Y:```P2Q`8.,?>;SB%AVM=ML[9%9T -M3A0>DML,"DALN.2?7;UN0^_$ICFH,:33-_*+U3*+0VY9VK"0?$)QQ,RJD-@&!?1F5@Z)R>YV3CK$RNS(C/2NZEP -M!XDSIRVV/"(5DLD@ATFJ_U!XI7H#CUGX"8`:%V7:US&$QM"X@L,IL%IW'A%[ -MRZC\;=8L.@``````````````````*``H*"@H*"@H*"@H*"@H*"@H*"@H*"@H -M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@``````````````````"`# -M````````````````````````````````````````````=V%I=%]M96%S7W-T -M871I@!Z`'D`>`!X`'<`=@!V`'4`=`!T`',` -M<@!R`'$`<`!P`&\`;@!N`&T`6`!8`%<`5@!6`%4`5`!4`%,`4@!2`%$`4`!0 -M`$\`3@!.`$T`3`!,`$L`2@!*`$D`2`!(`$<`1@!&`$4`1`!$`$,`0@!"`$$` -M0`!```D`"``(``<`J@$``*P!``"N`0``L`$``+(!``"T`0``M@$``#$Q+"PL -M+"D`^/\(`#``0`!L`(``G0```/O[!0`*!04````````````````R```````` M```````````````````````````````````````````````````````````` -M````````````;&UA8U]P;W=E_-U\V[S:/-B\UW3;M-HTV+37;-N -MLVBS8K-=DVZ3:)-BDUUS;G-HVA[8GM=6VY;:%MB6UT[;CMH.V([71MN&V@;8AM=0VY#:$-B0UTC;B-H -M(V(C70-N`V@#8@-=:VYK:&MB:UU+;DMH2V)+72MN*V@K8BM="VX+:`MB"UWS -M>_-U\V[S:/-B\UW3;M-HTV+37;-NLVBS8K-=DVZ3:)-BDUW[-CXU[#;,-FPV+#7:-NHVBC8J-=@VZ#:8-D.V([ -M71MN&V@;8AM=0VY#:$-B0UTC;B-H(V(C70-N`V@#8@-=:VYK:&MB:UU+;DMH -M2V)+72MN*V@K8BM="VX+:`MB"UWS>_-U\V[S:/-B\UW3;M-HTV+37;-PLVJS -M9+-?DV^3:)-B^WO[=?MN^VC[9/M?VW';:]MEVU_;6;MLNV>[8;M:XW_C>.-R -MXVSC9L-WPW##:J-_HWFC4MR2VQ+9RMX*W$K:RME*UX`31D? -M'@`L`0(`````32$AU/XL`0``````31D@(P`L`0$`````32$D(P`L`?____\` -M31\@*``L`0(`````30X4U/[Z_P,`````31(4U/[P_P(`````3148'@`L`0(` -M````31$4U/X%``0`````320FU/[F__W___\`32$K&@`L`?____\`32$K'@`L -M`?____\`32`@U/[F__[___\`32`@U/[F_P(`````32$FU/[Z_P(`````32$F -MU/[P_P,```#P#O0/^!#\$0@2#!,0%"(5)!8F%R@8*ADL&BX;,!PT'3@>/!]` -M(&0A:")L(W`D="5X)GPG@"B$*8@JC"N1+)4MF2Z;+YTPH3&E,@`````````` -M`````````````#(_#A$`````^O\R/R$G````````,C\H+$,```#V_S(_*"PC -M````]O\R/R@L`P```/;_,C\M,$,`X/\``#(_+3`C`.#_```R/RTP`P!H```` -M,C\Q,4,`X/_Z_S(_,3$C`.#_^O\R/S$Q`P!H`/K_,C\R,D,`X/_T_S(_,C(C -M`.#_]/\R/S(R`P!H`/K_/DT.$0````#Z_SY-*"L`````[_\^22PP``#@_P`` -M/DDQ,@``X/_Z_TI-+3(`````XO\R30X@``````8`,DTA)`````#Z_S)-)2<` -M````]/\R.3$R``````P`(DT.$0```````")-$A0````````````````````` -M````````````````````````````````````````*``````````````````` -M```````````````````````````````````````````````````````````` -M````````````````````````````````````````8VUD7W=A:71?9F]R7W)E -MP!Z`'H`>0!X`'@`=P!V`'8`=0!T`',`<@!Q`'``;P!N -M`&T`;`!K`&H`:0!H`%$`40!0`$\`3@!.`$T`3`!+`$L`2@!)`$@`2`!'`!`` -M$``/``X`#@`-``P`#``+``H`"@`)``@`"``'``8`!@`%``0``P#$>A"`,(`7 -M````&0```!$`%P#X_R``#````#4`!P````,```"$@)`0D222*I,\E`.5?Z8@ -MIPJM?Z\/M0/@@N$@XD#EH.8RYX7O`)8!F`'S0/0@``"``8$"B$".0*DBJB*K -M(M4"U@7U^("#GQ"H$*F(JC.K,ZX0LY&V`\`<]1```($"B@"@`+$"N0+"`($` -MB@&@`;$"N0'"',(```#"%```&.X!S.?1X?ON*/LX`"T`)``M^SCN*.'[Y]$! -MS!CN$A+N&,P!T>?[X2CN./LM`"0`+0`X^RCN^^'1Y\P![A@2$ACN`'[ -M[BC[.``M`"0`+?LX[BCA^^?1`?,`>X8$A(8[@',Y]'A^^XH^S@`+0`D`"W[..XHX?OGT0',&.X2$NX8 +M````````````````````````````%`@#6N9JQNJHJ<1Q5%3@. +MJ@HWW__P"`BRZJ*G$< +M11=5%3@.J@HZ-]@W_O=:QWE214&`#`JG.?589YV*UYDV:[$6/ +MG1]`B8?Z%>_KLLF."_OL06>S_5_J1;\C]U.6Y%N;PG4G2@PH33\E6"_$=ZK,CGNBLRE>:@P)@9T9Y_HV9$?E2K.X,+ +MRHPIQ]-K/"AYI^*\'19VK3O;5F1.=!X4VY(*#&Q(Y+A=GVZ][T.FQ*@YI#$W +MTXOR,M5#BUENM]J,`62QTIS@2;38^JP'\R7/K\J.].E'&!#5;XCP;TIR7"0X +M\5?'G,[8M(CR2%2#)28?_JGA0>J6/`_A9 +M@`D7&MIE,=?&A+C0PX*P*7=:$1[+>_RHUFTZ+,:E^(3NF?:-_PW6O=ZQD51@ +M4`(#SJE6?><9M6)-YNR:CT4?G8E`^H?O%;+KCLG["T'LLV=?_47J([]3]^26 +MFUMUPN$,"@W +MH0H/+[4."20V&YO?/J?$AL=GEAT-"XV+=RRM.Y;^Z3V=DVW87W. +M4GO=/EYQ$Y>F];EH``#!+$!@XQ]YR+;MU+Z-1F?9T6AL6:UV95$92*S^D0!`;^@:#P>$0ENDOCHO-=_H#`!8H_K2&\<$CQ!&/? +M=\&O=4)C(##E&OT.OVV!3!@4)C7#+[[A-:*(S"XYDU=5\OR">D?(K+KG,BOF +ME<"@&9B>T:-_1&94?CNK"X.,RL@./6?@)@!H79=K7,83&T+B"PRFP6G<>$7O+J/QMUBPZ +M```````````````````H`"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H*"@H +M*"@H*"@H*"@H*"@H*"@H*"@H*"@H*```````````````````(`,````````` +M``````````````````````````````````!W86ET7VUE87-?P!Z`'H`>0!X`'@`=P!V`'8`=0!T`'0`&QO8VM?`00!`0``````````!`$`C-S>X.(````````?``"#``,`_P`!```` +M_P````````!N`&X``0```$`?``````````````````````````````$````` +M````````````"0`,``D`"0`'``````````````````````````4`$``0`!`` +M$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0 +M`!``$``0`!``$``0`!``$``0`!``$``0`!``$``0`!``&``````````````` +M```````````````````````````````````````````````````````````` +M`````````!\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?'Q\?(2$,%`P4#14.%A`8 +M$AH5'1DA&B(;(QLC'"0=)1TE'B8?)Q\G'R%1T4 +M'!(:$AH1&1`8$!@0&!`8$!@0&````````!\?'Q\?'Q\?'Q\?'Q\A```#"0D+ +M`P@("@('!PD!!@4'`04$!@`$`P0``P(#_P(!`?X```#]_OW^_/O[_/OZ^?KZ +M^/CX^O?W]_GU]?;W]//U]?+Q\_/P[_+R[^WP\>WL[@`````````````````` +M`````````````````````````````````````@(&^OKZ^OK\_@```````/S^ +M```````````````````````````"`````````````````````````````@(& +M^OKZ^OK\_@```````/S^`/-[\W7S;O-H\V+S7=-NTVC38M-=LVZS:+-BLUV3 +M;I-HDV*377-NVY[:'MB +M>UU;;EMH6V);73MN.V@[8CM=&VX;:!MB&UU#;D-H0V)#72-N(V@C8B-=`VX# +M:`-B`UUK;FMH:V)K74MN2VA+8DM=*VXK:"MB*UT+;@MH"V(+7?-[\W7S;O-H +M\V+S7=-NTVC38M-=LVZS:+-BLUV3;I-HDV*37?MQ^VO[9?M@VV_;:MMGVV/; +M7;MNNVB[8N-IXV/C7L-LPV;#8L-=HVZC:*-BHUV#;H-I@V0[8CM=&VX;:!MB +M&UU#;D-H0V)#72-N(V@C8B-=`VX#:`-B`UUK;FMH:V)K74MN2VA+8DM=*VXK +M:"MB*UT+;@MH"V(+7?-[\W7S;O-H\V+S7=-NTVC38M-=LW"S:K-DLU^3;Y-H +MDV+[>_MU^V[[:/MD^U_;<=MKVV7;7]M9NVR[9[MANUKC?^-XXW+C;.-FPW?# +M<,-JHW^C>:-RHVRC9J-A@V^#:H-E@U_K<>MKZV5#>4-R0VQ#9D-A(W$C:R-F +M(V`#<0-K`V4#7VMP:V9K94MY2W)+;$MG*W@K<2MK*V4K7@!-&1\>`"P!`@`` +M``!-(2'4_BP!``````!-&2`C`"P!`0````!-(20C`"P!_____P!-'R`H`"P! +M`@````!-#A34_OK_`P````!-$A34_O#_`@````!-%1@>`"P!`@````!-$134 +M_@4`!`````!-)";4_N;__?___P!-(2L:`"P!_____P!-(2L>`"P!_____P!- +M("#4_N;__O___P!-("#4_N;_`@````!-(2;4_OK_`@````!-(2;4_O#_`P`` +M`/`.]`_X$/P1"!(,$Q`4(A4D%B87*!@J&2P:+ALP'#0=.!X\'T`@9"%H(FPC +M<"1T)7@F?">`*(0IB"J,*Y$LE2V9+ILOG3"A,:4R```````````````````` +M````,C\.$0````#Z_S(_(2<````````R/R@L0P```/;_,C\H+",```#V_S(_ +M*"P#````]O\R/RTP0P#@_P``,C\M,",`X/\``#(_+3`#`&@````R/S$Q0P#@ +M__K_,C\Q,2,`X/_Z_S(_,3$#`&@`^O\R/S(R0P#@__3_,C\R,B,`X/_T_S(_ +M,C(#`&@`^O\^30X1`````/K_/DTH*P````#O_SY)+#```.#_```^23$R``#@ +M__K_2DTM,@````#B_S)-#B``````!@`R32$D`````/K_,DTE)P````#T_S(Y +M,3(`````#``B30X1````````(DT2%``````````````````````````````` +M```````````````````````````````H```````````````````````````` +M```````````````````````````````````````````````````````````` +M``````````````````````````````!C;61?=V%I=%]F;W)?"YC`````````````````````0`!``````````8`&``>`'!W +M5]C;VUP=71A=&EO;BYC``````````````#_________ +M_W-P96-T%!O=V5R0V%L:6(N8P`````````````````` +M``````$````"````!`````@````0````5'AC=')L+F,`````CX[ZB,+LJ:VP +M````L0(``+$#``"I_ZK_J_^H/P```````(A_+S`#,!0`,W\',`,P%``S?S\P +M`S`4`#-_!S```!@0,W\`,`,`&!`S?P!`!$`8$(B!='5N97(N8P!_`'X`?@!] +M`'P`?`![`'H`>@!Y`'@`>`!W`'8`=@!U`'0`\`E@&8`?-`]"```(`!@0*(0(Y`J2*J(JLBU0+6!?7X +M@(.?$*@0J8BJ,ZLSKA"SD;8#P!SU$```@0**`*``L0*Y`L(`@0"*`:`!L0*Y +M`<(?[X2CN./LM`"0`+0`X^RCN^^'1Y\P! -M_`(&W^W:V@76)]SA73&_DB%Q86]0C:#^`F!"LK#SKT+_X7)@`]Z2;1 -M_L;TU0_\*R`F)@\+".H6WA?E^>O3XL[7\=T9]B8)'0(5YA'3`-K@[LOTW>D* -MXR3Z%R7Z/OO_""`='1OW",[[P0;1)><[\B_Q".KFY>#I\/S[&_`OW"#7].?-]LOQ -MZMX'V@[T#1@8(BT"+M,3PO?;^@87'207"@S=$LLFX"T`&A'^%?<="B8C&2GQ -M'LX5TQOY(A<6%O4(V@_@)@0K*P\Z]"_^%R8`/>DFT?[&]-4/_"L@)B8/"PCJ -M%MX7Y?GKT^+.U_'=&?8F"1T"%>81TP#:X.[+]-WI"N,D^AK>!]H.]`T8&"(M`B[3 -M$\+WV_H&%QTD%PH,W1++)N`M`!H1_A7W'0HF(QDI\1[.%=,;^2(7%A;U"-H/ -MX"8$*RL/.O0O_A'EZ -M>WQ]?G\`!@``,)@`=3#X:]4``,O`8``C```2```````!`0$6`1````````$! -M#@`#`0$``0`$`P,#`P,`"@`$"@```````0(```("!`08&!@8&!@8&!@8&!@8 -M&!@8&!@8&"`8&!@8&!@8&!@8&"`4&A@8E!H8&!`:&!@0&A@8"AH8&`H:&!@0 -M&A@8$!H8&!@@'!P8+"08&"4@'1HW*P0$$0P)!B,7&!H4%!06%!0!``$``@`" -M``,``P`$``4`!@`(``H`#0`0`!0`&0`@`"@`,@`_`$\`9`!^`)X`R`#[`#P! -MC@'U`7<"&@/H`^L$,0;+!]`)6@R-#Y03IA@''Q`G+3'I/?%-'V*'>X.;Q\-X -M]@$``0`!``$`T````/\`'@#\_P``/0```"0`"@`>`!8````!``(`=``@```` -M`````````````0HL7G]_7BP*`0````````````````````````````,85']4 -M&`,````````````!````$0```!$`$P`0`#\``0`_`/\`_P`!````&0`J``H` -M_P```)8`,@!D`````0``80``%`````$``@`#``0`!0`&``<`"``)``H`"P`, -M``T`#@`/`!``$0`2`!,`%``5`!8`%P`8`!D`&@`;`!P`'0`>`!\`(``A`"(` -M(P`D`"4`)@`G`"@`*0`J`"L`+``M`"X`+P`P`#$`,@`S`#0`-0`V`#<`.``Y -M`#H`.P`\`#T`/@`_`$``00!"`$,`1`!%`$8`1P!(`$D`2@!+`$P`30!.`$\` -M4`!1`%(`4P!4`%4`5@!7`%@`60!:`%L`7`!=`%X`7P!@`&$`8@!C`&0`90!F -M`&<`:`!I`&H`:P!L`&T`;@!O`'``<0!R`',`=`!U`'8`=P!X`'D`>@![`'P` -M?0!^`'\````8`"X`0@!5`&<`>`"'`)4`H@"N`+D`PP#+`-,`V@#A`.8`ZP#O -M`/,`]@#X`/H`_`#]`/X`_@#_`/\`_P#_`!(`````````_P#_`*\`[0`````` -M<&AY7VEN:71I86QI>F%T:6]N+F,``````0`!`*X?``"N$P``[X`````````` -M``````````````!P;W=E%!O=V5R0V%L:6)!0D"YC -M`/#P\/`````````````````````````````````````````````````````` +M[A@2$ACN`'[[BC[.``M`"0`+?LX[BCA^^?1`?,`>X8$A(8[@',Y]'A^^XH^S@`+0`D`"W[..XH +MX?OGT0',&.X2$NX8S`'1Y_OA*.XX^RT`)``M`#C[*.[[X='GS`'\`@;?[=K: +M!=8GUR36_]/K>!]H.]`T8&"(M`B[3$\+WV_H&%QTD%PH,W1++)N`M`!H1_A7W +M'0HF(QDI\1[.%=,;^2(7%A;U"-H/X"8$*RL/.O0O_A%^7YZ]/BSM?QW1GV)@D=`A7F$=,`VN#NR_3=Z0KC)/H7)?H^ +M]RT3_B[>+>D8#`TF#B('#^H*RQG-*?0D(!`O!1L0_"#I&N7XZM'QQ?+;Y_K1 +M!<'XSN7WXQWX(!7_*-TMW"K_*20J)R8%%]@`P^G8V@76)]SA73&_DB +M%Q86]0C:#^`F!"LK#SKT+_X7)@`]Z2;1_L;TU0_\*R`F)@\+".H6WA?E^>O3 +MXL[7\=T9]B8)'0(5YA'3`-K@[LOTW>D*XR3Z%R7Z/OO_""`='1OW",[[P0;1)><[ +M\B_Q".KFY>#I\/S[&_`OW"#7].?-]LOQZMX'V@[T#1@8(BT"+M,3PO?;^@87 +M'207"@S=$LLFX"T`&A'^%?<="B8C&2GQ'LX5TQOY(A<6%O4(V@_@)@0K*P\Z +M]"_^%R8`/>DF$A(!`!```````````````````````````0`"```````!``(` +M``````(``0```````@`!`````````````````````````````````0(```(! +M``````!T`0(#!`4&!P@)"@L,#0X/$!$2$Q05%A<8&1H;'!T>'R`A(B,D)28G +M*"DJ*RPM+B\P,3(S-#4V-S@Y.CL\/3X_0$%"0T1%1D=(24I+3$U.3U!14E-4 +M55976%E:6UQ=7E]@86)C9&5F9VAI:FML;6YO<'%R7I[?'U^?P`& +M```PF`!U,/AKU0``R\!@`",``!(```````$!`18!$````````0$.``,!`0`! +M``0#`P,#`P`*``0*```````!`@```@($!!@8&!@8&!@8&!@8&!@8&!@8&!@8 +M(!@8&!@8&!@8&!@8(!0:&!B4&A@8$!H8&!`:&!@*&A@8"AH8&!`:&!@0&A@8 +M&"`<'!@L)!@8)2`=&CD]\4T?8H=[@YO'PWCV`0`!``$` +M`0#0````_P`>`/S_```]````)``*`!X`%@````$``@!T`"`````````````` +M```!"BQ>?W]>+`H!`````````````````````````````QA4?U08`P`````` +M``````$````1````$0`3`!``/P`!`#\`_P#_``$````9`"H`"@#_````E@`R +M`&0````!``!A```4`````0`"``,`!``%``8`!P`(``D`"@`+``P`#0`.``\` +M$``1`!(`$P`4`!4`%@`7`!@`&0`:`!L`'``=`!X`'P`@`"$`(@`C`"0`)0`F +M`"<`*``I`"H`*P`L`"T`+@`O`#``,0`R`#,`-``U`#8`-P`X`#D`.@`[`#P` +M/0`^`#\`0`!!`$(`0P!$`$4`1@!'`$@`20!*`$L`3`!-`$X`3P!0`%$`4@!3 +M`%0`50!6`%<`6`!9`%H`6P!<`%T`7@!?`&``80!B`&,`9`!E`&8`9P!H`&D` +M:@!K`&P`;0!N`&\`<`!Q`'(`0!Z`'L`?`!]`'X`?P`` +M`!@`+@!"`%4`9P!X`(<`E0"B`*X`N0##`,L`TP#:`.$`Y@#K`.\`\P#V`/@` +M^@#\`/T`_@#^`/\`_P#_`/\`$@````````#_`/\`KP#M``````!P:'E?:6YI +M=&EA;&EZ871I;VXN8P`````!``$`KA\``*X3``#O@``````````````````` +M`````'!O=V5R7W)E9 +M@@"!@@``V8#;@-V`WX"7@)F`1$-/9F9S970N8P``D)^HKH&`K(*5````1FEL +M=&5RW5N:&)=5U).2D5"/CHW-#$```!4>%!O=V5R0V%L:6)"1RYC`````%1X4&]W +M97)#86QI8D%"1RYC``````````````!,;6%C+F,``%!K='1X+F,`\/#P\``` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -4304,9 +4301,9 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -M`````````````````````````````````````````````````````/<"`.`$ -M``````````````````#$"0`````````````````````````````````````` M```````````````````````````````````````````````````````````` +M````````````````````````````````````````````]P(`X`0````````` +M`````````,0)```````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` @@ -4332,6 +4329,7 @@ M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` -C```````````````````````````````````````````````` +M```````````````````````````````````````````````````````````` +<```````````````````````````````````````` ` end diff --git a/sys/contrib/dev/iwi/ipw2200-sniffer.fw.uu b/sys/contrib/dev/iwi/ipw2200-sniffer.fw.uu index 5a9f0f3d2214..a7c185537e3e 100644 --- a/sys/contrib/dev/iwi/ipw2200-sniffer.fw.uu +++ b/sys/contrib/dev/iwi/ipw2200-sniffer.fw.uu @@ -1,213 +1,216 @@ -/*- - * TERMS AND CONDITIONS - * IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE - * - * Do not use or load this firmware (the "Software") until you have carefully read - * the following terms and conditions. By loading or using the Software, you agree - * to the terms of this Agreement. If you do not wish to so agree, do not install - * or use the Software. - * - * LICENSEES: - * - * Please note: - * - * * If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, - * applies. - * * If you are an Original Equipment Manufacturer (OEM), Independent Hardware - * Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement - * applies - * - * -------------------------------------------------------------------------------- - * - * For OEMs, IHVs, and ISVs: - * - * LICENSE. This Software is licensed for use only in conjunction with Intel - * component products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. Subject to the terms of this Agreement, - * Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up - * license under Intel's copyrights to: (i) copy the Software internally for your - * own development and maintenance purposes; (ii) copy and distribute the Software - * to your end-users, but only under a license agreement with terms at least as - * restrictive as those contained in Intel's Final, Single User License Agreement, - * attached as Exhibit A; and (iii) modify, copy and distribute the end-user - * documentation which may accompany the Software, but only in association with - * the Software. - * - * If you are not the final manufacturer or vendor of a computer system or software - * program incorporating the Software, then you may transfer a copy of the - * Software, including any related documentation (modified or unmodified) to your - * recipient for use in accordance with the terms of this Agreement, provided such - * recipient agrees to be fully bound by the terms hereof. You shall not otherwise - * assign, sublicense, lease, or in any other way transfer or disclose Software to - * any third party. You may not, nor may you assist any other person or entity to - * modify, translate, convert to another programming language, decompile, reverse - * engineer, or disassemble any portion of the Software or otherwise attempt to - * derive source code from any object code modules of the Software or any internal - * data files generated by the Software. Your rights to redistribute the Software - * shall be contingent upon your installation of this Agreement in its entirety in - * the same directory as the Software. - * - * CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything - * to the contrary hereunder, solely with respect to the requirements for - * compliance with the terms hereunder, any contractors or consultants that You - * use to perform the work or otherwise assist You in the development or products - * using this Software shall be deemed to be End Users and accordingly, upon - * receipt of the Software, shall be bound by the terms of Exhibit A, Software - * License Agreement. No additional agreement between You and such consultants or - * contractors is required under this Agreement to detail such compliance. - * - * TRADEMARKS. Except as expressly provided herein, you shall not use Intel's - * name in any publications, advertisements, or other announcements without - * Intel's prior written consent. You do not have any rights to use any Intel - * trademarks or logos. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if - * any, are owned by Intel or its suppliers and licensors and may be protected by - * copyright, trademark, patent and trade secret law and international treaties. - * Any rights, express or implied, in the intellectual property embodied in the - * foregoing, other than those specified in this Agreement, are reserved by Intel - * and its suppliers and licensors or otherwise as set forth in any applicable - * open source license agreement. You will keep the Software free of liens, - * attachments, and other encumbrances. You agree not to remove any proprietary - * notices and/or any labels from the Software and accompanying materials without - * prior written approval by Intel - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS - * BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND - * (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST - * INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE - * INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR - * SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS - * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT - * EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR - * INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE - * OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. - * - * EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH - * FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND - * LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR - * OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant - * or assume responsibility for the accuracy or completeness of any information, - * text, graphics, links or other items contained within the Software. You assume - * all liability, financial or otherwise, associated with Your use or disposition - * of the Software. - * - * APPLICABLE LAW. Claims arising under this Agreement shall be governed by the - * laws of State of California], excluding its principles of conflict of laws and - * the United Nations Convention on Contracts for the Sale of Goods. - * - * WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of - * this Agreement shall be effective unless in writing and signed by an officer of - * Intel. No failure or delay in exercising any right, power, or remedy under - * this Agreement shall operate as a waiver of any such right, power or remedy. - * Without limiting the foregoing, terms and conditions on any purchase orders or - * similar materials submitted by you to Intel, and any terms contained in IntelÂ’s - * standard acknowledgment form that are in conflict with these terms, shall be of - * no force or effect. - * - * SEVERABILITY. If any provision of this Agreement is held by a court of - * competent jurisdiction to be contrary to law, such provision shall be changed - * and interpreted so as to best accomplish the objectives of the original - * provision to the fullest extent allowed by law and the remaining provisions of - * this Agreement shall remain in full force and effect. - * - * EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to - * applicable import and export regulations of the United States and of the - * countries in which each party transacts business, specifically including U.S. - * Export Administration Act and Export Administration Regulations. Each party - * shall comply with such laws and regulations, as well as all other laws and - * regulations applicable to the Software. Without limiting the generality of the - * foregoing, each party agrees that it will not export, re-export, transfer or - * divert any of the Software or the direct programs thereof to any restricted - * place or party in accordance with U.S. export regulations. Note that Software - * containing encryption may be subject to additional restrictions. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - * - * TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate - * its terms. Upon termination, you will immediately destroy the Software or - * return all copies of the Software to Intel. - * - * -------------------------------------------------------------------------------- - * - * EXHIBIT "A" - * - * SOFTWARE LICENSE AGREEMENT (Final, Single User) - * - * IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. - * - * Do not use or load this firmware image (the "Software") until you have carefully - * read the following terms and conditions. By loading or using the Software, you - * agree to the terms of this Agreement. If you do not wish to so agree, do not - * install or use the Software. - * - * LICENSE. You may copy and use the Software, subject to these conditions: - * 1. This Software is licensed for use only in conjunction with Intel component - * products. Use of the Software in conjunction with non-Intel component - * products is not licensed hereunder. - * 2. You may not copy, modify, rent, sell, distribute or transfer any part of the - * Software except as provided in this Agreement, and you agree to prevent - * unauthorized copying of the Software. - * 3. You may not reverse engineer, decompile, or disassemble the Software. - * 4. You may not sublicense the Software. - * 5. The Software may contain the software or other property of third party - * suppliers. - * - * OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software - * remains with Intel or its suppliers. The Software is copyrighted and protected - * by the laws of the United States and other countries, and international treaty - * provisions. You may not remove any copyright notices from the Software. Intel - * may make changes to the Software, or items referenced therein, at any time - * without notice, but is not obligated to support or update the Software. Except - * as otherwise expressly provided, Intel grants no express or implied right under - * Intel patents, copyrights, trademarks, or other intellectual property rights. - * You may transfer the Software only if a copy of this license accompanies the - * Software and the recipient agrees to be fully bound by these terms. - * - * EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED - * "AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING - * WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR - * PURPOSE. Intel does not warrant or assume responsibility for the accuracy or - * completeness of any information, text, graphics, links or other items contained - * within the Software. - * - * LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR - * ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS - * INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO - * USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR - * IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE - * LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY - * BETWEEN JURISDICTIONS. - * - * TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if - * you violate its terms. Upon termination, you will immediately destroy the - * Software. - * - * APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the - * laws of California, excluding its principles of conflict of laws and the United - * Nations Convention on Contracts for the Sale of Goods. You may not export the - * Software in violation of applicable export laws and regulations. Intel is not - * obligated under any other agreements unless they are in writing and signed by - * an authorized representative - * of Intel. - * - * GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." - * Use, duplication, or disclosure by the Government is subject to restrictions as - * set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use - * of the Software by the Government constitutes acknowledgment of Intel's - * proprietary rights therein. Contractor or Manufacturer is Intel Corporation, - * 2200 Mission College Blvd., Santa Clara, CA 95052. - */ -#define IWI_FW_VERSION 3.0 + TERMS AND CONDITIONS + IMPORTANT - PLEASE READ BEFORE INSTALLING OR USING THIS INTEL(C) SOFTWARE + +Do not use or load this firmware (the "Software") until you have carefully read +the following terms and conditions. By loading or using the Software, you agree +to the terms of this Agreement. If you do not wish to so agree, do not install +or use the Software. + +LICENSEES: + +Please note: + +* If you are an End-User, only Exhibit A, the SOFTWARE LICENSE AGREEMENT, + applies. +* If you are an Original Equipment Manufacturer (OEM), Independent Hardware + Vendor (IHV), or Independent Software Vendor (ISV), this complete Agreement + applies + +-------------------------------------------------------------------------------- + +For OEMs, IHVs, and ISVs: + +LICENSE. This Software is licensed for use only in conjunction with Intel +component products. Use of the Software in conjunction with non-Intel component +products is not licensed hereunder. Subject to the terms of this Agreement, +Intel grants to you a nonexclusive, nontransferable, worldwide, fully paid-up +license under Intel's copyrights to: (i) copy the Software internally for your +own development and maintenance purposes; (ii) copy and distribute the Software +to your end-users, but only under a license agreement with terms at least as +restrictive as those contained in Intel's Final, Single User License Agreement, +attached as Exhibit A; and (iii) modify, copy and distribute the end-user +documentation which may accompany the Software, but only in association with +the Software. + +If you are not the final manufacturer or vendor of a computer system or software +program incorporating the Software, then you may transfer a copy of the +Software, including any related documentation (modified or unmodified) to your +recipient for use in accordance with the terms of this Agreement, provided such +recipient agrees to be fully bound by the terms hereof. You shall not otherwise +assign, sublicense, lease, or in any other way transfer or disclose Software to +any third party. You may not, nor may you assist any other person or entity to +modify, translate, convert to another programming language, decompile, reverse +engineer, or disassemble any portion of the Software or otherwise attempt to +derive source code from any object code modules of the Software or any internal +data files generated by the Software. Your rights to redistribute the Software +shall be contingent upon your installation of this Agreement in its entirety in +the same directory as the Software. + +CONTRACTORS. For the purpose of this Agreement, and notwithstanding anything +to the contrary hereunder, solely with respect to the requirements for +compliance with the terms hereunder, any contractors or consultants that You +use to perform the work or otherwise assist You in the development or products +using this Software shall be deemed to be End Users and accordingly, upon +receipt of the Software, shall be bound by the terms of Exhibit A, Software +License Agreement. No additional agreement between You and such consultants or +contractors is required under this Agreement to detail such compliance. + +TRADEMARKS. Except as expressly provided herein, you shall not use Intel's +name in any publications, advertisements, or other announcements without +Intel's prior written consent. You do not have any rights to use any Intel +trademarks or logos. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Software and accompanying materials, if +any, are owned by Intel or its suppliers and licensors and may be protected by +copyright, trademark, patent and trade secret law and international treaties. +Any rights, express or implied, in the intellectual property embodied in the +foregoing, other than those specified in this Agreement, are reserved by Intel +and its suppliers and licensors or otherwise as set forth in any applicable +open source license agreement. You will keep the Software free of liens, +attachments, and other encumbrances. You agree not to remove any proprietary +notices and/or any labels from the Software and accompanying materials without +prior written approval by Intel + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS AND LICENSORS +BE LIABLE FOR ANY DAMAGES WHATSOEVER FROM ANY CAUSE OF ACTION OF ANY KIND +(INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS INTERRUPTION, OR LOST +INFORMATION) ARISING OUT OF THE USE, MODIFICATION, OR INABILITY TO USE THE +INTEL SOFTWARE, OR OTHERWISE, NOR FOR PUNITIVE, INCIDENTAL, CONSEQUENTIAL, OR +SPECIAL DAMAGES OF ANY KIND, EVEN IF INTEL OR ITS SUPPLIERS AND LICENSORS HAS +BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME JURISDICTIONS PROHIBIT +EXCLUSION OR LIMITATION OF LIABILITY FOR IMPLIED WARRANTIES, CONSEQUENTIAL OR +INCIDENTAL DAMAGES, SO CERTAIN LIMITATIONS MAY NOT APPLY. YOU MAY ALSO HAVE +OTHER LEGAL RIGHTS THAT VARY BETWEEN JURISDICTIONS. + +EXCLUSION OF WARRANTIES. THE SOFTWARE IS PROVIDED "AS IS" AND POSSIBLY WITH +FAULTS. UNLESS EXPRESSLY AGREED OTHERWISE, INTEL AND ITS SUPPLIERS AND +LICENSORS DISCLAIM ANY AND ALL WARRANTIES AND GUARANTEES, EXPRESS, IMPLIED OR +OTHERWISE, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR PURPOSE. Intel does not warrant +or assume responsibility for the accuracy or completeness of any information, +text, graphics, links or other items contained within the Software. You assume +all liability, financial or otherwise, associated with Your use or disposition +of the Software. + +APPLICABLE LAW. Claims arising under this Agreement shall be governed by the +laws of State of California], excluding its principles of conflict of laws and +the United Nations Convention on Contracts for the Sale of Goods. + +WAIVER AND AMENDMENT. No modification, amendment or waiver of any provision of +this Agreement shall be effective unless in writing and signed by an officer of +Intel. No failure or delay in exercising any right, power, or remedy under +this Agreement shall operate as a waiver of any such right, power or remedy. +Without limiting the foregoing, terms and conditions on any purchase orders or +similar materials submitted by you to Intel, and any terms contained in IntelÂ’s +standard acknowledgment form that are in conflict with these terms, shall be of +no force or effect. + +SEVERABILITY. If any provision of this Agreement is held by a court of +competent jurisdiction to be contrary to law, such provision shall be changed +and interpreted so as to best accomplish the objectives of the original +provision to the fullest extent allowed by law and the remaining provisions of +this Agreement shall remain in full force and effect. + +EXPORT RESTRICTIONS. Each party acknowledges that the Software is subject to +applicable import and export regulations of the United States and of the +countries in which each party transacts business, specifically including U.S. +Export Administration Act and Export Administration Regulations. Each party +shall comply with such laws and regulations, as well as all other laws and +regulations applicable to the Software. Without limiting the generality of the +foregoing, each party agrees that it will not export, re-export, transfer or +divert any of the Software or the direct programs thereof to any restricted +place or party in accordance with U.S. export regulations. Note that Software +containing encryption may be subject to additional restrictions. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + +TERMINATION OF THE AGREEMENT. Intel may terminate this Agreement if you violate +its terms. Upon termination, you will immediately destroy the Software or +return all copies of the Software to Intel. + +-------------------------------------------------------------------------------- + +EXHIBIT "A" + +SOFTWARE LICENSE AGREEMENT (Final, Single User) + +IMPORTANT - READ BEFORE COPYING, INSTALLING OR USING. + +Do not use or load this firmware image (the "Software") until you have carefully +read the following terms and conditions. By loading or using the Software, you +agree to the terms of this Agreement. If you do not wish to so agree, do not +install or use the Software. + +LICENSE. You may copy and use the Software, subject to these conditions: +1. This Software is licensed for use only in conjunction with Intel component + products. Use of the Software in conjunction with non-Intel component + products is not licensed hereunder. +2. You may not copy, modify, rent, sell, distribute or transfer any part of the + Software except as provided in this Agreement, and you agree to prevent + unauthorized copying of the Software. +3. You may not reverse engineer, decompile, or disassemble the Software. +4. You may not sublicense the Software. +5. The Software may contain the software or other property of third party + suppliers. + +OWNERSHIP OF SOFTWARE AND COPYRIGHTS. Title to all copies of the Software +remains with Intel or its suppliers. The Software is copyrighted and protected +by the laws of the United States and other countries, and international treaty +provisions. You may not remove any copyright notices from the Software. Intel +may make changes to the Software, or items referenced therein, at any time +without notice, but is not obligated to support or update the Software. Except +as otherwise expressly provided, Intel grants no express or implied right under +Intel patents, copyrights, trademarks, or other intellectual property rights. +You may transfer the Software only if a copy of this license accompanies the +Software and the recipient agrees to be fully bound by these terms. + +EXCLUSION OF OTHER WARRANTIES EXCEPT AS PROVIDED ABOVE, THE SOFTWARE IS PROVIDED +"AS IS" WITHOUT ANY EXPRESS OR IMPLIED WARRANTY OF ANY KIND INCLUDING +WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT, OR FITNESS FOR A PARTICULAR +PURPOSE. Intel does not warrant or assume responsibility for the accuracy or +completeness of any information, text, graphics, links or other items contained +within the Software. + +LIMITATION OF LIABILITY. IN NO EVENT SHALL INTEL OR ITS SUPPLIERS BE LIABLE FOR +ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, LOST PROFITS, BUSINESS +INTERRUPTION, OR LOST INFORMATION) ARISING OUT OF THE USE OF OR INABILITY TO +USE THE SOFTWARE, EVEN IF INTEL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. SOME JURISDICTIONS PROHIBIT EXCLUSION OR LIMITATION OF LIABILITY FOR +IMPLIED WARRANTIES OR CONSEQUENTIAL OR INCIDENTAL DAMAGES, SO THE ABOVE +LIMITATION MAY NOT APPLY TO YOU. YOU MAY ALSO HAVE OTHER LEGAL RIGHTS THAT VARY +BETWEEN JURISDICTIONS. + +TERMINATION OF THIS AGREEMENT. Intel may terminate this Agreement at any time if +you violate its terms. Upon termination, you will immediately destroy the +Software. + +APPLICABLE LAWS. Claims arising under this Agreement shall be governed by the +laws of California, excluding its principles of conflict of laws and the United +Nations Convention on Contracts for the Sale of Goods. You may not export the +Software in violation of applicable export laws and regulations. Intel is not +obligated under any other agreements unless they are in writing and signed by +an authorized representative +of Intel. + +GOVERNMENT RESTRICTED RIGHTS. The Software is provided with "RESTRICTED RIGHTS." +Use, duplication, or disclosure by the Government is subject to restrictions as +set forth in FAR52.227-14 and DFAR252.227-7013 et seq. or their successors. Use +of the Software by the Government constitutes acknowledgment of Intel's +proprietary rights therein. Contractor or Manufacturer is Intel Corporation, +2200 Mission College Blvd., Santa Clara, CA 95052. + + + + + +#define IWI_FW_VERSION 3.1 begin 644 ipw2200-sniffer.fw -M```#`$`9``#0/P``G(0"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` +M`0`#`$`9``#0/P``G(0"``````!(```````?.!@`````_O\?`/[_'P#^_Q\` M_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P#^_Q\`_O\?`/[_'P`` M'S@5````4````!0&````@`\X`'X?$@(```D``0\X`/X?8`#^/V``_E]@`/Y_ M8`#^GV``_K]@`/[?8`#^_V``_A]A`/X_80#^7V$`_G]A`/Z?80#^OV$`_M]A From c95ae8c852c9587ad64e04990c47ec55f0043781 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 18:54:18 +0000 Subject: [PATCH 071/544] Makefile to record the technique by which the .uu files are generated from the Intel-distributed .fw files --- sys/contrib/dev/iwi/Makefile | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 sys/contrib/dev/iwi/Makefile diff --git a/sys/contrib/dev/iwi/Makefile b/sys/contrib/dev/iwi/Makefile new file mode 100644 index 000000000000..867145d80ed1 --- /dev/null +++ b/sys/contrib/dev/iwi/Makefile @@ -0,0 +1,24 @@ +# $FreeBSD$ + +FW_VERSION=3.1 +ALL= ipw2200-bss.fw.uu ipw2200-ibss.fw.uu ipw2200-sniffer.fw.uu + +all: ${ALL} + +ipw2200-bss.fw.uu: ipw2200-bss.fw LICENSE + (cat LICENSE; \ + echo '#define IWI_FW_VERSION' ${FW_VERSION}; \ + uuencode ipw2200-bss.fw ipw2200-bss.fw) > ${.TARGET} + +ipw2200-ibss.fw.uu: ipw2200-ibss.fw LICENSE + (cat LICENSE; \ + echo '#define IWI_FW_VERSION ' ${FW_VERSION}; \ + uuencode ipw2200-ibss.fw ipw2200-ibss.fw) > ${.TARGET} + +ipw2200-sniffer.fw.uu: ipw2200-sniffer.fw LICENSE + (cat LICENSE; \ + echo '#define IWI_FW_VERSION ' ${FW_VERSION}; \ + uuencode ipw2200-sniffer.fw ipw2200-sniffer.fw) > ${.TARGET} + +clean: + rm -f ${ALL} From e678f09a1504fdbf556dd96aba9835ca4194b040 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 May 2009 19:00:47 +0000 Subject: [PATCH 072/544] Retire kern.vm.kmem.size. It was marked as obsolete prior to 5.2, so it can go. --- sys/kern/kern_malloc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/kern/kern_malloc.c b/sys/kern/kern_malloc.c index 7bb5a8105260..e699a4e51e67 100644 --- a/sys/kern/kern_malloc.c +++ b/sys/kern/kern_malloc.c @@ -603,10 +603,6 @@ kmeminit(void *dummy) vm_kmem_size = vm_kmem_size_max; /* Allow final override from the kernel environment */ -#ifndef BURN_BRIDGES - if (TUNABLE_ULONG_FETCH("kern.vm.kmem.size", &vm_kmem_size) != 0) - printf("kern.vm.kmem.size is now called vm.kmem_size!\n"); -#endif TUNABLE_ULONG_FETCH("vm.kmem_size", &vm_kmem_size); /* From da7e5864c601fa0c235cd15ed5144d65f5e5ffe7 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sat, 9 May 2009 19:01:24 +0000 Subject: [PATCH 073/544] Clean up . - Just use #error when including in the kernel. Code hasn't used this header for years now and probably doesn't compile anyway, because of -Werror. - Get rid of struct ttysize, TIOCGSIZE and TIOCSSIZE. All code nowadays use both TIOC[GS]SIZE and TIOC[GS]WINSZ. Because we have other popular systems that don't implement the first, it's of little use to support interfaces nowadays. --- sys/sys/ioctl.h | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/sys/sys/ioctl.h b/sys/sys/ioctl.h index 670240928ccc..07d941481267 100644 --- a/sys/sys/ioctl.h +++ b/sys/sys/ioctl.h @@ -39,33 +39,13 @@ #define _SYS_IOCTL_H_ #ifdef _KERNEL -#ifndef _SYS_CDEFS_H_ -#error this file needs sys/cdefs.h as a prerequisite -#endif -#ifdef __CC_SUPPORTS_WARNING -#warning "Don't #include ioctl.h in the kernel. Include xxxio.h instead." -#endif +#error "Don't #include ioctl.h in the kernel. Include xxxio.h instead." #endif /* _KERNEL */ -#include - -/* - * Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ - * and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented - * notwithstanding). - */ -struct ttysize { - unsigned short ts_lines; - unsigned short ts_cols; - unsigned short ts_xxx; - unsigned short ts_yyy; -}; -#define TIOCGSIZE TIOCGWINSZ -#define TIOCSSIZE TIOCSWINSZ - #include #include #include +#include #endif /* !_SYS_IOCTL_H_ */ From 7cddab635ba4a5cb1a3d8821ca2baab28de24a92 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Sat, 9 May 2009 19:08:22 +0000 Subject: [PATCH 074/544] Spell NULL properly, use (void) rather than () for functions with no parameters. Mark two items as static that aren't used elsewhere... --- sys/kern/subr_kdb.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/sys/kern/subr_kdb.c b/sys/kern/subr_kdb.c index 602093b42f4b..e6af53e67b06 100644 --- a/sys/kern/subr_kdb.c +++ b/sys/kern/subr_kdb.c @@ -47,9 +47,9 @@ __FBSDID("$FreeBSD$"); #endif int kdb_active = 0; -void *kdb_jmpbufp = NULL; +static void *kdb_jmpbufp = NULL; struct kdb_dbbe *kdb_dbbe = NULL; -struct pcb kdb_pcb; +static struct pcb kdb_pcb; struct pcb *kdb_thrctx = NULL; struct thread *kdb_thread = NULL; struct trapframe *kdb_frame = NULL; @@ -66,22 +66,22 @@ static int kdb_sysctl_trap_code(SYSCTL_HANDLER_ARGS); SYSCTL_NODE(_debug, OID_AUTO, kdb, CTLFLAG_RW, NULL, "KDB nodes"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, 0, 0, - kdb_sysctl_available, "A", "list of available KDB backends"); +SYSCTL_PROC(_debug_kdb, OID_AUTO, available, CTLTYPE_STRING | CTLFLAG_RD, NULL, + 0, kdb_sysctl_available, "A", "list of available KDB backends"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, 0, 0, - kdb_sysctl_current, "A", "currently selected KDB backend"); +SYSCTL_PROC(_debug_kdb, OID_AUTO, current, CTLTYPE_STRING | CTLFLAG_RW, NULL, + 0, kdb_sysctl_current, "A", "currently selected KDB backend"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, 0, 0, +SYSCTL_PROC(_debug_kdb, OID_AUTO, enter, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, kdb_sysctl_enter, "I", "set to enter the debugger"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, panic, CTLTYPE_INT | CTLFLAG_RW, 0, 0, +SYSCTL_PROC(_debug_kdb, OID_AUTO, panic, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, kdb_sysctl_panic, "I", "set to panic the kernel"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, 0, 0, +SYSCTL_PROC(_debug_kdb, OID_AUTO, trap, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, kdb_sysctl_trap, "I", "set to cause a page fault via data access"); -SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, 0, 0, +SYSCTL_PROC(_debug_kdb, OID_AUTO, trap_code, CTLTYPE_INT | CTLFLAG_RW, NULL, 0, kdb_sysctl_trap_code, "I", "set to cause a page fault via code access"); /* @@ -292,7 +292,7 @@ kdb_alt_break(int key, int *state) */ void -kdb_backtrace() +kdb_backtrace(void) { if (kdb_dbbe != NULL && kdb_dbbe->dbbe_trace != NULL) { @@ -346,7 +346,7 @@ kdb_enter(const char *why, const char *msg) */ void -kdb_init() +kdb_init(void) { struct kdb_dbbe *be, **iter; int cur_pri, pri; From 638e35d58c3f8e9028cfb4e538ca369a42fb2948 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 19:19:19 +0000 Subject: [PATCH 075/544] iwn firmware --- share/man/man4/iwnfw.4 | 52 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 share/man/man4/iwnfw.4 diff --git a/share/man/man4/iwnfw.4 b/share/man/man4/iwnfw.4 new file mode 100644 index 000000000000..1f9faa9c89cf --- /dev/null +++ b/share/man/man4/iwnfw.4 @@ -0,0 +1,52 @@ +.\" Copyright (c) 2009 Sam Leffler, Errno Consulting +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. The name of the author may not be used to endorse or promote products +.\" derived from this software without specific prior written permission. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 9, 2009 +.Dt IWNFW 4 +.Os +.Sh NAME +.Nm iwnfw +.Nd "Firmware Module for Intel Wireless driver" +.Sh SYNOPSIS +To compile this module into the kernel, +place the following line in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device iwnfw" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +iwnfw_load="YES" +.Ed +.Sh DESCRIPTION +This module provides access to firmware sets for the +Intel Wireless WiFi Link 4965AGN IEEE 802.11n adapters. +It may be +statically linked into the kernel, or loaded as a module. +.Sh SEE ALSO +.Xr iwn 4 , +.Xr firmware 8 From 3c29ede04d5fa0db2a7ac7d0c91772ecc9dedbdb Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 19:19:30 +0000 Subject: [PATCH 076/544] restore ref to iwnfw --- share/man/man4/iwn.4 | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/iwn.4 b/share/man/man4/iwn.4 index a2d2dcfac156..26f1627a9ca1 100644 --- a/share/man/man4/iwn.4 +++ b/share/man/man4/iwn.4 @@ -146,6 +146,7 @@ failed. This should not happen. .El .Sh SEE ALSO +.Xr iwnfw 4 , .Xr pci 4 , .Xr wlan 4 , .Xr wlan_ccmp 4 , From 853569c6ecafafb47052d8a9f54f0dad447f5967 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 19:22:37 +0000 Subject: [PATCH 077/544] push wme parameter setting to the taskq thread; the update callback from net80211 can happen from the ithread and submitting the fw cmd requires a sleepable context --- sys/dev/iwi/if_iwi.c | 25 +++++++++++++++++++------ sys/dev/iwi/if_iwivar.h | 3 ++- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index b04403b0a645..6513522ab5b1 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include @@ -154,6 +153,7 @@ static void iwi_media_status(struct ifnet *, struct ifmediareq *); static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwi_wme_init(struct iwi_softc *); static int iwi_wme_setparams(struct iwi_softc *, struct ieee80211com *); +static void iwi_update_wme(void *, int); static int iwi_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, @@ -291,6 +291,7 @@ iwi_attach(device_t dev) TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); TASK_INIT(&sc->sc_disassoctask, 0, iwi_disassoc, sc); + TASK_INIT(&sc->sc_wmetask, 0, iwi_update_wme, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0); @@ -1082,6 +1083,18 @@ iwi_wme_setparams(struct iwi_softc *sc, struct ieee80211com *ic) #undef IWI_USEC #undef IWI_EXP2 +static void +iwi_update_wme(void *arg, int npending) +{ + struct ieee80211com *ic = arg; + struct iwi_softc *sc = ic->ic_ifp->if_softc; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + (void) iwi_wme_setparams(sc, ic); + IWI_UNLOCK(sc); +} + static int iwi_wme_update(struct ieee80211com *ic) { @@ -1091,13 +1104,13 @@ iwi_wme_update(struct ieee80211com *ic) /* * We may be called to update the WME parameters in * the adapter at various places. If we're already - * associated then initiate the request immediately - * (via the taskqueue); otherwise we assume the params - * will get sent down to the adapter as part of the - * work iwi_auth_and_assoc does. + * associated then initiate the request immediately; + * otherwise we assume the params will get sent down + * to the adapter as part of the work iwi_auth_and_assoc + * does. */ if (vap->iv_state == IEEE80211_S_RUN) - (void) iwi_wme_setparams(sc, ic); + ieee80211_runtask(ic, &sc->sc_wmetask); return (0); } diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index 25db9cfc6121..b31af36c05ad 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -190,6 +190,7 @@ struct iwi_softc { struct task sc_radiofftask; /* radio off processing */ struct task sc_restarttask; /* restart adapter processing */ struct task sc_disassoctask; + struct task sc_wmetask; /* set wme parameters */ unsigned int sc_softled : 1, /* enable LED gpio status */ sc_ledstate: 1, /* LED on/off state */ @@ -220,7 +221,7 @@ struct iwi_softc { #define IWI_STATE_BEGIN(_sc, _state) do { \ KASSERT(_sc->fw_state == IWI_FW_IDLE, \ - ("iwi firmware not idle")); \ + ("iwi firmware not idle, state %s", iwi_fw_states[_sc->fw_state]));\ _sc->fw_state = _state; \ _sc->sc_state_timer = 5; \ DPRINTF(("enter %s state\n", iwi_fw_states[_state])); \ From 8d0f23a5722da8362967476abf2c542d72fd1a5d Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 9 May 2009 19:44:23 +0000 Subject: [PATCH 078/544] hookup iwnfw.4 --- share/man/man4/Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 9cc8d7ce499b..911b7a6f8e17 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -151,6 +151,7 @@ MAN= aac.4 \ ispfw.4 \ iwi.4 \ iwn.4 \ + iwnfw.4 \ ixgb.4 \ ixgbe.4 \ jme.4 \ From dc974bbb9bb3cc7b258c6d4b8b494bdde8bbf715 Mon Sep 17 00:00:00 2001 From: Ivan Voras Date: Sat, 9 May 2009 20:18:20 +0000 Subject: [PATCH 079/544] Describe the topology_spec sysctl and do some minor adjustments to relating documentation. Reviewed by: brooks (older version) Approved by: gnn (mentor) --- share/man/man4/smp.4 | 63 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/share/man/man4/smp.4 b/share/man/man4/smp.4 index c20745ec8e96..2c06d1d6c02e 100644 --- a/share/man/man4/smp.4 +++ b/share/man/man4/smp.4 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 17, 2004 +.Dd May 7, 2008 .Dt SMP 4 .Os .Sh NAME @@ -69,12 +69,63 @@ is an integer bitmask denoting CPUs to halt, counting from 0. Setting a bit to 1 will result in the corresponding CPU being disabled. .Pp +The +.Xr sched_ule 4 +scheduler implements CPU topology detection and adjusts the scheduling +algorithms to make better use of modern multi-core CPUs. +The sysctl variable +.Va kern.sched.topology_spec +reflects the detected CPU hardware in a parsable XML format. +The top level XML tag is , which encloses one or more tags +containing data about individual CPU groups. +A CPU group contains CPUs that are detected to be "close" together, usually +by being cores in a single multi-core processor. +Attributes available in a tag are "level", corresponding to the +nesting level of the CPU group and "cache-level", corresponding to the +level of CPU caches shared by the CPUs in the group. +The tag contains the and tags. +The tag describes CPUs in the group. +Its attributes are "count", corresponding to the number of CPUs in the +group and "mask", corresponding to the integer binary mask in which +each bit position set to 1 signifies a CPU belonging to the group. +The contents (CDATA) of the tag is the comma-delimited list +of CPU indexes (derived from the "mask" attribute). +The tag contains special tags (if any) describing the relation +of the CPUs in the group. +The possible flags are currently "HTT" and "SMT", corresponding to +the various implementations of hardware multithreading. +An example topology_spec output for a system consisting of +two quad-core processors is: +.Bd -literal + + + 0, 1, 2, 3, 4, 5, 6, 7 + + + + 0, 1, 2, 3 + + + + 4, 5, 6, 7 + + + + + +.Ed +.Pp +This information is used internally by the kernel to schedule related +tasks on CPUs that are closely grouped together. +.Pp .Fx -supports hyperthreading on Intel CPU's on the i386 platform. +supports hyperthreading on Intel CPU's on the i386 and AMD64 platforms. Since using logical CPUs can cause performance penalties under certain loads, the logical CPUs can be disabled by setting the .Va machdep.hlt_logical_cpus -sysctl to one. +sysctl to one. +Note that this operation is different from the mechanism used by the +.Xr cpuset 1 . .Sh SEE ALSO .Xr mptable 1 , .Xr sysctl 8 , @@ -83,7 +134,11 @@ sysctl to one. .Xr mtx_pool 9 , .Xr mutex 9 , .Xr sema 9 , -.Xr sx 9 +.Xr sx 9 , +.Xr rwlock 9 , +.Xr sched_4bsd 4 , +.Xr sched_ule 4 , +.Xr cpuset 1 .Sh HISTORY The .Nm From b3b17597eab61d4ea34f1cfd653c53d284e18c75 Mon Sep 17 00:00:00 2001 From: Jun Kuriyama Date: Sun, 10 May 2009 00:00:25 +0000 Subject: [PATCH 080/544] - Use "device\t" and "options \t" for consistency. --- sys/amd64/conf/DEFAULTS | 2 +- sys/amd64/conf/GENERIC | 6 ++-- sys/amd64/conf/NOTES | 10 +++---- sys/amd64/conf/XENHVM | 8 +++--- sys/arm/conf/AVILA | 16 +++++------ sys/arm/conf/BWCT | 20 ++++++------- sys/arm/conf/CAMBRIA | 26 ++++++++--------- sys/arm/conf/CRB | 52 ++++++++++++++++----------------- sys/arm/conf/DB-78XXX | 26 ++++++++--------- sys/arm/conf/DB-88F5XXX | 30 +++++++++---------- sys/arm/conf/DB-88F6XXX | 26 ++++++++--------- sys/arm/conf/EP80219 | 58 ++++++++++++++++++------------------- sys/arm/conf/GUMSTIX | 28 +++++++++--------- sys/arm/conf/HL200 | 56 ++++++++++++++++++------------------ sys/arm/conf/IQ31244 | 48 +++++++++++++++---------------- sys/arm/conf/KB920X | 62 ++++++++++++++++++++-------------------- sys/arm/conf/NSLU | 2 +- sys/arm/conf/SIMICS | 8 +++--- sys/arm/conf/SKYEYE | 18 ++++++------ sys/conf/NOTES | 42 +++++++++++++-------------- sys/i386/conf/DEFAULTS | 4 +-- sys/i386/conf/GENERIC | 6 ++-- sys/i386/conf/NOTES | 16 +++++------ sys/i386/conf/PAE | 2 +- sys/i386/conf/XBOX | 6 ++-- sys/i386/conf/XEN | 14 ++++----- sys/ia64/conf/DEFAULTS | 2 +- sys/ia64/conf/NOTES | 14 ++++----- sys/mips/conf/ADM5120 | 46 ++++++++++++++--------------- sys/mips/conf/IDT | 32 ++++++++++----------- sys/mips/conf/MALTA | 42 +++++++++++++-------------- sys/mips/conf/QEMU | 26 ++++++++--------- sys/mips/conf/SENTRY5 | 36 +++++++++++------------ sys/pc98/conf/DEFAULTS | 2 +- sys/pc98/conf/NOTES | 8 +++--- sys/powerpc/conf/GENERIC | 2 +- sys/powerpc/conf/MPC85XX | 6 ++-- sys/powerpc/conf/NOTES | 2 +- sys/sparc64/conf/GENERIC | 2 +- 39 files changed, 406 insertions(+), 406 deletions(-) diff --git a/sys/amd64/conf/DEFAULTS b/sys/amd64/conf/DEFAULTS index 768d6a1bfaf6..c41e1c698d68 100644 --- a/sys/amd64/conf/DEFAULTS +++ b/sys/amd64/conf/DEFAULTS @@ -21,4 +21,4 @@ options GEOM_PART_EBR options GEOM_PART_EBR_COMPAT options GEOM_PART_MBR -options FLOWTABLE +options FLOWTABLE diff --git a/sys/amd64/conf/GENERIC b/sys/amd64/conf/GENERIC index 19cb70248310..569e0cd6790c 100644 --- a/sys/amd64/conf/GENERIC +++ b/sys/amd64/conf/GENERIC @@ -68,7 +68,7 @@ options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev options STOP_NMI # Stop CPUS using NMI instead of IPI -options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing #options KDTRACE_FRAME # Ensure frames are compiled in #options KDTRACE_HOOKS # Kernel DTrace hooks @@ -114,7 +114,7 @@ options AHD_REG_PRETTY_PRINT # Print register bitfields in debug device amd # AMD 53C974 (Tekram DC-390(T)) device hptiop # Highpoint RocketRaid 3xxx series device isp # Qlogic family -#device ispfw # Firmware for QLogic HBAs- normally a module +#device ispfw # Firmware for QLogic HBAs- normally a module device mpt # LSI-Logic MPT-Fusion #device ncr # NCR/Symbios Logic device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') @@ -260,7 +260,7 @@ device wlan_amrr # AMRR transmit rate control algorithm device an # Aironet 4500/4800 802.11 wireless NICs. device ath # Atheros pci/cardbus NIC's device ath_hal # pci/cardbus chip support -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath device ral # Ralink Technology RT2500 wireless NICs. device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES index 95ae9be4ce05..caddd339619a 100644 --- a/sys/amd64/conf/NOTES +++ b/sys/amd64/conf/NOTES @@ -33,7 +33,7 @@ options MP_WATCHDOG # # Debugging options. # -options STOP_NMI # Stop CPUS using NMI instead of IPI +options STOP_NMI # Stop CPUS using NMI instead of IPI @@ -82,7 +82,7 @@ options DEVICE_POLLING # BPF_JITTER adds support for BPF just-in-time compiler. -options BPF_JITTER +options BPF_JITTER ##################################################################### @@ -153,7 +153,7 @@ device agp # # AGP debugging. # -options AGP_DEBUG +options AGP_DEBUG ##################################################################### @@ -288,7 +288,7 @@ device wpi device ath # Atheros pci/cardbus NIC's device ath_hal # pci/cardbus chip support -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath #device ath_rate_amrr # AMRR rate control for ath driver #device ath_rate_onoe # Onoe rate control for ath driver @@ -457,7 +457,7 @@ options LINPROCFS #Enable the linux-like sys filesystem support (requires COMPAT_LINUX32 # and PSEUDOFS) -options LINSYSFS +options LINSYSFS # # SysVR4 ABI emulation diff --git a/sys/amd64/conf/XENHVM b/sys/amd64/conf/XENHVM index 6080737c9f07..5e108d51ea27 100644 --- a/sys/amd64/conf/XENHVM +++ b/sys/amd64/conf/XENHVM @@ -69,12 +69,12 @@ options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev options STOP_NMI # Stop CPUS using NMI instead of IPI -options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing #options KDTRACE_FRAME # Ensure frames are compiled in #options KDTRACE_HOOKS # Kernel DTrace hooks -options NO_ADAPTIVE_MUTEXES -options NO_ADAPTIVE_RWLOCKS +options NO_ADAPTIVE_MUTEXES +options NO_ADAPTIVE_RWLOCKS # Debugging for use in -current options KDB # Enable kernel debugger support. @@ -99,7 +99,7 @@ device pci device fdc # Xen HVM support -options XENHVM +options XENHVM device xenpci # ATA and ATAPI devices diff --git a/sys/arm/conf/AVILA b/sys/arm/conf/AVILA index cd1d33807e1e..826dea2cdcc1 100644 --- a/sys/arm/conf/AVILA +++ b/sys/arm/conf/AVILA @@ -99,12 +99,12 @@ device loop device if_bridge device md -device random # Entropy device +device random # Entropy device # Wireless NIC cards device wlan # 802.11 support -options IEEE80211_DEBUG -options IEEE80211_SUPPORT_TDMA +options IEEE80211_DEBUG +options IEEE80211_SUPPORT_TDMA device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support @@ -112,12 +112,12 @@ device wlan_xauth device ath # Atheros pci/cardbus NIC's options ATH_DEBUG -options ATH_DIAGAPI -#options ATH_TX99_DIAG +options ATH_DIAGAPI +#options ATH_TX99_DIAG device ath_rate_sample # SampleRate tx rate control for ath -#options AH_DEBUG -#options AH_ASSERT +#options AH_DEBUG +#options AH_ASSERT #device ath_ar5210 #device ath_ar5211 device ath_ar5212 @@ -129,7 +129,7 @@ device ath_rf5112 device ath_rf5413 # device ath_ar5416 -options AH_SUPPORT_AR5416 +options AH_SUPPORT_AR5416 device ath_ar9160 makeoptions WITH_LEGACY diff --git a/sys/arm/conf/BWCT b/sys/arm/conf/BWCT index 8b8ca11834ec..b92e626fb56d 100644 --- a/sys/arm/conf/BWCT +++ b/sys/arm/conf/BWCT @@ -19,9 +19,9 @@ ident BWCT -options VERBOSE_INIT_ARM +options VERBOSE_INIT_ARM -options AT91_BWCT +options AT91_BWCT include "../at91/std.bwct" #To statically compile in device wiring instead of /boot/device.hints @@ -30,8 +30,8 @@ hints "BWCT.hints" makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols -options DDB -options KDB +options DDB +options KDB options BREAK_TO_DEBUGGER options ALT_BREAK_TO_DEBUGGER @@ -43,15 +43,15 @@ options SOFTUPDATES #Enable FFS soft updates support #options UFS_ACL #Support for access control lists #options UFS_DIRHASH #Improve performance on big directories #options MD_ROOT #MD is a potential root device -#options MD_ROOT_SIZE=4096 # 3MB ram disk +#options MD_ROOT_SIZE=4096 # 3MB ram disk #options ROOTDEVNAME=\"ufs:md0\" #options ROOTDEVNAME=\"ufs:/dev/mmcsd0s1a\" options NFSCLIENT #Network Filesystem Client #options NFSSERVER #Network Filesystem Server #options NFSLOCKD #Network Lock Manager -options NFS_ROOT #NFS usable as /, requires NFSCLIENT -options BOOTP_NFSROOT -options BOOTP +options NFS_ROOT #NFS usable as /, requires NFSCLIENT +options BOOTP_NFSROOT +options BOOTP #options MSDOSFS #MSDOS Filesystem #options CD9660 #ISO 9660 Filesystem @@ -65,7 +65,7 @@ options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions #options SYSCTL_OMIT_DESCR options MUTEX_NOINLINE -options RWLOCK_NOINLINE +options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING device loop @@ -83,7 +83,7 @@ device rlswitch #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options DIAGNOSTIC +#options DIAGNOSTIC device md device at91_twi # TWI: Two Wire Interface diff --git a/sys/arm/conf/CAMBRIA b/sys/arm/conf/CAMBRIA index 70655dec377e..8375a74d0ca3 100644 --- a/sys/arm/conf/CAMBRIA +++ b/sys/arm/conf/CAMBRIA @@ -68,7 +68,7 @@ device uart device ixpwdog # watchdog timer -options IXP4XX_FLASH_SIZE=0x02000000 # stock 2358 comes w/ 32M +options IXP4XX_FLASH_SIZE=0x02000000 # stock 2358 comes w/ 32M device cfi # flash support device cfid # flash disk support device geom_redboot # redboot fis parser @@ -86,7 +86,7 @@ device cambria_fled # Font Panel LED on I2C bus device cambria_led # 8-LED latch device ata -device atadisk # ATA disk drives +device atadisk # ATA disk drives device avila_ata # Gateworks CF/IDE support device npe # Network Processing Engine @@ -102,12 +102,12 @@ device loop device if_bridge device md -device random # Entropy device +device random # Entropy device # Wireless NIC cards device wlan # 802.11 support -options IEEE80211_DEBUG -options IEEE80211_SUPPORT_TDMA +options IEEE80211_DEBUG +options IEEE80211_SUPPORT_TDMA device wlan_wep # 802.11 WEP support device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support @@ -115,13 +115,13 @@ device wlan_xauth device ath # Atheros pci/cardbus NIC's options ATH_DEBUG -options ATH_DIAGAPI -#options ATH_TX99_DIAG +options ATH_DIAGAPI +#options ATH_TX99_DIAG device ath_rate_sample # SampleRate tx rate control for ath -options AH_DEBUG -#options AH_ASSERT -options AH_PRIVATE_DIAG +options AH_DEBUG +#options AH_ASSERT +options AH_PRIVATE_DIAG #device ath_ar5210 #device ath_ar5211 # @@ -133,7 +133,7 @@ device ath_rf5112 device ath_rf5413 # #device ath_ar5416 -#options AH_SUPPORT_AR5416 # NB: for 11n descriptor format +#options AH_SUPPORT_AR5416 # NB: for 11n descriptor format #device ath_rf2133 #device ath_ar9160 #device ath_ar9280 @@ -142,8 +142,8 @@ device ath_rf5413 # NB: 2 USB 2.0 ports standard device usb -options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order -#options USB_DEBUG +options USB_EHCI_BIG_ENDIAN_DESC # handle big-endian byte order +#options USB_DEBUG device ehci device umass device scbus # SCSI bus (required for SCSI) diff --git a/sys/arm/conf/CRB b/sys/arm/conf/CRB index 525213246376..ef0265fa4cb6 100644 --- a/sys/arm/conf/CRB +++ b/sys/arm/conf/CRB @@ -20,11 +20,11 @@ ident CRB options PHYSADDR=0x00000000 -options KERNPHYSADDR=0x00200000 -options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm +options KERNPHYSADDR=0x00200000 +options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm -options COUNTS_PER_SEC=400000000 -options STARTUP_PAGETABLE_ADDR=0x00000000 +options COUNTS_PER_SEC=400000000 +options STARTUP_PAGETABLE_ADDR=0x00000000 include "../xscale/i8134x/std.crb" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. @@ -32,9 +32,9 @@ makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions CONF_CFLAGS=-mcpu=xscale -options HZ=100 -options BREAK_TO_DEBUGGER -#options DEVICE_POLLING +options HZ=100 +options BREAK_TO_DEBUGGER +#options DEVICE_POLLING options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -53,18 +53,18 @@ options CD9660 #ISO 9660 Filesystem options PSEUDOFS #Pseudo-filesystem framework options SCSI_DELAY=5000 #Delay (in ms) before probing SCSI options KTRACE #ktrace(1) support -options INTR_FILTER +options INTR_FILTER options SYSVSHM #SYSV-style shared memory options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=em0 -options BOOTP_COMPAT -#options PREEMPTION +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=em0 +options BOOTP_COMPAT +#options PREEMPTION device loop device ether #device saarm @@ -75,12 +75,12 @@ device uart device pci device ata -device atadisk # ATA disk drives -device ataraid # ATA RAID drives -device atapicd # ATAPI CDROM drives -device atapifd # ATAPI floppy drives -device atapist # ATAPI tape drives -options ATA_STATIC_ID # Static device numbering +device atadisk # ATA disk drives +device ataraid # ATA RAID drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID # Static device numbering device "7seg" @@ -93,22 +93,22 @@ device pty # output. Adds ~215k to driver. # Debugging for use in -current -options KDB +options KDB options DDB #Enable the kernel debugger #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options DIAGNOSTIC +#options DIAGNOSTIC # To make an SMP kernel, the next two are needed #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O -options XSCALE_CACHE_READ_WRITE_ALLOCATE -device md -device random # Entropy device +options XSCALE_CACHE_READ_WRITE_ALLOCATE +device md +device random # Entropy device device iopwdog -options ARM_USE_SMALL_ALLOC +options ARM_USE_SMALL_ALLOC # Floppy drives diff --git a/sys/arm/conf/DB-78XXX b/sys/arm/conf/DB-78XXX index 5d30cd1fdd7b..7f411a15869f 100644 --- a/sys/arm/conf/DB-78XXX +++ b/sys/arm/conf/DB-78XXX @@ -7,7 +7,7 @@ ident DB-88F78XX include "../mv/discovery/std.db78xxx" -options SOC_MV_DISCOVERY +options SOC_MV_DISCOVERY makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols @@ -18,34 +18,34 @@ options INET #InterNETworking options INET6 #IPv6 communications protocols options FFS #Berkeley Fast Filesystem options NFSCLIENT #Network Filesystem Client -options NFSLOCKD #Network Lock Manager +options NFSLOCKD #Network Lock Manager options NFS_ROOT #NFS usable as /, requires NFSCLIENT -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=mge0 +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=mge0 -#options ROOTDEVNAME=\"ufs:/dev/da0a\" +#options ROOTDEVNAME=\"ufs:/dev/da0a\" options SYSVSHM #SYSV-style shared memory options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options MUTEX_NOINLINE -options RWLOCK_NOINLINE +options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING # Debugging -options ALT_BREAK_TO_DEBUGGER -options DDB -options DIAGNOSTIC +options ALT_BREAK_TO_DEBUGGER +options DDB +options DIAGNOSTIC #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -options KDB +options KDB options WITNESS #Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options WITNESS_KDB +#options WITNESS_KDB device pci diff --git a/sys/arm/conf/DB-88F5XXX b/sys/arm/conf/DB-88F5XXX index 3b877cc910be..5989e3eec4b7 100644 --- a/sys/arm/conf/DB-88F5XXX +++ b/sys/arm/conf/DB-88F5XXX @@ -7,7 +7,7 @@ ident DB-88F5XXX include "../mv/orion/std.db88f5xxx" -options SOC_MV_ORION +options SOC_MV_ORION makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols @@ -18,34 +18,34 @@ options INET #InterNETworking options INET6 #IPv6 communications protocols options FFS #Berkeley Fast Filesystem options NFSCLIENT #Network Filesystem Client -options NFSLOCKD #Network Lock Manager +options NFSLOCKD #Network Lock Manager options NFS_ROOT #NFS usable as /, requires NFSCLIENT -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=mge0 +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=mge0 -#options ROOTDEVNAME=\"ufs:/dev/da0a\" +#options ROOTDEVNAME=\"ufs:/dev/da0a\" options SYSVSHM #SYSV-style shared memory options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options MUTEX_NOINLINE -options RWLOCK_NOINLINE +options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING # Debugging -options ALT_BREAK_TO_DEBUGGER -options DDB -options DIAGNOSTIC +options ALT_BREAK_TO_DEBUGGER +options DDB +options DIAGNOSTIC #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -options KDB +options KDB options WITNESS #Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options WITNESS_KDB +#options WITNESS_KDB device pci @@ -64,8 +64,8 @@ device mge # Marvell Gigabit Ethernet controller device mii device e1000phy device bpf -options DEVICE_POLLING -options HZ=1000 +options DEVICE_POLLING +options HZ=1000 # I2C (TWSI) device iic diff --git a/sys/arm/conf/DB-88F6XXX b/sys/arm/conf/DB-88F6XXX index 9831b3909681..c44f80118c73 100644 --- a/sys/arm/conf/DB-88F6XXX +++ b/sys/arm/conf/DB-88F6XXX @@ -7,7 +7,7 @@ ident DB-88F6XXX include "../mv/kirkwood/std.db88f6xxx" -options SOC_MV_KIRKWOOD +options SOC_MV_KIRKWOOD makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols @@ -18,34 +18,34 @@ options INET #InterNETworking options INET6 #IPv6 communications protocols options FFS #Berkeley Fast Filesystem options NFSCLIENT #Network Filesystem Client -options NFSLOCKD #Network Lock Manager +options NFSLOCKD #Network Lock Manager options NFS_ROOT #NFS usable as /, requires NFSCLIENT -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=mge0 +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=mge0 -#options ROOTDEVNAME=\"ufs:/dev/da0a\" +#options ROOTDEVNAME=\"ufs:/dev/da0a\" options SYSVSHM #SYSV-style shared memory options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options MUTEX_NOINLINE -options RWLOCK_NOINLINE +options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING # Debugging -options ALT_BREAK_TO_DEBUGGER -options DDB -options DIAGNOSTIC +options ALT_BREAK_TO_DEBUGGER +options DDB +options DIAGNOSTIC #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS -options KDB +options KDB options WITNESS #Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options WITNESS_KDB +#options WITNESS_KDB device pci diff --git a/sys/arm/conf/EP80219 b/sys/arm/conf/EP80219 index 44fe2621ca25..65121bc50733 100644 --- a/sys/arm/conf/EP80219 +++ b/sys/arm/conf/EP80219 @@ -20,11 +20,11 @@ ident EP80219 options PHYSADDR=0xa0000000 -options KERNPHYSADDR=0xa0200000 -options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm +options KERNPHYSADDR=0xa0200000 +options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm options STARTUP_PAGETABLE_ADDR=0xa0000000 -#options ARM32_NEW_VM_LAYOUT +#options ARM32_NEW_VM_LAYOUT include "../xscale/i80321/std.ep80219" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. @@ -32,8 +32,8 @@ makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions CONF_CFLAGS=-mcpu=xscale -options HZ=100 -#options DEVICE_POLLING +options HZ=100 +#options DEVICE_POLLING options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -57,15 +57,15 @@ options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options GEOM_PART_GPT # GUID Partition Tables. -options GEOM_LABEL # Providers labelization. +options GEOM_PART_GPT # GUID Partition Tables. +options GEOM_LABEL # Providers labelization. -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=fxp0 -options BOOTP_COMPAT -#options PREEMPTION +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=fxp0 +options BOOTP_COMPAT +#options PREEMPTION device loop device ether #device saarm @@ -75,12 +75,12 @@ device uart device pci device ata -device atadisk # ATA disk drives -device ataraid # ATA RAID drives -device atapicd # ATAPI CDROM drives -device atapifd # ATAPI floppy drives -device atapist # ATAPI tape drives -options ATA_STATIC_ID # Static device numbering +device atadisk # ATA disk drives +device ataraid # ATA RAID drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID # Static device numbering # SCSI Controllers @@ -89,27 +89,27 @@ device iopwdog # I80321 Watchdog device dma # I80321 DMA Controller # Debugging for use in -current -options KDB +options KDB options DDB #Enable the kernel debugger #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options DIAGNOSTIC +#options DIAGNOSTIC # To make an SMP kernel, the next two are needed #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O -options XSCALE_CACHE_READ_WRITE_ALLOCATE -device md +options XSCALE_CACHE_READ_WRITE_ALLOCATE +device md device random # Entropy device -options ARM_USE_SMALL_ALLOC +options ARM_USE_SMALL_ALLOC # Floppy drives -options INCLUDE_CONFIG_FILE # Include this file in kernel -#options VERBOSE_SYSINIT -options VERBOSE_INIT_ARM +options INCLUDE_CONFIG_FILE # Include this file in kernel +#options VERBOSE_SYSINIT +options VERBOSE_INIT_ARM -device bpf -#options ROOTDEVNAME=\"ufs:ad4s1a\" +device bpf +#options ROOTDEVNAME=\"ufs:ad4s1a\" diff --git a/sys/arm/conf/GUMSTIX b/sys/arm/conf/GUMSTIX index 05172ca3900b..864a4f5caf70 100644 --- a/sys/arm/conf/GUMSTIX +++ b/sys/arm/conf/GUMSTIX @@ -27,18 +27,18 @@ cpu CPU_XSCALE_PXA2X0 hints "GUMSTIX.hints" options PHYSADDR=0xa0000000 -options KERNPHYSADDR=0xa0200000 -options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm +options KERNPHYSADDR=0xa0200000 +options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm -options STARTUP_PAGETABLE_ADDR=0xa0000000 +options STARTUP_PAGETABLE_ADDR=0xa0000000 include "../xscale/pxa/std.pxa" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols -options HZ=100 -#options DEVICE_POLLING +options HZ=100 +#options DEVICE_POLLING options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -62,13 +62,13 @@ options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options BOOTP -options BOOTP_NFSROOT -options BOOTP_WIRED_TO=smc0 -options BOOTP_COMPAT -options BOOTP_NFSV3 -options BOOTP_BLOCKSIZE=4096 -options PREEMPTION +options BOOTP +options BOOTP_NFSROOT +options BOOTP_WIRED_TO=smc0 +options BOOTP_COMPAT +options BOOTP_NFSV3 +options BOOTP_BLOCKSIZE=4096 +options PREEMPTION device loop device ether device mii @@ -80,7 +80,7 @@ device uart_ns8250 device pty # Debugging for use in -current -options KDB +options KDB options DDB #Enable the kernel debugger #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS @@ -89,4 +89,4 @@ options DDB #Enable the kernel debugger #options DIAGNOSTIC device md -device random # Entropy device +device random # Entropy device diff --git a/sys/arm/conf/HL200 b/sys/arm/conf/HL200 index de322ec66de1..61f74cf6287f 100644 --- a/sys/arm/conf/HL200 +++ b/sys/arm/conf/HL200 @@ -26,8 +26,8 @@ hints "KB920X.hints" makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols -options DDB -options KDB +options DDB +options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -44,7 +44,7 @@ options NFSCLIENT #Network Filesystem Client #options NFSLOCKD #Network Lock Manager options NFS_ROOT #NFS usable as /, requires NFSCLIENT options BOOTP_NFSROOT -options BOOTP +options BOOTP options BOOTP_NFSV3 options BOOTP_WIRED_TO=ate0 options BOOTP_COMPAT @@ -61,7 +61,7 @@ options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions #options SYSCTL_OMIT_DESCR options MUTEX_NOINLINE -options RWLOCK_NOINLINE +options RWLOCK_NOINLINE options NO_FFS_SNAPSHOT options NO_SWAPPING device random @@ -94,23 +94,23 @@ device icee device bpf # USB support -device ohci # OHCI localbus->USB interface -device usb # USB Bus (required) -#device udbp # USB Double Bulk Pipe devices -device uhid # "Human Interface Devices" -device ulpt # Printer -device umass # Disks/Mass storage - Requires scbus and da -device ural # Ralink Technology RT2500USB wireless NICs -device rum # Ralink Technology RT2501USB wireless NICs -device urio # Diamond Rio 500 MP3 player +device ohci # OHCI localbus->USB interface +device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +device uhid # "Human Interface Devices" +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ural # Ralink Technology RT2500USB wireless NICs +device rum # Ralink Technology RT2501USB wireless NICs +device urio # Diamond Rio 500 MP3 player # USB Ethernet, requires miibus device miibus -device aue # ADMtek USB Ethernet -device axe # ASIX Electronics USB Ethernet -device cdce # Generic USB over Ethernet -device cue # CATC USB Ethernet -device kue # Kawasaki LSI USB Ethernet -device rue # RealTek RTL8150 USB Ethernet +device aue # ADMtek USB Ethernet +device axe # ASIX Electronics USB Ethernet +device cdce # Generic USB over Ethernet +device cue # CATC USB Ethernet +device kue # Kawasaki LSI USB Ethernet +device rue # RealTek RTL8150 USB Ethernet device udav # usb serial device uark @@ -122,13 +122,13 @@ device uplcom device uvisor device uvscom # SCSI peripherals -device scbus # SCSI bus (required for SCSI) -device da # Direct Access (disks) -device cd # CD -device pass # Passthrough device (direct SCSI access) +device scbus # SCSI bus (required for SCSI) +device da # Direct Access (disks) +device cd # CD +device pass # Passthrough device (direct SCSI access) # Wireless NIC cards -device wlan # 802.11 support -device wlan_wep # 802.11 WEP support -device wlan_ccmp # 802.11 CCMP support -device wlan_tkip # 802.11 TKIP support -device wlan_amrr # AMRR transmit rate control algorithm +device wlan # 802.11 support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm diff --git a/sys/arm/conf/IQ31244 b/sys/arm/conf/IQ31244 index d3c225bc8d51..e8ed9e872338 100644 --- a/sys/arm/conf/IQ31244 +++ b/sys/arm/conf/IQ31244 @@ -20,10 +20,10 @@ ident IQ31244 options PHYSADDR=0xa0000000 -options KERNPHYSADDR=0xa0200000 -options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm -options FLASHADDR=0xf0000000 -options LOADERRAMADDR=0x00000000 +options KERNPHYSADDR=0xa0200000 +options KERNVIRTADDR=0xc0200000 # Used in ldscript.arm +options FLASHADDR=0xf0000000 +options LOADERRAMADDR=0x00000000 options STARTUP_PAGETABLE_ADDR=0xa0000000 include "../xscale/i80321/std.iq31244" @@ -33,8 +33,8 @@ makeoptions MODULES_OVERRIDE="" #makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions CONF_CFLAGS=-mcpu=xscale -options HZ=100 -#options DEVICE_POLLING +options HZ=100 +#options DEVICE_POLLING options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -58,12 +58,12 @@ options SYSVMSG #SYSV-style message queues options SYSVSEM #SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING #Posix P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev -options BOOTP -options BOOTP_NFSROOT -options BOOTP_NFSV3 -options BOOTP_WIRED_TO=em0 -options BOOTP_COMPAT -#options PREEMPTION +options BOOTP +options BOOTP_NFSROOT +options BOOTP_NFSV3 +options BOOTP_WIRED_TO=em0 +options BOOTP_COMPAT +#options PREEMPTION device loop device ether #device saarm @@ -74,12 +74,12 @@ device uart device pci device ata -device atadisk # ATA disk drives -device ataraid # ATA RAID drives -device atapicd # ATAPI CDROM drives -device atapifd # ATAPI floppy drives -device atapist # ATAPI tape drives -options ATA_STATIC_ID # Static device numbering +device atadisk # ATA disk drives +device ataraid # ATA RAID drives +device atapicd # ATAPI CDROM drives +device atapifd # ATAPI floppy drives +device atapist # ATAPI tape drives +options ATA_STATIC_ID # Static device numbering # SCSI Controllers @@ -94,21 +94,21 @@ device "iq31244_7seg" # IQ31244 7 seg # output. Adds ~215k to driver. # Debugging for use in -current -options KDB +options KDB options DDB #Enable the kernel debugger #options INVARIANTS #Enable calls of extra sanity checking #options INVARIANT_SUPPORT #Extra sanity checks of internal structures, required by INVARIANTS #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -#options DIAGNOSTIC +#options DIAGNOSTIC # To make an SMP kernel, the next two are needed #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O -options XSCALE_CACHE_READ_WRITE_ALLOCATE -device md -device random # Entropy device +options XSCALE_CACHE_READ_WRITE_ALLOCATE +device md +device random # Entropy device -options ARM_USE_SMALL_ALLOC +options ARM_USE_SMALL_ALLOC # Floppy drives diff --git a/sys/arm/conf/KB920X b/sys/arm/conf/KB920X index 1f688f809af6..31f009622445 100644 --- a/sys/arm/conf/KB920X +++ b/sys/arm/conf/KB920X @@ -95,40 +95,40 @@ device icee device bpf # USB support -device ohci # OHCI localbus->USB interface -device usb # USB Bus (required) -#device udbp # USB Double Bulk Pipe devices -device uhid # "Human Interface Devices" -device ulpt # Printer -device umass # Disks/Mass storage - Requires scbus and da -device ural # Ralink Technology RT2500USB wireless NICs -device rum # Ralink Technology RT2501USB wireless NICs -device urio # Diamond Rio 500 MP3 player +device ohci # OHCI localbus->USB interface +device usb # USB Bus (required) +#device udbp # USB Double Bulk Pipe devices +device uhid # "Human Interface Devices" +device ulpt # Printer +device umass # Disks/Mass storage - Requires scbus and da +device ural # Ralink Technology RT2500USB wireless NICs +device rum # Ralink Technology RT2501USB wireless NICs +device urio # Diamond Rio 500 MP3 player # USB Ethernet, requires miibus device miibus -device aue # ADMtek USB Ethernet -device axe # ASIX Electronics USB Ethernet -device cdce # Generic USB over Ethernet -device cue # CATC USB Ethernet -device kue # Kawasaki LSI USB Ethernet -device rue # RealTek RTL8150 USB Ethernet +device aue # ADMtek USB Ethernet +device axe # ASIX Electronics USB Ethernet +device cdce # Generic USB over Ethernet +device cue # CATC USB Ethernet +device kue # Kawasaki LSI USB Ethernet +device rue # RealTek RTL8150 USB Ethernet device udav # usb serial -device uark -device ubsa -device uftdi -device uipaq -device uplcom -device uvisor -device uvscom +device uark +device ubsa +device uftdi +device uipaq +device uplcom +device uvisor +device uvscom # SCSI peripherals -device scbus # SCSI bus (required for SCSI) -device da # Direct Access (disks) -device cd # CD -device pass # Passthrough device (direct SCSI access) +device scbus # SCSI bus (required for SCSI) +device da # Direct Access (disks) +device cd # CD +device pass # Passthrough device (direct SCSI access) # Wireless NIC cards -device wlan # 802.11 support -device wlan_wep # 802.11 WEP support -device wlan_ccmp # 802.11 CCMP support -device wlan_tkip # 802.11 TKIP support -device wlan_amrr # AMRR transmit rate control algorithm +device wlan # 802.11 support +device wlan_wep # 802.11 WEP support +device wlan_ccmp # 802.11 CCMP support +device wlan_tkip # 802.11 TKIP support +device wlan_amrr # AMRR transmit rate control algorithm diff --git a/sys/arm/conf/NSLU b/sys/arm/conf/NSLU index 614a8a06b91c..f14a77969197 100644 --- a/sys/arm/conf/NSLU +++ b/sys/arm/conf/NSLU @@ -104,7 +104,7 @@ device pty device loop device md -device random # Entropy device +device random # Entropy device #options ARM_USE_SMALL_ALLOC diff --git a/sys/arm/conf/SIMICS b/sys/arm/conf/SIMICS index ef1ccb06780f..e225795f689b 100644 --- a/sys/arm/conf/SIMICS +++ b/sys/arm/conf/SIMICS @@ -29,8 +29,8 @@ makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions CONF_CFLAGS=-mcpu=strongarm -options DDB -options KDB +options DDB +options KDB options SCHED_4BSD #4BSD scheduler options INET #InterNETworking @@ -40,7 +40,7 @@ options SOFTUPDATES #Enable FFS soft updates support options UFS_ACL #Support for access control lists options UFS_DIRHASH #Improve performance on big directories options MD_ROOT #MD is a potential root device -options ROOTDEVNAME=\"ufs:md0\" +options ROOTDEVNAME=\"ufs:md0\" options NFSCLIENT #Network Filesystem Client options NFSSERVER #Network Filesystem Server options NFSLOCKD #Network Lock Manager @@ -68,4 +68,4 @@ device uart #options WITNESS #Enable checks to detect deadlocks and cycles #options WITNESS_SKIPSPIN #Don't run witness on spinlocks for speed -device md +device md diff --git a/sys/arm/conf/SKYEYE b/sys/arm/conf/SKYEYE index 007d49e3bf83..56fa39c738d0 100644 --- a/sys/arm/conf/SKYEYE +++ b/sys/arm/conf/SKYEYE @@ -20,9 +20,9 @@ ident KB920X -options KERNPHYSADDR=0xc0000000 -options KERNVIRTADDR=0xc0000000 -options PHYSADDR=0xc0000000 +options KERNPHYSADDR=0xc0000000 +options KERNVIRTADDR=0xc0000000 +options PHYSADDR=0xc0000000 include "../at91/std.kb920x" #To statically compile in device wiring instead of /boot/device.hints #hints "GENERIC.hints" #Default places to look for devices. @@ -30,8 +30,8 @@ makeoptions MODULES_OVERRIDE="" makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols makeoptions CONF_CFLAGS=-mcpu=arm9 -options DDB -options KDB +options DDB +options KDB options SCHED_4BSD #4BSD scheduler @@ -42,8 +42,8 @@ options SOFTUPDATES #Enable FFS soft updates support options UFS_ACL #Support for access control lists options UFS_DIRHASH #Improve performance on big directories options MD_ROOT #MD is a potential root device -options MD_ROOT_SIZE=4096 -options ROOTDEVNAME=\"ufs:md0\" +options MD_ROOT_SIZE=4096 +options ROOTDEVNAME=\"ufs:md0\" options NFSCLIENT #Network Filesystem Client options NFSSERVER #Network Filesystem Server options NFSLOCKD #Network Lock Manager @@ -79,8 +79,8 @@ device uart #options SMP # Symmetric MultiProcessor Kernel #options APIC_IO # Symmetric (APIC) I/O -device md -options SKYEYE_WORKAROUNDS +device md +options SKYEYE_WORKAROUNDS # Floppy drives diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 185ff8f2a6a4..7ba6ac497479 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -192,7 +192,7 @@ options ROOTDEVNAME=\"ufs:da0s2e\" # tree at 'kern.sched.stats' and is useful for debugging scheduling decisions. # options SCHED_4BSD -options SCHED_STATS +options SCHED_STATS #options SCHED_ULE ##################################################################### @@ -504,7 +504,7 @@ options STACK # Additional configuration options may be required on specific architectures, # please see hwpmc(4). -device hwpmc # Driver (also a loadable module) +device hwpmc # Driver (also a loadable module) options HWPMC_HOOKS # Other necessary kernel hooks @@ -517,7 +517,7 @@ options HWPMC_HOOKS # Other necessary kernel hooks options INET #Internet communications protocols options INET6 #IPv6 communications protocols -options ROUTETABLES=2 # max 16. 1 is back compatible. +options ROUTETABLES=2 # max 16. 1 is back compatible. # In order to enable IPSEC you MUST also add device crypto to # your kernel configuration @@ -551,10 +551,10 @@ options NETSMB #SMB/CIFS requester options LIBMCHAIN # libalias library, performing NAT -options LIBALIAS +options LIBALIAS # flowtable cache -options FLOWTABLE +options FLOWTABLE # # SCTP is a NEW transport protocol defined by @@ -571,7 +571,7 @@ options FLOWTABLE # the V6 and V4.. since an association can span # both a V6 and V4 address at the SAME time :-) # -options SCTP +options SCTP # There are bunches of options: # this one turns on all sorts of # nastly printing that you can @@ -583,7 +583,7 @@ options SCTP # option we don't do any of the tests for # bits and prints.. which makes the code run # faster.. if you are not debugging don't use. -options SCTP_DEBUG +options SCTP_DEBUG # # This option turns off the CRC32c checksum. Basically # You will not be able to talk to anyone else that @@ -596,7 +596,7 @@ options SCTP_DEBUG # splitting 8's algorithm its not as bad as it used # to be.. but it does speed things up try only # for in a captured lab environment :-) -options SCTP_WITH_NO_CSUM +options SCTP_WITH_NO_CSUM # # @@ -619,7 +619,7 @@ options SCTP_LOCK_LOGGING options SCTP_MBUF_LOGGING options SCTP_MBCNT_LOGGING options SCTP_PACKET_LOGGING -options SCTP_LTRACE_CHUNKS +options SCTP_LTRACE_CHUNKS options SCTP_LTRACE_ERRORS @@ -644,7 +644,7 @@ options ALTQ_DEBUG # It allows transparent proxies to pretend to be other machines. # How the packet GET to that machine is a problem solved elsewhere, # smart routers, ipfw fwd, etc. -options IP_NONLOCALBIND # Allow impersonation for proxies. +options IP_NONLOCALBIND # Allow impersonation for proxies. # netgraph(4). Enable the base netgraph code with the NETGRAPH option. # Individual node types can be enabled with the corresponding option @@ -734,8 +734,8 @@ device vlan # drivers, including host AP mode; it is MANDATORY for the wi, # and ath drivers and will eventually be required by all 802.11 drivers. device wlan -options IEEE80211_DEBUG #enable debugging msgs -options IEEE80211_AMPDU_AGE #age frames in AMPDU reorder q's +options IEEE80211_DEBUG #enable debugging msgs +options IEEE80211_AMPDU_AGE #age frames in AMPDU reorder q's # The `wlan_wep', `wlan_tkip', and `wlan_ccmp' devices provide # support for WEP, TKIP, and AES-CCMP crypto protocols optionally @@ -905,7 +905,7 @@ options TCPDEBUG # return a logarithmic histogram of monitored parameters # (e.g. packet size, wasted space, number of mbufs in chain). options MBUF_STRESS_TEST -options MBUF_PROFILING +options MBUF_PROFILING # Statically Link in accept filters options ACCEPT_FILTER_DATA @@ -962,7 +962,7 @@ options FDESCFS #File descriptor filesystem options HPFS #OS/2 File system options MSDOSFS #MS DOS File System (FAT, FAT32) options NFSSERVER #Network File System server -options NFSLOCKD #Network Lock Manager +options NFSLOCKD #Network Lock Manager # NT File System. Read-mostly, see mount_ntfs(8) for details. # For a full read-write NTFS support consider sysutils/fusefs-ntfs @@ -1397,8 +1397,8 @@ options SC_NO_SUSPEND_VTYSWITCH # 0x100 Probe for a keyboard device periodically if one is not present # Enable experimental features of the syscons terminal emulator (teken). -options TEKEN_UTF8 # UTF-8 output handling -options TEKEN_XTERM # xterm-style terminal emulation +options TEKEN_UTF8 # UTF-8 output handling +options TEKEN_XTERM # xterm-style terminal emulation # # Optional devices: @@ -1524,7 +1524,7 @@ options ADW_ALLOW_MEMIO # Options used in dev/iscsi (Software iSCSI stack) # -options ISCSI_INITIATOR_DEBUG=9 +options ISCSI_INITIATOR_DEBUG=9 # Options used in dev/isp/ (Qlogic SCSI/FC driver). # @@ -1618,7 +1618,7 @@ device mly device ida # Compaq Smart RAID device mlx # Mylex DAC960 device amr # AMI MegaRAID -device amrp # SCSI Passthrough interface (optional, CAM req.) +device amrp # SCSI Passthrough interface (optional, CAM req.) device mfi # LSI MegaRAID SAS device mfip # LSI MegaRAID SAS passthrough, requires CAM options MFI_DEBUG @@ -2348,7 +2348,7 @@ options BOOTP_NFSROOT # NFS mount root filesystem using BOOTP info options BOOTP_NFSV3 # Use NFS v3 to NFS mount root options BOOTP_COMPAT # Workaround for broken bootp daemons. options BOOTP_WIRED_TO=fxp0 # Use interface fxp0 for BOOTP -options BOOTP_BLOCKSIZE=8192 # Override NFS block size +options BOOTP_BLOCKSIZE=8192 # Override NFS block size # # Add software watchdog routines. @@ -2393,7 +2393,7 @@ device ohci # EHCI controller device ehci # SL811 Controller -#device slhci +#device slhci # General USB code (mandatory for USB) device usb # @@ -2490,7 +2490,7 @@ device zyd # debugging options for the USB subsystem # options USB_DEBUG -options U3G_DEBUG +options U3G_DEBUG # options for ukbd: options UKBD_DFLT_KEYMAP # specify the built-in keymap diff --git a/sys/i386/conf/DEFAULTS b/sys/i386/conf/DEFAULTS index 03fbf36a9ab5..b94ef53e9f99 100644 --- a/sys/i386/conf/DEFAULTS +++ b/sys/i386/conf/DEFAULTS @@ -7,7 +7,7 @@ machine i386 # Bus support. device isa -options ISAPNP +options ISAPNP # Floating point support. device npx @@ -29,4 +29,4 @@ options GEOM_PART_MBR options NATIVE device atpic -options FLOWTABLE +options FLOWTABLE diff --git a/sys/i386/conf/GENERIC b/sys/i386/conf/GENERIC index df00de1ca4bf..7475efd48c2f 100644 --- a/sys/i386/conf/GENERIC +++ b/sys/i386/conf/GENERIC @@ -69,7 +69,7 @@ options SYSVSEM # SYSV-style semaphores options _KPOSIX_PRIORITY_SCHEDULING # POSIX P1003_1B real-time extensions options KBD_INSTALL_CDEV # install a CDEV entry in /dev options STOP_NMI # Stop CPUS using NMI instead of IPI -options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) +options HWPMC_HOOKS # Necessary kernel hooks for hwpmc(4) options AUDIT # Security event auditing #options KDTRACE_HOOKS # Kernel DTrace hooks @@ -117,7 +117,7 @@ options AHD_REG_PRETTY_PRINT # Print register bitfields in debug device amd # AMD 53C974 (Tekram DC-390(T)) device hptiop # Highpoint RocketRaid 3xxx series device isp # Qlogic family -#device ispfw # Firmware for QLogic HBAs- normally a module +#device ispfw # Firmware for QLogic HBAs- normally a module device mpt # LSI-Logic MPT-Fusion #device ncr # NCR/Symbios Logic device sym # NCR/Symbios Logic (newer chipsets + those of `ncr') @@ -272,7 +272,7 @@ device wlan_amrr # AMRR transmit rate control algorithm device an # Aironet 4500/4800 802.11 wireless NICs. device ath # Atheros pci/cardbus NIC's device ath_hal # pci/cardbus chip support -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath device ral # Ralink Technology RT2500 wireless NICs. device wi # WaveLAN/Intersil/Symbol 802.11 wireless NICs. diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index b9c3fd113a83..9fc7ab6fe6fe 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -49,7 +49,7 @@ options MP_WATCHDOG # Debugging options. # -options STOP_NMI # Stop CPUS using NMI instead of IPI +options STOP_NMI # Stop CPUS using NMI instead of IPI options COUNT_XINVLTLB_HITS # Counters for TLB events options COUNT_IPIS # Per-CPU IPI interrupt counters @@ -225,7 +225,7 @@ options PERFMON # include both in your kernel; you will not get any video output. Ordinary # PC's do not suffer from this. # -options XBOX +options XBOX device xboxfb @@ -253,7 +253,7 @@ options DEVICE_POLLING # BPF_JITTER adds support for BPF just-in-time compiler. -options BPF_JITTER +options BPF_JITTER ##################################################################### @@ -348,7 +348,7 @@ device pci device agp # AGP debugging. -options AGP_DEBUG +options AGP_DEBUG ##################################################################### @@ -484,7 +484,7 @@ device acpi_asus device acpi_fujitsu # ACPI extras driver for IBM laptops -device acpi_ibm +device acpi_ibm # ACPI Panasonic Extras (LCD backlight/brightness, video output, etc.) device acpi_panasonic @@ -569,7 +569,7 @@ device ath_hal # pci/cardbus chip support #device ath_rf5112 #device ath_rf5413 #device ath_ar5416 # AR5416 chips -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath device ce device cp @@ -846,7 +846,7 @@ options LINPROCFS #Enable the linux-like sys filesystem support (requires COMPAT_LINUX # and PSEUDOFS) -options LINSYSFS +options LINSYSFS # # SysVR4 ABI emulation @@ -921,4 +921,4 @@ options VM_KMEM_SIZE_SCALE # asr old ioctls support, needed by raidutils -options ASR_COMPAT +options ASR_COMPAT diff --git a/sys/i386/conf/PAE b/sys/i386/conf/PAE index be8616ef43e7..5e69a593e6ef 100644 --- a/sys/i386/conf/PAE +++ b/sys/i386/conf/PAE @@ -8,7 +8,7 @@ include GENERIC ident PAE-GENERIC # To make a PAE kernel, the next option is needed -options PAE # Physical Address Extensions Kernel +options PAE # Physical Address Extensions Kernel # Compile acpi in statically since the module isn't built properly. Most # machines which support large amounts of memory require acpi. diff --git a/sys/i386/conf/XBOX b/sys/i386/conf/XBOX index 0a2e8c042085..96719659ed1f 100644 --- a/sys/i386/conf/XBOX +++ b/sys/i386/conf/XBOX @@ -10,14 +10,14 @@ makeoptions MODULES_OVERRIDE="" options KDB options DDB -options XBOX # kernel is for XBOX +options XBOX # kernel is for XBOX device xboxfb # frame buffer support (REQUIRED!) device sc # syscons device fb # no support yet for root device name fetching -options ROOTDEVNAME=\"ufs:ad0s1a\" -#options ROOTDEVNAME=\"cd9660:acd0\" +options ROOTDEVNAME=\"ufs:ad0s1a\" +#options ROOTDEVNAME=\"cd9660:acd0\" options SCHED_4BSD # 4BSD scheduler options INET # InterNETworking diff --git a/sys/i386/conf/XEN b/sys/i386/conf/XEN index 7ddc776d8cb7..6c949663f82c 100644 --- a/sys/i386/conf/XEN +++ b/sys/i386/conf/XEN @@ -11,7 +11,7 @@ makeoptions MODULES_OVERRIDE="" options SCHED_ULE # ULE scheduler options PREEMPTION # Enable kernel thread preemption -#options SCHED_4BSD +#options SCHED_4BSD options INET # InterNETworking options INET6 # IPv6 communications protocols @@ -54,22 +54,22 @@ options INVARIANT_SUPPORT # Extra sanity checks of internal structures, require options WITNESS # Enable checks to detect deadlocks and cycles options WITNESS_SKIPSPIN # Don't run witness on spinlocks for speed -options PAE +options PAE nooption NATIVE option XEN nodevice atpic nodevice isa -options MCLSHIFT=12 +options MCLSHIFT=12 # To make an SMP kernel, the next two lines are needed options SMP # Symmetric MultiProcessor Kernel device apic # I/O APIC -device atkbdc # AT keyboard controller -device atkbd # AT keyboard -device psm # PS/2 mouse -device pci +device atkbdc # AT keyboard controller +device atkbd # AT keyboard +device psm # PS/2 mouse +device pci device kbdmux # keyboard multiplexer diff --git a/sys/ia64/conf/DEFAULTS b/sys/ia64/conf/DEFAULTS index 1a96cd6b7519..625ff90955cc 100644 --- a/sys/ia64/conf/DEFAULTS +++ b/sys/ia64/conf/DEFAULTS @@ -6,7 +6,7 @@ machine ia64 # Bus support. -device acpi # ACPI support +device acpi # ACPI support # Pseudo devices. device mem # Memory and kernel memory devices diff --git a/sys/ia64/conf/NOTES b/sys/ia64/conf/NOTES index 138396aeaa70..873199a61b01 100644 --- a/sys/ia64/conf/NOTES +++ b/sys/ia64/conf/NOTES @@ -15,7 +15,7 @@ cpu ITANIUM2 # option: COMPAT_IA32 # This option enables the support for execution of i386 (32-bit) programs on # ia64. It is based on the ia32 emulation in the processor. -options COMPAT_IA32 +options COMPAT_IA32 # option: LOG2_ID_PAGE_SIZE # Specify the log2 size of the identity (direct) mappings in regions 6 and 7 @@ -25,20 +25,20 @@ options LOG2_ID_PAGE_SIZE=27 # 128M # option: LOG2_PAGE_SIZE # Specify the log2 size of the page to be used for virtual memory management. # The page size being equal to 1<USB interface diff --git a/sys/pc98/conf/DEFAULTS b/sys/pc98/conf/DEFAULTS index c16a29b3b8dd..0002cf0a30cc 100644 --- a/sys/pc98/conf/DEFAULTS +++ b/sys/pc98/conf/DEFAULTS @@ -8,7 +8,7 @@ options PC98 # Bus support. device isa -options ISAPNP +options ISAPNP # Floating point support. device npx diff --git a/sys/pc98/conf/NOTES b/sys/pc98/conf/NOTES index 34823daaf0fd..02f8d07ecf29 100644 --- a/sys/pc98/conf/NOTES +++ b/sys/pc98/conf/NOTES @@ -31,7 +31,7 @@ options MP_WATCHDOG # Debugging options. # -options STOP_NMI # Stop CPUS using NMI instead of IPI +options STOP_NMI # Stop CPUS using NMI instead of IPI @@ -193,7 +193,7 @@ options DEVICE_POLLING # BPF_JITTER adds support for BPF just-in-time compiler. -options BPF_JITTER +options BPF_JITTER ##################################################################### @@ -295,7 +295,7 @@ device pci device agp # AGP debugging. -options AGP_DEBUG +options AGP_DEBUG ##################################################################### @@ -437,7 +437,7 @@ device ath_hal # pci/cardbus chip support #device ath_rf5112 #device ath_rf5413 #device ath_ar5416 # AR5416 chips -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath # diff --git a/sys/powerpc/conf/GENERIC b/sys/powerpc/conf/GENERIC index a85ded05e8f9..36231c7fe273 100644 --- a/sys/powerpc/conf/GENERIC +++ b/sys/powerpc/conf/GENERIC @@ -135,7 +135,7 @@ device ehci # EHCI PCI->USB interface device usb # USB Bus (required) device uhid # "Human Interface Devices" device ukbd # Keyboard -options KBD_INSTALL_CDEV # install a CDEV entry in /dev +options KBD_INSTALL_CDEV # install a CDEV entry in /dev device ulpt # Printer device umass # Disks/Mass storage - Requires scbus and da0 device ums # Mouse diff --git a/sys/powerpc/conf/MPC85XX b/sys/powerpc/conf/MPC85XX index 901d18c77b58..b517ee1e68fb 100644 --- a/sys/powerpc/conf/MPC85XX +++ b/sys/powerpc/conf/MPC85XX @@ -22,8 +22,8 @@ options BOOTP_WIRED_TO=tsec0 options CD9660 options COMPAT_43 options DDB -options DEVICE_POLLING -options HZ=1000 +options DEVICE_POLLING +options HZ=1000 #options DIAGNOSTIC options FFS options GDB @@ -39,7 +39,7 @@ options MPC85XX options MSDOSFS options NFS_ROOT options NFSCLIENT -options NFSLOCKD +options NFSLOCKD options PROCFS options PSEUDOFS options SCHED_4BSD diff --git a/sys/powerpc/conf/NOTES b/sys/powerpc/conf/NOTES index e78a0425e57e..c22d86ff824f 100644 --- a/sys/powerpc/conf/NOTES +++ b/sys/powerpc/conf/NOTES @@ -19,7 +19,7 @@ options FPU_EMU options POWERMAC #NewWorld Apple PowerMacs options PSIM #GDB PSIM ppc simulator -options SC_OFWFB # OFW frame buffer +options SC_OFWFB # OFW frame buffer # Standard busses device pci diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index 46c363ea4803..e1c80547ef19 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -200,7 +200,7 @@ device wlan_ccmp # 802.11 CCMP support device wlan_tkip # 802.11 TKIP support device ath # Atheros pci/cardbus NIC's device ath_hal # Atheros HAL (Hardware Access Layer) -options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors +options AH_SUPPORT_AR5416 # enable AR5416 tx/rx descriptors device ath_rate_sample # SampleRate tx rate control for ath # Pseudo devices. From b016f58c5184b450789cddf7b2261b946d04ba36 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 10 May 2009 02:21:19 +0000 Subject: [PATCH 081/544] Cancel the scan when going to INIT state. Should do this for other states here too as once the protocol newstate handler runs the scan has always ended. --- sys/net80211/ieee80211_proto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 157dc5b7a1e9..467a3623dd18 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1834,6 +1834,8 @@ ieee80211_new_state_locked(struct ieee80211vap *vap, } break; case IEEE80211_S_INIT: + /* cancel any scan in progress */ + ieee80211_cancel_scan(vap); if (ostate == IEEE80211_S_INIT ) { /* XXX don't believe this */ /* INIT -> INIT. nothing to do */ From e1d2045e3fc583a96ccba6d0da14c26a596136ae Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Sun, 10 May 2009 02:44:19 +0000 Subject: [PATCH 082/544] Abort any scan on a fatal firmware. ic_scan_curchan is overridden to perform the scan in firmware and this relies on the firmware to wake up the scan task on completion. --- sys/dev/ipw/if_ipw.c | 3 +++ sys/dev/iwi/if_iwi.c | 3 +++ sys/dev/iwn/if_iwn.c | 3 +++ sys/dev/wpi/if_wpi.c | 3 +++ 4 files changed, 12 insertions(+) diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index eac9091a748e..c69ab6d8d975 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -1384,8 +1384,11 @@ ipw_fatal_error_intr(struct ipw_softc *sc) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); + if (vap != NULL) + ieee80211_cancel_scan(vap); ieee80211_runtask(ic, &sc->sc_init_task); } diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 6513522ab5b1..f7d891e3d6fe 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -1635,8 +1635,11 @@ iwi_fatal_error_intr(struct iwi_softc *sc) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "firmware error\n"); + if (vap != NULL) + ieee80211_cancel_scan(vap); ieee80211_runtask(ic, &sc->sc_restarttask); sc->flags &= ~IWI_FLAG_BUSY; diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index f32bdaa602db..9913d90ce68b 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -1789,11 +1789,14 @@ iwn_error_intr(struct iwn_softc *sc, uint32_t r1, uint32_t r2) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); IWN_LOCK_ASSERT(sc); device_printf(sc->sc_dev, "error, INTR=%b STATUS=0x%x\n", r1, IWN_INTR_BITS, r2); + if (vap != NULL) + ieee80211_cancel_scan(vap); ieee80211_runtask(ic, &sc->sc_reinit_task); } diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 0ab86800a64d..9537dd4e0fa5 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -1786,10 +1786,13 @@ wpi_intr(void *arg) if (r & (WPI_SW_ERROR | WPI_HW_ERROR)) { struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); device_printf(sc->sc_dev, "fatal firmware error\n"); DPRINTFN(6,("(%s)\n", (r & WPI_SW_ERROR) ? "(Software Error)" : "(Hardware Error)")); + if (vap != NULL) + ieee80211_cancel_scan(vap); ieee80211_runtask(ic, &sc->sc_restarttask); sc->flags &= ~WPI_FLAG_BUSY; WPI_UNLOCK(sc); From 36ffa1b9de88ed89d4a1254c63df3253705386d7 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Sun, 10 May 2009 08:54:10 +0000 Subject: [PATCH 083/544] - Fix promisc/multicast/broadcast parameters setting by introducing the new ate_rxfilter function to set requested parameters. Use this function on parameters change rather than reinitializing the chip. --- sys/arm/at91/if_ate.c | 65 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 53 insertions(+), 12 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 9e7995fbff7f..01bf3e5c9e55 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -76,6 +76,11 @@ __FBSDID("$FreeBSD$"); #define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */ #define ATE_MAX_RX_BUFFERS 64 +/* + * Driver-specific flags. + */ +#define ATE_FLAG_DETACHING 0x01 + struct ate_softc { struct ifnet *ifp; /* ifnet pointer */ @@ -100,6 +105,8 @@ struct ate_softc eth_rx_desc_t *rx_descs; int use_rmii; struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */ + int flags; + int if_flags; }; static inline uint32_t @@ -149,6 +156,7 @@ static int ate_ifmedia_upd(struct ifnet *ifp); static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); static int ate_get_mac(struct ate_softc *sc, u_char *eaddr); static void ate_set_mac(struct ate_softc *sc, u_char *eaddr); +static void ate_rxfilter(struct ate_softc *sc); /* * The AT91 family of products has the ethernet called EMAC. However, @@ -238,6 +246,7 @@ ate_attach(device_t dev) ifp->if_linkmib = &sc->mibdata; ifp->if_linkmiblen = sizeof(sc->mibdata); sc->mibdata.dot3Compliance = DOT3COMPLIANCE_COLLS; + sc->if_flags = ifp->if_flags; ether_ifattach(ifp, eaddr); @@ -763,13 +772,6 @@ ateinit_locked(void *xsc) else WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII); - /* - * Turn on the multicast hash, and write 0's to it. - */ - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_MTI); - WR4(sc, ETH_HSH, 0); - WR4(sc, ETH_HSL, 0); - WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); @@ -780,6 +782,7 @@ ateinit_locked(void *xsc) * swapping to do. Again, if we need it (which I don't think we do). */ ate_setmcast(sc); + ate_rxfilter(sc); /* enable big packets */ WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); @@ -940,25 +943,63 @@ atestop(struct ate_softc *sc) */ } +static void +ate_rxfilter(struct ate_softc *sc) +{ + struct ifnet *ifp; + uint32_t reg; + + KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); + ATE_ASSERT_LOCKED(sc); + ifp = sc->ifp; + + /* + * Wipe out old filter settings. + */ + reg = RD4(sc, ETH_CFG); + reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI); + reg |= ETH_CFG_NBC; + + /* + * Set new parameters. + */ + if ((ifp->if_flags & IFF_BROADCAST) != 0) + reg &= ~ETH_CFG_NBC; + if ((ifp->if_flags & IFF_PROMISC) != 0) + reg |= ETH_CFG_CAF; + if ((ifp->if_flags & IFF_ALLMULTI) != 0) + reg |= ETH_CFG_MTI; + WR4(sc, ETH_CFG, reg); +} + static int ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ate_softc *sc = ifp->if_softc; struct mii_data *mii; struct ifreq *ifr = (struct ifreq *)data; + int drv_flags, flags; int mask, error = 0; + flags = ifp->if_flags; + drv_flags = ifp->if_drv_flags; switch (cmd) { case SIOCSIFFLAGS: ATE_LOCK(sc); - if ((ifp->if_flags & IFF_UP) == 0 && - ifp->if_drv_flags & IFF_DRV_RUNNING) { + if ((flags & IFF_UP) != 0) { + if ((drv_flags & IFF_DRV_RUNNING) != 0) { + if (((flags ^ sc->if_flags) + & (IFF_PROMISC | IFF_ALLMULTI)) != 0) + ate_rxfilter(sc); + } else { + if ((sc->flags & ATE_FLAG_DETACHING) == 0) + ateinit_locked(sc); + } + } else if ((drv_flags & IFF_DRV_RUNNING) != 0) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; atestop(sc); - } else { - /* reinitialize card on any parameter change */ - ateinit_locked(sc); } + sc->if_flags = flags; ATE_UNLOCK(sc); break; From 5c04df6cb62a928b06c74fe285cd28397cc7a71a Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Sun, 10 May 2009 10:32:29 +0000 Subject: [PATCH 084/544] - Fix multicast operation that I broke in previous commit. - Do not enable multicast hash lookup if no multicast addresses were configured or if promisc mode is enabled. --- sys/arm/at91/if_ate.c | 60 +++++++++++++++++++++++++++++++------------ 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 01bf3e5c9e55..1b92cc2ac9b5 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -80,6 +80,7 @@ __FBSDID("$FreeBSD$"); * Driver-specific flags. */ #define ATE_FLAG_DETACHING 0x01 +#define ATE_FLAG_MULTICAST 0x02 struct ate_softc { @@ -316,26 +317,39 @@ ate_load_rx_buf(void *arg, bus_dma_segment_t *segs, int nsegs, int error) * of different MAC chips use this method (or the reverse the bits) * method. */ -static void +static int ate_setmcast(struct ate_softc *sc) { uint32_t index; uint32_t mcaf[2]; u_char *af = (u_char *) mcaf; struct ifmultiaddr *ifma; + struct ifnet *ifp; + ifp = sc->ifp; + + if ((ifp->if_flags & IFF_PROMISC) != 0) + return (0); + if ((ifp->if_flags & IFF_ALLMULTI) != 0) { + WR4(sc, ETH_HSL, 0xffffffff); + WR4(sc, ETH_HSH, 0xffffffff); + return (1); + } + + /* + * Compute the multicast hash. + */ mcaf[0] = 0; mcaf[1] = 0; - - IF_ADDR_LOCK(sc->ifp); - TAILQ_FOREACH(ifma, &sc->ifp->if_multiaddrs, ifma_link) { + IF_ADDR_LOCK(ifp); + TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { if (ifma->ifma_addr->sa_family != AF_LINK) continue; index = ether_crc32_be(LLADDR((struct sockaddr_dl *) ifma->ifma_addr), ETHER_ADDR_LEN) >> 26; af[index >> 3] |= 1 << (index & 7); } - IF_ADDR_UNLOCK(sc->ifp); + IF_ADDR_UNLOCK(ifp); /* * Write the hash to the hash register. This card can also @@ -346,6 +360,7 @@ ate_setmcast(struct ate_softc *sc) */ WR4(sc, ETH_HSL, mcaf[0]); WR4(sc, ETH_HSH, mcaf[1]); + return (mcaf[0] || mcaf[1]); } static int @@ -772,6 +787,11 @@ ateinit_locked(void *xsc) else WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII); + ate_rxfilter(sc); + + /* + * Turn on MACs and interrupt processing. + */ WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); @@ -781,8 +801,6 @@ ateinit_locked(void *xsc) * the byte order is big endian, not little endian, so we have some * swapping to do. Again, if we need it (which I don't think we do). */ - ate_setmcast(sc); - ate_rxfilter(sc); /* enable big packets */ WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); @@ -948,6 +966,7 @@ ate_rxfilter(struct ate_softc *sc) { struct ifnet *ifp; uint32_t reg; + int enabled; KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); ATE_ASSERT_LOCKED(sc); @@ -959,16 +978,22 @@ ate_rxfilter(struct ate_softc *sc) reg = RD4(sc, ETH_CFG); reg &= ~(ETH_CFG_CAF | ETH_CFG_MTI | ETH_CFG_UNI); reg |= ETH_CFG_NBC; + sc->flags &= ~ATE_FLAG_MULTICAST; /* * Set new parameters. */ if ((ifp->if_flags & IFF_BROADCAST) != 0) reg &= ~ETH_CFG_NBC; - if ((ifp->if_flags & IFF_PROMISC) != 0) + if ((ifp->if_flags & IFF_PROMISC) != 0) { reg |= ETH_CFG_CAF; - if ((ifp->if_flags & IFF_ALLMULTI) != 0) - reg |= ETH_CFG_MTI; + } else { + enabled = ate_setmcast(sc); + if (enabled != 0) { + reg |= ETH_CFG_MTI; + sc->flags |= ATE_FLAG_MULTICAST; + } + } WR4(sc, ETH_CFG, reg); } @@ -979,8 +1004,9 @@ ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data) struct mii_data *mii; struct ifreq *ifr = (struct ifreq *)data; int drv_flags, flags; - int mask, error = 0; + int mask, error, enabled; + error = 0; flags = ifp->if_flags; drv_flags = ifp->if_drv_flags; switch (cmd) { @@ -1005,11 +1031,13 @@ ateioctl(struct ifnet *ifp, u_long cmd, caddr_t data) case SIOCADDMULTI: case SIOCDELMULTI: - /* update multicast filter list. */ - ATE_LOCK(sc); - ate_setmcast(sc); - ATE_UNLOCK(sc); - error = 0; + if ((drv_flags & IFF_DRV_RUNNING) != 0) { + ATE_LOCK(sc); + enabled = ate_setmcast(sc); + if (enabled != (sc->flags & ATE_FLAG_MULTICAST)) + ate_rxfilter(sc); + ATE_UNLOCK(sc); + } break; case SIOCSIFMEDIA: From bdb08649ebea522e16779b62d15f447d1d2c1330 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Sun, 10 May 2009 11:05:22 +0000 Subject: [PATCH 085/544] - Fix build with INVARIANTS enabled. --- sys/arm/at91/at91_cfata.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/at91/at91_cfata.c b/sys/arm/at91/at91_cfata.c index dcddceaa82ba..dcc06bb18a8b 100644 --- a/sys/arm/at91/at91_cfata.c +++ b/sys/arm/at91/at91_cfata.c @@ -131,9 +131,9 @@ ata_at91_release_resource(device_t dev, device_t child, int type, int rid, struct resource *r) { - KASSERT(type == SYS_RES_IRQ && *rid == ATA_IRQ_RID, + KASSERT(type == SYS_RES_IRQ && rid == ATA_IRQ_RID, ("[at91_cfata, %d]: illegal resource request (type %u rid %u)", - __LINE__, type, *rid)); + __LINE__, type, rid)); return (0); } From c299fae2ccebca281ec8203b8bebe404d5c07f64 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Sun, 10 May 2009 16:00:41 +0000 Subject: [PATCH 086/544] PowerPC does not, in general, have ISA sound devices or an ISA bus, so add PowerPC to list of platforms for which we don't want to depend on ISA. --- sys/modules/sound/sound/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/sound/sound/Makefile b/sys/modules/sound/sound/Makefile index adfd36b82be5..8f71b023ea1a 100644 --- a/sys/modules/sound/sound/Makefile +++ b/sys/modules/sound/sound/Makefile @@ -18,7 +18,7 @@ SRCS+= midi.c mpu401.c sequencer.c EXPORT_SYMS= YES # XXX evaluate -.if ${MACHINE_ARCH} == "sparc64" +.if ${MACHINE_ARCH} == "sparc64" || ${MACHINE_ARCH} == "powerpc" # Create an empty opt_isa.h in order to keep kmod.mk from linking in an # existing one from KERNBUILDDIR which possibly has DEV_ISA defined so # sound.ko is always built without isadma support. From f45cc06eb17338f0ccf1bf1d6b2379f9c63e87e8 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 10 May 2009 17:05:43 +0000 Subject: [PATCH 087/544] Eliminate stale comments. Eliminate a case of unnecessary page queues locking. --- sys/fs/smbfs/smbfs_io.c | 4 ---- sys/nfsclient/nfs_bio.c | 7 +------ 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index 2944a6bfbdef..b0988f6bf0ed 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -456,8 +456,6 @@ smbfs_getpages(ap) VM_OBJECT_LOCK(object); if (m->valid != 0) { - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ vm_page_lock_queues(); for (i = 0; i < npages; ++i) { if (i != reqpage) @@ -526,8 +524,6 @@ smbfs_getpages(ap) */ m->valid = 0; vm_page_set_validclean(m, 0, size - toff); - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ } else { /* * Read operation was short. If no error occured diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 97820f03e8a4..0d1f3fa8ec1a 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -138,10 +138,8 @@ nfs_getpages(struct vop_getpages_args *ap) vm_page_t m = pages[ap->a_reqpage]; VM_OBJECT_LOCK(object); - vm_page_lock_queues(); if (m->valid != 0) { - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ + vm_page_lock_queues(); for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) vm_page_free(pages[i]); @@ -150,7 +148,6 @@ nfs_getpages(struct vop_getpages_args *ap) VM_OBJECT_UNLOCK(object); return(0); } - vm_page_unlock_queues(); VM_OBJECT_UNLOCK(object); } @@ -219,8 +216,6 @@ nfs_getpages(struct vop_getpages_args *ap) */ m->valid = 0; vm_page_set_validclean(m, 0, size - toff); - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ } else { /* * Read operation was short. If no error occured From 1ca16454b3ca76ddf706aa419d6fcda0998002a6 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sun, 10 May 2009 18:16:07 +0000 Subject: [PATCH 088/544] Rework r189362, r191883. The frequency of the statistics clock is given by stathz. Use stathz if it is available, otherwise use hz. Pointed out by: bde Approved by: kib (mentor) --- sys/amd64/linux32/linux32_sysvec.c | 3 ++- sys/compat/linux/linux_misc.c | 4 +++- sys/compat/linux/linux_misc.h | 2 ++ sys/i386/linux/linux_sysvec.c | 3 ++- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 2d7103414b94..60100457dd58 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -261,7 +261,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) pos = base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, hz); + AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent); AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum); @@ -1125,6 +1125,7 @@ linux_elf_modevent(module_t mod, int type, void *data) linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); linux_osd_jail_register(); + stclohz = (stathz ? stathz : hz); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index 198818e3580d..c5b1e54569e9 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -92,6 +92,8 @@ __FBSDID("$FreeBSD$"); #include #include +int stclohz; /* Statistics clock frequency */ + #define BSD_TO_LINUX_SIGNAL(sig) \ (((sig) <= LINUX_SIGTBLSZ) ? bsd_to_linux_signal[_SIG_IDX(sig)] : sig) @@ -659,7 +661,7 @@ struct l_times_argv { l_clock_t tms_cstime; }; -#define CONVTCK(r) (r.tv_sec * hz + r.tv_usec / (1000000 / hz)) +#define CONVTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz)) int linux_times(struct thread *td, struct linux_times_args *args) diff --git a/sys/compat/linux/linux_misc.h b/sys/compat/linux/linux_misc.h index eddcd2cad748..5d4afc279d3a 100644 --- a/sys/compat/linux/linux_misc.h +++ b/sys/compat/linux/linux_misc.h @@ -65,4 +65,6 @@ extern const char *linux_platform; #define __LINUX_NPXCW__ 0x37f #endif +extern int stclohz; + #endif /* _LINUX_MISC_H_ */ diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 7af87a76986d..0a3d297e76b1 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -255,7 +255,7 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, hz); + AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY(pos, AT_PHENT, args->phent); AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); @@ -1092,6 +1092,7 @@ linux_elf_modevent(module_t mod, int type, void *data) linux_szplatform = roundup(strlen(linux_platform) + 1, sizeof(char *)); linux_osd_jail_register(); + stclohz = (stathz ? stathz : hz); if (bootverbose) printf("Linux ELF exec handler installed\n"); } else From 580dd797fd39fcd07162a4dd9c53e683bcff96ff Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sun, 10 May 2009 18:27:20 +0000 Subject: [PATCH 089/544] Introduce linux_kernver() interface which is intended for an exact designation of the emulated kernel version. linux_kernver() returns integer value formatted as 'VVVMMMIII' where VVV - version, MMM - major revision, III - minor revision. Approved by: kib (mentor) --- sys/compat/linux/linux_mib.c | 73 ++++++++++++++++++++++++++++-------- sys/compat/linux/linux_mib.h | 6 ++- 2 files changed, 62 insertions(+), 17 deletions(-) diff --git a/sys/compat/linux/linux_mib.c b/sys/compat/linux/linux_mib.c index 676ddcd0d9aa..f3d5ec7a2ca5 100644 --- a/sys/compat/linux/linux_mib.c +++ b/sys/compat/linux/linux_mib.c @@ -54,7 +54,7 @@ struct linux_prison { char pr_osname[LINUX_MAX_UTSNAME]; char pr_osrelease[LINUX_MAX_UTSNAME]; int pr_oss_version; - int pr_use_linux26; /* flag to determine whether to use 2.6 emulation */ + int pr_osrel; }; static unsigned linux_osd_jail_slot; @@ -87,7 +87,7 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, osname, "Linux kernel OS name"); static char linux_osrelease[LINUX_MAX_UTSNAME] = "2.6.16"; -static int linux_use_linux26 = 1; +static int linux_osrel = 2006016; static int linux_sysctl_osrelease(SYSCTL_HANDLER_ARGS) @@ -129,6 +129,37 @@ SYSCTL_PROC(_compat_linux, OID_AUTO, oss_version, 0, 0, linux_sysctl_oss_version, "I", "Linux OSS version"); +/* + * Map the osrelease into integer + */ +static int +linux_map_osrel(char *osrelease, int *osrel) +{ + char *sep, *eosrelease; + int len, v0, v1, v2, v; + + len = strlen(osrelease); + eosrelease = osrelease + len; + v0 = strtol(osrelease, &sep, 10); + if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') + return (EINVAL); + osrelease = sep + 1; + v1 = strtol(osrelease, &sep, 10); + if (osrelease == sep || sep + 1 >= eosrelease || *sep != '.') + return (EINVAL); + osrelease = sep + 1; + v2 = strtol(osrelease, &sep, 10); + if (osrelease == sep || sep != eosrelease) + return (EINVAL); + + v = v0 * 1000000 + v1 * 1000 + v2; + if (v < 1000000) + return (EINVAL); + + *osrel = v; + return (0); +} + /* * Returns holding the prison mutex if return non-NULL. */ @@ -187,7 +218,7 @@ linux_alloc_prison(struct prison *pr, struct linux_prison **lprp) strncpy(lpr->pr_osname, linux_osname, LINUX_MAX_UTSNAME); strncpy(lpr->pr_osrelease, linux_osrelease, LINUX_MAX_UTSNAME); lpr->pr_oss_version = linux_oss_version; - lpr->pr_use_linux26 = linux_use_linux26; + lpr->pr_osrel = linux_osrel; mtx_unlock(&osname_lock); } done: @@ -297,14 +328,17 @@ linux_prison_set(void *obj, void *data) mtx_unlock(&pr->pr_mtx); return (error); } - if (osname) - strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME); if (osrelease) { + error = linux_map_osrel(osrelease, &lpr->pr_osrel); + if (error) { + mtx_unlock(&pr->pr_mtx); + return (error); + } strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME); - lpr->pr_use_linux26 = strlen(osrelease) >= 3 && - osrelease[2] == '6'; } + if (osname) + strlcpy(lpr->pr_osname, osname, LINUX_MAX_UTSNAME); if (gotversion) lpr->pr_oss_version = oss_version; mtx_unlock(&pr->pr_mtx); @@ -471,19 +505,19 @@ linux_get_osrelease(struct thread *td, char *dst) } int -linux_use26(struct thread *td) +linux_kernver(struct thread *td) { struct prison *pr; struct linux_prison *lpr; - int use26; + int osrel; lpr = linux_get_prison(td, &pr); if (lpr != NULL) { - use26 = lpr->pr_use_linux26; + osrel = lpr->pr_osrel; mtx_unlock(&pr->pr_mtx); } else - use26 = linux_use_linux26; - return (use26); + osrel = linux_osrel; + return (osrel); } int @@ -491,18 +525,25 @@ linux_set_osrelease(struct thread *td, char *osrelease) { struct prison *pr; struct linux_prison *lpr; + int error; lpr = linux_get_prison(td, &pr); if (lpr != NULL) { + error = linux_map_osrel(osrelease, &lpr->pr_osrel); + if (error) { + mtx_unlock(&pr->pr_mtx); + return (error); + } strlcpy(lpr->pr_osrelease, osrelease, LINUX_MAX_UTSNAME); - lpr->pr_use_linux26 = - strlen(osrelease) >= 3 && osrelease[2] == '6'; mtx_unlock(&pr->pr_mtx); } else { mtx_lock(&osname_lock); + error = linux_map_osrel(osrelease, &linux_osrel); + if (error) { + mtx_unlock(&osname_lock); + return (error); + } strcpy(linux_osrelease, osrelease); - linux_use_linux26 = - strlen(osrelease) >= 3 && osrelease[2] == '6'; mtx_unlock(&osname_lock); } diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h index 8e5d650f981b..9f0f41c0d84e 100644 --- a/sys/compat/linux/linux_mib.h +++ b/sys/compat/linux/linux_mib.h @@ -43,6 +43,10 @@ int linux_set_osrelease(struct thread *td, char *osrelease); int linux_get_oss_version(struct thread *td); int linux_set_oss_version(struct thread *td, int oss_version); -int linux_use26(struct thread *td); +int linux_kernver(struct thread *td); + +#define LINUX_KERNVER_2006000 2006000 + +#define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000) #endif /* _LINUX_MIB_H_ */ From 8d30f381ef4262426fae3baff499218555b512b7 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sun, 10 May 2009 18:43:43 +0000 Subject: [PATCH 090/544] Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, as it has appeared in the 2.4.0-rc7 first time. Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), glibc falls back to the hard-coded CLK_TCK value when aux entry is not present. Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value. For older applications/libc's which depends on hard-coded CLK_TCK value user should set compat.linux.osrelease less than 2.4.0. Approved by: kib (mentor) --- sys/amd64/linux32/linux32_sysvec.c | 12 +++++++++++- sys/compat/linux/linux_mib.h | 1 + sys/compat/linux/linux_misc.c | 14 +++++++++++++- sys/i386/linux/linux_sysvec.c | 12 +++++++++++- 4 files changed, 36 insertions(+), 3 deletions(-) diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 60100457dd58..2626ccfec91f 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -261,7 +261,17 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) pos = base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY_32(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz); + + /* + * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, + * as it has appeared in the 2.4.0-rc7 first time. + * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), + * glibc falls back to the hard-coded CLK_TCK value when aux entry + * is not present. + * Also see linux_times() implementation. + */ + if (linux_kernver(curthread) >= LINUX_KERNVER_2004000) + AUXARGS_ENTRY_32(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent); AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum); diff --git a/sys/compat/linux/linux_mib.h b/sys/compat/linux/linux_mib.h index 9f0f41c0d84e..f78a5e501402 100644 --- a/sys/compat/linux/linux_mib.h +++ b/sys/compat/linux/linux_mib.h @@ -45,6 +45,7 @@ int linux_set_oss_version(struct thread *td, int oss_version); int linux_kernver(struct thread *td); +#define LINUX_KERNVER_2004000 2004000 #define LINUX_KERNVER_2006000 2006000 #define linux_use26(t) (linux_kernver(t) >= LINUX_KERNVER_2006000) diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c index c5b1e54569e9..72791971c7be 100644 --- a/sys/compat/linux/linux_misc.c +++ b/sys/compat/linux/linux_misc.c @@ -661,7 +661,19 @@ struct l_times_argv { l_clock_t tms_cstime; }; -#define CONVTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz)) + +/* + * Glibc versions prior to 2.2.1 always use hard-coded CLK_TCK value. + * Since 2.2.1 Glibc uses value exported from kernel via AT_CLKTCK + * auxiliary vector entry. + */ +#define CLK_TCK 100 + +#define CONVOTCK(r) (r.tv_sec * CLK_TCK + r.tv_usec / (1000000 / CLK_TCK)) +#define CONVNTCK(r) (r.tv_sec * stclohz + r.tv_usec / (1000000 / stclohz)) + +#define CONVTCK(r) (linux_kernver(td) >= LINUX_KERNVER_2004000 ? \ + CONVNTCK(r) : CONVOTCK(r)) int linux_times(struct thread *td, struct linux_times_args *args) diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index 0a3d297e76b1..186e14c421f8 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -255,7 +255,17 @@ elf_linux_fixup(register_t **stack_base, struct image_params *imgp) pos = *stack_base + (imgp->args->argc + imgp->args->envc + 2); AUXARGS_ENTRY(pos, LINUX_AT_HWCAP, cpu_feature); - AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); + + /* + * Do not export AT_CLKTCK when emulating Linux kernel prior to 2.4.0, + * as it has appeared in the 2.4.0-rc7 first time. + * Being exported, AT_CLKTCK is returned by sysconf(_SC_CLK_TCK), + * glibc falls back to the hard-coded CLK_TCK value when aux entry + * is not present. + * Also see linux_times() implementation. + */ + if (linux_kernver(curthread) >= LINUX_KERNVER_2004000) + AUXARGS_ENTRY(pos, LINUX_AT_CLKTCK, stclohz); AUXARGS_ENTRY(pos, AT_PHDR, args->phdr); AUXARGS_ENTRY(pos, AT_PHENT, args->phent); AUXARGS_ENTRY(pos, AT_PHNUM, args->phnum); From 0ec607133b205545609e5bfe6e5d859b0e6b55d0 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 10 May 2009 20:14:19 +0000 Subject: [PATCH 091/544] Change uses of the struct ccb_hdr timeout_ch missed when isp(4) was adapted to MPSAFE cam(4) to a isp(4) specific callout structure. Thanks to Florian Smeets for providing access to a machine exhibiting this problem for debugging. Approved by: mjacob MFC after: 3 days --- sys/dev/isp/isp_freebsd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/isp/isp_freebsd.c b/sys/dev/isp/isp_freebsd.c index 2e7981fb84f0..beb8fa12d1e5 100644 --- a/sys/dev/isp/isp_freebsd.c +++ b/sys/dev/isp/isp_freebsd.c @@ -1988,7 +1988,8 @@ isp_watchdog_work(ispsoftc_t *isp, XS_T *xs) isp_done(xs); } else { XS_CMD_C_WDOG(xs); - xs->ccb_h.timeout_ch = timeout(isp_watchdog, xs, hz); + callout_reset(&PISP_PCMD((union ccb *)xs)->wdog, hz, + isp_watchdog, xs); XS_CMD_S_GRACE(xs); isp->isp_sendmarker |= 1 << XS_CHANNEL(xs); } @@ -3004,7 +3005,7 @@ isp_done(struct ccb_scsiio *sccb) XS_CMD_S_DONE(sccb); if (XS_CMD_WDOG_P(sccb) == 0) { - untimeout(isp_watchdog, sccb, sccb->ccb_h.timeout_ch); + callout_stop(&PISP_PCMD(sccb)->wdog); if (XS_CMD_GRACE_P(sccb)) { isp_prt(isp, ISP_LOGDEBUG2, "finished command on borrowed time"); From c68975278359ad67abfa826bc55f5810fca12d46 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 10 May 2009 20:22:41 +0000 Subject: [PATCH 092/544] - Fix style. - Use __FBSDID. --- sys/sparc64/sparc64/vm_machdep.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index b769753ad9b7..a5b7629c5656 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -39,23 +39,26 @@ * * from: @(#)vm_machdep.c 7.3 (Berkeley) 5/13/91 * Utah $Hdr: vm_machdep.c 1.16.1.1 89/06/23$ - * from: FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.167 2001/07/12 - * $FreeBSD$ + * from: FreeBSD: src/sys/i386/i386/vm_machdep.c,v 1.167 2001/07/12 */ +#include +__FBSDID("$FreeBSD$"); + #include "opt_pmap.h" #include #include -#include -#include #include #include #include #include +#include #include #include +#include #include +#include #include #include #include @@ -74,11 +77,10 @@ #include #include -#include #include #include -#include #include +#include #include #include #include @@ -94,7 +96,7 @@ static void sf_buf_init(void *arg); SYSINIT(sock_sf, SI_SUB_MBUF, SI_ORDER_ANY, sf_buf_init, NULL); /* - * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the + * Expanded sf_freelist head. Really an SLIST_HEAD() in disguise, with the * sf_freelist head with the sf_lock mutex. */ static struct { @@ -124,11 +126,13 @@ cpu_exit(struct thread *td) void cpu_thread_exit(struct thread *td) { + } void cpu_thread_clean(struct thread *td) { + } void @@ -146,16 +150,19 @@ cpu_thread_alloc(struct thread *td) void cpu_thread_free(struct thread *td) { + } - + void cpu_thread_swapin(struct thread *td) { + } void cpu_thread_swapout(struct thread *td) { + } void @@ -328,6 +335,7 @@ cpu_reset(void) 0, (cell_t)bspec }; + if ((chosen = OF_finddevice("/chosen")) != 0) { if (OF_getprop(chosen, "bootpath", bspec, sizeof(bspec)) == -1) bspec[0] = '\0'; @@ -392,7 +400,7 @@ sf_buf_init(void *arg) } /* - * Get an sf_buf from the freelist. Will block if none are available. + * Get an sf_buf from the freelist. Will block if none are available. */ struct sf_buf * sf_buf_alloc(struct vm_page *m, int flags) @@ -411,7 +419,7 @@ sf_buf_alloc(struct vm_page *m, int flags) sf_buf_alloc_want--; /* - * If we got a signal, don't risk going back to sleep. + * If we got a signal, don't risk going back to sleep. */ if (error) break; From 1eb3155347487cc788902a452c2d3e0ebf83fd15 Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Sun, 10 May 2009 20:41:52 +0000 Subject: [PATCH 093/544] Just like in cpu_halt(), use cpu_shutdown() rather than ofw_exit() directly in cpu_reset() in order to idle the APs before exiting the kernel and letting the BSP enter the firmware so that processes like init(8) which still might be running on an AP at that point don't cause a panic there when it crashes due to the fact it no longer can be supported by the kernel. MFC after: 3 days --- sys/sparc64/sparc64/vm_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c index a5b7629c5656..76521a6bca36 100644 --- a/sys/sparc64/sparc64/vm_machdep.c +++ b/sys/sparc64/sparc64/vm_machdep.c @@ -342,7 +342,7 @@ cpu_reset(void) bspec[sizeof(bspec) - 1] = '\0'; } - ofw_exit(&args); + cpu_shutdown(&args); } /* From 879f0eff531eb2ab0988f7c7491c218f6b31baa1 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Mon, 11 May 2009 02:39:49 +0000 Subject: [PATCH 094/544] ports upgt(4) driver for USB2. --- sys/dev/usb/wlan/if_upgt.c | 2404 +++++++++++++++++++++++++++++++++ sys/dev/usb/wlan/if_upgtvar.h | 482 +++++++ sys/modules/usb/upgt/Makefile | 10 + 3 files changed, 2896 insertions(+) create mode 100644 sys/dev/usb/wlan/if_upgt.c create mode 100644 sys/dev/usb/wlan/if_upgtvar.h create mode 100644 sys/modules/usb/upgt/Makefile diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c new file mode 100644 index 000000000000..3bef0b43359d --- /dev/null +++ b/sys/dev/usb/wlan/if_upgt.c @@ -0,0 +1,2404 @@ +/* $OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 2007 Marcus Glocker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include "usbdevs.h" + +#include + +/* + * Driver for the USB PrismGT devices. + * + * For now just USB 2.0 devices with the GW3887 chipset are supported. + * The driver has been written based on the firmware version 2.13.1.0_LM87. + * + * TODO's: + * - MONITOR mode test. + * - Add HOSTAP mode. + * - Add IBSS mode. + * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets). + * + * Parts of this driver has been influenced by reading the p54u driver + * written by Jean-Baptiste Note and + * Sebastien Bourdeauducq . + */ + +SYSCTL_NODE(_hw, OID_AUTO, upgt, CTLFLAG_RD, 0, + "USB PrismGT GW3887 driver parameters"); + +#ifdef UPGT_DEBUG +int upgt_debug = 0; +SYSCTL_INT(_hw_upgt, OID_AUTO, debug, CTLFLAG_RW, &upgt_debug, + 0, "control debugging printfs"); +TUNABLE_INT("hw.upgt.debug", &upgt_debug); +enum { + UPGT_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ + UPGT_DEBUG_RECV = 0x00000002, /* basic recv operation */ + UPGT_DEBUG_RESET = 0x00000004, /* reset processing */ + UPGT_DEBUG_INTR = 0x00000008, /* INTR */ + UPGT_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */ + UPGT_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */ + UPGT_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */ + UPGT_DEBUG_STAT = 0x00000080, /* statistic */ + UPGT_DEBUG_FW = 0x00000100, /* firmware */ + UPGT_DEBUG_ANY = 0xffffffff +}; +#define DPRINTF(sc, m, fmt, ...) do { \ + if (sc->sc_debug & (m)) \ + printf(fmt, __VA_ARGS__); \ +} while (0) +#else +#define DPRINTF(sc, m, fmt, ...) do { \ + (void) sc; \ +} while (0) +#endif + +/* + * Prototypes. + */ +static device_probe_t upgt_match; +static device_attach_t upgt_attach; +static device_detach_t upgt_detach; +static int upgt_alloc_tx(struct upgt_softc *); +static int upgt_alloc_rx(struct upgt_softc *); +static int upgt_device_reset(struct upgt_softc *); +static void upgt_bulk_tx(struct upgt_softc *, struct upgt_data *); +static int upgt_fw_verify(struct upgt_softc *); +static int upgt_mem_init(struct upgt_softc *); +static int upgt_fw_load(struct upgt_softc *); +static int upgt_fw_copy(const uint8_t *, char *, int); +static uint32_t upgt_crc32_le(const void *, size_t); +static struct mbuf * + upgt_rxeof(struct usb2_xfer *, struct upgt_data *, int *); +static struct mbuf * + upgt_rx(struct upgt_softc *, uint8_t *, int, int *); +static void upgt_txeof(struct usb2_xfer *, struct upgt_data *); +static int upgt_eeprom_read(struct upgt_softc *); +static int upgt_eeprom_parse(struct upgt_softc *); +static void upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *); +static void upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int); +static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int); +static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int); +static uint32_t upgt_chksum_le(const uint32_t *, size_t); +static void upgt_tx_done(struct upgt_softc *, uint8_t *); +static void upgt_init(void *); +static void upgt_init_locked(struct upgt_softc *); +static int upgt_ioctl(struct ifnet *, u_long, caddr_t); +static void upgt_start(struct ifnet *); +static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); +static void upgt_scan_start(struct ieee80211com *); +static void upgt_scan_end(struct ieee80211com *); +static void upgt_set_channel(struct ieee80211com *); +static struct ieee80211vap *upgt_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void upgt_vap_delete(struct ieee80211vap *); +static void upgt_update_mcast(struct ifnet *); +static uint8_t upgt_rx_rate(struct upgt_softc *, const int); +static void upgt_set_multi(void *); +static void upgt_stop(struct upgt_softc *); +static void upgt_setup_rates(struct ieee80211vap *, struct ieee80211com *); +static int upgt_set_macfilter(struct upgt_softc *, uint8_t); +static int upgt_newstate(struct ieee80211vap *, enum ieee80211_state, int); +static void upgt_set_chan(struct upgt_softc *, struct ieee80211_channel *); +static void upgt_set_led(struct upgt_softc *, int); +static void upgt_set_led_blink(void *); +static void upgt_get_stats(struct upgt_softc *); +static void upgt_mem_free(struct upgt_softc *, uint32_t); +static uint32_t upgt_mem_alloc(struct upgt_softc *); +static void upgt_free_tx(struct upgt_softc *); +static void upgt_free_rx(struct upgt_softc *); +static void upgt_watchdog(void *); +static void upgt_abort_xfers(struct upgt_softc *); +static void upgt_abort_xfers_locked(struct upgt_softc *); +static void upgt_sysctl_node(struct upgt_softc *); +static struct upgt_data * + upgt_getbuf(struct upgt_softc *); +static struct upgt_data * + upgt_gettxbuf(struct upgt_softc *); +static int upgt_tx_start(struct upgt_softc *, struct mbuf *, + struct ieee80211_node *, struct upgt_data *); + +static const char *upgt_fwname = "upgt-gw3887"; + +static const struct usb2_device_id upgt_devs_2[] = { +#define UPGT_DEV(v,p) { USB_VP(USB_VENDOR_##v, USB_PRODUCT_##v##_##p) } + /* version 2 devices */ + UPGT_DEV(ACCTON, PRISM_GT), + UPGT_DEV(BELKIN, F5D7050), + UPGT_DEV(CISCOLINKSYS, WUSB54AG), + UPGT_DEV(CONCEPTRONIC, PRISM_GT), + UPGT_DEV(DELL, PRISM_GT_1), + UPGT_DEV(DELL, PRISM_GT_2), + UPGT_DEV(FSC, E5400), + UPGT_DEV(GLOBESPAN, PRISM_GT_1), + UPGT_DEV(GLOBESPAN, PRISM_GT_2), + UPGT_DEV(INTERSIL, PRISM_GT), + UPGT_DEV(SMC, 2862WG), + UPGT_DEV(WISTRONNEWEB, UR045G), + UPGT_DEV(XYRATEX, PRISM_GT_1), + UPGT_DEV(XYRATEX, PRISM_GT_2), + UPGT_DEV(ZCOM, XG703A), + UPGT_DEV(ZCOM, XM142) +}; + +static usb2_callback_t upgt_bulk_rx_callback; +static usb2_callback_t upgt_bulk_tx_callback; + +static const struct usb2_config upgt_config[UPGT_N_XFERS] = { + [UPGT_BULK_TX] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_OUT, + .bufsize = MCLBYTES, + .flags = { + .ext_buffer = 1, + .force_short_xfer = 1, + .pipe_bof = 1 + }, + .callback = upgt_bulk_tx_callback, + .timeout = UPGT_USB_TIMEOUT, /* ms */ + }, + [UPGT_BULK_RX] = { + .type = UE_BULK, + .endpoint = UE_ADDR_ANY, + .direction = UE_DIR_IN, + .bufsize = MCLBYTES, + .flags = { + .ext_buffer = 1, + .pipe_bof = 1, + .short_xfer_ok = 1 + }, + .callback = upgt_bulk_rx_callback, + }, +}; + +static int +upgt_match(device_t dev) +{ + struct usb2_attach_arg *uaa = device_get_ivars(dev); + + if (uaa->usb2_mode != USB_MODE_HOST) + return (ENXIO); + if (uaa->info.bConfigIndex != UPGT_CONFIG_INDEX) + return (ENXIO); + if (uaa->info.bIfaceIndex != UPGT_IFACE_INDEX) + return (ENXIO); + + return (usb2_lookup_id_by_uaa(upgt_devs_2, sizeof(upgt_devs_2), uaa)); +} + +static int +upgt_attach(device_t dev) +{ + int error; + struct ieee80211com *ic; + struct ifnet *ifp; + struct upgt_softc *sc = device_get_softc(dev); + struct usb2_attach_arg *uaa = device_get_ivars(dev); + uint8_t bands, iface_index = UPGT_IFACE_INDEX; + + sc->sc_dev = dev; + sc->sc_udev = uaa->device; +#ifdef UPGT_DEBUG + sc->sc_debug = upgt_debug; +#endif + + mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, + MTX_DEF); + callout_init(&sc->sc_led_ch, 0); + callout_init(&sc->sc_watchdog_ch, 0); + + /* Allocate TX and RX xfers. */ + error = upgt_alloc_tx(sc); + if (error) + goto fail1; + error = upgt_alloc_rx(sc); + if (error) + goto fail2; + + error = usb2_transfer_setup(uaa->device, &iface_index, sc->sc_xfer, + upgt_config, UPGT_N_XFERS, sc, &sc->sc_mtx); + if (error) { + device_printf(dev, "could not allocate USB transfers, " + "err=%s\n", usb2_errstr(error)); + goto fail3; + } + + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(dev, "can not if_alloc()\n"); + goto fail4; + } + + /* Initialize the device. */ + error = upgt_device_reset(sc); + if (error) + goto fail5; + /* Verify the firmware. */ + error = upgt_fw_verify(sc); + if (error) + goto fail5; + /* Calculate device memory space. */ + if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) { + device_printf(dev, + "could not find memory space addresses on FW!\n"); + error = EIO; + goto fail5; + } + sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1; + sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1; + + DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame start=0x%08x\n", + sc->sc_memaddr_frame_start); + DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame end=0x%08x\n", + sc->sc_memaddr_frame_end); + DPRINTF(sc, UPGT_DEBUG_FW, "memory address rx start=0x%08x\n", + sc->sc_memaddr_rx_start); + + upgt_mem_init(sc); + + /* Load the firmware. */ + error = upgt_fw_load(sc); + if (error) + goto fail5; + + /* Read the whole EEPROM content and parse it. */ + error = upgt_eeprom_read(sc); + if (error) + goto fail5; + error = upgt_eeprom_parse(sc); + if (error) + goto fail5; + + /* all works related with the device have done here. */ + upgt_abort_xfers(sc); + + /* Setup the 802.11 device. */ + ifp->if_softc = sc; + if_initname(ifp, "upgt", device_get_unit(sc->sc_dev)); + ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_init = upgt_init; + ifp->if_ioctl = upgt_ioctl; + ifp->if_start = upgt_start; + IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); + IFQ_SET_READY(&ifp->if_snd); + + ic = ifp->if_l2com; + ic->ic_ifp = ifp; + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; + /* set device capabilities */ + ic->ic_caps = + IEEE80211_C_STA /* station mode */ + | IEEE80211_C_MONITOR /* monitor mode */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_BGSCAN /* capable of bg scanning */ + | IEEE80211_C_WPA /* 802.11i */ + ; + + bands = 0; + setbit(&bands, IEEE80211_MODE_11B); + setbit(&bands, IEEE80211_MODE_11G); + ieee80211_init_channels(ic, NULL, &bands); + + ieee80211_ifattach(ic, sc->sc_myaddr); + ic->ic_raw_xmit = upgt_raw_xmit; + ic->ic_scan_start = upgt_scan_start; + ic->ic_scan_end = upgt_scan_end; + ic->ic_set_channel = upgt_set_channel; + + ic->ic_vap_create = upgt_vap_create; + ic->ic_vap_delete = upgt_vap_delete; + ic->ic_update_mcast = upgt_update_mcast; + + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); + sc->sc_rxtap_len = sizeof(sc->sc_rxtap); + sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); + sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT); + sc->sc_txtap_len = sizeof(sc->sc_txtap); + sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); + sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT); + + upgt_sysctl_node(sc); + + if (bootverbose) + ieee80211_announce(ic); + + return (0); + +fail5: if_free(ifp); +fail4: usb2_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); +fail3: upgt_free_rx(sc); +fail2: upgt_free_tx(sc); +fail1: mtx_destroy(&sc->sc_mtx); + + return (error); +} + +static void +upgt_txeof(struct usb2_xfer *xfer, struct upgt_data *data) +{ + struct upgt_softc *sc = xfer->priv_sc; + struct ifnet *ifp = sc->sc_ifp; + struct mbuf *m; + + UPGT_ASSERT_LOCKED(sc); + + /* + * Do any tx complete callback. Note this must be done before releasing + * the node reference. + */ + if (data->m) { + m = data->m; + if (m->m_flags & M_TXCB) { + /* XXX status? */ + ieee80211_process_callback(data->ni, m, 0); + } + m_freem(m); + data->m = NULL; + } + if (data->ni) { + ieee80211_free_node(data->ni); + data->ni = NULL; + } + ifp->if_opackets++; +} + +static void +upgt_get_stats(struct upgt_softc *sc) +{ + struct upgt_data *data_cmd; + struct upgt_lmac_mem *mem; + struct upgt_lmac_stats *stats; + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + device_printf(sc->sc_dev, "%s: out of buffer.\n", __func__); + return; + } + + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + stats = (struct upgt_lmac_stats *)(mem + 1); + + stats->header1.flags = 0; + stats->header1.type = UPGT_H1_TYPE_CTRL; + stats->header1.len = htole16( + sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header)); + + stats->header2.reqid = htole32(sc->sc_memaddr_frame_start); + stats->header2.type = htole16(UPGT_H2_TYPE_STATS); + stats->header2.flags = 0; + + data_cmd->buflen = sizeof(*mem) + sizeof(*stats); + + mem->chksum = upgt_chksum_le((uint32_t *)stats, + data_cmd->buflen - sizeof(*mem)); + + upgt_bulk_tx(sc, data_cmd); +} + +static int +upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) +{ + struct upgt_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; + + switch (cmd) { + case SIOCSIFFLAGS: + mtx_lock(&Giant); + if (ifp->if_flags & IFF_UP) { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + if ((ifp->if_flags ^ sc->sc_if_flags) & + (IFF_ALLMULTI | IFF_PROMISC)) + upgt_set_multi(sc); + } else { + upgt_init(sc); + startall = 1; + } + } else { + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + upgt_stop(sc); + } + sc->sc_if_flags = ifp->if_flags; + if (startall) + ieee80211_start_all(ic); + mtx_unlock(&Giant); + break; + case SIOCGIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; + case SIOCGIFADDR: + error = ether_ioctl(ifp, cmd, data); + break; + default: + error = EINVAL; + break; + } + return error; +} + +static void +upgt_stop_locked(struct upgt_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + + UPGT_ASSERT_LOCKED(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + upgt_set_macfilter(sc, IEEE80211_S_INIT); + upgt_abort_xfers_locked(sc); +} + +static void +upgt_stop(struct upgt_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + + UPGT_LOCK(sc); + upgt_stop_locked(sc); + UPGT_UNLOCK(sc); + + /* device down */ + sc->sc_tx_timer = 0; + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->sc_flags &= ~UPGT_FLAG_INITDONE; +} + +static void +upgt_set_led(struct upgt_softc *sc, int action) +{ + struct upgt_data *data_cmd; + struct upgt_lmac_mem *mem; + struct upgt_lmac_led *led; + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__); + return; + } + + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + led = (struct upgt_lmac_led *)(mem + 1); + + led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; + led->header1.type = UPGT_H1_TYPE_CTRL; + led->header1.len = htole16( + sizeof(struct upgt_lmac_led) - + sizeof(struct upgt_lmac_header)); + + led->header2.reqid = htole32(sc->sc_memaddr_frame_start); + led->header2.type = htole16(UPGT_H2_TYPE_LED); + led->header2.flags = 0; + + switch (action) { + case UPGT_LED_OFF: + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = 0; + led->action_tmp = htole16(UPGT_LED_ACTION_OFF); + led->action_tmp_dur = 0; + break; + case UPGT_LED_ON: + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = 0; + led->action_tmp = htole16(UPGT_LED_ACTION_ON); + led->action_tmp_dur = 0; + break; + case UPGT_LED_BLINK: + if (sc->sc_state != IEEE80211_S_RUN) { + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next); + return; + } + if (sc->sc_led_blink) { + /* previous blink was not finished */ + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next); + return; + } + led->mode = htole16(UPGT_LED_MODE_SET); + led->action_fix = htole16(UPGT_LED_ACTION_OFF); + led->action_tmp = htole16(UPGT_LED_ACTION_ON); + led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR); + /* lock blink */ + sc->sc_led_blink = 1; + callout_reset(&sc->sc_led_ch, hz, upgt_set_led_blink, sc); + break; + default: + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data_cmd, next); + return; + } + + data_cmd->buflen = sizeof(*mem) + sizeof(*led); + + mem->chksum = upgt_chksum_le((uint32_t *)led, + data_cmd->buflen - sizeof(*mem)); + + upgt_bulk_tx(sc, data_cmd); +} + +static void +upgt_set_led_blink(void *arg) +{ + struct upgt_softc *sc = arg; + + /* blink finished, we are ready for a next one */ + sc->sc_led_blink = 0; +} + +static void +upgt_init(void *priv) +{ + struct upgt_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + UPGT_LOCK(sc); + upgt_init_locked(sc); + UPGT_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void +upgt_init_locked(struct upgt_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + + UPGT_ASSERT_LOCKED(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + upgt_stop_locked(sc); + + usb2_transfer_start(sc->sc_xfer[UPGT_BULK_RX]); + + (void)upgt_set_macfilter(sc, IEEE80211_S_SCAN); + + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + ifp->if_drv_flags |= IFF_DRV_RUNNING; + sc->sc_flags |= UPGT_FLAG_INITDONE; + + callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); +} + +static int +upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; + struct upgt_data *data_cmd; + struct upgt_lmac_mem *mem; + struct upgt_lmac_filter *filter; + uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + UPGT_ASSERT_LOCKED(sc); + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + device_printf(sc->sc_dev, "out of TX buffers.\n"); + return (ENOBUFS); + } + + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + filter = (struct upgt_lmac_filter *)(mem + 1); + + filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; + filter->header1.type = UPGT_H1_TYPE_CTRL; + filter->header1.len = htole16( + sizeof(struct upgt_lmac_filter) - + sizeof(struct upgt_lmac_header)); + + filter->header2.reqid = htole32(sc->sc_memaddr_frame_start); + filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER); + filter->header2.flags = 0; + + switch (state) { + case IEEE80211_S_INIT: + DPRINTF(sc, UPGT_DEBUG_STATE, "%s: set MAC filter to INIT\n", + __func__); + filter->type = htole16(UPGT_FILTER_TYPE_RESET); + break; + case IEEE80211_S_SCAN: + DPRINTF(sc, UPGT_DEBUG_STATE, + "set MAC filter to SCAN (bssid %s)\n", + ether_sprintf(broadcast)); + filter->type = htole16(UPGT_FILTER_TYPE_NONE); + IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); + IEEE80211_ADDR_COPY(filter->src, broadcast); + filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); + filter->rxaddr = htole32(sc->sc_memaddr_rx_start); + filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2); + filter->rxhw = htole32(sc->sc_eeprom_hwrx); + filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); + break; + case IEEE80211_S_RUN: + /* XXX monitor mode isn't tested yet. */ + if (vap->iv_opmode == IEEE80211_M_MONITOR) { + filter->type = htole16(UPGT_FILTER_TYPE_MONITOR); + IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); + IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); + filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1); + filter->rxaddr = htole32(sc->sc_memaddr_rx_start); + filter->unknown2 = htole16(UPGT_FILTER_MONITOR_UNKNOWN2); + filter->rxhw = htole32(sc->sc_eeprom_hwrx); + filter->unknown3 = htole16(UPGT_FILTER_MONITOR_UNKNOWN3); + } else { + DPRINTF(sc, UPGT_DEBUG_STATE, + "set MAC filter to RUN (bssid %s)\n", + ether_sprintf(ni->ni_bssid)); + filter->type = htole16(UPGT_FILTER_TYPE_STA); + IEEE80211_ADDR_COPY(filter->dst, sc->sc_myaddr); + IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); + filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); + filter->rxaddr = htole32(sc->sc_memaddr_rx_start); + filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2); + filter->rxhw = htole32(sc->sc_eeprom_hwrx); + filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); + } + break; + default: + device_printf(sc->sc_dev, + "MAC filter does not know that state!\n"); + break; + } + + data_cmd->buflen = sizeof(*mem) + sizeof(*filter); + + mem->chksum = upgt_chksum_le((uint32_t *)filter, + data_cmd->buflen - sizeof(*mem)); + + upgt_bulk_tx(sc, data_cmd); + + return (0); +} + +static void +upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct upgt_softc *sc = ifp->if_softc; + const struct ieee80211_txparam *tp; + + /* + * 0x01 = OFMD6 0x10 = DS1 + * 0x04 = OFDM9 0x11 = DS2 + * 0x06 = OFDM12 0x12 = DS5 + * 0x07 = OFDM18 0x13 = DS11 + * 0x08 = OFDM24 + * 0x09 = OFDM36 + * 0x0a = OFDM48 + * 0x0b = OFDM54 + */ + const uint8_t rateset_auto_11b[] = + { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 }; + const uint8_t rateset_auto_11g[] = + { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 }; + const uint8_t rateset_fix_11bg[] = + { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07, + 0x08, 0x09, 0x0a, 0x0b }; + + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; + + /* XXX */ + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { + /* + * Automatic rate control is done by the device. + * We just pass the rateset from which the device + * will pickup a rate. + */ + if (ic->ic_curmode == IEEE80211_MODE_11B) + bcopy(rateset_auto_11b, sc->sc_cur_rateset, + sizeof(sc->sc_cur_rateset)); + if (ic->ic_curmode == IEEE80211_MODE_11G || + ic->ic_curmode == IEEE80211_MODE_AUTO) + bcopy(rateset_auto_11g, sc->sc_cur_rateset, + sizeof(sc->sc_cur_rateset)); + } else { + /* set a fixed rate */ + memset(sc->sc_cur_rateset, rateset_fix_11bg[tp->ucastrate], + sizeof(sc->sc_cur_rateset)); + } +} + +static void +upgt_set_multi(void *arg) +{ + struct upgt_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + + if (!(ifp->if_flags & IFF_UP)) + return; + + /* + * XXX don't know how to set a device. Lack of docs. Just try to set + * IFF_ALLMULTI flag here. + */ + IF_ADDR_LOCK(ifp); + ifp->if_flags |= IFF_ALLMULTI; + IF_ADDR_UNLOCK(ifp); +} + +static void +upgt_start(struct ifnet *ifp) +{ + struct upgt_softc *sc = ifp->if_softc; + struct upgt_data *data_tx; + struct ieee80211_node *ni; + struct mbuf *m; + + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; + + UPGT_LOCK(sc); + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + + data_tx = upgt_gettxbuf(sc); + if (data_tx == NULL) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + break; + } + + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m->m_pkthdr.rcvif = NULL; + + if (upgt_tx_start(sc, m, ni, data_tx) != 0) { + STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next); + UPGT_STAT_INC(sc, st_tx_inactive); + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } + sc->sc_tx_timer = 5; + } + UPGT_UNLOCK(sc); +} + +static int +upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; + struct upgt_softc *sc = ifp->if_softc; + struct upgt_data *data_tx = NULL; + + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + m_freem(m); + ieee80211_free_node(ni); + return ENETDOWN; + } + + UPGT_LOCK(sc); + data_tx = upgt_gettxbuf(sc); + if (data_tx == NULL) { + ieee80211_free_node(ni); + m_freem(m); + UPGT_UNLOCK(sc); + return (ENOBUFS); + } + + if (upgt_tx_start(sc, m, ni, data_tx) != 0) { + STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, data_tx, next); + UPGT_STAT_INC(sc, st_tx_inactive); + ieee80211_free_node(ni); + ifp->if_oerrors++; + UPGT_UNLOCK(sc); + return (EIO); + } + UPGT_UNLOCK(sc); + + sc->sc_tx_timer = 5; + return (0); +} + +static void +upgt_watchdog(void *arg) +{ + struct upgt_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + + if (sc->sc_tx_timer > 0) { + if (--sc->sc_tx_timer == 0) { + device_printf(sc->sc_dev, "watchdog timeout\n"); + /* upgt_init(ifp); XXX needs a process context ? */ + ifp->if_oerrors++; + return; + } + callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); + } +} + +static uint32_t +upgt_mem_alloc(struct upgt_softc *sc) +{ + int i; + + for (i = 0; i < sc->sc_memory.pages; i++) { + if (sc->sc_memory.page[i].used == 0) { + sc->sc_memory.page[i].used = 1; + return (sc->sc_memory.page[i].addr); + } + } + + return (0); +} + +static void +upgt_scan_start(struct ieee80211com *ic) +{ + /* do nothing. */ +} + +static void +upgt_scan_end(struct ieee80211com *ic) +{ + /* do nothing. */ +} + +static void +upgt_set_channel(struct ieee80211com *ic) +{ + struct upgt_softc *sc = ic->ic_ifp->if_softc; + + UPGT_LOCK(sc); + upgt_set_chan(sc, ic->ic_curchan); + UPGT_UNLOCK(sc); +} + +static void +upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct upgt_data *data_cmd; + struct upgt_lmac_mem *mem; + struct upgt_lmac_channel *chan; + int channel; + + UPGT_ASSERT_LOCKED(sc); + + channel = ieee80211_chan2ieee(ic, c); + if (channel == 0 || channel == IEEE80211_CHAN_ANY) { + /* XXX should NEVER happen */ + device_printf(sc->sc_dev, + "%s: invalid channel %x\n", __func__, channel); + return; + } + + DPRINTF(sc, UPGT_DEBUG_STATE, "%s: channel %d\n", __func__, channel); + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + device_printf(sc->sc_dev, "%s: out of buffers.\n", __func__); + return; + } + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + chan = (struct upgt_lmac_channel *)(mem + 1); + + chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; + chan->header1.type = UPGT_H1_TYPE_CTRL; + chan->header1.len = htole16( + sizeof(struct upgt_lmac_channel) - sizeof(struct upgt_lmac_header)); + + chan->header2.reqid = htole32(sc->sc_memaddr_frame_start); + chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL); + chan->header2.flags = 0; + + chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1); + chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2); + chan->freq6 = sc->sc_eeprom_freq6[channel]; + chan->settings = sc->sc_eeprom_freq6_settings; + chan->unknown3 = UPGT_CHANNEL_UNKNOWN3; + + bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_1, + sizeof(chan->freq3_1)); + bcopy(&sc->sc_eeprom_freq4[channel], chan->freq4, + sizeof(sc->sc_eeprom_freq4[channel])); + bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_2, + sizeof(chan->freq3_2)); + + data_cmd->buflen = sizeof(*mem) + sizeof(*chan); + + mem->chksum = upgt_chksum_le((uint32_t *)chan, + data_cmd->buflen - sizeof(*mem)); + + upgt_bulk_tx(sc, data_cmd); +} + +static struct ieee80211vap * +upgt_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct upgt_vap *uvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + uvp = (struct upgt_vap *) malloc(sizeof(struct upgt_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (uvp == NULL) + return NULL; + vap = &uvp->vap; + /* enable s/w bmiss handling for sta mode */ + ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + /* override state transition machine */ + uvp->newstate = vap->iv_newstate; + vap->iv_newstate = upgt_newstate; + + /* setup device rates */ + upgt_setup_rates(vap, ic); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, + ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static int +upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct upgt_vap *uvp = UPGT_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; + struct upgt_softc *sc = ic->ic_ifp->if_softc; + + /* do it in a process context */ + sc->sc_state = nstate; + + IEEE80211_UNLOCK(ic); + UPGT_LOCK(sc); + callout_stop(&sc->sc_led_ch); + callout_stop(&sc->sc_watchdog_ch); + + switch (nstate) { + case IEEE80211_S_INIT: + /* do not accept any frames if the device is down */ + (void)upgt_set_macfilter(sc, sc->sc_state); + upgt_set_led(sc, UPGT_LED_OFF); + break; + case IEEE80211_S_SCAN: + upgt_set_chan(sc, ic->ic_curchan); + break; + case IEEE80211_S_AUTH: + upgt_set_chan(sc, ic->ic_curchan); + break; + case IEEE80211_S_ASSOC: + break; + case IEEE80211_S_RUN: + upgt_set_macfilter(sc, sc->sc_state); + upgt_set_led(sc, UPGT_LED_ON); + break; + default: + break; + } + UPGT_UNLOCK(sc); + IEEE80211_LOCK(ic); + return (uvp->newstate(vap, nstate, arg)); +} + +static void +upgt_vap_delete(struct ieee80211vap *vap) +{ + struct upgt_vap *uvp = UPGT_VAP(vap); + + ieee80211_vap_detach(vap); + free(uvp, M_80211_VAP); +} + +static void +upgt_update_mcast(struct ifnet *ifp) +{ + struct upgt_softc *sc = ifp->if_softc; + + upgt_set_multi(sc); +} + +static int +upgt_eeprom_parse(struct upgt_softc *sc) +{ + struct upgt_eeprom_header *eeprom_header; + struct upgt_eeprom_option *eeprom_option; + uint16_t option_len; + uint16_t option_type; + uint16_t preamble_len; + int option_end = 0; + + /* calculate eeprom options start offset */ + eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom; + preamble_len = le16toh(eeprom_header->preamble_len); + eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom + + (sizeof(struct upgt_eeprom_header) + preamble_len)); + + while (!option_end) { + /* the eeprom option length is stored in words */ + option_len = + (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t); + option_type = + le16toh(eeprom_option->type); + + switch (option_type) { + case UPGT_EEPROM_TYPE_NAME: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM name len=%d\n", option_len); + break; + case UPGT_EEPROM_TYPE_SERIAL: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM serial len=%d\n", option_len); + break; + case UPGT_EEPROM_TYPE_MAC: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM mac len=%d\n", option_len); + + IEEE80211_ADDR_COPY(sc->sc_myaddr, eeprom_option->data); + break; + case UPGT_EEPROM_TYPE_HWRX: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM hwrx len=%d\n", option_len); + + upgt_eeprom_parse_hwrx(sc, eeprom_option->data); + break; + case UPGT_EEPROM_TYPE_CHIP: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM chip len=%d\n", option_len); + break; + case UPGT_EEPROM_TYPE_FREQ3: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM freq3 len=%d\n", option_len); + + upgt_eeprom_parse_freq3(sc, eeprom_option->data, + option_len); + break; + case UPGT_EEPROM_TYPE_FREQ4: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM freq4 len=%d\n", option_len); + + upgt_eeprom_parse_freq4(sc, eeprom_option->data, + option_len); + break; + case UPGT_EEPROM_TYPE_FREQ5: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM freq5 len=%d\n", option_len); + break; + case UPGT_EEPROM_TYPE_FREQ6: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM freq6 len=%d\n", option_len); + + upgt_eeprom_parse_freq6(sc, eeprom_option->data, + option_len); + break; + case UPGT_EEPROM_TYPE_END: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM end len=%d\n", option_len); + option_end = 1; + break; + case UPGT_EEPROM_TYPE_OFF: + DPRINTF(sc, UPGT_DEBUG_FW, + "%s: EEPROM off without end option!\n", __func__); + return (EIO); + default: + DPRINTF(sc, UPGT_DEBUG_FW, + "EEPROM unknown type 0x%04x len=%d\n", + option_type, option_len); + break; + } + + /* jump to next EEPROM option */ + eeprom_option = (struct upgt_eeprom_option *) + (eeprom_option->data + option_len); + } + + return (0); +} + +static void +upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len) +{ + struct upgt_eeprom_freq3_header *freq3_header; + struct upgt_lmac_freq3 *freq3; + int i, elements, flags; + unsigned channel; + + freq3_header = (struct upgt_eeprom_freq3_header *)data; + freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1); + + flags = freq3_header->flags; + elements = freq3_header->elements; + + DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d\n", + flags, elements); + + for (i = 0; i < elements; i++) { + channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0); + if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) + continue; + + sc->sc_eeprom_freq3[channel] = freq3[i]; + + DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", + le16toh(sc->sc_eeprom_freq3[channel].freq), channel); + } +} + +void +upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len) +{ + struct upgt_eeprom_freq4_header *freq4_header; + struct upgt_eeprom_freq4_1 *freq4_1; + struct upgt_eeprom_freq4_2 *freq4_2; + int i, j, elements, settings, flags; + unsigned channel; + + freq4_header = (struct upgt_eeprom_freq4_header *)data; + freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1); + flags = freq4_header->flags; + elements = freq4_header->elements; + settings = freq4_header->settings; + + /* we need this value later */ + sc->sc_eeprom_freq6_settings = freq4_header->settings; + + DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d settings=%d\n", + flags, elements, settings); + + for (i = 0; i < elements; i++) { + channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0); + if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) + continue; + + freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data; + for (j = 0; j < settings; j++) { + sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j]; + sc->sc_eeprom_freq4[channel][j].pad = 0; + } + + DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", + le16toh(freq4_1[i].freq), channel); + } +} + +void +upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len) +{ + struct upgt_lmac_freq6 *freq6; + int i, elements; + unsigned channel; + + freq6 = (struct upgt_lmac_freq6 *)data; + elements = len / sizeof(struct upgt_lmac_freq6); + + DPRINTF(sc, UPGT_DEBUG_FW, "elements=%d\n", elements); + + for (i = 0; i < elements; i++) { + channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0); + if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) + continue; + + sc->sc_eeprom_freq6[channel] = freq6[i]; + + DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", + le16toh(sc->sc_eeprom_freq6[channel].freq), channel); + } +} + +static void +upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data) +{ + struct upgt_eeprom_option_hwrx *option_hwrx; + + option_hwrx = (struct upgt_eeprom_option_hwrx *)data; + + sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST; + + DPRINTF(sc, UPGT_DEBUG_FW, "hwrx option value=0x%04x\n", + sc->sc_eeprom_hwrx); +} + +static int +upgt_eeprom_read(struct upgt_softc *sc) +{ + struct upgt_data *data_cmd; + struct upgt_lmac_mem *mem; + struct upgt_lmac_eeprom *eeprom; + int block, error, offset; + + UPGT_LOCK(sc); + usb2_pause_mtx(&sc->sc_mtx, 100); + + offset = 0; + block = UPGT_EEPROM_BLOCK_SIZE; + while (offset < UPGT_EEPROM_SIZE) { + DPRINTF(sc, UPGT_DEBUG_FW, + "request EEPROM block (offset=%d, len=%d)\n", offset, block); + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + UPGT_UNLOCK(sc); + return (ENOBUFS); + } + + /* + * Transmit the URB containing the CMD data. + */ + bzero(data_cmd->buf, MCLBYTES); + + mem = (struct upgt_lmac_mem *)data_cmd->buf; + mem->addr = htole32(sc->sc_memaddr_frame_start + + UPGT_MEMSIZE_FRAME_HEAD); + + eeprom = (struct upgt_lmac_eeprom *)(mem + 1); + eeprom->header1.flags = 0; + eeprom->header1.type = UPGT_H1_TYPE_CTRL; + eeprom->header1.len = htole16(( + sizeof(struct upgt_lmac_eeprom) - + sizeof(struct upgt_lmac_header)) + block); + + eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start); + eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM); + eeprom->header2.flags = 0; + + eeprom->offset = htole16(offset); + eeprom->len = htole16(block); + + data_cmd->buflen = sizeof(*mem) + sizeof(*eeprom) + block; + + mem->chksum = upgt_chksum_le((uint32_t *)eeprom, + data_cmd->buflen - sizeof(*mem)); + upgt_bulk_tx(sc, data_cmd); + + error = mtx_sleep(sc, &sc->sc_mtx, 0, "eeprom_request", hz); + if (error != 0) { + device_printf(sc->sc_dev, + "timeout while waiting for EEPROM data!\n"); + UPGT_UNLOCK(sc); + return (EIO); + } + + offset += block; + if (UPGT_EEPROM_SIZE - offset < block) + block = UPGT_EEPROM_SIZE - offset; + } + + UPGT_UNLOCK(sc); + return (0); +} + +/* + * When a rx data came in the function returns a mbuf and a rssi values. + */ +static struct mbuf * +upgt_rxeof(struct usb2_xfer *xfer, struct upgt_data *data, int *rssi) +{ + struct mbuf *m = NULL; + struct upgt_softc *sc = xfer->priv_sc; + struct upgt_lmac_header *header; + struct upgt_lmac_eeprom *eeprom; + uint8_t h1_type; + uint16_t h2_type; + + UPGT_ASSERT_LOCKED(sc); + + if (xfer->actlen < 1) + return (NULL); + + /* Check only at the very beginning. */ + if (!(sc->sc_flags & UPGT_FLAG_FWLOADED) && + (memcmp(data->buf, "OK", 2) == 0)) { + sc->sc_flags |= UPGT_FLAG_FWLOADED; + wakeup_one(sc); + return (NULL); + } + + if (xfer->actlen < UPGT_RX_MINSZ) + return (NULL); + + /* + * Check what type of frame came in. + */ + header = (struct upgt_lmac_header *)(data->buf + 4); + + h1_type = header->header1.type; + h2_type = le16toh(header->header2.type); + + if (h1_type == UPGT_H1_TYPE_CTRL && h2_type == UPGT_H2_TYPE_EEPROM) { + eeprom = (struct upgt_lmac_eeprom *)(data->buf + 4); + uint16_t eeprom_offset = le16toh(eeprom->offset); + uint16_t eeprom_len = le16toh(eeprom->len); + + DPRINTF(sc, UPGT_DEBUG_FW, + "received EEPROM block (offset=%d, len=%d)\n", + eeprom_offset, eeprom_len); + + bcopy(data->buf + sizeof(struct upgt_lmac_eeprom) + 4, + sc->sc_eeprom + eeprom_offset, eeprom_len); + + /* EEPROM data has arrived in time, wakeup. */ + wakeup(sc); + } else if (h1_type == UPGT_H1_TYPE_CTRL && + h2_type == UPGT_H2_TYPE_TX_DONE) { + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: received 802.11 TX done\n", + __func__); + upgt_tx_done(sc, data->buf + 4); + } else if (h1_type == UPGT_H1_TYPE_RX_DATA || + h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) { + DPRINTF(sc, UPGT_DEBUG_RECV, "%s: received 802.11 RX data\n", + __func__); + m = upgt_rx(sc, data->buf + 4, le16toh(header->header1.len), + rssi); + } else if (h1_type == UPGT_H1_TYPE_CTRL && + h2_type == UPGT_H2_TYPE_STATS) { + DPRINTF(sc, UPGT_DEBUG_STAT, "%s: received statistic data\n", + __func__); + /* TODO: what could we do with the statistic data? */ + } else { + /* ignore unknown frame types */ + DPRINTF(sc, UPGT_DEBUG_INTR, + "received unknown frame type 0x%02x\n", + header->header1.type); + } + return (m); +} + +/* + * The firmware awaits a checksum for each frame we send to it. + * The algorithm used therefor is uncommon but somehow similar to CRC32. + */ +static uint32_t +upgt_chksum_le(const uint32_t *buf, size_t size) +{ + int i; + uint32_t crc = 0; + + for (i = 0; i < size; i += sizeof(uint32_t)) { + crc = htole32(crc ^ *buf++); + crc = htole32((crc >> 5) ^ (crc << 3)); + } + + return (crc); +} + +static struct mbuf * +upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct upgt_lmac_rx_desc *rxdesc; + struct mbuf *m; + + /* + * don't pass packets to the ieee80211 framework if the driver isn't + * RUNNING. + */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return (NULL); + + /* access RX packet descriptor */ + rxdesc = (struct upgt_lmac_rx_desc *)data; + + /* create mbuf which is suitable for strict alignment archs */ + KASSERT((pkglen + ETHER_ALIGN) < MCLBYTES, + ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN)); + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) { + device_printf(sc->sc_dev, "could not create RX mbuf!\n"); + return (NULL); + } + m_adj(m, ETHER_ALIGN); + bcopy(rxdesc->data, mtod(m, char *), pkglen); + /* trim FCS */ + m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN; + m->m_pkthdr.rcvif = ifp; + + if (bpf_peers_present(ifp->if_bpf)) { + struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap; + + tap->wr_flags = 0; + tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate); + tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wr_antsignal = rxdesc->rssi; + + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + } + ifp->if_ipackets++; + + DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__); + *rssi = rxdesc->rssi; + return (m); +} + +static uint8_t +upgt_rx_rate(struct upgt_softc *sc, const int rate) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 }; + static const uint8_t ofdm_upgt2rate[12] = + { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; + + if (ic->ic_curmode == IEEE80211_MODE_11B && + !(rate < 0 || rate > 3)) + return cck_upgt2rate[rate & 0xf]; + + if (ic->ic_curmode == IEEE80211_MODE_11G && + !(rate < 0 || rate > 11)) + return ofdm_upgt2rate[rate & 0xf]; + + return (0); +} + +static void +upgt_tx_done(struct upgt_softc *sc, uint8_t *data) +{ + struct ifnet *ifp = sc->sc_ifp; + struct upgt_lmac_tx_done_desc *desc; + int i, freed = 0; + + UPGT_ASSERT_LOCKED(sc); + + desc = (struct upgt_lmac_tx_done_desc *)data; + + for (i = 0; i < UPGT_TX_MAXCOUNT; i++) { + struct upgt_data *data_tx = &sc->sc_tx_data[i]; + + if (data_tx->addr == le32toh(desc->header2.reqid)) { + upgt_mem_free(sc, data_tx->addr); + data_tx->ni = NULL; + data_tx->addr = 0; + data_tx->m = NULL; + data_tx->use = 0; + + DPRINTF(sc, UPGT_DEBUG_TX_PROC, + "TX done: memaddr=0x%08x, status=0x%04x, rssi=%d, ", + le32toh(desc->header2.reqid), + le16toh(desc->status), le16toh(desc->rssi)); + DPRINTF(sc, UPGT_DEBUG_TX_PROC, "seq=%d\n", + le16toh(desc->seq)); + + freed++; + } + } + + if (freed != 0) { + sc->sc_tx_timer = 0; + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + UPGT_UNLOCK(sc); + upgt_start(ifp); + UPGT_LOCK(sc); + } +} + +static void +upgt_mem_free(struct upgt_softc *sc, uint32_t addr) +{ + int i; + + for (i = 0; i < sc->sc_memory.pages; i++) { + if (sc->sc_memory.page[i].addr == addr) { + sc->sc_memory.page[i].used = 0; + return; + } + } + + device_printf(sc->sc_dev, + "could not free memory address 0x%08x!\n", addr); +} + +static int +upgt_fw_load(struct upgt_softc *sc) +{ + const struct firmware *fw; + struct upgt_data *data_cmd; + struct upgt_fw_x2_header *x2; + char start_fwload_cmd[] = { 0x3c, 0x0d }; + int error = 0, offset, bsize, n; + uint32_t crc32; + + fw = firmware_get(upgt_fwname); + if (fw == NULL) { + device_printf(sc->sc_dev, "could not read microcode %s!\n", + upgt_fwname); + return (EIO); + } + + UPGT_LOCK(sc); + + /* send firmware start load command */ + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + error = ENOBUFS; + goto fail; + } + data_cmd->buflen = sizeof(start_fwload_cmd); + bcopy(start_fwload_cmd, data_cmd->buf, data_cmd->buflen); + upgt_bulk_tx(sc, data_cmd); + + /* send X2 header */ + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + error = ENOBUFS; + goto fail; + } + data_cmd->buflen = sizeof(struct upgt_fw_x2_header); + x2 = (struct upgt_fw_x2_header *)data_cmd->buf; + bcopy(UPGT_X2_SIGNATURE, x2->signature, UPGT_X2_SIGNATURE_SIZE); + x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START); + x2->len = htole32(fw->datasize); + x2->crc = upgt_crc32_le((uint8_t *)data_cmd->buf + + UPGT_X2_SIGNATURE_SIZE, + sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE - + sizeof(uint32_t)); + upgt_bulk_tx(sc, data_cmd); + + /* download firmware */ + for (offset = 0; offset < fw->datasize; offset += bsize) { + if (fw->datasize - offset > UPGT_FW_BLOCK_SIZE) + bsize = UPGT_FW_BLOCK_SIZE; + else + bsize = fw->datasize - offset; + + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + error = ENOBUFS; + goto fail; + } + n = upgt_fw_copy((const uint8_t *)fw->data + offset, + data_cmd->buf, bsize); + data_cmd->buflen = bsize; + upgt_bulk_tx(sc, data_cmd); + + DPRINTF(sc, UPGT_DEBUG_FW, "FW offset=%d, read=%d, sent=%d\n", + offset, n, bsize); + bsize = n; + } + DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware downloaded\n", __func__); + + /* load firmware */ + data_cmd = upgt_getbuf(sc); + if (data_cmd == NULL) { + error = ENOBUFS; + goto fail; + } + crc32 = upgt_crc32_le(fw->data, fw->datasize); + *((uint32_t *)(data_cmd->buf) ) = crc32; + *((uint8_t *)(data_cmd->buf) + 4) = 'g'; + *((uint8_t *)(data_cmd->buf) + 5) = '\r'; + data_cmd->buflen = 6; + upgt_bulk_tx(sc, data_cmd); + + /* waiting 'OK' response. */ + usb2_transfer_start(sc->sc_xfer[UPGT_BULK_RX]); + error = mtx_sleep(sc, &sc->sc_mtx, 0, "upgtfw", 2 * hz); + if (error != 0) { + device_printf(sc->sc_dev, "firmware load failed!\n"); + error = EIO; + } + + DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware loaded\n", __func__); +fail: + UPGT_UNLOCK(sc); + firmware_put(fw, FIRMWARE_UNLOAD); + return (error); +} + +static uint32_t +upgt_crc32_le(const void *buf, size_t size) +{ + uint32_t crc; + + crc = ether_crc32_le(buf, size); + + /* apply final XOR value as common for CRC-32 */ + crc = htole32(crc ^ 0xffffffffU); + + return (crc); +} + +/* + * While copying the version 2 firmware, we need to replace two characters: + * + * 0x7e -> 0x7d 0x5e + * 0x7d -> 0x7d 0x5d + */ +static int +upgt_fw_copy(const uint8_t *src, char *dst, int size) +{ + int i, j; + + for (i = 0, j = 0; i < size && j < size; i++) { + switch (src[i]) { + case 0x7e: + dst[j] = 0x7d; + j++; + dst[j] = 0x5e; + j++; + break; + case 0x7d: + dst[j] = 0x7d; + j++; + dst[j] = 0x5d; + j++; + break; + default: + dst[j] = src[i]; + j++; + break; + } + } + + return (i); +} + +static int +upgt_mem_init(struct upgt_softc *sc) +{ + int i; + + for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) { + sc->sc_memory.page[i].used = 0; + + if (i == 0) { + /* + * The first memory page is always reserved for + * command data. + */ + sc->sc_memory.page[i].addr = + sc->sc_memaddr_frame_start + MCLBYTES; + } else { + sc->sc_memory.page[i].addr = + sc->sc_memory.page[i - 1].addr + MCLBYTES; + } + + if (sc->sc_memory.page[i].addr + MCLBYTES >= + sc->sc_memaddr_frame_end) + break; + + DPRINTF(sc, UPGT_DEBUG_FW, "memory address page %d=0x%08x\n", + i, sc->sc_memory.page[i].addr); + } + + sc->sc_memory.pages = i; + + DPRINTF(sc, UPGT_DEBUG_FW, "memory pages=%d\n", sc->sc_memory.pages); + return (0); +} + +static int +upgt_fw_verify(struct upgt_softc *sc) +{ + const struct firmware *fw; + const struct upgt_fw_bra_option *bra_opt; + const struct upgt_fw_bra_descr *descr; + const uint8_t *p; + const uint32_t *uc; + uint32_t bra_option_type, bra_option_len; + int offset, bra_end = 0, error = 0; + + fw = firmware_get(upgt_fwname); + if (fw == NULL) { + device_printf(sc->sc_dev, "could not read microcode %s!\n", + upgt_fwname); + return EIO; + } + + /* + * Seek to beginning of Boot Record Area (BRA). + */ + for (offset = 0; offset < fw->datasize; offset += sizeof(*uc)) { + uc = (const uint32_t *)((const uint8_t *)fw->data + offset); + if (*uc == 0) + break; + } + for (; offset < fw->datasize; offset += sizeof(*uc)) { + uc = (const uint32_t *)((const uint8_t *)fw->data + offset); + if (*uc != 0) + break; + } + if (offset == fw->datasize) { + device_printf(sc->sc_dev, + "firmware Boot Record Area not found!\n"); + error = EIO; + goto fail; + } + + DPRINTF(sc, UPGT_DEBUG_FW, + "firmware Boot Record Area found at offset %d\n", offset); + + /* + * Parse Boot Record Area (BRA) options. + */ + while (offset < fw->datasize && bra_end == 0) { + /* get current BRA option */ + p = (const uint8_t *)fw->data + offset; + bra_opt = (const struct upgt_fw_bra_option *)p; + bra_option_type = le32toh(bra_opt->type); + bra_option_len = le32toh(bra_opt->len) * sizeof(*uc); + + switch (bra_option_type) { + case UPGT_BRA_TYPE_FW: + DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_FW len=%d\n", + bra_option_len); + + if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) { + device_printf(sc->sc_dev, + "wrong UPGT_BRA_TYPE_FW len!\n"); + error = EIO; + goto fail; + } + if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_opt->data, + bra_option_len) == 0) { + sc->sc_fw_type = UPGT_FWTYPE_LM86; + break; + } + if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_opt->data, + bra_option_len) == 0) { + sc->sc_fw_type = UPGT_FWTYPE_LM87; + break; + } + device_printf(sc->sc_dev, + "unsupported firmware type!\n"); + error = EIO; + goto fail; + case UPGT_BRA_TYPE_VERSION: + DPRINTF(sc, UPGT_DEBUG_FW, + "UPGT_BRA_TYPE_VERSION len=%d\n", bra_option_len); + break; + case UPGT_BRA_TYPE_DEPIF: + DPRINTF(sc, UPGT_DEBUG_FW, + "UPGT_BRA_TYPE_DEPIF len=%d\n", bra_option_len); + break; + case UPGT_BRA_TYPE_EXPIF: + DPRINTF(sc, UPGT_DEBUG_FW, + "UPGT_BRA_TYPE_EXPIF len=%d\n", bra_option_len); + break; + case UPGT_BRA_TYPE_DESCR: + DPRINTF(sc, UPGT_DEBUG_FW, + "UPGT_BRA_TYPE_DESCR len=%d\n", bra_option_len); + + descr = (const struct upgt_fw_bra_descr *)bra_opt->data; + + sc->sc_memaddr_frame_start = + le32toh(descr->memaddr_space_start); + sc->sc_memaddr_frame_end = + le32toh(descr->memaddr_space_end); + + DPRINTF(sc, UPGT_DEBUG_FW, + "memory address space start=0x%08x\n", + sc->sc_memaddr_frame_start); + DPRINTF(sc, UPGT_DEBUG_FW, + "memory address space end=0x%08x\n", + sc->sc_memaddr_frame_end); + break; + case UPGT_BRA_TYPE_END: + DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_END len=%d\n", + bra_option_len); + bra_end = 1; + break; + default: + DPRINTF(sc, UPGT_DEBUG_FW, "unknown BRA option len=%d\n", + bra_option_len); + error = EIO; + goto fail; + } + + /* jump to next BRA option */ + offset += sizeof(struct upgt_fw_bra_option) + bra_option_len; + } + + DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware verified", __func__); +fail: + firmware_put(fw, FIRMWARE_UNLOAD); + return (error); +} + +static void +upgt_bulk_tx(struct upgt_softc *sc, struct upgt_data *data) +{ + + UPGT_ASSERT_LOCKED(sc); + + STAILQ_INSERT_TAIL(&sc->sc_tx_pending, data, next); + UPGT_STAT_INC(sc, st_tx_pending); + usb2_transfer_start(sc->sc_xfer[UPGT_BULK_TX]); +} + +static int +upgt_device_reset(struct upgt_softc *sc) +{ + struct upgt_data *data; + char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e }; + + UPGT_LOCK(sc); + + data = upgt_getbuf(sc); + if (data == NULL) { + UPGT_UNLOCK(sc); + return (ENOBUFS); + } + bcopy(init_cmd, data->buf, sizeof(init_cmd)); + data->buflen = sizeof(init_cmd); + upgt_bulk_tx(sc, data); + usb2_pause_mtx(&sc->sc_mtx, 100); + + UPGT_UNLOCK(sc); + DPRINTF(sc, UPGT_DEBUG_FW, "%s: device initialized\n", __func__); + return (0); +} + +static int +upgt_alloc_tx(struct upgt_softc *sc) +{ + int i; + + STAILQ_INIT(&sc->sc_tx_active); + STAILQ_INIT(&sc->sc_tx_inactive); + STAILQ_INIT(&sc->sc_tx_pending); + + for (i = 0; i < UPGT_TX_MAXCOUNT; i++) { + struct upgt_data *data = &sc->sc_tx_data[i]; + + data->buf = malloc(MCLBYTES, M_USBDEV, M_NOWAIT | M_ZERO); + if (data->buf == NULL) { + device_printf(sc->sc_dev, + "could not allocate TX buffer!\n"); + return (ENOMEM); + } + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); + UPGT_STAT_INC(sc, st_tx_inactive); + } + + return (0); +} + +static int +upgt_alloc_rx(struct upgt_softc *sc) +{ + int i; + + STAILQ_INIT(&sc->sc_rx_active); + STAILQ_INIT(&sc->sc_rx_inactive); + + for (i = 0; i < UPGT_RX_MAXCOUNT; i++) { + struct upgt_data *data = &sc->sc_rx_data[i]; + + data->buf = malloc(MCLBYTES, M_USBDEV, M_NOWAIT | M_ZERO); + if (data->buf == NULL) { + device_printf(sc->sc_dev, + "could not allocate RX buffer!\n"); + return (ENOMEM); + } + STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); + } + + return (0); +} + +static int +upgt_detach(device_t dev) +{ + struct upgt_softc *sc = device_get_softc(dev); + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + if (!device_is_attached(dev)) + return 0; + + upgt_stop(sc); + ieee80211_ifdetach(ic); + + callout_drain(&sc->sc_led_ch); + callout_drain(&sc->sc_watchdog_ch); + + usb2_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); + upgt_free_rx(sc); + upgt_free_tx(sc); + + bpfdetach(ifp); + if_free(ifp); + mtx_destroy(&sc->sc_mtx); + + return (0); +} + +static void +upgt_free_rx(struct upgt_softc *sc) +{ + int i; + + for (i = 0; i < UPGT_RX_MAXCOUNT; i++) { + struct upgt_data *data = &sc->sc_rx_data[i]; + + free(data->buf, M_USBDEV); + data->ni = NULL; + } +} + +static void +upgt_free_tx(struct upgt_softc *sc) +{ + int i; + + for (i = 0; i < UPGT_TX_MAXCOUNT; i++) { + struct upgt_data *data = &sc->sc_tx_data[i]; + + free(data->buf, M_USBDEV); + data->ni = NULL; + } +} + +static void +upgt_abort_xfers_locked(struct upgt_softc *sc) +{ + int i; + + UPGT_ASSERT_LOCKED(sc); + /* abort any pending transfers */ + for (i = 0; i < UPGT_N_XFERS; i++) + usb2_transfer_stop(sc->sc_xfer[i]); +} + +static void +upgt_abort_xfers(struct upgt_softc *sc) +{ + + UPGT_LOCK(sc); + upgt_abort_xfers_locked(sc); + UPGT_UNLOCK(sc); +} + +#define UPGT_SYSCTL_STAT_ADD32(c, h, n, p, d) \ + SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d) + +static void +upgt_sysctl_node(struct upgt_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *child; + struct sysctl_oid *tree; + struct upgt_stat *stats; + + stats = &sc->sc_stat; + ctx = device_get_sysctl_ctx(sc->sc_dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->sc_dev)); + + tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD, + NULL, "UPGT statistics"); + child = SYSCTL_CHILDREN(tree); + UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_active", + &stats->st_tx_active, "Active numbers in TX queue"); + UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_inactive", + &stats->st_tx_inactive, "Inactive numbers in TX queue"); + UPGT_SYSCTL_STAT_ADD32(ctx, child, "tx_pending", + &stats->st_tx_pending, "Pending numbers in TX queue"); +} + +#undef UPGT_SYSCTL_STAT_ADD32 + +static struct upgt_data * +_upgt_getbuf(struct upgt_softc *sc) +{ + struct upgt_data *bf; + + bf = STAILQ_FIRST(&sc->sc_tx_inactive); + if (bf != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_tx_inactive, next); + UPGT_STAT_DEC(sc, st_tx_inactive); + } else + bf = NULL; + if (bf == NULL) + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: %s\n", __func__, + "out of xmit buffers"); + return (bf); +} + +static struct upgt_data * +upgt_getbuf(struct upgt_softc *sc) +{ + struct upgt_data *bf; + + UPGT_ASSERT_LOCKED(sc); + + bf = _upgt_getbuf(sc); + if (bf == NULL) { + struct ifnet *ifp = sc->sc_ifp; + + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: stop queue\n", __func__); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + } + + return (bf); +} + +static struct upgt_data * +upgt_gettxbuf(struct upgt_softc *sc) +{ + struct upgt_data *bf; + + UPGT_ASSERT_LOCKED(sc); + + bf = upgt_getbuf(sc); + if (bf == NULL) + return (NULL); + + bf->addr = upgt_mem_alloc(sc); + if (bf->addr == 0) { + struct ifnet *ifp = sc->sc_ifp; + + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: no free prism memory!\n", + __func__); + STAILQ_INSERT_HEAD(&sc->sc_tx_inactive, bf, next); + UPGT_STAT_INC(sc, st_tx_inactive); + if (!(ifp->if_drv_flags & IFF_DRV_OACTIVE)) + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + return (NULL); + } + return (bf); +} + +static int +upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni, + struct upgt_data *data) +{ + int error = 0, len; + struct ieee80211_frame *wh; + struct ieee80211_key *k; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct upgt_lmac_mem *mem; + struct upgt_lmac_tx_desc *txdesc; + + UPGT_ASSERT_LOCKED(sc); + + upgt_set_led(sc, UPGT_LED_BLINK); + + /* + * Software crypto. + */ + wh = mtod(m, struct ieee80211_frame *); + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + k = ieee80211_crypto_encap(ni, m); + if (k == NULL) { + device_printf(sc->sc_dev, + "ieee80211_crypto_encap returns NULL.\n"); + error = EIO; + goto done; + } + + /* in case packet header moved, reset pointer */ + wh = mtod(m, struct ieee80211_frame *); + } + + /* Transmit the URB containing the TX data. */ + bzero(data->buf, MCLBYTES); + mem = (struct upgt_lmac_mem *)data->buf; + mem->addr = htole32(data->addr); + txdesc = (struct upgt_lmac_tx_desc *)(mem + 1); + + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == + IEEE80211_FC0_TYPE_MGT) { + /* mgmt frames */ + txdesc->header1.flags = UPGT_H1_FLAGS_TX_MGMT; + /* always send mgmt frames at lowest rate (DS1) */ + memset(txdesc->rates, 0x10, sizeof(txdesc->rates)); + } else { + /* data frames */ + txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA; + bcopy(sc->sc_cur_rateset, txdesc->rates, sizeof(txdesc->rates)); + } + txdesc->header1.type = UPGT_H1_TYPE_TX_DATA; + txdesc->header1.len = htole16(m->m_pkthdr.len); + txdesc->header2.reqid = htole32(data->addr); + txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES); + txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES); + txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA); + txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE; + + if (bpf_peers_present(ifp->if_bpf)) { + struct upgt_tx_radiotap_header *tap = &sc->sc_txtap; + + tap->wt_flags = 0; + tap->wt_rate = 0; /* XXX where to get from? */ + tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); + tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); + + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); + } + + /* copy frame below our TX descriptor header */ + m_copydata(m, 0, m->m_pkthdr.len, + data->buf + (sizeof(*mem) + sizeof(*txdesc))); + /* calculate frame size */ + len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len; + /* we need to align the frame to a 4 byte boundary */ + len = (len + 3) & ~3; + /* calculate frame checksum */ + mem->chksum = upgt_chksum_le((uint32_t *)txdesc, len - sizeof(*mem)); + data->ni = ni; + data->m = m; + data->buflen = len; + + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: TX start data sending (%d bytes)\n", + __func__, len); + KASSERT(len <= MCLBYTES, ("mbuf is small for saving data")); + + upgt_bulk_tx(sc, data); +done: + /* + * If we don't regulary read the device statistics, the RX queue + * will stall. It's strange, but it works, so we keep reading + * the statistics here. *shrug* + */ + if (!(ifp->if_opackets % UPGT_TX_STAT_INTERVAL)) + upgt_get_stats(sc); + + return (error); +} + +static void +upgt_bulk_rx_callback(struct usb2_xfer *xfer) +{ + struct upgt_softc *sc = xfer->priv_sc; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211_frame *wh; + struct ieee80211_node *ni; + struct mbuf *m = NULL; + struct upgt_data *data; + int8_t nf; + int rssi = -1; + + UPGT_ASSERT_LOCKED(sc); + + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + data = STAILQ_FIRST(&sc->sc_rx_active); + if (data == NULL) + goto setup; + STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); + m = upgt_rxeof(xfer, data, &rssi); + STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); + /* FALLTHROUGH */ + case USB_ST_SETUP: +setup: + data = STAILQ_FIRST(&sc->sc_rx_inactive); + if (data == NULL) + return; + STAILQ_REMOVE_HEAD(&sc->sc_rx_inactive, next); + STAILQ_INSERT_TAIL(&sc->sc_rx_active, data, next); + usb2_set_frame_data(xfer, data->buf, 0); + xfer->frlengths[0] = xfer->max_data_length; + usb2_start_hardware(xfer); + + /* + * To avoid LOR we should unlock our private mutex here to call + * ieee80211_input() because here is at the end of a USB + * callback and safe to unlock. + */ + UPGT_UNLOCK(sc); + if (m != NULL) { + wh = mtod(m, struct ieee80211_frame *); + ni = ieee80211_find_rxnode(ic, + (struct ieee80211_frame_min *)wh); + nf = -95; /* XXX */ + if (ni != NULL) { + (void) ieee80211_input(ni, m, rssi, nf, 0); + /* node is no longer needed */ + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, nf, 0); + m = NULL; + } + UPGT_LOCK(sc); + break; + default: + /* needs it to the inactive queue due to a error. */ + data = STAILQ_FIRST(&sc->sc_rx_active); + if (data != NULL) { + STAILQ_REMOVE_HEAD(&sc->sc_rx_active, next); + STAILQ_INSERT_TAIL(&sc->sc_rx_inactive, data, next); + } + if (xfer->error != USB_ERR_CANCELLED) { + xfer->flags.stall_pipe = 1; + ifp->if_ierrors++; + goto setup; + } + break; + } +} + +static void +upgt_bulk_tx_callback(struct usb2_xfer *xfer) +{ + struct upgt_softc *sc = xfer->priv_sc; + struct ifnet *ifp = sc->sc_ifp; + struct upgt_data *data; + + UPGT_ASSERT_LOCKED(sc); + switch (USB_GET_STATE(xfer)) { + case USB_ST_TRANSFERRED: + data = STAILQ_FIRST(&sc->sc_tx_active); + if (data == NULL) + goto setup; + STAILQ_REMOVE_HEAD(&sc->sc_tx_active, next); + UPGT_STAT_DEC(sc, st_tx_active); + upgt_txeof(xfer, data); + STAILQ_INSERT_TAIL(&sc->sc_tx_inactive, data, next); + UPGT_STAT_INC(sc, st_tx_inactive); + /* FALLTHROUGH */ + case USB_ST_SETUP: +setup: + data = STAILQ_FIRST(&sc->sc_tx_pending); + if (data == NULL) { + DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: empty pending queue\n", + __func__); + return; + } + STAILQ_REMOVE_HEAD(&sc->sc_tx_pending, next); + UPGT_STAT_DEC(sc, st_tx_pending); + STAILQ_INSERT_TAIL(&sc->sc_tx_active, data, next); + UPGT_STAT_INC(sc, st_tx_active); + + usb2_set_frame_data(xfer, data->buf, 0); + xfer->frlengths[0] = data->buflen; + usb2_start_hardware(xfer); + UPGT_UNLOCK(sc); + upgt_start(ifp); + UPGT_LOCK(sc); + break; + default: + data = STAILQ_FIRST(&sc->sc_tx_active); + if (data == NULL) + goto setup; + if (data->ni != NULL) { + ieee80211_free_node(data->ni); + data->ni = NULL; + ifp->if_oerrors++; + } + if (xfer->error != USB_ERR_CANCELLED) { + xfer->flags.stall_pipe = 1; + goto setup; + } + break; + } +} + +static device_method_t upgt_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, upgt_match), + DEVMETHOD(device_attach, upgt_attach), + DEVMETHOD(device_detach, upgt_detach), + + { 0, 0 } +}; + +static driver_t upgt_driver = { + "upgt", + upgt_methods, + sizeof(struct upgt_softc) +}; + +static devclass_t upgt_devclass; + +DRIVER_MODULE(if_upgt, uhub, upgt_driver, upgt_devclass, NULL, 0); +MODULE_VERSION(if_upgt, 1); +MODULE_DEPEND(if_upgt, usb, 1, 1, 1); +MODULE_DEPEND(if_upgt, wlan, 1, 1, 1); +MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1); diff --git a/sys/dev/usb/wlan/if_upgtvar.h b/sys/dev/usb/wlan/if_upgtvar.h new file mode 100644 index 000000000000..719d8c29186d --- /dev/null +++ b/sys/dev/usb/wlan/if_upgtvar.h @@ -0,0 +1,482 @@ +/* $OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */ +/* $FreeBSD$ */ + +/* + * Copyright (c) 2007 Marcus Glocker + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +struct upgt_softc; + +/* + * General values. + */ +enum { + UPGT_BULK_RX, + UPGT_BULK_TX, + UPGT_N_XFERS = 2, +}; + +#define UPGT_CONFIG_INDEX 0 +#define UPGT_IFACE_INDEX 0 +#define UPGT_USB_TIMEOUT 1000 +#define UPGT_FIRMWARE_TIMEOUT 10 + +#define UPGT_MEMADDR_FIRMWARE_START 0x00020000 /* 512 bytes large */ +#define UPGT_MEMSIZE_FRAME_HEAD 0x0070 +#define UPGT_MEMSIZE_RX 0x3500 + +#define UPGT_RX_MAXCOUNT 6 +#define UPGT_TX_MAXCOUNT 128 +#define UPGT_TX_STAT_INTERVAL 5 +#define UPGT_RX_MINSZ (sizeof(struct upgt_lmac_header) + 4) + +/* device flags */ +#define UPGT_DEVICE_ATTACHED (1 << 0) + +/* leds */ +#define UPGT_LED_OFF 0 +#define UPGT_LED_ON 1 +#define UPGT_LED_BLINK 2 + +/* + * Firmware. + */ +#define UPGT_FW_BLOCK_SIZE 256 + +#define UPGT_BRA_FWTYPE_SIZE 4 +#define UPGT_BRA_FWTYPE_LM86 "LM86" +#define UPGT_BRA_FWTYPE_LM87 "LM87" +enum upgt_fw_type { + UPGT_FWTYPE_LM86, + UPGT_FWTYPE_LM87 +}; + +#define UPGT_BRA_TYPE_FW 0x80000001 +#define UPGT_BRA_TYPE_VERSION 0x80000002 +#define UPGT_BRA_TYPE_DEPIF 0x80000003 +#define UPGT_BRA_TYPE_EXPIF 0x80000004 +#define UPGT_BRA_TYPE_DESCR 0x80000101 +#define UPGT_BRA_TYPE_END 0xff0000ff +struct upgt_fw_bra_option { + uint32_t type; + uint32_t len; + uint8_t data[]; +} __packed; + +struct upgt_fw_bra_descr { + uint32_t unknown1; + uint32_t memaddr_space_start; + uint32_t memaddr_space_end; + uint32_t unknown2; + uint32_t unknown3; + uint8_t rates[20]; +} __packed; + +#define UPGT_X2_SIGNATURE_SIZE 4 +#define UPGT_X2_SIGNATURE "x2 " +struct upgt_fw_x2_header { + uint8_t signature[4]; + uint32_t startaddr; + uint32_t len; + uint32_t crc; +} __packed; + +/* + * EEPROM. + */ +#define UPGT_EEPROM_SIZE 8192 +#define UPGT_EEPROM_BLOCK_SIZE 1020 + +struct upgt_eeprom_header { + /* 14 bytes */ + uint32_t magic; + uint16_t pad1; + uint16_t preamble_len; + uint32_t pad2; + /* data */ +} __packed; + +#define UPGT_EEPROM_TYPE_END 0x0000 +#define UPGT_EEPROM_TYPE_NAME 0x0001 +#define UPGT_EEPROM_TYPE_SERIAL 0x0003 +#define UPGT_EEPROM_TYPE_MAC 0x0101 +#define UPGT_EEPROM_TYPE_HWRX 0x1001 +#define UPGT_EEPROM_TYPE_CHIP 0x1002 +#define UPGT_EEPROM_TYPE_FREQ3 0x1903 +#define UPGT_EEPROM_TYPE_FREQ4 0x1904 +#define UPGT_EEPROM_TYPE_FREQ5 0x1905 +#define UPGT_EEPROM_TYPE_FREQ6 0x1906 +#define UPGT_EEPROM_TYPE_OFF 0xffff +struct upgt_eeprom_option { + uint16_t len; + uint16_t type; + uint8_t data[]; + /* data */ +} __packed; + +#define UPGT_EEPROM_RX_CONST 0x88 +struct upgt_eeprom_option_hwrx { + uint32_t pad1; + uint8_t rxfilter; + uint8_t pad2[15]; +} __packed; + +struct upgt_eeprom_freq3_header { + uint8_t flags; + uint8_t elements; +} __packed; + +struct upgt_eeprom_freq4_header { + uint8_t flags; + uint8_t elements; + uint8_t settings; + uint8_t type; +} __packed; + +struct upgt_eeprom_freq4_1 { + uint16_t freq; + uint8_t data[50]; +} __packed; + +struct upgt_eeprom_freq4_2 { + uint16_t head; + uint8_t subtails[4]; + uint8_t tail; +} __packed; + +/* + * LMAC protocol. + */ +struct upgt_lmac_mem { + uint32_t addr; + uint32_t chksum; +} __packed; + +#define UPGT_H1_FLAGS_TX_MGMT 0x00 /* for TX: mgmt frame */ +#define UPGT_H1_FLAGS_TX_NO_CALLBACK 0x01 /* for TX: no USB callback */ +#define UPGT_H1_FLAGS_TX_DATA 0x10 /* for TX: data frame */ +#define UPGT_H1_TYPE_RX_DATA 0x00 /* 802.11 RX data frame */ +#define UPGT_H1_TYPE_RX_DATA_MGMT 0x04 /* 802.11 RX mgmt frame */ +#define UPGT_H1_TYPE_TX_DATA 0x40 /* 802.11 TX data frame */ +#define UPGT_H1_TYPE_CTRL 0x80 /* control frame */ +struct upgt_lmac_h1 { + /* 4 bytes */ + uint8_t flags; + uint8_t type; + uint16_t len; +} __packed; + +#define UPGT_H2_TYPE_TX_ACK_NO 0x0000 +#define UPGT_H2_TYPE_TX_ACK_YES 0x0001 +#define UPGT_H2_TYPE_MACFILTER 0x0000 +#define UPGT_H2_TYPE_CHANNEL 0x0001 +#define UPGT_H2_TYPE_TX_DONE 0x0008 +#define UPGT_H2_TYPE_STATS 0x000a +#define UPGT_H2_TYPE_EEPROM 0x000c +#define UPGT_H2_TYPE_LED 0x000d +#define UPGT_H2_FLAGS_TX_ACK_NO 0x0101 +#define UPGT_H2_FLAGS_TX_ACK_YES 0x0707 +struct upgt_lmac_h2 { + /* 8 bytes */ + uint32_t reqid; + uint16_t type; + uint16_t flags; +} __packed; + +struct upgt_lmac_header { + /* 12 bytes */ + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; +} __packed; + +struct upgt_lmac_eeprom { + /* 16 bytes */ + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint16_t offset; + uint16_t len; + /* data */ +} __packed; + +#define UPGT_FILTER_TYPE_NONE 0x0000 +#define UPGT_FILTER_TYPE_STA 0x0001 +#define UPGT_FILTER_TYPE_IBSS 0x0002 +#define UPGT_FILTER_TYPE_HOSTAP 0x0004 +#define UPGT_FILTER_TYPE_MONITOR 0x0010 +#define UPGT_FILTER_TYPE_RESET 0x0020 +#define UPGT_FILTER_UNKNOWN1 0x0002 +#define UPGT_FILTER_UNKNOWN2 0x0ca8 +#define UPGT_FILTER_UNKNOWN3 0xffff +#define UPGT_FILTER_MONITOR_UNKNOWN1 0x0000 +#define UPGT_FILTER_MONITOR_UNKNOWN2 0x0000 +#define UPGT_FILTER_MONITOR_UNKNOWN3 0x0000 +struct upgt_lmac_filter { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + /* 32 bytes */ + uint16_t type; + uint8_t dst[IEEE80211_ADDR_LEN]; + uint8_t src[IEEE80211_ADDR_LEN]; + uint16_t unknown1; + uint32_t rxaddr; + uint16_t unknown2; + uint32_t rxhw; + uint16_t unknown3; + uint32_t unknown4; +} __packed; + +/* frequence 3 data */ +struct upgt_lmac_freq3 { + uint16_t freq; + uint8_t data[6]; +} __packed; + +/* frequence 4 data */ +struct upgt_lmac_freq4 { + struct upgt_eeprom_freq4_2 cmd; + uint8_t pad; +}; + +/* frequence 6 data */ +struct upgt_lmac_freq6 { + uint16_t freq; + uint8_t data[8]; +} __packed; + +#define UPGT_CHANNEL_UNKNOWN1 0x0001 +#define UPGT_CHANNEL_UNKNOWN2 0x0000 +#define UPGT_CHANNEL_UNKNOWN3 0x48 +struct upgt_lmac_channel { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + /* 112 bytes */ + uint16_t unknown1; + uint16_t unknown2; + uint8_t pad1[20]; + struct upgt_lmac_freq6 freq6; + uint8_t settings; + uint8_t unknown3; + uint8_t freq3_1[4]; + struct upgt_lmac_freq4 freq4[8]; + uint8_t freq3_2[4]; + uint32_t pad2; +} __packed; + +#define UPGT_LED_MODE_SET 0x0003 +#define UPGT_LED_ACTION_OFF 0x0002 +#define UPGT_LED_ACTION_ON 0x0003 +#define UPGT_LED_ACTION_TMP_DUR 100 /* ms */ +struct upgt_lmac_led { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint16_t mode; + uint16_t action_fix; + uint16_t action_tmp; + uint16_t action_tmp_dur; +} __packed; + +struct upgt_lmac_stats { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint8_t data[76]; +} __packed; + +struct upgt_lmac_rx_desc { + struct upgt_lmac_h1 header1; + /* 16 bytes */ + uint16_t freq; + uint8_t unknown1; + uint8_t rate; + uint8_t rssi; + uint8_t pad; + uint16_t unknown2; + uint32_t timestamp; + uint32_t unknown3; + uint8_t data[]; +} __packed; + +#define UPGT_TX_DESC_KEY_EXISTS 0x01 +struct upgt_lmac_tx_desc_wep { + uint8_t key_exists; + uint8_t key_len; + uint8_t key_val[16]; +} __packed; + +#define UPGT_TX_DESC_TYPE_BEACON 0x00000000 +#define UPGT_TX_DESC_TYPE_PROBE 0x00000001 +#define UPGT_TX_DESC_TYPE_MGMT 0x00000002 +#define UPGT_TX_DESC_TYPE_DATA 0x00000004 +#define UPGT_TX_DESC_PAD3_SIZE 2 +struct upgt_lmac_tx_desc { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint8_t rates[8]; + uint16_t pad1; + struct upgt_lmac_tx_desc_wep wep_key; + uint32_t type; + uint32_t pad2; + uint32_t unknown1; + uint32_t unknown2; + uint8_t pad3[2]; + /* 802.11 frame data */ +} __packed; + +#define UPGT_TX_DONE_DESC_STATUS_OK 0x0001 +struct upgt_lmac_tx_done_desc { + struct upgt_lmac_h1 header1; + struct upgt_lmac_h2 header2; + uint16_t status; + uint16_t rssi; + uint16_t seq; + uint16_t unknown; +} __packed; + +/* + * USB xfers. + */ +struct upgt_data { + uint8_t *buf; + uint32_t buflen; + struct ieee80211_node *ni; + struct mbuf *m; + uint32_t addr; + uint8_t use; + STAILQ_ENTRY(upgt_data) next; +}; +typedef STAILQ_HEAD(, upgt_data) upgt_datahead; + +/* + * Prism memory. + */ +struct upgt_memory_page { + uint8_t used; + uint32_t addr; +} __packed; + +#define UPGT_MEMORY_MAX_PAGES 8 +struct upgt_memory { + uint8_t pages; + struct upgt_memory_page page[UPGT_MEMORY_MAX_PAGES]; +} __packed; + +/* + * BPF + */ +struct upgt_rx_radiotap_header { + struct ieee80211_radiotap_header wr_ihdr; + uint8_t wr_flags; + uint8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + int8_t wr_antsignal; +} __packed; + +#define UPGT_RX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + +struct upgt_tx_radiotap_header { + struct ieee80211_radiotap_header wt_ihdr; + uint8_t wt_flags; + uint8_t wt_rate; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; +} __packed; + +#define UPGT_TX_RADIOTAP_PRESENT \ + ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL)) + +struct upgt_stat { + uint32_t st_tx_active; + uint32_t st_tx_inactive; + uint32_t st_tx_pending; +}; + +#define UPGT_STAT_INC(sc, var) (sc)->sc_stat.var++ +#define UPGT_STAT_DEC(sc, var) (sc)->sc_stat.var-- + +struct upgt_vap { + struct ieee80211vap vap; + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define UPGT_VAP(vap) ((struct upgt_vap *)(vap)) + +struct upgt_softc { + device_t sc_dev; + struct ifnet *sc_ifp; + struct usb2_device *sc_udev; + struct mtx sc_mtx; + struct upgt_stat sc_stat; + int sc_flags; +#define UPGT_FLAG_FWLOADED (1 << 0) +#define UPGT_FLAG_INITDONE (1 << 1) + int sc_if_flags; + int sc_debug; + + uint8_t sc_myaddr[IEEE80211_ADDR_LEN]; + + enum ieee80211_state sc_state; + int sc_arg; + int sc_led_blink; + struct callout sc_led_ch; + uint8_t sc_cur_rateset[8]; + + /* watchdog */ + int sc_tx_timer; + struct callout sc_watchdog_ch; + + /* Firmware. */ + int sc_fw_type; + /* memory addresses on device */ + uint32_t sc_memaddr_frame_start; + uint32_t sc_memaddr_frame_end; + uint32_t sc_memaddr_rx_start; + struct upgt_memory sc_memory; + + /* data which we found in the EEPROM */ + uint8_t sc_eeprom[UPGT_EEPROM_SIZE]; + uint16_t sc_eeprom_hwrx; + struct upgt_lmac_freq3 sc_eeprom_freq3[IEEE80211_CHAN_MAX]; + struct upgt_lmac_freq4 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8]; + struct upgt_lmac_freq6 sc_eeprom_freq6[IEEE80211_CHAN_MAX]; + uint8_t sc_eeprom_freq6_settings; + + /* RX/TX */ + struct usb2_xfer *sc_xfer[UPGT_N_XFERS]; + int sc_rx_no; + int sc_tx_no; + struct upgt_data sc_rx_data[UPGT_RX_MAXCOUNT]; + upgt_datahead sc_rx_active; + upgt_datahead sc_rx_inactive; + struct upgt_data sc_tx_data[UPGT_TX_MAXCOUNT]; + upgt_datahead sc_tx_active; + upgt_datahead sc_tx_inactive; + upgt_datahead sc_tx_pending; + + /* BPF */ + struct upgt_rx_radiotap_header sc_rxtap; + int sc_rxtap_len; + struct upgt_tx_radiotap_header sc_txtap; + int sc_txtap_len; +}; + +#define UPGT_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define UPGT_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define UPGT_ASSERT_LOCKED(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) diff --git a/sys/modules/usb/upgt/Makefile b/sys/modules/usb/upgt/Makefile new file mode 100644 index 000000000000..74aa1450700a --- /dev/null +++ b/sys/modules/usb/upgt/Makefile @@ -0,0 +1,10 @@ +# $FreeBSD$ + +.PATH: ${.CURDIR}/../../../dev/usb/wlan + +KMOD = if_upgt +SRCS = if_upgt.c if_upgtvar.h \ + bus_if.h device_if.h \ + opt_bus.h opt_usb.h usb_if.h usbdevs.h + +.include From 469ef3e563f0cd32a6d29c127efbfe9291064e02 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Mon, 11 May 2009 04:18:58 +0000 Subject: [PATCH 095/544] rename xdr support files to avoid conflicts when linking in to the kernel --- .../opensolaris/uts/common/rpc/{xdr.c => opensolaris_xdr.c} | 0 .../uts/common/rpc/{xdr_array.c => opensolaris_xdr_array.c} | 0 .../uts/common/rpc/{xdr_mem.c => opensolaris_xdr_mem.c} | 0 sys/modules/zfs/Makefile | 6 +++--- 4 files changed, 3 insertions(+), 3 deletions(-) rename sys/cddl/contrib/opensolaris/uts/common/rpc/{xdr.c => opensolaris_xdr.c} (100%) rename sys/cddl/contrib/opensolaris/uts/common/rpc/{xdr_array.c => opensolaris_xdr_array.c} (100%) rename sys/cddl/contrib/opensolaris/uts/common/rpc/{xdr_mem.c => opensolaris_xdr_mem.c} (100%) diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c similarity index 100% rename from sys/cddl/contrib/opensolaris/uts/common/rpc/xdr.c rename to sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr.c diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_array.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c similarity index 100% rename from sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_array.c rename to sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_array.c diff --git a/sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_mem.c b/sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c similarity index 100% rename from sys/cddl/contrib/opensolaris/uts/common/rpc/xdr_mem.c rename to sys/cddl/contrib/opensolaris/uts/common/rpc/opensolaris_xdr_mem.c diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index 87b6ea1820cf..ae7ce471d26c 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -44,9 +44,9 @@ SRCS+= nvpair_alloc_system.c SRCS+= taskq.c .PATH: ${SUNW}/uts/common/rpc -SRCS+= xdr.c -SRCS+= xdr_array.c -SRCS+= xdr_mem.c +SRCS+= opensolaris_xdr.c +SRCS+= opensolaris_xdr_array.c +SRCS+= opensolaris_xdr_mem.c .PATH: ${SUNW}/uts/common/zmod SRCS+= adler32.c From c8fb85151b79cda0e0850cf8a3d9c21f769df0c0 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 11 May 2009 04:57:40 +0000 Subject: [PATCH 096/544] Fix typo in bwi driver. --- sys/conf/files | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/conf/files b/sys/conf/files index 567f32cf40f4..9301a3db1389 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -712,9 +712,9 @@ dev/buslogic/bt_eisa.c optional bt eisa dev/buslogic/bt_isa.c optional bt isa dev/buslogic/bt_mca.c optional bt mca dev/buslogic/bt_pci.c optional bt pci -dev/bwi/bwiirf.c optional bwi dev/bwi/bwimac.c optional bwi dev/bwi/bwiphy.c optional bwi +dev/bwi/bwirf.c optional bwi dev/bwi/if_bwi.c optional bwi dev/bwi/if_bwi_pci.c optional bwi pci dev/cardbus/cardbus.c optional cardbus From c3d3fe63145aec2ab4b1606d108675a0e3d5b19b Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 11 May 2009 05:16:57 +0000 Subject: [PATCH 097/544] Revert CVS revision 1.94 (svn r16840). Current pmap implementations don't suffer from the race condition that motivated revision 1.94. Consequently, the work-around that was implemented by revision 1.94 is no longer needed. Moreover, reverting this work-around eliminates the need for vfs_busy_pages() to acquire the page queues lock when preparing a buffer for read. Reviewed by: tegge --- sys/kern/vfs_bio.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index b9ae5ca8acc8..58e349147ba6 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3519,7 +3519,8 @@ vfs_busy_pages(struct buf *bp, int clear_modify) goto retry; } bogus = 0; - vm_page_lock_queues(); + if (clear_modify) + vm_page_lock_queues(); for (i = 0; i < bp->b_npages; i++) { m = bp->b_pages[i]; @@ -3542,17 +3543,18 @@ vfs_busy_pages(struct buf *bp, int clear_modify) * It may not work properly with small-block devices. * We need to find a better way. */ - pmap_remove_all(m); - if (clear_modify) + if (clear_modify) { + pmap_remove_write(m); vfs_page_set_valid(bp, foff, m); - else if (m->valid == VM_PAGE_BITS_ALL && + } else if (m->valid == VM_PAGE_BITS_ALL && (bp->b_flags & B_CACHE) == 0) { bp->b_pages[i] = bogus_page; bogus++; } foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; } - vm_page_unlock_queues(); + if (clear_modify) + vm_page_unlock_queues(); VM_OBJECT_UNLOCK(obj); if (bogus) pmap_qenter(trunc_page((vm_offset_t)bp->b_data), From 763b218748ec43afad77fda8e0a3749e2d5d3182 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 11 May 2009 07:57:29 +0000 Subject: [PATCH 098/544] less has been updated to v429 --- release/doc/en_US.ISO8859-1/relnotes/article.sgml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index e27db7f7eb5e..babbd3d402c2 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -450,7 +450,7 @@ 4.1.23 to 4.1.28. less has been updated from - v408 to v416. + v408 to v429. ncurses has been updated from 5.6-20061217 to 5.6-20080503. From 3980a435a2f6b57287c1d66bcb9c30b3d003b1e5 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Mon, 11 May 2009 13:42:40 +0000 Subject: [PATCH 099/544] Add forgotten linux to bsd flags argument mapping into the linux_recv(). PR: kern/134276 Submitted by: Thomas Mueller Approved by: kib (mentor) MFC after: 2 weeks --- sys/compat/linux/linux_socket.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 5d77f22b2e3d..7df87e6e1de8 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -924,7 +924,7 @@ linux_recv(struct thread *td, struct linux_recv_args *args) bsd_args.s = args->s; bsd_args.buf = (caddr_t)PTRIN(args->msg); bsd_args.len = args->len; - bsd_args.flags = args->flags; + bsd_args.flags = linux_to_bsd_msg_flags(args->flags); bsd_args.from = NULL; bsd_args.fromlenaddr = 0; return (recvfrom(td, &bsd_args)); From 03cc95d21a36ab2a353cbbfbcfbc5d83e4f4a6e1 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Mon, 11 May 2009 13:50:42 +0000 Subject: [PATCH 100/544] Translate l_timeval arg to native struct timeval in linux_setsockopt()/linux_getsockopt() for SO_RCVTIMEO, SO_SNDTIMEO opts as l_timeval has MD members. Remove bogus __packed attribute from l_timeval struct on __amd64__. PR: kern/134276 Submitted by: Thomas Mueller Approved by: kib (mentor) MFC after: 2 weeks --- sys/amd64/linux32/linux.h | 2 +- sys/compat/linux/linux_socket.c | 40 +++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 78abf63f38a7..59970fdd3ce9 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -96,7 +96,7 @@ typedef struct { typedef struct { l_time_t tv_sec; l_suseconds_t tv_usec; -} __packed l_timeval; +} l_timeval; #define l_fd_set fd_set diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 7df87e6e1de8..bb2090c77725 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1278,6 +1278,8 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) caddr_t val; int valsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; int error, name; bsd_args.s = args->s; @@ -1285,6 +1287,23 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args) switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + error = copyin(PTRIN(args->optval), &linux_tv, + sizeof(linux_tv)); + if (error) + return (error); + tv.tv_sec = linux_tv.tv_sec; + tv.tv_usec = linux_tv.tv_usec; + return (kern_setsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, sizeof(tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); @@ -1333,6 +1352,9 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) caddr_t val; int *avalsize; } */ bsd_args; + l_timeval linux_tv; + struct timeval tv; + socklen_t tv_len; int error, name; bsd_args.s = args->s; @@ -1340,6 +1362,24 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) switch (bsd_args.level) { case SOL_SOCKET: name = linux_to_bsd_so_sockopt(args->optname); + switch (name) { + case SO_RCVTIMEO: + /* FALLTHROUGH */ + case SO_SNDTIMEO: + tv_len = sizeof(tv); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &tv, UIO_SYSSPACE, &tv_len); + if (error) + return (error); + linux_tv.tv_sec = tv.tv_sec; + linux_tv.tv_usec = tv.tv_usec; + return (copyout(&linux_tv, PTRIN(args->optval), + sizeof(linux_tv))); + /* NOTREACHED */ + break; + default: + break; + } break; case IPPROTO_IP: name = linux_to_bsd_ip_sockopt(args->optname); From dfd233edd5040ed82a16a0074e220188e2c67ad4 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 11 May 2009 15:33:26 +0000 Subject: [PATCH 101/544] Remove the thread argument from the FSD (File-System Dependent) parts of the VFS. Now all the VFS_* functions and relating parts don't want the context as long as it always refers to curthread. In some points, in particular when dealing with VOPs and functions living in the same namespace (eg. vflush) which still need to be converted, pass curthread explicitly in order to retain the old behaviour. Such loose ends will be fixed ASAP. While here fix a bug: now, UFS_EXTATTR can be compiled alone without the UFS_EXTATTR_AUTOSTART option. VFS KPI is heavilly changed by this commit so thirdy parts modules needs to be recompiled. Bump __FreeBSD_version in order to signal such situation. --- .../opensolaris/kern/opensolaris_lookup.c | 3 +- .../compat/opensolaris/kern/opensolaris_vfs.c | 6 +-- .../uts/common/fs/zfs/zfs_ctldir.c | 4 +- .../uts/common/fs/zfs/zfs_vfsops.c | 29 +++++++------- sys/fs/cd9660/cd9660_vfsops.c | 18 ++++----- sys/fs/coda/coda_vfsops.c | 20 +++++----- sys/fs/devfs/devfs.h | 3 +- sys/fs/devfs/devfs_vfsops.c | 14 +++---- sys/fs/devfs/devfs_vnops.c | 21 ++++------ sys/fs/fdescfs/fdesc.h | 2 +- sys/fs/fdescfs/fdesc_vfsops.c | 22 +++++------ sys/fs/fdescfs/fdesc_vnops.c | 7 ++-- sys/fs/hpfs/hpfs_vfsops.c | 22 +++++------ sys/fs/msdosfs/msdosfs_vfsops.c | 25 +++++++----- sys/fs/nfs/nfs_commonsubs.c | 16 ++++---- sys/fs/nfs/nfs_var.h | 2 +- sys/fs/nfsclient/nfs_clvfsops.c | 23 ++++++++--- sys/fs/nfsserver/nfs_nfsdport.c | 7 +--- sys/fs/nfsserver/nfs_nfsdserv.c | 4 +- sys/fs/ntfs/ntfs_vfsops.c | 22 +++++------ sys/fs/nullfs/null_vfsops.c | 31 ++++++--------- sys/fs/nwfs/nwfs_vfsops.c | 28 ++++++++------ sys/fs/portalfs/portal_vfsops.c | 17 ++++----- sys/fs/pseudofs/pseudofs.c | 13 ++++--- sys/fs/pseudofs/pseudofs.h | 18 ++++----- sys/fs/smbfs/smbfs_vfsops.c | 26 ++++++++----- sys/fs/tmpfs/tmpfs.h | 4 +- sys/fs/tmpfs/tmpfs_subr.c | 12 +++--- sys/fs/tmpfs/tmpfs_vfsops.c | 25 ++++++------ sys/fs/tmpfs/tmpfs_vnops.c | 9 ++--- sys/fs/udf/udf_vfsops.c | 12 +++--- sys/fs/unionfs/union_vfsops.c | 29 +++++++------- sys/geom/journal/g_journal.c | 2 +- sys/gnu/fs/ext2fs/ext2_vfsops.c | 23 ++++++----- sys/gnu/fs/reiserfs/reiserfs_vfsops.c | 19 +++++----- sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c | 29 ++++++-------- sys/kern/kern_acct.c | 2 +- sys/kern/uipc_mqueue.c | 11 +++--- sys/kern/vfs_default.c | 20 ++++------ sys/kern/vfs_export.c | 2 +- sys/kern/vfs_extattr.c | 2 +- sys/kern/vfs_lookup.c | 7 ++-- sys/kern/vfs_mount.c | 37 +++++++++--------- sys/kern/vfs_subr.c | 4 +- sys/kern/vfs_syscalls.c | 14 +++---- sys/kern/vfs_vnops.c | 3 +- sys/nfs4client/nfs4_vfsops.c | 23 ++++++----- sys/nfsclient/nfs.h | 2 +- sys/nfsclient/nfs_vfsops.c | 27 ++++++++----- sys/nfsserver/nfs_serv.c | 4 +- sys/security/audit/audit_worker.c | 2 +- sys/sys/mount.h | 38 +++++++++---------- sys/sys/param.h | 2 +- sys/ufs/ffs/ffs_vfsops.c | 29 +++++++------- sys/ufs/ufs/extattr.h | 2 +- sys/ufs/ufs/ufs_extattr.c | 7 +++- sys/ufs/ufs/ufs_vfsops.c | 8 ++-- 57 files changed, 412 insertions(+), 401 deletions(-) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c index 47df799b20b2..ba7902781e16 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c @@ -66,7 +66,6 @@ lookupnameat(char *dirname, enum uio_seg seg, enum symfollow follow, int traverse(vnode_t **cvpp, int lktype) { - kthread_t *td = curthread; vnode_t *cvp; vnode_t *tvp; vfs_t *vfsp; @@ -101,7 +100,7 @@ traverse(vnode_t **cvpp, int lktype) * The read lock must be held across the call to VFS_ROOT() to * prevent a concurrent unmount from destroying the vfs. */ - error = VFS_ROOT(vfsp, lktype, &tvp, td); + error = VFS_ROOT(vfsp, lktype, &tvp); if (error != 0) return (error); cvp = tvp; diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 045b8aa2f6c2..a716b6395fbd 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -160,14 +160,14 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, */ cr = td->td_ucred; td->td_ucred = kcred; - error = VFS_MOUNT(mp, td); + error = VFS_MOUNT(mp); td->td_ucred = cr; if (!error) { if (mp->mnt_opt != NULL) vfs_freeopts(mp->mnt_opt); mp->mnt_opt = mp->mnt_optnew; - (void)VFS_STATFS(mp, &mp->mnt_stat, td); + (void)VFS_STATFS(mp, &mp->mnt_stat); } /* * Prevent external consumers of mount options from reading @@ -192,7 +192,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); mtx_unlock(&mountlist_mtx); vfs_event_signal(NULL, VQ_MOUNT, 0); - if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp, td)) + if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp)) panic("mount: lost mount"); mountcheckdirs(vp, mvp); vput(mvp); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c index 654d2f949b3f..eef1d21bb972 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c @@ -180,7 +180,7 @@ zfsctl_create(zfsvfs_t *zfsvfs) zcp = vp->v_data; zcp->zc_id = ZFSCTL_INO_ROOT; - VERIFY(VFS_ROOT(zfsvfs->z_vfs, LK_EXCLUSIVE, &rvp, curthread) == 0); + VERIFY(VFS_ROOT(zfsvfs->z_vfs, LK_EXCLUSIVE, &rvp) == 0); ZFS_TIME_DECODE(&zcp->zc_cmtime, VTOZ(rvp)->z_phys->zp_crtime); VN_URELE(rvp); @@ -415,7 +415,7 @@ zfsctl_root_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, pathname_t *pnp, ZFS_ENTER(zfsvfs); if (strcmp(nm, "..") == 0) { - err = VFS_ROOT(dvp->v_vfsp, LK_EXCLUSIVE, vpp, curthread); + err = VFS_ROOT(dvp->v_vfsp, LK_EXCLUSIVE, vpp); if (err == 0) VOP_UNLOCK(*vpp, 0); } else { diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 5becdb46a9f1..835aa532327a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -91,12 +91,12 @@ static int zfs_version_zpl = ZPL_VERSION; SYSCTL_INT(_vfs_zfs_version, OID_AUTO, zpl, CTLFLAG_RD, &zfs_version_zpl, 0, "ZPL_VERSION"); -static int zfs_mount(vfs_t *vfsp, kthread_t *td); -static int zfs_umount(vfs_t *vfsp, int fflag, kthread_t *td); -static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp, kthread_t *td); -static int zfs_statfs(vfs_t *vfsp, struct statfs *statp, kthread_t *td); +static int zfs_mount(vfs_t *vfsp); +static int zfs_umount(vfs_t *vfsp, int fflag); +static int zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp); +static int zfs_statfs(vfs_t *vfsp, struct statfs *statp); static int zfs_vget(vfs_t *vfsp, ino_t ino, int flags, vnode_t **vpp); -static int zfs_sync(vfs_t *vfsp, int waitfor, kthread_t *td); +static int zfs_sync(vfs_t *vfsp, int waitfor); static int zfs_fhtovp(vfs_t *vfsp, fid_t *fidp, vnode_t **vpp); static void zfs_objset_close(zfsvfs_t *zfsvfs); static void zfs_freevfs(vfs_t *vfsp); @@ -122,7 +122,7 @@ static uint32_t zfs_active_fs_count = 0; /*ARGSUSED*/ static int -zfs_sync(vfs_t *vfsp, int waitfor, kthread_t *td) +zfs_sync(vfs_t *vfsp, int waitfor) { /* @@ -139,7 +139,7 @@ zfs_sync(vfs_t *vfsp, int waitfor, kthread_t *td) zfsvfs_t *zfsvfs = vfsp->vfs_data; int error; - error = vfs_stdsync(vfsp, waitfor, td); + error = vfs_stdsync(vfsp, waitfor); if (error != 0) return (error); @@ -688,8 +688,9 @@ zfs_unregister_callbacks(zfsvfs_t *zfsvfs) /*ARGSUSED*/ static int -zfs_mount(vfs_t *vfsp, kthread_t *td) +zfs_mount(vfs_t *vfsp) { + kthread_t *td = curthread; vnode_t *mvp = vfsp->mnt_vnodecovered; cred_t *cr = td->td_ucred; char *osname; @@ -782,7 +783,7 @@ zfs_mount(vfs_t *vfsp, kthread_t *td) } static int -zfs_statfs(vfs_t *vfsp, struct statfs *statp, kthread_t *td) +zfs_statfs(vfs_t *vfsp, struct statfs *statp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; uint64_t refdbytes, availbytes, usedobjs, availobjs; @@ -840,7 +841,7 @@ zfs_statfs(vfs_t *vfsp, struct statfs *statp, kthread_t *td) } static int -zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp, kthread_t *td) +zfs_root(vfs_t *vfsp, int flags, vnode_t **vpp) { zfsvfs_t *zfsvfs = vfsp->vfs_data; znode_t *rootzp; @@ -957,11 +958,11 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting) /*ARGSUSED*/ static int -zfs_umount(vfs_t *vfsp, int fflag, kthread_t *td) +zfs_umount(vfs_t *vfsp, int fflag) { zfsvfs_t *zfsvfs = vfsp->vfs_data; objset_t *os; - cred_t *cr = td->td_ucred; + cred_t *cr = curthread->td_ucred; int ret; if (fflag & MS_FORCE) { @@ -992,7 +993,7 @@ zfs_umount(vfs_t *vfsp, int fflag, kthread_t *td) if (zfsvfs->z_ctldir != NULL) { if ((ret = zfsctl_umount_snapshots(vfsp, fflag, cr)) != 0) return (ret); - ret = vflush(vfsp, 0, 0, td); + ret = vflush(vfsp, 0, 0, curthread); ASSERT(ret == EBUSY); if (!(fflag & MS_FORCE)) { if (zfsvfs->z_ctldir->v_count > 1) @@ -1006,7 +1007,7 @@ zfs_umount(vfs_t *vfsp, int fflag, kthread_t *td) /* * Flush all the files. */ - ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, td); + ret = vflush(vfsp, 1, (fflag & MS_FORCE) ? FORCECLOSE : 0, curthread); if (ret != 0) { if (!zfsvfs->z_issnap) { zfsctl_create(zfsvfs); diff --git a/sys/fs/cd9660/cd9660_vfsops.c b/sys/fs/cd9660/cd9660_vfsops.c index 95a9a23e9c87..b4c65e109291 100644 --- a/sys/fs/cd9660/cd9660_vfsops.c +++ b/sys/fs/cd9660/cd9660_vfsops.c @@ -95,7 +95,7 @@ static int iso_mountfs(struct vnode *devvp, struct mount *mp); */ static int -cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +cd9660_cmount(struct mntarg *ma, void *data, int flags) { struct iso_args args; int error; @@ -123,15 +123,18 @@ cd9660_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) } static int -cd9660_mount(struct mount *mp, struct thread *td) +cd9660_mount(struct mount *mp) { struct vnode *devvp; + struct thread *td; char *fspec; int error; accmode_t accmode; struct nameidata ndp; struct iso_mnt *imp = 0; + td = curthread; + /* * Unconditionally mount as read-only. */ @@ -490,17 +493,16 @@ iso_mountfs(devvp, mp) * unmount system call */ static int -cd9660_unmount(mp, mntflags, td) +cd9660_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { struct iso_mnt *isomp; int error, flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - if ((error = vflush(mp, 0, flags, td))) + if ((error = vflush(mp, 0, flags, curthread))) return (error); isomp = VFSTOISOFS(mp); @@ -530,11 +532,10 @@ cd9660_unmount(mp, mntflags, td) * Return root of a filesystem */ static int -cd9660_root(mp, flags, vpp, td) +cd9660_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct iso_mnt *imp = VFSTOISOFS(mp); struct iso_directory_record *dp = @@ -553,10 +554,9 @@ cd9660_root(mp, flags, vpp, td) * Get filesystem statistics. */ static int -cd9660_statfs(mp, sbp, td) +cd9660_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { struct iso_mnt *isomp; diff --git a/sys/fs/coda/coda_vfsops.c b/sys/fs/coda/coda_vfsops.c index 5ce6499e179b..b12c43bc3626 100644 --- a/sys/fs/coda/coda_vfsops.c +++ b/sys/fs/coda/coda_vfsops.c @@ -106,7 +106,7 @@ static const char *coda_opts[] = { "from", NULL }; */ /*ARGSUSED*/ int -coda_mount(struct mount *vfsp, struct thread *td) +coda_mount(struct mount *vfsp) { struct vnode *dvp; struct cnode *cp; @@ -136,7 +136,7 @@ coda_mount(struct mount *vfsp, struct thread *td) /* * Validate mount device. Similar to getmdev(). */ - NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, td); + NDINIT(&ndp, LOOKUP, FOLLOW, UIO_SYSSPACE, from, curthread); error = namei(&ndp); dvp = ndp.ni_vp; if (error) { @@ -206,7 +206,7 @@ coda_mount(struct mount *vfsp, struct thread *td) } int -coda_unmount(struct mount *vfsp, int mntflags, struct thread *td) +coda_unmount(struct mount *vfsp, int mntflags) { struct coda_mntinfo *mi = vftomi(vfsp); int active, error = 0; @@ -232,7 +232,7 @@ coda_unmount(struct mount *vfsp, int mntflags, struct thread *td) vrele(coda_ctlvp); coda_ctlvp = NULL; active = coda_kill(vfsp, NOT_DOWNCALL); - error = vflush(mi->mi_vfsp, 0, FORCECLOSE, td); + error = vflush(mi->mi_vfsp, 0, FORCECLOSE, curthread); #ifdef CODA_VERBOSE printf("coda_unmount: active = %d, vflush active %d\n", active, error); @@ -262,15 +262,17 @@ coda_unmount(struct mount *vfsp, int mntflags, struct thread *td) * Find root of cfs. */ int -coda_root(struct mount *vfsp, int flags, struct vnode **vpp, - struct thread *td) +coda_root(struct mount *vfsp, int flags, struct vnode **vpp) { struct coda_mntinfo *mi = vftomi(vfsp); int error; - struct proc *p = td->td_proc; + struct proc *p; + struct thread *td; CodaFid VFid; static const CodaFid invalfid = INVAL_FID; + td = curthread; + p = td->td_proc; ENTRY; MARK_ENTRY(CODA_ROOT_STATS); if (vfsp == mi->mi_vfsp) { @@ -345,7 +347,7 @@ coda_root(struct mount *vfsp, int flags, struct vnode **vpp, * Get filesystem statistics. */ int -coda_statfs(struct mount *vfsp, struct statfs *sbp, struct thread *td) +coda_statfs(struct mount *vfsp, struct statfs *sbp) { ENTRY; @@ -377,7 +379,7 @@ coda_statfs(struct mount *vfsp, struct statfs *sbp, struct thread *td) * Flush any pending I/O. */ int -coda_sync(struct mount *vfsp, int waitfor, struct thread *td) +coda_sync(struct mount *vfsp, int waitfor) { ENTRY; diff --git a/sys/fs/devfs/devfs.h b/sys/fs/devfs/devfs.h index 1050ba5fa155..524bec830173 100644 --- a/sys/fs/devfs/devfs.h +++ b/sys/fs/devfs/devfs.h @@ -172,7 +172,8 @@ extern unsigned devfs_rule_depth; void devfs_rules_apply(struct devfs_mount *dm, struct devfs_dirent *de); void devfs_rules_cleanup (struct devfs_mount *dm); int devfs_rules_ioctl(struct devfs_mount *dm, u_long cmd, caddr_t data, struct thread *td); -int devfs_allocv (struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td); +int devfs_allocv (struct devfs_dirent *de, struct mount *mp, + struct vnode **vpp); void devfs_delete(struct devfs_mount *dm, struct devfs_dirent *de, int vp_locked); void devfs_dirent_free(struct devfs_dirent *de); void devfs_populate (struct devfs_mount *dm); diff --git a/sys/fs/devfs/devfs_vfsops.c b/sys/fs/devfs/devfs_vfsops.c index 9a9bc3850010..ff86e36859fe 100644 --- a/sys/fs/devfs/devfs_vfsops.c +++ b/sys/fs/devfs/devfs_vfsops.c @@ -60,7 +60,7 @@ static vfs_statfs_t devfs_statfs; * Mount the filesystem */ static int -devfs_mount(struct mount *mp, struct thread *td) +devfs_mount(struct mount *mp) { int error; struct devfs_mount *fmp; @@ -92,7 +92,7 @@ devfs_mount(struct mount *mp, struct thread *td) fmp->dm_rootdir = devfs_vmkdir(fmp, NULL, 0, NULL, DEVFS_ROOTINO); - error = devfs_root(mp, LK_EXCLUSIVE, &rvp, td); + error = devfs_root(mp, LK_EXCLUSIVE, &rvp); if (error) { sx_destroy(&fmp->dm_lock); free_unr(devfs_unr, fmp->dm_idx); @@ -115,7 +115,7 @@ devfs_unmount_final(struct devfs_mount *fmp) } static int -devfs_unmount(struct mount *mp, int mntflags, struct thread *td) +devfs_unmount(struct mount *mp, int mntflags) { int error; int flags = 0; @@ -127,7 +127,7 @@ devfs_unmount(struct mount *mp, int mntflags, struct thread *td) KASSERT(fmp->dm_mount != NULL, ("devfs_unmount unmounted devfs_mount")); /* There is 1 extra root vnode reference from devfs_mount(). */ - error = vflush(mp, 1, flags, td); + error = vflush(mp, 1, flags, curthread); if (error) return (error); sx_xlock(&fmp->dm_lock); @@ -147,7 +147,7 @@ devfs_unmount(struct mount *mp, int mntflags, struct thread *td) /* Return locked reference to root. */ static int -devfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +devfs_root(struct mount *mp, int flags, struct vnode **vpp) { int error; struct vnode *vp; @@ -155,7 +155,7 @@ devfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) dmp = VFSTODEVFS(mp); sx_xlock(&dmp->dm_lock); - error = devfs_allocv(dmp->dm_rootdir, mp, &vp, td); + error = devfs_allocv(dmp->dm_rootdir, mp, &vp); if (error) return (error); vp->v_vflag |= VV_ROOT; @@ -164,7 +164,7 @@ devfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) } static int -devfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +devfs_statfs(struct mount *mp, struct statfs *sbp) { sbp->f_flags = 0; diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index 215f9438f4de..ece95597375e 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -330,14 +330,13 @@ devfs_insmntque_dtr(struct vnode *vp, void *arg) * it on return. */ int -devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, struct thread *td) +devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp) { int error; struct vnode *vp; struct cdev *dev; struct devfs_mount *dmp; - KASSERT(td == curthread, ("devfs_allocv: td != curthread")); dmp = VFSTODEVFS(mp); if (de->de_flags & DE_DOOMED) { sx_xunlock(&dmp->dm_lock); @@ -351,7 +350,7 @@ devfs_allocv(struct devfs_dirent *de, struct mount *mp, struct vnode **vpp, stru VI_LOCK(vp); mtx_unlock(&devfs_de_interlock); sx_xunlock(&dmp->dm_lock); - error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td); + error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, curthread); sx_xlock(&dmp->dm_lock); if (devfs_allocv_drop_refs(0, dmp, de)) { if (error == 0) @@ -761,7 +760,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) de = TAILQ_FIRST(&dd->de_dlist); /* "." */ de = TAILQ_NEXT(de, de_list); /* ".." */ de = de->de_dir; - error = devfs_allocv(de, dvp->v_mount, vpp, td); + error = devfs_allocv(de, dvp->v_mount, vpp); *dm_unlock = 0; vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); return (error); @@ -844,7 +843,7 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock) return (0); } } - error = devfs_allocv(de, dvp->v_mount, vpp, td); + error = devfs_allocv(de, dvp->v_mount, vpp); *dm_unlock = 0; return (error); } @@ -870,7 +869,6 @@ devfs_mknod(struct vop_mknod_args *ap) { struct componentname *cnp; struct vnode *dvp, **vpp; - struct thread *td; struct devfs_dirent *dd, *de; struct devfs_mount *dmp; int error; @@ -886,7 +884,6 @@ devfs_mknod(struct vop_mknod_args *ap) cnp = ap->a_cnp; vpp = ap->a_vpp; - td = cnp->cn_thread; dd = dvp->v_data; error = ENOENT; @@ -904,7 +901,7 @@ devfs_mknod(struct vop_mknod_args *ap) if (de == NULL) goto notfound; de->de_flags &= ~DE_WHITEOUT; - error = devfs_allocv(de, dvp->v_mount, vpp, td); + error = devfs_allocv(de, dvp->v_mount, vpp); return (error); notfound: sx_xunlock(&dmp->dm_lock); @@ -1427,12 +1424,8 @@ devfs_symlink(struct vop_symlink_args *ap) struct devfs_dirent *dd; struct devfs_dirent *de; struct devfs_mount *dmp; - struct thread *td; - td = ap->a_cnp->cn_thread; - KASSERT(td == curthread, ("devfs_symlink: td != curthread")); - - error = priv_check(td, PRIV_DEVFS_SYMLINK); + error = priv_check(curthread, PRIV_DEVFS_SYMLINK); if (error) return(error); dmp = VFSTODEVFS(ap->a_dvp->v_mount); @@ -1451,7 +1444,7 @@ devfs_symlink(struct vop_symlink_args *ap) mac_devfs_create_symlink(ap->a_cnp->cn_cred, dmp->dm_mount, dd, de); #endif TAILQ_INSERT_TAIL(&dd->de_dlist, de, de_list); - return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp, td)); + return (devfs_allocv(de, ap->a_dvp->v_mount, ap->a_vpp)); } static int diff --git a/sys/fs/fdescfs/fdesc.h b/sys/fs/fdescfs/fdesc.h index 06f53fb2ce86..477193aebc0d 100644 --- a/sys/fs/fdescfs/fdesc.h +++ b/sys/fs/fdescfs/fdesc.h @@ -65,5 +65,5 @@ extern struct mtx fdesc_hashmtx; extern vfs_init_t fdesc_init; extern vfs_uninit_t fdesc_uninit; extern int fdesc_allocvp(fdntype, unsigned, int, struct mount *, - struct vnode **, struct thread *); + struct vnode **); #endif /* _KERNEL */ diff --git a/sys/fs/fdescfs/fdesc_vfsops.c b/sys/fs/fdescfs/fdesc_vfsops.c index 96513130ce20..fdbcaba043be 100644 --- a/sys/fs/fdescfs/fdesc_vfsops.c +++ b/sys/fs/fdescfs/fdesc_vfsops.c @@ -64,7 +64,7 @@ static vfs_root_t fdesc_root; * Compatibility shim for old mount(2) system call. */ int -fdesc_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +fdesc_cmount(struct mntarg *ma, void *data, int flags) { return kernel_mount(ma, flags); } @@ -73,7 +73,7 @@ fdesc_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) * Mount the per-process file descriptors (/dev/fd) */ static int -fdesc_mount(struct mount *mp, struct thread *td) +fdesc_mount(struct mount *mp) { int error = 0; struct fdescmount *fmp; @@ -94,7 +94,7 @@ fdesc_mount(struct mount *mp, struct thread *td) */ mp->mnt_data = (qaddr_t) fmp; fmp->flags = 0; - error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp, td); + error = fdesc_allocvp(Froot, -1, FD_ROOT, mp, &rvp); if (error) { free(fmp, M_FDESCMNT); mp->mnt_data = 0; @@ -116,10 +116,9 @@ fdesc_mount(struct mount *mp, struct thread *td) } static int -fdesc_unmount(mp, mntflags, td) +fdesc_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { struct fdescmount *fmp; caddr_t data; @@ -143,7 +142,7 @@ fdesc_unmount(mp, mntflags, td) * There is 1 extra root vnode reference corresponding * to f_root. */ - if ((error = vflush(mp, 1, flags, td)) != 0) + if ((error = vflush(mp, 1, flags, curthread)) != 0) return (error); /* @@ -160,11 +159,10 @@ fdesc_unmount(mp, mntflags, td) } static int -fdesc_root(mp, flags, vpp, td) +fdesc_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct vnode *vp; @@ -172,23 +170,25 @@ fdesc_root(mp, flags, vpp, td) * Return locked reference to root. */ vp = VFSTOFDESC(mp)->f_root; - vget(vp, LK_EXCLUSIVE | LK_RETRY, td); + vget(vp, LK_EXCLUSIVE | LK_RETRY, curthread); *vpp = vp; return (0); } static int -fdesc_statfs(mp, sbp, td) +fdesc_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { + struct thread *td; struct filedesc *fdp; int lim; int i; int last; int freefd; + td = curthread; + /* * Compute number of free file descriptors. * [ Strange results will ensue if the open file diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index d1788ae43490..9857d937f67f 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -145,20 +145,21 @@ fdesc_remove_entry(struct fdescnode *fd) } int -fdesc_allocvp(ftype, fd_fd, ix, mp, vpp, td) +fdesc_allocvp(ftype, fd_fd, ix, mp, vpp) fdntype ftype; unsigned fd_fd; int ix; struct mount *mp; struct vnode **vpp; - struct thread *td; { struct fdescmount *fmp; struct fdhashhead *fc; struct fdescnode *fd, *fd2; struct vnode *vp, *vp2; + struct thread *td; int error = 0; + td = curthread; fc = FD_NHASH(ix); loop: mtx_lock(&fdesc_hashmtx); @@ -328,7 +329,7 @@ fdesc_lookup(ap) vhold(dvp); VOP_UNLOCK(dvp, 0); error = fdesc_allocvp(Fdesc, fd, FD_DESC + fd, dvp->v_mount, - &fvp, td); + &fvp); fdrop(fp, td); /* * The root vnode must be locked last to prevent deadlock condition. diff --git a/sys/fs/hpfs/hpfs_vfsops.c b/sys/fs/hpfs/hpfs_vfsops.c index a20614b3f481..9aa95ffd3c37 100644 --- a/sys/fs/hpfs/hpfs_vfsops.c +++ b/sys/fs/hpfs/hpfs_vfsops.c @@ -73,8 +73,7 @@ static int hpfs_cmount ( struct mntarg *ma, void *data, - int flags, - struct thread *td ) + int flags) { struct hpfs_args args; int error; @@ -103,16 +102,16 @@ static const char *hpfs_opts[] = { }; static int -hpfs_mount ( - struct mount *mp, - struct thread *td ) +hpfs_mount (struct mount *mp) { int err = 0, error; struct vnode *devvp; + struct thread *td; struct nameidata ndp; struct export_args export; char *from; + td = curthread; dprintf(("hpfs_omount():\n")); /* *** @@ -299,7 +298,7 @@ hpfs_mountfs(devvp, mp, td) goto failed; } - error = hpfs_root(mp, LK_EXCLUSIVE, &vp, td); + error = hpfs_root(mp, LK_EXCLUSIVE, &vp); if (error) { hpfs_cpdeinit(hpmp); hpfs_bmdeinit(hpmp); @@ -331,8 +330,7 @@ hpfs_mountfs(devvp, mp, td) static int hpfs_unmount( struct mount *mp, - int mntflags, - struct thread *td) + int mntflags) { int error, flags; register struct hpfsmount *hpmp = VFSTOHPFS(mp); @@ -345,7 +343,7 @@ hpfs_unmount( dprintf(("hpfs_unmount: vflushing...\n")); - error = vflush(mp, 0, flags, td); + error = vflush(mp, 0, flags, curthread); if (error) { printf("hpfs_unmount: vflush failed: %d\n",error); return (error); @@ -375,8 +373,7 @@ static int hpfs_root( struct mount *mp, int flags, - struct vnode **vpp, - struct thread *td ) + struct vnode **vpp) { int error = 0; struct hpfsmount *hpmp = VFSTOHPFS(mp); @@ -394,8 +391,7 @@ hpfs_root( static int hpfs_statfs( struct mount *mp, - struct statfs *sbp, - struct thread *td) + struct statfs *sbp) { struct hpfsmount *hpmp = VFSTOHPFS(mp); diff --git a/sys/fs/msdosfs/msdosfs_vfsops.c b/sys/fs/msdosfs/msdosfs_vfsops.c index 2da25a74eb24..81867634e0d5 100644 --- a/sys/fs/msdosfs/msdosfs_vfsops.c +++ b/sys/fs/msdosfs/msdosfs_vfsops.c @@ -184,7 +184,7 @@ update_mp(struct mount *mp, struct thread *td) pmp->pm_flags |= MSDOSFSMNT_LONGNAME; else { if ((error = - msdosfs_root(mp, LK_EXCLUSIVE, &rootvp, td)) != 0) + msdosfs_root(mp, LK_EXCLUSIVE, &rootvp)) != 0) return error; pmp->pm_flags |= findwin95(VTODE(rootvp)) ? MSDOSFSMNT_LONGNAME : MSDOSFSMNT_SHORTNAME; @@ -195,7 +195,7 @@ update_mp(struct mount *mp, struct thread *td) } static int -msdosfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +msdosfs_cmount(struct mntarg *ma, void *data, int flags) { struct msdosfs_args args; int error; @@ -233,9 +233,10 @@ msdosfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) * special file to treat as a filesystem. */ static int -msdosfs_mount(struct mount *mp, struct thread *td) +msdosfs_mount(struct mount *mp) { struct vnode *devvp; /* vnode for blk device to mount */ + struct thread *td; /* msdosfs specific mount control block */ struct msdosfsmount *pmp = NULL; struct nameidata ndp; @@ -243,6 +244,7 @@ msdosfs_mount(struct mount *mp, struct thread *td) accmode_t accmode; char *from; + td = curthread; if (vfs_filteropt(mp->mnt_optnew, msdosfs_opts)) return (EINVAL); @@ -265,7 +267,7 @@ msdosfs_mount(struct mount *mp, struct thread *td) } if (!(pmp->pm_flags & MSDOSFSMNT_RONLY) && vfs_flagopt(mp->mnt_optnew, "ro", NULL, 0)) { - error = VFS_SYNC(mp, MNT_WAIT, td); + error = VFS_SYNC(mp, MNT_WAIT); if (error) return (error); flags = WRITECLOSE; @@ -392,7 +394,7 @@ msdosfs_mount(struct mount *mp, struct thread *td) error = update_mp(mp, td); if (error) { if ((mp->mnt_flag & MNT_UPDATE) == 0) - msdosfs_unmount(mp, MNT_FORCE, td); + msdosfs_unmount(mp, MNT_FORCE); return error; } @@ -774,7 +776,7 @@ mountmsdosfs(struct vnode *devvp, struct mount *mp) * Unmount the filesystem described by mp. */ static int -msdosfs_unmount(struct mount *mp, int mntflags, struct thread *td) +msdosfs_unmount(struct mount *mp, int mntflags) { struct msdosfsmount *pmp; int error, flags; @@ -782,7 +784,7 @@ msdosfs_unmount(struct mount *mp, int mntflags, struct thread *td) flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - error = vflush(mp, 0, flags, td); + error = vflush(mp, 0, flags, curthread); if (error && error != ENXIO) return error; pmp = VFSTOMSDOSFS(mp); @@ -844,7 +846,7 @@ msdosfs_unmount(struct mount *mp, int mntflags, struct thread *td) } static int -msdosfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +msdosfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); struct denode *ndep; @@ -861,7 +863,7 @@ msdosfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) } static int -msdosfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +msdosfs_statfs(struct mount *mp, struct statfs *sbp) { struct msdosfsmount *pmp; @@ -877,13 +879,16 @@ msdosfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) } static int -msdosfs_sync(struct mount *mp, int waitfor, struct thread *td) +msdosfs_sync(struct mount *mp, int waitfor) { struct vnode *vp, *nvp; + struct thread *td; struct denode *dep; struct msdosfsmount *pmp = VFSTOMSDOSFS(mp); int error, allerror = 0; + td = curthread; + /* * If we ever switch to not updating all of the fats all the time, * this would be the place to update them from the first one. diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index bb1990272627..a398a72f5959 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -1446,7 +1446,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA, - USRQUOTA), cred->cr_uid, (caddr_t)&dqb, p)) + USRQUOTA), cred->cr_uid, (caddr_t)&dqb)) freenum = min(dqb.dqb_bhardlimit, freenum); p->p_cred->p_ruid = savuid; #endif /* QUOTA */ @@ -1475,7 +1475,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA, - USRQUOTA), cred->cr_uid, (caddr_t)&dqb, p)) + USRQUOTA), cred->cr_uid, (caddr_t)&dqb)) freenum = min(dqb.dqb_bsoftlimit, freenum); p->p_cred->p_ruid = savuid; #endif /* QUOTA */ @@ -1501,7 +1501,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA, - USRQUOTA), cred->cr_uid, (caddr_t)&dqb, p)) + USRQUOTA), cred->cr_uid, (caddr_t)&dqb)) freenum = dqb.dqb_curblocks; p->p_cred->p_ruid = savuid; #endif /* QUOTA */ @@ -1943,7 +1943,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp, * Get the VFS_STATFS(), since some attributes need them. */ if (NFSISSETSTATFS_ATTRBIT(retbitp)) { - error = VFS_STATFS(vnode_mount(vp), &fs, p); + error = VFS_STATFS(vnode_mount(vp), &fs); if (error != 0) { if (reterr) { nd->nd_repstat = NFSERR_ACCES; @@ -2138,7 +2138,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA), - cred->cr_uid, (caddr_t)&dqb, p)) + cred->cr_uid, (caddr_t)&dqb)) freenum = min(dqb.dqb_isoftlimit-dqb.dqb_curinodes, freenum); p->p_cred->p_ruid = savuid; @@ -2245,7 +2245,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA), - cred->cr_uid, (caddr_t)&dqb, p)) + cred->cr_uid, (caddr_t)&dqb)) freenum = min(dqb.dqb_bhardlimit, freenum); p->p_cred->p_ruid = savuid; #endif /* QUOTA */ @@ -2269,7 +2269,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA), - cred->cr_uid, (caddr_t)&dqb, p)) + cred->cr_uid, (caddr_t)&dqb)) freenum = min(dqb.dqb_bsoftlimit, freenum); p->p_cred->p_ruid = savuid; #endif /* QUOTA */ @@ -2290,7 +2290,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, vnode_t vp, NFSACL_T *saclp, savuid = p->p_cred->p_ruid; p->p_cred->p_ruid = cred->cr_uid; if (!VFS_QUOTACTL(vnode_mount(vp),QCMD(Q_GETQUOTA,USRQUOTA), - cred->cr_uid, (caddr_t)&dqb, p)) + cred->cr_uid, (caddr_t)&dqb)) freenum = dqb.dqb_curblocks; p->p_cred->p_ruid = savuid; #endif /* QUOTA */ diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 64b1e9026e6e..b41e0a679009 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -558,7 +558,7 @@ int nfsvno_rename(struct nameidata *, struct nameidata *, u_int32_t, int nfsvno_link(struct nameidata *, vnode_t, struct ucred *, NFSPROC_T *, struct nfsexstuff *); int nfsvno_fsync(vnode_t, u_int64_t, int, struct ucred *, NFSPROC_T *); -int nfsvno_statfs(vnode_t, struct statfs *, struct ucred *, NFSPROC_T *); +int nfsvno_statfs(vnode_t, struct statfs *); void nfsvno_getfs(struct nfsfsinfo *, int); void nfsvno_open(struct nfsrv_descript *, struct nameidata *, nfsquad_t, nfsv4stateid_t *, struct nfsstate *, int *, struct nfsvattr *, u_char *, diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 1ceba85b8532..66ea55b8c9ee 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -244,9 +244,10 @@ nfs_convert_diskless(void) * nfs statfs call */ static int -nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +nfs_statfs(struct mount *mp, struct statfs *sbp) { struct vnode *vp; + struct thread *td; struct nfsmount *nmp = VFSTONFS(mp); struct nfsvattr nfsva; struct nfsfsinfo fs; @@ -254,6 +255,8 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) int error = 0, attrflag, gotfsinfo = 0, ret; struct nfsnode *np; + td = curthread; + error = vfs_busy(mp, MBF_NOWAIT); if (error) return (error); @@ -659,7 +662,7 @@ static const char *nfs_opts[] = { "from", "nfs_args", */ /* ARGSUSED */ static int -nfs_mount(struct mount *mp, struct thread *td) +nfs_mount(struct mount *mp) { struct nfs_args args = { .version = NFS_ARGSVERSION, @@ -689,6 +692,7 @@ nfs_mount(struct mount *mp, struct thread *td) int error; struct sockaddr *nam; struct vnode *vp; + struct thread *td; char hst[MNAMELEN]; size_t len; u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; @@ -698,6 +702,7 @@ nfs_mount(struct mount *mp, struct thread *td) goto out; } + td = curthread; if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) { error = ncl_mountroot(mp, td); goto out; @@ -835,7 +840,7 @@ nfs_mount(struct mount *mp, struct thread *td) */ /* ARGSUSED */ static int -nfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +nfs_cmount(struct mntarg *ma, void *data, int flags) { int error; struct nfs_args args; @@ -1069,11 +1074,14 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, * unmount system call */ static int -nfs_unmount(struct mount *mp, int mntflags, struct thread *td) +nfs_unmount(struct mount *mp, int mntflags) { + struct thread *td; struct nfsmount *nmp; int error, flags = 0, trycnt = 0; + td = curthread; + if (mntflags & MNT_FORCE) flags |= FORCECLOSE; nmp = VFSTONFS(mp); @@ -1120,7 +1128,7 @@ nfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return root of a filesystem */ static int -nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +nfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct vnode *vp; struct nfsmount *nmp; @@ -1153,11 +1161,14 @@ nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) */ /* ARGSUSED */ static int -nfs_sync(struct mount *mp, int waitfor, struct thread *td) +nfs_sync(struct mount *mp, int waitfor) { struct vnode *vp, *mvp; + struct thread *td; int error, allerror = 0; + td = curthread; + /* * Force stale buffer cache information to be flushed. */ diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 09a1d73ac9da..5dbb21d3e3ab 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1257,13 +1257,10 @@ nfsvno_fsync(struct vnode *vp, u_int64_t off, int cnt, struct ucred *cred, * Statfs vnode op. */ int -nfsvno_statfs(struct vnode *vp, struct statfs *sf, struct ucred *cred, - struct thread *p) +nfsvno_statfs(struct vnode *vp, struct statfs *sf) { - int error; - error = VFS_STATFS(vp->v_mount, sf, p); - return (error); + return (VFS_STATFS(vp->v_mount, sf)); } /* diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 141a61474663..61c646c32f69 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -1907,7 +1907,7 @@ nfsrvd_statfs(struct nfsrv_descript *nd, __unused int isdgram, return (0); } sf = &sfs; - nd->nd_repstat = nfsvno_statfs(vp, sf, nd->nd_cred, p); + nd->nd_repstat = nfsvno_statfs(vp, sf); getret = nfsvno_getattr(vp, &at, nd->nd_cred, p); vput(vp); if (nd->nd_flag & ND_NFSV3) @@ -3285,7 +3285,7 @@ nfsrvd_verify(struct nfsrv_descript *nd, int isdgram, nd->nd_repstat = nfsvno_getattr(vp, &nva, nd->nd_cred, p); if (!nd->nd_repstat) - nd->nd_repstat = nfsvno_statfs(vp, &sf, nd->nd_cred, p); + nd->nd_repstat = nfsvno_statfs(vp, &sf); if (!nd->nd_repstat) nd->nd_repstat = nfsvno_getfh(vp, &fh, p); if (!nd->nd_repstat) { diff --git a/sys/fs/ntfs/ntfs_vfsops.c b/sys/fs/ntfs/ntfs_vfsops.c index 7b57949ab212..07dc2ddb2f24 100644 --- a/sys/fs/ntfs/ntfs_vfsops.c +++ b/sys/fs/ntfs/ntfs_vfsops.c @@ -117,8 +117,7 @@ static int ntfs_cmount ( struct mntarg *ma, void *data, - int flags, - struct thread *td ) + int flags) { int error; struct ntfs_args args; @@ -149,9 +148,7 @@ static const char *ntfs_opts[] = { }; static int -ntfs_mount ( - struct mount *mp, - struct thread *td ) +ntfs_mount (struct mount *mp) { int err = 0, error; struct vnode *devvp; @@ -184,7 +181,7 @@ ntfs_mount ( * Not an update, or updating the name: look up the name * and verify that it refers to a sensible block device. */ - NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, td); + NDINIT(&ndp, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, from, curthread); err = namei(&ndp); if (err) { /* can't get devvp!*/ @@ -231,7 +228,7 @@ ntfs_mount ( /* Save "mounted from" info for mount point (NULL pad)*/ vfs_mountedfrom(mp, from); - err = ntfs_mountfs(devvp, mp, td); + err = ntfs_mountfs(devvp, mp, curthread); } if (err) { vrele(devvp); @@ -471,13 +468,14 @@ ntfs_mountfs(devvp, mp, td) static int ntfs_unmount( struct mount *mp, - int mntflags, - struct thread *td) + int mntflags) { + struct thread *td; struct ntfsmount *ntmp; int error, flags, i; dprintf(("ntfs_unmount: unmounting...\n")); + td = curthread; ntmp = VFSTONTFS(mp); flags = 0; @@ -534,8 +532,7 @@ static int ntfs_root( struct mount *mp, int flags, - struct vnode **vpp, - struct thread *td ) + struct vnode **vpp) { struct vnode *nvp; int error = 0; @@ -587,8 +584,7 @@ ntfs_calccfree( static int ntfs_statfs( struct mount *mp, - struct statfs *sbp, - struct thread *td) + struct statfs *sbp) { struct ntfsmount *ntmp = VFSTONTFS(mp); u_int64_t mftsize,mftallocated; diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c index 841c9cab60d9..7bd4ab7d2794 100644 --- a/sys/fs/nullfs/null_vfsops.c +++ b/sys/fs/nullfs/null_vfsops.c @@ -69,7 +69,7 @@ static vfs_extattrctl_t nullfs_extattrctl; * Mount null layer */ static int -nullfs_mount(struct mount *mp, struct thread *td) +nullfs_mount(struct mount *mp) { int error = 0; struct vnode *lowerrootvp, *vp; @@ -115,8 +115,7 @@ nullfs_mount(struct mount *mp, struct thread *td) /* * Find lower node */ - NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF, - UIO_SYSSPACE, target, td); + NDINIT(ndp, LOOKUP, FOLLOW|LOCKLEAF, UIO_SYSSPACE, target, curthread); error = namei(ndp); /* * Re-lock vnode. @@ -200,10 +199,9 @@ nullfs_mount(struct mount *mp, struct thread *td) * Free reference to null layer */ static int -nullfs_unmount(mp, mntflags, td) +nullfs_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { void *mntdata; int error; @@ -215,7 +213,7 @@ nullfs_unmount(mp, mntflags, td) flags |= FORCECLOSE; /* There is 1 extra root vnode reference (nullm_rootvp). */ - error = vflush(mp, 1, flags, td); + error = vflush(mp, 1, flags, curthread); if (error) return (error); @@ -229,11 +227,10 @@ nullfs_unmount(mp, mntflags, td) } static int -nullfs_root(mp, flags, vpp, td) +nullfs_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct vnode *vp; @@ -257,21 +254,19 @@ nullfs_root(mp, flags, vpp, td) } static int -nullfs_quotactl(mp, cmd, uid, arg, td) +nullfs_quotactl(mp, cmd, uid, arg) struct mount *mp; int cmd; uid_t uid; void *arg; - struct thread *td; { - return VFS_QUOTACTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, uid, arg, td); + return VFS_QUOTACTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, uid, arg); } static int -nullfs_statfs(mp, sbp, td) +nullfs_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { int error; struct statfs mstat; @@ -282,7 +277,7 @@ nullfs_statfs(mp, sbp, td) bzero(&mstat, sizeof(mstat)); - error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat, td); + error = VFS_STATFS(MOUNTTONULLMOUNT(mp)->nullm_vfs, &mstat); if (error) return (error); @@ -300,10 +295,9 @@ nullfs_statfs(mp, sbp, td) } static int -nullfs_sync(mp, waitfor, td) +nullfs_sync(mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { /* * XXX - Assumes no data cached at null layer. @@ -341,16 +335,15 @@ nullfs_fhtovp(mp, fidp, vpp) } static int -nullfs_extattrctl(mp, cmd, filename_vp, namespace, attrname, td) +nullfs_extattrctl(mp, cmd, filename_vp, namespace, attrname) struct mount *mp; int cmd; struct vnode *filename_vp; int namespace; const char *attrname; - struct thread *td; { return VFS_EXTATTRCTL(MOUNTTONULLMOUNT(mp)->nullm_vfs, cmd, filename_vp, - namespace, attrname, td); + namespace, attrname); } diff --git a/sys/fs/nwfs/nwfs_vfsops.c b/sys/fs/nwfs/nwfs_vfsops.c index a7880b601afd..eed51c6b49c5 100644 --- a/sys/fs/nwfs/nwfs_vfsops.c +++ b/sys/fs/nwfs/nwfs_vfsops.c @@ -129,8 +129,7 @@ nwfs_initnls(struct nwmount *nmp) { return 0; } -static int nwfs_cmount(struct mntarg *ma, void *data, int flags, - struct thread *td) +static int nwfs_cmount(struct mntarg *ma, void *data, int flags) { struct nwfs_args args; /* will hold data from mount request */ int error; @@ -155,7 +154,7 @@ static int nwfs_cmount(struct mntarg *ma, void *data, int flags, * mp - path - addr in user space of mount point (ie /usr or whatever) * data - addr in user space of mount params */ -static int nwfs_mount(struct mount *mp, struct thread *td) +static int nwfs_mount(struct mount *mp) { struct nwfs_args args; /* will hold data from mount request */ int error; @@ -163,8 +162,10 @@ static int nwfs_mount(struct mount *mp, struct thread *td) struct ncp_conn *conn = NULL; struct ncp_handle *handle = NULL; struct vnode *vp; + struct thread *td; char *pc,*pe; + td = curthread; if (mp->mnt_flag & MNT_ROOTFS) return (EOPNOTSUPP); if (mp->mnt_flag & MNT_UPDATE) { @@ -224,7 +225,7 @@ static int nwfs_mount(struct mount *mp, struct thread *td) /* protect against invalid mount points */ nmp->m.mount_point[sizeof(nmp->m.mount_point)-1] = '\0'; vfs_getnewfsid(mp); - error = nwfs_root(mp, LK_EXCLUSIVE, &vp, td); + error = nwfs_root(mp, LK_EXCLUSIVE, &vp); if (error) goto bad; /* @@ -243,13 +244,15 @@ static int nwfs_mount(struct mount *mp, struct thread *td) /* Unmount the filesystem described by mp. */ static int -nwfs_unmount(struct mount *mp, int mntflags, struct thread *td) +nwfs_unmount(struct mount *mp, int mntflags) { + struct thread *td; struct nwmount *nmp = VFSTONWFS(mp); struct ncp_conn *conn; int error, flags; NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags); + td = curthread; flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; @@ -275,16 +278,20 @@ nwfs_unmount(struct mount *mp, int mntflags, struct thread *td) /* Return locked vnode to root of a filesystem */ static int -nwfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) { +nwfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct vnode *vp; struct nwmount *nmp; struct nwnode *np; struct ncp_conn *conn; struct nw_entry_info fattr; - struct ucred *cred = td->td_ucred; + struct thread *td; + struct ucred *cred; int error, nsf, opt; u_char vol; + td = curthread; + cred = td->td_ucred; + nmp = VFSTONWFS(mp); conn = NWFSTOCONN(nmp); if (nmp->n_root) { @@ -371,12 +378,11 @@ nwfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) { */ /* ARGSUSED */ static int -nwfs_quotactl(mp, cmd, uid, arg, td) +nwfs_quotactl(mp, cmd, uid, arg) struct mount *mp; int cmd; uid_t uid; void *arg; - struct thread *td; { NCPVODEBUG("return EOPNOTSUPP\n"); return (EOPNOTSUPP); @@ -406,12 +412,12 @@ nwfs_uninit(struct vfsconf *vfsp) * nwfs_statfs call */ int -nwfs_statfs(mp, sbp, td) +nwfs_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { struct nwmount *nmp = VFSTONWFS(mp); + struct thread *td = curthread; int error = 0, secsize; struct nwnode *np = nmp->n_root; struct ncp_volume_info vi; diff --git a/sys/fs/portalfs/portal_vfsops.c b/sys/fs/portalfs/portal_vfsops.c index c2057c67c642..a8c16c4b17fa 100644 --- a/sys/fs/portalfs/portal_vfsops.c +++ b/sys/fs/portalfs/portal_vfsops.c @@ -68,7 +68,7 @@ static const char *portal_opts[] = { }; static int -portal_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +portal_cmount(struct mntarg *ma, void *data, int flags) { struct portal_args args; int error; @@ -90,16 +90,18 @@ portal_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) * Mount the per-process file descriptors (/dev/fd) */ static int -portal_mount(struct mount *mp, struct thread *td) +portal_mount(struct mount *mp) { struct file *fp; struct portalmount *fmp; struct socket *so; struct vnode *rvp; + struct thread *td; struct portalnode *pn; int error, v; char *p; + td = curthread; if (vfs_filteropt(mp->mnt_optnew, portal_opts)) return (EINVAL); @@ -165,10 +167,9 @@ portal_mount(struct mount *mp, struct thread *td) } static int -portal_unmount(mp, mntflags, td) +portal_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { int error, flags = 0; @@ -187,7 +188,7 @@ portal_unmount(mp, mntflags, td) return (EBUSY); #endif /* There is 1 extra root vnode reference (pm_root). */ - error = vflush(mp, 1, flags, td); + error = vflush(mp, 1, flags, curthread); if (error) return (error); @@ -211,11 +212,10 @@ portal_unmount(mp, mntflags, td) } static int -portal_root(mp, flags, vpp, td) +portal_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct vnode *vp; @@ -230,10 +230,9 @@ portal_root(mp, flags, vpp, td) } static int -portal_statfs(mp, sbp, td) +portal_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { sbp->f_flags = 0; diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index f7a042603c0b..f13aa83527a3 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -299,7 +299,7 @@ pfs_destroy(struct pfs_node *pn) * Mount a pseudofs instance */ int -pfs_mount(struct pfs_info *pi, struct mount *mp, struct thread *td) +pfs_mount(struct pfs_info *pi, struct mount *mp) { struct statfs *sbp; @@ -330,7 +330,7 @@ pfs_mount(struct pfs_info *pi, struct mount *mp, struct thread *td) * Compatibility shim for old mount(2) system call */ int -pfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +pfs_cmount(struct mntarg *ma, void *data, int flags) { int error; @@ -342,11 +342,12 @@ pfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) * Unmount a pseudofs instance */ int -pfs_unmount(struct mount *mp, int mntflags, struct thread *td) +pfs_unmount(struct mount *mp, int mntflags) { int error; - error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, td); + error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, + curthread); return (error); } @@ -354,7 +355,7 @@ pfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return a root vnode */ int -pfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +pfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct pfs_info *pi; @@ -366,7 +367,7 @@ pfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) * Return filesystem stats */ int -pfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +pfs_statfs(struct mount *mp, struct statfs *sbp) { /* no-op: always called with mp->mnt_stat */ return (0); diff --git a/sys/fs/pseudofs/pseudofs.h b/sys/fs/pseudofs/pseudofs.h index c9e1697245e0..6dc55356786a 100644 --- a/sys/fs/pseudofs/pseudofs.h +++ b/sys/fs/pseudofs/pseudofs.h @@ -241,16 +241,12 @@ struct pfs_node { /* * VFS interface */ -int pfs_mount (struct pfs_info *pi, struct mount *mp, - struct thread *td); -int pfs_cmount (struct mntarg *ma, void *data, int flags, - struct thread *td); -int pfs_unmount (struct mount *mp, int mntflags, - struct thread *td); +int pfs_mount (struct pfs_info *pi, struct mount *mp); +int pfs_cmount (struct mntarg *ma, void *data, int flags); +int pfs_unmount (struct mount *mp, int mntflags); int pfs_root (struct mount *mp, int flags, - struct vnode **vpp, struct thread *td); -int pfs_statfs (struct mount *mp, struct statfs *sbp, - struct thread *td); + struct vnode **vpp); +int pfs_statfs (struct mount *mp, struct statfs *sbp); int pfs_init (struct pfs_info *pi, struct vfsconf *vfc); int pfs_uninit (struct pfs_info *pi, struct vfsconf *vfc); @@ -284,8 +280,8 @@ static struct pfs_info name##_info = { \ }; \ \ static int \ -_##name##_mount(struct mount *mp, struct thread *td) { \ - return pfs_mount(&name##_info, mp, td); \ +_##name##_mount(struct mount *mp) { \ + return pfs_mount(&name##_info, mp); \ } \ \ static int \ diff --git a/sys/fs/smbfs/smbfs_vfsops.c b/sys/fs/smbfs/smbfs_vfsops.c index 71b3960893ba..b762bde99aff 100644 --- a/sys/fs/smbfs/smbfs_vfsops.c +++ b/sys/fs/smbfs/smbfs_vfsops.c @@ -104,7 +104,7 @@ MODULE_DEPEND(smbfs, libmchain, 1, 1, 1); int smbfs_pbuf_freecnt = -1; /* start out unlimited */ static int -smbfs_cmount(struct mntarg *ma, void * data, int flags, struct thread *td) +smbfs_cmount(struct mntarg *ma, void * data, int flags) { struct smbfs_args args; int error; @@ -143,16 +143,18 @@ static const char *smbfs_opts[] = { }; static int -smbfs_mount(struct mount *mp, struct thread *td) +smbfs_mount(struct mount *mp) { struct smbmount *smp = NULL; struct smb_vc *vcp; struct smb_share *ssp = NULL; struct vnode *vp; + struct thread *td; struct smb_cred scred; int error, v; char *pc, *pe; + td = curthread; if (mp->mnt_flag & (MNT_UPDATE | MNT_ROOTFS)) return EOPNOTSUPP; @@ -249,7 +251,7 @@ smbfs_mount(struct mount *mp, struct thread *td) } } vfs_getnewfsid(mp); - error = smbfs_root(mp, LK_EXCLUSIVE, &vp, td); + error = smbfs_root(mp, LK_EXCLUSIVE, &vp); if (error) { vfs_mount_error(mp, "smbfs_root error: %d", error); goto bad; @@ -279,13 +281,15 @@ smbfs_mount(struct mount *mp, struct thread *td) /* Unmount the filesystem described by mp. */ static int -smbfs_unmount(struct mount *mp, int mntflags, struct thread *td) +smbfs_unmount(struct mount *mp, int mntflags) { + struct thread *td; struct smbmount *smp = VFSTOSMBFS(mp); struct smb_cred scred; int error, flags; SMBVDEBUG("smbfs_unmount: flags=%04x\n", mntflags); + td = curthread; flags = 0; if (mntflags & MNT_FORCE) flags |= FORCECLOSE; @@ -329,16 +333,20 @@ smbfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return locked root vnode of a filesystem */ static int -smbfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +smbfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct smbmount *smp = VFSTOSMBFS(mp); struct vnode *vp; struct smbnode *np; struct smbfattr fattr; - struct ucred *cred = td->td_ucred; + struct thread *td; + struct ucred *cred; struct smb_cred scred; int error; + td = curthread; + cred = td->td_ucred; + if (smp == NULL) { SMBERROR("smp == NULL (bug in umount)\n"); vfs_mount_error(mp, "smp == NULL (bug in umount)"); @@ -368,12 +376,11 @@ smbfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) */ /* ARGSUSED */ static int -smbfs_quotactl(mp, cmd, uid, arg, td) +smbfs_quotactl(mp, cmd, uid, arg) struct mount *mp; int cmd; uid_t uid; void *arg; - struct thread *td; { SMBVDEBUG("return EOPNOTSUPP\n"); return EOPNOTSUPP; @@ -404,8 +411,9 @@ smbfs_uninit(struct vfsconf *vfsp) * smbfs_statfs call */ int -smbfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +smbfs_statfs(struct mount *mp, struct statfs *sbp) { + struct thread *td = curthread; struct smbmount *smp = VFSTOSMBFS(mp); struct smbnode *np = smp->sm_root; struct smb_share *ssp = smp->sm_share; diff --git a/sys/fs/tmpfs/tmpfs.h b/sys/fs/tmpfs/tmpfs.h index 1ae8ca63c278..ffd705fe026d 100644 --- a/sys/fs/tmpfs/tmpfs.h +++ b/sys/fs/tmpfs/tmpfs.h @@ -394,14 +394,14 @@ struct tmpfs_fid { int tmpfs_alloc_node(struct tmpfs_mount *, enum vtype, uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *, - char *, dev_t, struct thread *, struct tmpfs_node **); + char *, dev_t, struct tmpfs_node **); void tmpfs_free_node(struct tmpfs_mount *, struct tmpfs_node *); int tmpfs_alloc_dirent(struct tmpfs_mount *, struct tmpfs_node *, const char *, uint16_t, struct tmpfs_dirent **); void tmpfs_free_dirent(struct tmpfs_mount *, struct tmpfs_dirent *, boolean_t); int tmpfs_alloc_vp(struct mount *, struct tmpfs_node *, int, - struct vnode **, struct thread *); + struct vnode **); void tmpfs_free_vp(struct vnode *); int tmpfs_alloc_file(struct vnode *, struct vnode **, struct vattr *, struct componentname *, char *); diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 3e5adf790c67..f2be735465e3 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -82,7 +82,7 @@ __FBSDID("$FreeBSD$"); int tmpfs_alloc_node(struct tmpfs_mount *tmp, enum vtype type, uid_t uid, gid_t gid, mode_t mode, struct tmpfs_node *parent, - char *target, dev_t rdev, struct thread *p, struct tmpfs_node **node) + char *target, dev_t rdev, struct tmpfs_node **node) { struct tmpfs_node *nnode; @@ -303,7 +303,7 @@ tmpfs_free_dirent(struct tmpfs_mount *tmp, struct tmpfs_dirent *de, */ int tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag, - struct vnode **vpp, struct thread *td) + struct vnode **vpp) { int error = 0; struct vnode *vp; @@ -314,7 +314,7 @@ tmpfs_alloc_vp(struct mount *mp, struct tmpfs_node *node, int lkflag, VI_LOCK(vp); TMPFS_NODE_UNLOCK(node); vholdl(vp); - (void) vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, td); + (void) vget(vp, lkflag | LK_INTERLOCK | LK_RETRY, curthread); vdrop(vp); /* @@ -482,8 +482,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, /* Allocate a node that represents the new file. */ error = tmpfs_alloc_node(tmp, vap->va_type, cnp->cn_cred->cr_uid, - dnode->tn_gid, vap->va_mode, parent, target, vap->va_rdev, - cnp->cn_thread, &node); + dnode->tn_gid, vap->va_mode, parent, target, vap->va_rdev, &node); if (error != 0) goto out; @@ -496,8 +495,7 @@ tmpfs_alloc_file(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, } /* Allocate a vnode for the new file. */ - error = tmpfs_alloc_vp(dvp->v_mount, node, LK_EXCLUSIVE, vpp, - cnp->cn_thread); + error = tmpfs_alloc_vp(dvp->v_mount, node, LK_EXCLUSIVE, vpp); if (error != 0) { tmpfs_free_dirent(tmp, de, TRUE); tmpfs_free_node(tmp, node); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 264e19f83eef..f0ae6be143e5 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -68,12 +68,11 @@ MALLOC_DEFINE(M_TMPFSNAME, "tmpfs name", "tmpfs file names"); /* --------------------------------------------------------------------- */ -static int tmpfs_mount(struct mount *, struct thread *); -static int tmpfs_unmount(struct mount *, int, struct thread *); -static int tmpfs_root(struct mount *, int flags, struct vnode **, - struct thread *); +static int tmpfs_mount(struct mount *); +static int tmpfs_unmount(struct mount *, int); +static int tmpfs_root(struct mount *, int flags, struct vnode **); static int tmpfs_fhtovp(struct mount *, struct fid *, struct vnode **); -static int tmpfs_statfs(struct mount *, struct statfs *, struct thread *); +static int tmpfs_statfs(struct mount *, struct statfs *); /* --------------------------------------------------------------------- */ @@ -178,7 +177,7 @@ tmpfs_node_fini(void *mem, int size) } static int -tmpfs_mount(struct mount *mp, struct thread *td) +tmpfs_mount(struct mount *mp) { struct tmpfs_mount *tmp; struct tmpfs_node *root; @@ -278,7 +277,7 @@ tmpfs_mount(struct mount *mp, struct thread *td) /* Allocate the root node. */ error = tmpfs_alloc_node(tmp, VDIR, root_uid, root_gid, root_mode & ALLPERMS, NULL, NULL, - VNOVAL, td, &root); + VNOVAL, &root); if (error != 0 || root == NULL) { uma_zdestroy(tmp->tm_node_pool); @@ -307,7 +306,7 @@ tmpfs_mount(struct mount *mp, struct thread *td) /* ARGSUSED2 */ static int -tmpfs_unmount(struct mount *mp, int mntflags, struct thread *l) +tmpfs_unmount(struct mount *mp, int mntflags) { int error; int flags = 0; @@ -319,7 +318,7 @@ tmpfs_unmount(struct mount *mp, int mntflags, struct thread *l) flags |= FORCECLOSE; /* Finalize all pending I/O. */ - error = vflush(mp, 0, flags, l); + error = vflush(mp, 0, flags, curthread); if (error != 0) return error; @@ -374,10 +373,10 @@ tmpfs_unmount(struct mount *mp, int mntflags, struct thread *l) /* --------------------------------------------------------------------- */ static int -tmpfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +tmpfs_root(struct mount *mp, int flags, struct vnode **vpp) { int error; - error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp, td); + error = tmpfs_alloc_vp(mp, VFS_TO_TMPFS(mp)->tm_root, flags, vpp); if (!error) (*vpp)->v_vflag |= VV_ROOT; @@ -417,7 +416,7 @@ tmpfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) TMPFS_UNLOCK(tmp); if (found) - return (tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp, curthread)); + return (tmpfs_alloc_vp(mp, node, LK_EXCLUSIVE, vpp)); return (EINVAL); } @@ -426,7 +425,7 @@ tmpfs_fhtovp(struct mount *mp, struct fid *fhp, struct vnode **vpp) /* ARGSUSED2 */ static int -tmpfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *l) +tmpfs_statfs(struct mount *mp, struct statfs *sbp) { fsfilcnt_t freenodes; struct tmpfs_mount *tmp; diff --git a/sys/fs/tmpfs/tmpfs_vnops.c b/sys/fs/tmpfs/tmpfs_vnops.c index 16dad1b7e26b..64114fa94fca 100644 --- a/sys/fs/tmpfs/tmpfs_vnops.c +++ b/sys/fs/tmpfs/tmpfs_vnops.c @@ -67,7 +67,6 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) struct vnode *dvp = v->a_dvp; struct vnode **vpp = v->a_vpp; struct componentname *cnp = v->a_cnp; - struct thread *td = cnp->cn_thread; int error; struct tmpfs_dirent *de; @@ -77,7 +76,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) *vpp = NULLVP; /* Check accessibility of requested node as a first step. */ - error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td); + error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, cnp->cn_thread); if (error != 0) goto out; @@ -94,7 +93,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) VOP_UNLOCK(dvp, 0); /* Allocate a new vnode on the matching entry. */ error = tmpfs_alloc_vp(dvp->v_mount, dnode->tn_dir.tn_parent, - cnp->cn_lkflags, vpp, td); + cnp->cn_lkflags, vpp); vn_lock(dvp, ltype | LK_RETRY); vdrop(dvp); @@ -155,7 +154,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) /* Allocate a new vnode on the matching entry. */ error = tmpfs_alloc_vp(dvp->v_mount, tnode, - cnp->cn_lkflags, vpp, td); + cnp->cn_lkflags, vpp); if (error != 0) goto out; @@ -170,7 +169,7 @@ tmpfs_lookup(struct vop_cachedlookup_args *v) cnp->cn_flags |= SAVENAME; } else { error = tmpfs_alloc_vp(dvp->v_mount, tnode, - cnp->cn_lkflags, vpp, td); + cnp->cn_lkflags, vpp); } } } diff --git a/sys/fs/udf/udf_vfsops.c b/sys/fs/udf/udf_vfsops.c index 8519a0701201..7be538436ce5 100644 --- a/sys/fs/udf/udf_vfsops.c +++ b/sys/fs/udf/udf_vfsops.c @@ -186,15 +186,17 @@ udf_uninit(struct vfsconf *foo) } static int -udf_mount(struct mount *mp, struct thread *td) +udf_mount(struct mount *mp) { struct vnode *devvp; /* vnode of the mount device */ + struct thread *td; struct udf_mnt *imp = 0; struct vfsoptlist *opts; char *fspec, *cs_disk, *cs_local; int error, len, *udf_flags; struct nameidata nd, *ndp = &nd; + td = curthread; opts = mp->mnt_optnew; /* @@ -510,7 +512,7 @@ udf_mountfs(struct vnode *devvp, struct mount *mp) }; static int -udf_unmount(struct mount *mp, int mntflags, struct thread *td) +udf_unmount(struct mount *mp, int mntflags) { struct udf_mnt *udfmp; int error, flags = 0; @@ -520,7 +522,7 @@ udf_unmount(struct mount *mp, int mntflags, struct thread *td) if (mntflags & MNT_FORCE) flags |= FORCECLOSE; - if ((error = vflush(mp, 0, flags, td))) + if ((error = vflush(mp, 0, flags, curthread))) return (error); if (udfmp->im_flags & UDFMNT_KICONV && udf_iconv) { @@ -554,7 +556,7 @@ udf_unmount(struct mount *mp, int mntflags, struct thread *td) } static int -udf_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +udf_root(struct mount *mp, int flags, struct vnode **vpp) { struct udf_mnt *udfmp; ino_t id; @@ -567,7 +569,7 @@ udf_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) } static int -udf_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +udf_statfs(struct mount *mp, struct statfs *sbp) { struct udf_mnt *udfmp; diff --git a/sys/fs/unionfs/union_vfsops.c b/sys/fs/unionfs/union_vfsops.c index d74d1eae0e26..604d4a3943f0 100644 --- a/sys/fs/unionfs/union_vfsops.c +++ b/sys/fs/unionfs/union_vfsops.c @@ -70,12 +70,13 @@ static struct vfsops unionfs_vfsops; * Mount unionfs layer. */ static int -unionfs_domount(struct mount *mp, struct thread *td) +unionfs_domount(struct mount *mp) { int error; struct vnode *lowerrootvp; struct vnode *upperrootvp; struct unionfs_mount *ump; + struct thread *td; char *target; char *tmp; char *ep; @@ -103,6 +104,7 @@ unionfs_domount(struct mount *mp, struct thread *td) copymode = UNIONFS_TRANSPARENT; /* default */ whitemode = UNIONFS_WHITE_ALWAYS; ndp = &nd; + td = curthread; if (mp->mnt_flag & MNT_ROOTFS) { vfs_mount_error(mp, "Cannot union mount root filesystem"); @@ -343,7 +345,7 @@ unionfs_domount(struct mount *mp, struct thread *td) * Free reference to unionfs layer */ static int -unionfs_unmount(struct mount *mp, int mntflags, struct thread *td) +unionfs_unmount(struct mount *mp, int mntflags) { struct unionfs_mount *ump; int error; @@ -360,7 +362,7 @@ unionfs_unmount(struct mount *mp, int mntflags, struct thread *td) flags |= FORCECLOSE; /* vflush (no need to call vrele) */ - for (freeing = 0; (error = vflush(mp, 1, flags, td)) != 0;) { + for (freeing = 0; (error = vflush(mp, 1, flags, curthread)) != 0;) { num = mp->mnt_nvnodelistsize; if (num == freeing) break; @@ -377,7 +379,7 @@ unionfs_unmount(struct mount *mp, int mntflags, struct thread *td) } static int -unionfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +unionfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct unionfs_mount *ump; struct vnode *vp; @@ -398,8 +400,7 @@ unionfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) } static int -unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, - struct thread *td) +unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg) { struct unionfs_mount *ump; @@ -408,11 +409,11 @@ unionfs_quotactl(struct mount *mp, int cmd, uid_t uid, void *arg, /* * Writing is always performed to upper vnode. */ - return (VFS_QUOTACTL(ump->um_uppervp->v_mount, cmd, uid, arg, td)); + return (VFS_QUOTACTL(ump->um_uppervp->v_mount, cmd, uid, arg)); } static int -unionfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +unionfs_statfs(struct mount *mp, struct statfs *sbp) { struct unionfs_mount *ump; int error; @@ -426,7 +427,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) bzero(&mstat, sizeof(mstat)); - error = VFS_STATFS(ump->um_lowervp->v_mount, &mstat, td); + error = VFS_STATFS(ump->um_lowervp->v_mount, &mstat); if (error) return (error); @@ -436,7 +437,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) lbsize = mstat.f_bsize; - error = VFS_STATFS(ump->um_uppervp->v_mount, &mstat, td); + error = VFS_STATFS(ump->um_uppervp->v_mount, &mstat); if (error) return (error); @@ -461,7 +462,7 @@ unionfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) } static int -unionfs_sync(struct mount *mp, int waitfor, struct thread *td) +unionfs_sync(struct mount *mp, int waitfor) { /* nothing to do */ return (0); @@ -488,7 +489,7 @@ unionfs_checkexp(struct mount *mp, struct sockaddr *nam, int *extflagsp, static int unionfs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, - int namespace, const char *attrname, struct thread *td) + int namespace, const char *attrname) { struct unionfs_mount *ump; struct unionfs_node *unp; @@ -498,10 +499,10 @@ unionfs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, if (unp->un_uppervp != NULLVP) { return (VFS_EXTATTRCTL(ump->um_uppervp->v_mount, cmd, - unp->un_uppervp, namespace, attrname, td)); + unp->un_uppervp, namespace, attrname)); } else { return (VFS_EXTATTRCTL(ump->um_lowervp->v_mount, cmd, - unp->un_lowervp, namespace, attrname, td)); + unp->un_lowervp, namespace, attrname)); } } diff --git a/sys/geom/journal/g_journal.c b/sys/geom/journal/g_journal.c index 2db236440fcd..e6592d0c82d7 100644 --- a/sys/geom/journal/g_journal.c +++ b/sys/geom/journal/g_journal.c @@ -2939,7 +2939,7 @@ g_journal_do_switch(struct g_class *classp) GJ_TIMER_STOP(1, &bt, "Msync time of %s", mountpoint); GJ_TIMER_START(1, &bt); - error = VFS_SYNC(mp, MNT_NOWAIT, curthread); + error = VFS_SYNC(mp, MNT_NOWAIT); if (error == 0) GJ_TIMER_STOP(1, &bt, "Sync time of %s", mountpoint); else { diff --git a/sys/gnu/fs/ext2fs/ext2_vfsops.c b/sys/gnu/fs/ext2fs/ext2_vfsops.c index 5f4a84afca4b..c8d79fbc7048 100644 --- a/sys/gnu/fs/ext2fs/ext2_vfsops.c +++ b/sys/gnu/fs/ext2fs/ext2_vfsops.c @@ -127,12 +127,12 @@ static const char *ext2_opts[] = { "from", "export", "acls", "noexec", * mount system call */ static int -ext2_mount(mp, td) +ext2_mount(mp) struct mount *mp; - struct thread *td; { struct vfsoptlist *opts; struct vnode *devvp; + struct thread *td; struct ext2mount *ump = 0; struct ext2_sb_info *fs; char *path, *fspec; @@ -140,6 +140,7 @@ ext2_mount(mp, td) accmode_t accmode; struct nameidata nd, *ndp = &nd; + td = curthread; opts = mp->mnt_optnew; if (vfs_filteropt(opts, ext2_opts)) @@ -165,7 +166,7 @@ ext2_mount(mp, td) error = 0; if (fs->s_rd_only == 0 && vfs_flagopt(opts, "ro", NULL, 0)) { - error = VFS_SYNC(mp, MNT_WAIT, td); + error = VFS_SYNC(mp, MNT_WAIT); if (error) return (error); flags = WRITECLOSE; @@ -734,10 +735,9 @@ ext2_mountfs(devvp, mp) * unmount system call */ static int -ext2_unmount(mp, mntflags, td) +ext2_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { struct ext2mount *ump; struct ext2_sb_info *fs; @@ -749,7 +749,7 @@ ext2_unmount(mp, mntflags, td) return (EINVAL); flags |= FORCECLOSE; } - if ((error = ext2_flushfiles(mp, flags, td)) != 0) + if ((error = ext2_flushfiles(mp, flags, curthread)) != 0) return (error); ump = VFSTOEXT2(mp); fs = ump->um_e2fs; @@ -810,10 +810,9 @@ ext2_flushfiles(mp, flags, td) * taken from ext2/super.c ext2_statfs */ static int -ext2_statfs(mp, sbp, td) +ext2_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { unsigned long overhead; struct ext2mount *ump; @@ -862,17 +861,18 @@ ext2_statfs(mp, sbp, td) * Note: we are always called with the filesystem marked `MPBUSY'. */ static int -ext2_sync(mp, waitfor, td) +ext2_sync(mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { struct vnode *mvp, *vp; + struct thread *td; struct inode *ip; struct ext2mount *ump = VFSTOEXT2(mp); struct ext2_sb_info *fs; int error, allerror = 0; + td = curthread; fs = ump->um_e2fs; if (fs->s_dirt != 0 && fs->s_rd_only != 0) { /* XXX */ printf("fs = %s\n", fs->fs_fsmnt); @@ -1143,11 +1143,10 @@ printf("\nupdating superblock, waitfor=%s\n", waitfor == MNT_WAIT ? "yes":"no"); * Return the root of a filesystem. */ static int -ext2_root(mp, flags, vpp, td) +ext2_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct vnode *nvp; int error; diff --git a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c index 6704b07b1b4f..739eff9a56bf 100644 --- a/sys/gnu/fs/reiserfs/reiserfs_vfsops.c +++ b/sys/gnu/fs/reiserfs/reiserfs_vfsops.c @@ -49,7 +49,7 @@ MALLOC_DEFINE(M_REISERFSNODE, "reiserfs_node", "ReiserFS vnode private part"); * -------------------------------------------------------------------*/ static int -reiserfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +reiserfs_cmount(struct mntarg *ma, void *data, int flags) { struct reiserfs_args args; int error; @@ -70,7 +70,7 @@ reiserfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) * Mount system call */ static int -reiserfs_mount(struct mount *mp, struct thread *td) +reiserfs_mount(struct mount *mp) { size_t size; int error, len; @@ -81,7 +81,9 @@ reiserfs_mount(struct mount *mp, struct thread *td) struct reiserfs_mount *rmp; struct reiserfs_sb_info *sbi; struct nameidata nd, *ndp = &nd; + struct thread *td; + td = curthread; if (!(mp->mnt_flag & MNT_RDONLY)) return EROFS; @@ -158,7 +160,7 @@ reiserfs_mount(struct mount *mp, struct thread *td) reiserfs_log(LOG_DEBUG, "prepare statfs data\n"); (void)copystr(fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, &size); bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - (void)reiserfs_statfs(mp, &mp->mnt_stat, td); + (void)reiserfs_statfs(mp, &mp->mnt_stat); reiserfs_log(LOG_DEBUG, "done\n"); return (0); @@ -168,7 +170,7 @@ reiserfs_mount(struct mount *mp, struct thread *td) * Unmount system call */ static int -reiserfs_unmount(struct mount *mp, int mntflags, struct thread *td) +reiserfs_unmount(struct mount *mp, int mntflags) { int error, flags = 0; struct reiserfs_mount *rmp; @@ -185,7 +187,7 @@ reiserfs_unmount(struct mount *mp, int mntflags, struct thread *td) /* Flush files -> vflush */ reiserfs_log(LOG_DEBUG, "flush vnodes\n"); - if ((error = vflush(mp, 0, flags, td))) + if ((error = vflush(mp, 0, flags, curthread))) return (error); /* XXX Super block update */ @@ -252,8 +254,7 @@ reiserfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return the root of a filesystem. */ static int -reiserfs_root(struct mount *mp, int flags, struct vnode **vpp, - struct thread *td) +reiserfs_root(struct mount *mp, int flags, struct vnode **vpp) { int error; struct vnode *vp; @@ -262,7 +263,7 @@ reiserfs_root(struct mount *mp, int flags, struct vnode **vpp, rootkey.on_disk_key.k_dir_id = REISERFS_ROOT_PARENT_OBJECTID; rootkey.on_disk_key.k_objectid = REISERFS_ROOT_OBJECTID; - error = reiserfs_iget(mp, &rootkey, &vp, td); + error = reiserfs_iget(mp, &rootkey, &vp, curthread); if (error == 0) *vpp = vp; @@ -273,7 +274,7 @@ reiserfs_root(struct mount *mp, int flags, struct vnode **vpp, * The statfs syscall */ static int -reiserfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +reiserfs_statfs(struct mount *mp, struct statfs *sbp) { struct reiserfs_mount *rmp; struct reiserfs_sb_info *sbi; diff --git a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c index 1374fa55c3c7..f89618e93d02 100644 --- a/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c +++ b/sys/gnu/fs/xfs/FreeBSD/xfs_mountops.c @@ -180,8 +180,7 @@ _xfs_param_copyin(struct mount *mp, struct thread *td) } static int -_xfs_mount(struct mount *mp, - struct thread *td) +_xfs_mount(struct mount *mp) { struct xfsmount *xmp; struct xfs_vnode *rootvp; @@ -189,8 +188,10 @@ _xfs_mount(struct mount *mp, struct vnode *rvp, *devvp; struct cdev *ddev; struct g_consumer *cp; + struct thread *td; int error; + td = curthread; ddev = NULL; cp = NULL; @@ -229,7 +230,7 @@ _xfs_mount(struct mount *mp, mp->mnt_stat.f_fsid.val[0] = dev2udev(ddev); mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum; - if ((error = VFS_STATFS(mp, &mp->mnt_stat, td)) != 0) + if ((error = VFS_STATFS(mp, &mp->mnt_stat)) != 0) goto fail_unmount; rvp = rootvp->v_vnode; @@ -263,10 +264,9 @@ _xfs_mount(struct mount *mp, * Free reference to null layer */ static int -_xfs_unmount(mp, mntflags, td) +_xfs_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { struct vnode *devvp; struct g_consumer *cp; @@ -278,7 +278,7 @@ _xfs_unmount(mp, mntflags, td) if (devvp != NULL) cp = devvp->v_bufobj.bo_private; - XVFS_UNMOUNT(MNTTOVFS(mp), 0, td->td_ucred, error); + XVFS_UNMOUNT(MNTTOVFS(mp), 0, curthread->td_ucred, error); if (error == 0) { if (cp != NULL) { DROP_GIANT(); @@ -292,11 +292,10 @@ _xfs_unmount(mp, mntflags, td) } static int -_xfs_root(mp, flags, vpp, td) +_xfs_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { xfs_vnode_t *vp; int error; @@ -310,22 +309,20 @@ _xfs_root(mp, flags, vpp, td) } static int -_xfs_quotactl(mp, cmd, uid, arg, td) +_xfs_quotactl(mp, cmd, uid, arg) struct mount *mp; int cmd; uid_t uid; void *arg; - struct thread *td; { printf("xfs_quotactl\n"); return EOPNOTSUPP; } static int -_xfs_statfs(mp, sbp, td) +_xfs_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { int error; @@ -340,10 +337,9 @@ _xfs_statfs(mp, sbp, td) } static int -_xfs_sync(mp, waitfor, td) +_xfs_sync(mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { int error; int flags = SYNC_FSDATA|SYNC_ATTR|SYNC_REFCACHE; @@ -352,7 +348,7 @@ _xfs_sync(mp, waitfor, td) flags |= SYNC_WAIT; else if (waitfor == MNT_LAZY) flags |= SYNC_BDFLUSH; - XVFS_SYNC(MNTTOVFS(mp), flags, td->td_ucred, error); + XVFS_SYNC(MNTTOVFS(mp), flags, curthread->td_ucred, error); return (error); } @@ -386,8 +382,7 @@ _xfs_fhtovp(mp, fidp, vpp) static int _xfs_extattrctl(struct mount *mp, int cm, struct vnode *filename_v, - int attrnamespace, const char *attrname, - struct thread *td) + int attrnamespace, const char *attrname) { printf("xfs_extattrctl\n"); return ENOSYS; diff --git a/sys/kern/kern_acct.c b/sys/kern/kern_acct.c index 8355ca51df41..a7ddb17cada4 100644 --- a/sys/kern/kern_acct.c +++ b/sys/kern/kern_acct.c @@ -586,7 +586,7 @@ acctwatch(void) * Stopping here is better than continuing, maybe it will be VBAD * next time around. */ - if (VFS_STATFS(acct_vp->v_mount, &sb, curthread) < 0) { + if (VFS_STATFS(acct_vp->v_mount, &sb) < 0) { VFS_UNLOCK_GIANT(vfslocked); return; } diff --git a/sys/kern/uipc_mqueue.c b/sys/kern/uipc_mqueue.c index 451f5c22ec56..9343f54c996e 100644 --- a/sys/kern/uipc_mqueue.c +++ b/sys/kern/uipc_mqueue.c @@ -561,7 +561,7 @@ mqfs_destroy(struct mqfs_node *node) * Mount a mqfs instance */ static int -mqfs_mount(struct mount *mp, struct thread *td) +mqfs_mount(struct mount *mp) { struct statfs *sbp; @@ -591,11 +591,12 @@ mqfs_mount(struct mount *mp, struct thread *td) * Unmount a mqfs instance */ static int -mqfs_unmount(struct mount *mp, int mntflags, struct thread *td) +mqfs_unmount(struct mount *mp, int mntflags) { int error; - error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, td); + error = vflush(mp, 0, (mntflags & MNT_FORCE) ? FORCECLOSE : 0, + curthread); return (error); } @@ -603,7 +604,7 @@ mqfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return a root vnode */ static int -mqfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +mqfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct mqfs_info *mqfs; int ret; @@ -617,7 +618,7 @@ mqfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) * Return filesystem stats */ static int -mqfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +mqfs_statfs(struct mount *mp, struct statfs *sbp) { /* XXX update statistics */ return (0); diff --git a/sys/kern/vfs_default.c b/sys/kern/vfs_default.c index 2fe64b3deb71..bbaca4b9f98a 100644 --- a/sys/kern/vfs_default.c +++ b/sys/kern/vfs_default.c @@ -795,47 +795,45 @@ vop_stdvptocnp(struct vop_vptocnp_args *ap) * used to fill the vfs function table to get reasonable default return values. */ int -vfs_stdroot (mp, flags, vpp, td) +vfs_stdroot (mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { return (EOPNOTSUPP); } int -vfs_stdstatfs (mp, sbp, td) +vfs_stdstatfs (mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { return (EOPNOTSUPP); } int -vfs_stdquotactl (mp, cmds, uid, arg, td) +vfs_stdquotactl (mp, cmds, uid, arg) struct mount *mp; int cmds; uid_t uid; void *arg; - struct thread *td; { return (EOPNOTSUPP); } int -vfs_stdsync(mp, waitfor, td) +vfs_stdsync(mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { struct vnode *vp, *mvp; + struct thread *td; int error, lockreq, allerror = 0; + td = curthread; lockreq = LK_EXCLUSIVE | LK_INTERLOCK; if (waitfor != MNT_WAIT) lockreq |= LK_NOWAIT; @@ -872,10 +870,9 @@ vfs_stdsync(mp, waitfor, td) } int -vfs_stdnosync (mp, waitfor, td) +vfs_stdnosync (mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { return (0); @@ -919,13 +916,12 @@ vfs_stduninit (vfsp) } int -vfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname, td) +vfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, attrname) struct mount *mp; int cmd; struct vnode *filename_vp; int attrnamespace; const char *attrname; - struct thread *td; { if (filename_vp != NULL) diff --git a/sys/kern/vfs_export.c b/sys/kern/vfs_export.c index 8e3464611ad7..6ac4cc218f92 100644 --- a/sys/kern/vfs_export.c +++ b/sys/kern/vfs_export.c @@ -361,7 +361,7 @@ vfs_setpublicfs(struct mount *mp, struct netexport *nep, bzero(&nfs_pub.np_handle, sizeof(nfs_pub.np_handle)); nfs_pub.np_handle.fh_fsid = mp->mnt_stat.f_fsid; - if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp, curthread /* XXX */))) + if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp))) return (error); if ((error = VOP_VPTOFH(rvp, &nfs_pub.np_handle.fh_fid))) diff --git a/sys/kern/vfs_extattr.c b/sys/kern/vfs_extattr.c index 18890b798d65..b75d364ee3fd 100644 --- a/sys/kern/vfs_extattr.c +++ b/sys/kern/vfs_extattr.c @@ -133,7 +133,7 @@ extattrctl(td, uap) } error = VFS_EXTATTRCTL(mp, uap->cmd, filename_vp, uap->attrnamespace, - uap->attrname != NULL ? attrname : NULL, td); + uap->attrname != NULL ? attrname : NULL); vn_finished_write(mp_writable); out: diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 757e56e7c571..6dbb8d05ad86 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -453,7 +453,6 @@ lookup(struct nameidata *ndp) int error = 0; int dpunlocked = 0; /* dp has already been unlocked */ struct componentname *cnp = &ndp->ni_cnd; - struct thread *td = cnp->cn_thread; int vfslocked; /* VFS Giant state for child */ int dvfslocked; /* VFS Giant state for parent */ int tvfslocked; @@ -637,7 +636,8 @@ lookup(struct nameidata *ndp) unionlookup: #ifdef MAC if ((cnp->cn_flags & NOMACCHECK) == 0) { - error = mac_vnode_check_lookup(td->td_ucred, dp, cnp); + error = mac_vnode_check_lookup(cnp->cn_thread->td_ucred, dp, + cnp); if (error) goto bad; } @@ -758,7 +758,8 @@ lookup(struct nameidata *ndp) dvfslocked = 0; vref(vp_crossmp); ndp->ni_dvp = vp_crossmp; - error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags), &tdp, td); + error = VFS_ROOT(mp, compute_cn_lkflags(mp, cnp->cn_lkflags), + &tdp); vfs_unbusy(mp); if (vn_lock(vp_crossmp, LK_SHARED | LK_NOWAIT)) panic("vp_crossmp exclusively locked or reclaimed"); diff --git a/sys/kern/vfs_mount.c b/sys/kern/vfs_mount.c index e4256c7f28e2..becc525a969b 100644 --- a/sys/kern/vfs_mount.c +++ b/sys/kern/vfs_mount.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #define ROOTNAME "root_device" #define VFS_MOUNTARG_SIZE_MAX (1024 * 64) +static void set_rootvnode(void); static int vfs_domount(struct thread *td, const char *fstype, char *fspath, int fsflags, void *fsdata); static int vfs_mountroot_ask(void); @@ -782,7 +783,7 @@ mount(td, uap) ma = mount_argb(ma, !(uap->flags & MNT_NOSUID), "nosuid"); ma = mount_argb(ma, !(uap->flags & MNT_NOEXEC), "noexec"); - error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags, td); + error = vfsp->vfc_vfsops->vfs_cmount(ma, uap->data, uap->flags); mtx_unlock(&Giant); return (error); } @@ -977,7 +978,7 @@ vfs_domount( * XXX The final recipients of VFS_MOUNT just overwrite the ndp they * get. No freeing of cn_pnbuf. */ - error = VFS_MOUNT(mp, td); + error = VFS_MOUNT(mp); /* * Process the export option only if we are @@ -1006,7 +1007,7 @@ vfs_domount( if (mp->mnt_opt != NULL) vfs_freeopts(mp->mnt_opt); mp->mnt_opt = mp->mnt_optnew; - (void)VFS_STATFS(mp, &mp->mnt_stat, td); + (void)VFS_STATFS(mp, &mp->mnt_stat); } /* * Prevent external consumers of mount options from reading @@ -1063,7 +1064,7 @@ vfs_domount( TAILQ_INSERT_TAIL(&mountlist, mp, mnt_list); mtx_unlock(&mountlist_mtx); vfs_event_signal(NULL, VQ_MOUNT, 0); - if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp, td)) + if (VFS_ROOT(mp, LK_EXCLUSIVE, &newdp)) panic("mount: lost mount"); mountcheckdirs(vp, newdp); vput(newdp); @@ -1269,7 +1270,7 @@ dounmount(mp, flags, td) * such references to cause an EBUSY error. */ if ((flags & MNT_FORCE) && - VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp, td) == 0) { + VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { if (mp->mnt_vnodecovered != NULL) mountcheckdirs(fsrootvp, mp->mnt_vnodecovered); if (fsrootvp == rootvnode) { @@ -1279,10 +1280,8 @@ dounmount(mp, flags, td) vput(fsrootvp); } if (((mp->mnt_flag & MNT_RDONLY) || - (error = VFS_SYNC(mp, MNT_WAIT, td)) == 0) || - (flags & MNT_FORCE)) { - error = VFS_UNMOUNT(mp, flags, td); - } + (error = VFS_SYNC(mp, MNT_WAIT)) == 0) || (flags & MNT_FORCE) != 0) + error = VFS_UNMOUNT(mp, flags); vn_finished_write(mp); /* * If we failed to flush the dirty blocks for this mount point, @@ -1292,7 +1291,7 @@ dounmount(mp, flags, td) */ if (error && error != ENXIO) { if ((flags & MNT_FORCE) && - VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp, td) == 0) { + VFS_ROOT(mp, LK_EXCLUSIVE, &fsrootvp) == 0) { if (mp->mnt_vnodecovered != NULL) mountcheckdirs(mp->mnt_vnodecovered, fsrootvp); if (rootvnode == NULL) { @@ -1464,14 +1463,14 @@ root_mount_wait(void) } static void -set_rootvnode(struct thread *td) +set_rootvnode() { struct proc *p; - if (VFS_ROOT(TAILQ_FIRST(&mountlist), LK_EXCLUSIVE, &rootvnode, td)) + if (VFS_ROOT(TAILQ_FIRST(&mountlist), LK_EXCLUSIVE, &rootvnode)) panic("Cannot find root vnode"); - p = td->td_proc; + p = curthread->td_proc; FILEDESC_XLOCK(p->p_fd); if (p->p_fd->fd_cdir != NULL) @@ -1512,7 +1511,7 @@ devfs_first(void) mp = vfs_mount_alloc(NULLVP, vfsp, "/dev", td->td_ucred); - error = VFS_MOUNT(mp, td); + error = VFS_MOUNT(mp); KASSERT(error == 0, ("VFS_MOUNT(devfs) failed %d", error)); if (error) return; @@ -1525,7 +1524,7 @@ devfs_first(void) TAILQ_INSERT_HEAD(&mountlist, mp, mnt_list); mtx_unlock(&mountlist_mtx); - set_rootvnode(td); + set_rootvnode(); error = kern_symlink(td, "/", "dev", UIO_SYSSPACE); if (error) @@ -1551,7 +1550,7 @@ devfs_fixup(struct thread *td) mtx_unlock(&mountlist_mtx); cache_purgevfs(mp); - VFS_ROOT(mp, LK_EXCLUSIVE, &dvp, td); + VFS_ROOT(mp, LK_EXCLUSIVE, &dvp); VI_LOCK(dvp); dvp->v_iflag &= ~VI_MOUNT; VI_UNLOCK(dvp); @@ -1559,7 +1558,7 @@ devfs_fixup(struct thread *td) /* Set up the real rootvnode, and purge the cache */ TAILQ_FIRST(&mountlist)->mnt_vnodecovered = NULL; - set_rootvnode(td); + set_rootvnode(); cache_purgevfs(rootvnode->v_mount); NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_SYSSPACE, "/dev", td); @@ -2176,11 +2175,11 @@ __mnt_vnode_markerfree(struct vnode **mvp, struct mount *mp) int -__vfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +__vfs_statfs(struct mount *mp, struct statfs *sbp) { int error; - error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat, td); + error = mp->mnt_op->vfs_statfs(mp, &mp->mnt_stat); if (sbp != &mp->mnt_stat) *sbp = mp->mnt_stat; return (error); diff --git a/sys/kern/vfs_subr.c b/sys/kern/vfs_subr.c index fcaf5140c691..8c26b13139bd 100644 --- a/sys/kern/vfs_subr.c +++ b/sys/kern/vfs_subr.c @@ -2404,7 +2404,7 @@ vflush( struct mount *mp, int rootrefs, int flags, struct thread *td) * Get the filesystem root vnode. We can vput() it * immediately, since with rootrefs > 0, it won't go away. */ - if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rootvp, td)) != 0) { + if ((error = VFS_ROOT(mp, LK_EXCLUSIVE, &rootvp)) != 0) { CTR2(KTR_VFS, "%s: vfs_root lookup failed with %d", __func__, error); return (error); @@ -3448,7 +3448,7 @@ sync_fsync(struct vop_fsync_args *ap) mp->mnt_kern_flag &= ~MNTK_ASYNC; MNT_IUNLOCK(mp); vfs_msync(mp, MNT_NOWAIT); - error = VFS_SYNC(mp, MNT_LAZY, ap->a_td); + error = VFS_SYNC(mp, MNT_LAZY); MNT_ILOCK(mp); mp->mnt_noasync--; if ((mp->mnt_flag & MNT_ASYNC) != 0 && mp->mnt_noasync == 0) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 202f2d119d59..98fbf1fc4dfb 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -146,7 +146,7 @@ sync(td, uap) mp->mnt_kern_flag &= ~MNTK_ASYNC; MNT_IUNLOCK(mp); vfs_msync(mp, MNT_NOWAIT); - VFS_SYNC(mp, MNT_NOWAIT, td); + VFS_SYNC(mp, MNT_NOWAIT); MNT_ILOCK(mp); mp->mnt_noasync--; if ((mp->mnt_flag & MNT_ASYNC) != 0 && @@ -215,7 +215,7 @@ quotactl(td, uap) VFS_UNLOCK_GIANT(vfslocked); return (error); } - error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg, td); + error = VFS_QUOTACTL(mp, uap->cmd, uap->uid, uap->arg); vfs_unbusy(mp); VFS_UNLOCK_GIANT(vfslocked); return (error); @@ -326,7 +326,7 @@ kern_statfs(struct thread *td, char *path, enum uio_seg pathseg, sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - error = VFS_STATFS(mp, sp, td); + error = VFS_STATFS(mp, sp); if (error) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { @@ -415,7 +415,7 @@ kern_fstatfs(struct thread *td, int fd, struct statfs *buf) sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - error = VFS_STATFS(mp, sp, td); + error = VFS_STATFS(mp, sp); if (error) goto out; if (priv_check(td, PRIV_VFS_GENERATION)) { @@ -522,7 +522,7 @@ kern_getfsstat(struct thread *td, struct statfs **buf, size_t bufsize, */ if (((flags & (MNT_LAZY|MNT_NOWAIT)) == 0 || (flags & MNT_WAIT)) && - (error = VFS_STATFS(mp, sp, td))) { + (error = VFS_STATFS(mp, sp))) { VFS_UNLOCK_GIANT(vfslocked); mtx_lock(&mountlist_mtx); nmp = TAILQ_NEXT(mp, mnt_list); @@ -766,7 +766,7 @@ fchdir(td, uap) if (vfs_busy(mp, 0)) continue; tvfslocked = VFS_LOCK_GIANT(mp); - error = VFS_ROOT(mp, LK_SHARED, &tdp, td); + error = VFS_ROOT(mp, LK_SHARED, &tdp); vfs_unbusy(mp); if (error) { VFS_UNLOCK_GIANT(tvfslocked); @@ -4638,7 +4638,7 @@ kern_fhstatfs(struct thread *td, fhandle_t fh, struct statfs *buf) sp->f_version = STATFS_VERSION; sp->f_namemax = NAME_MAX; sp->f_flags = mp->mnt_flag & MNT_VISFLAGMASK; - error = VFS_STATFS(mp, sp, td); + error = VFS_STATFS(mp, sp); if (error == 0) *buf = *sp; out: diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 00082093431d..3cc6f22bfd80 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -1107,7 +1107,6 @@ int vfs_write_suspend(mp) struct mount *mp; { - struct thread *td = curthread; int error; MNT_ILOCK(mp); @@ -1124,7 +1123,7 @@ vfs_write_suspend(mp) MNT_MTX(mp), (PUSER - 1)|PDROP, "suspwt", 0); else MNT_IUNLOCK(mp); - if ((error = VFS_SYNC(mp, MNT_SUSPEND, td)) != 0) + if ((error = VFS_SYNC(mp, MNT_SUSPEND)) != 0) vfs_write_resume(mp); return (error); } diff --git a/sys/nfs4client/nfs4_vfsops.c b/sys/nfs4client/nfs4_vfsops.c index 8980cef42709..808b63d9116a 100644 --- a/sys/nfs4client/nfs4_vfsops.c +++ b/sys/nfs4client/nfs4_vfsops.c @@ -185,9 +185,10 @@ nfs4_uninit(struct vfsconf *vfsp) * nfs statfs call */ static int -nfs4_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +nfs4_statfs(struct mount *mp, struct statfs *sbp) { struct vnode *vp; + struct thread *td; struct nfs_statfs *sfp; caddr_t bpos, dpos; struct nfsmount *nmp = VFSTONFS(mp); @@ -198,6 +199,7 @@ nfs4_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) struct nfs4_oparg_getattr ga; struct nfsv4_fattr *fap = &ga.fa; + td = curthread; #ifndef nolint sfp = NULL; #endif @@ -393,7 +395,7 @@ nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp) */ /* ARGSUSED */ static int -nfs4_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +nfs4_cmount(struct mntarg *ma, void *data, int flags) { struct nfs_args args; int error; @@ -407,7 +409,7 @@ nfs4_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) } static int -nfs4_mount(struct mount *mp, struct thread *td) +nfs4_mount(struct mount *mp) { int error; struct nfs_args args; @@ -451,7 +453,7 @@ nfs4_mount(struct mount *mp, struct thread *td) error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen); if (error) return (error); - error = mountnfs(&args, mp, nam, hst, &vp, td->td_ucred); + error = mountnfs(&args, mp, nam, hst, &vp, curthread->td_ucred); return (error); } @@ -669,7 +671,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, * unmount system call */ static int -nfs4_unmount(struct mount *mp, int mntflags, struct thread *td) +nfs4_unmount(struct mount *mp, int mntflags) { struct nfsmount *nmp; int error, flags = 0; @@ -679,7 +681,7 @@ nfs4_unmount(struct mount *mp, int mntflags, struct thread *td) nmp = VFSTONFS(mp); /* * Goes something like this.. - * - Call vflush(, td) to clear out vnodes for this filesystem + * - Call vflush to clear out vnodes for this filesystem * - Close the socket * - Free up the data structures */ @@ -691,7 +693,7 @@ nfs4_unmount(struct mount *mp, int mntflags, struct thread *td) nfs4dev_purge(); } - error = vflush(mp, 0, flags, td); + error = vflush(mp, 0, flags, curthread); if (error) return (error); @@ -713,7 +715,7 @@ nfs4_unmount(struct mount *mp, int mntflags, struct thread *td) * Return root of a filesystem */ static int -nfs4_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +nfs4_root(struct mount *mp, int flags, struct vnode **vpp) { struct vnode *vp; struct nfsmount *nmp; @@ -738,11 +740,14 @@ nfs4_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) * Flush out the buffer cache */ static int -nfs4_sync(struct mount *mp, int waitfor, struct thread *td) +nfs4_sync(struct mount *mp, int waitfor) { struct vnode *vp, *mvp; + struct thread *td; int error, allerror = 0; + td = curthread; + /* * Force stale buffer cache information to be flushed. */ diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 4dce2fe03464..7f3a0f311650 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -307,7 +307,7 @@ enum nfs_rto_timer_t { vfs_init_t nfs_init; vfs_uninit_t nfs_uninit; -int nfs_mountroot(struct mount *mp, struct thread *td); +int nfs_mountroot(struct mount *mp); #ifdef NFS_LEGACYRPC #ifndef NFS4_USE_RPCCLNT diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index 9118d302e39a..d8ce36c1584e 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -256,9 +256,10 @@ nfs_convert_diskless(void) * nfs statfs call */ static int -nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) +nfs_statfs(struct mount *mp, struct statfs *sbp) { struct vnode *vp; + struct thread *td; struct nfs_statfs *sfp; caddr_t bpos, dpos; struct nfsmount *nmp = VFSTONFS(mp); @@ -267,6 +268,7 @@ nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) struct nfsnode *np; u_quad_t tquad; + td = curthread; #ifndef nolint sfp = NULL; #endif @@ -411,8 +413,9 @@ nfs_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, * client activity occurs. */ int -nfs_mountroot(struct mount *mp, struct thread *td) +nfs_mountroot(struct mount *mp) { + struct thread *td = curthread; INIT_VPROCG(TD_TO_VPROCG(td)); struct nfsv3_diskless *nd = &nfsv3_diskless; struct socket *so; @@ -799,7 +802,7 @@ static const char *nfs_opts[] = { "from", "nfs_args", */ /* ARGSUSED */ static int -nfs_mount(struct mount *mp, struct thread *td) +nfs_mount(struct mount *mp) { struct nfs_args args = { .version = NFS_ARGSVERSION, @@ -846,7 +849,7 @@ nfs_mount(struct mount *mp, struct thread *td) } if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) { - error = nfs_mountroot(mp, td); + error = nfs_mountroot(mp); goto out; } @@ -1131,7 +1134,8 @@ nfs_mount(struct mount *mp, struct thread *td) } } } - error = mountnfs(&args, mp, nam, args.hostname, &vp, td->td_ucred); + error = mountnfs(&args, mp, nam, args.hostname, &vp, + curthread->td_ucred); out: if (!error) { MNT_ILOCK(mp); @@ -1153,7 +1157,7 @@ nfs_mount(struct mount *mp, struct thread *td) */ /* ARGSUSED */ static int -nfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +nfs_cmount(struct mntarg *ma, void *data, int flags) { int error; struct nfs_args args; @@ -1298,7 +1302,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, * unmount system call */ static int -nfs_unmount(struct mount *mp, int mntflags, struct thread *td) +nfs_unmount(struct mount *mp, int mntflags) { struct nfsmount *nmp; int error, flags = 0; @@ -1319,7 +1323,7 @@ nfs_unmount(struct mount *mp, int mntflags, struct thread *td) goto out; } /* We hold 1 extra ref on the root vnode; see comment in mountnfs(). */ - error = vflush(mp, 1, flags, td); + error = vflush(mp, 1, flags, curthread); if (error) goto out; @@ -1339,7 +1343,7 @@ nfs_unmount(struct mount *mp, int mntflags, struct thread *td) * Return root of a filesystem */ static int -nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) +nfs_root(struct mount *mp, int flags, struct vnode **vpp) { struct vnode *vp; struct nfsmount *nmp; @@ -1373,11 +1377,14 @@ nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td) */ /* ARGSUSED */ static int -nfs_sync(struct mount *mp, int waitfor, struct thread *td) +nfs_sync(struct mount *mp, int waitfor) { struct vnode *vp, *mvp; + struct thread *td; int error, allerror = 0; + td = curthread; + /* * Force stale buffer cache information to be flushed. */ diff --git a/sys/nfsserver/nfs_serv.c b/sys/nfsserver/nfs_serv.c index 5c52da6caa18..b6a61a82e8a6 100644 --- a/sys/nfsserver/nfs_serv.c +++ b/sys/nfsserver/nfs_serv.c @@ -3988,7 +3988,7 @@ nfsrv_statfs(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, goto nfsmout; } sf = &statfs; - error = VFS_STATFS(vp->v_mount, sf, curthread); + error = VFS_STATFS(vp->v_mount, sf); getret = VOP_GETATTR(vp, &at, cred); vput(vp); vp = NULL; @@ -4083,7 +4083,7 @@ nfsrv_fsinfo(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp, } /* XXX Try to make a guess on the max file size. */ - VFS_STATFS(vp->v_mount, &sb, curthread); + VFS_STATFS(vp->v_mount, &sb); maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1; getret = VOP_GETATTR(vp, &at, cred); diff --git a/sys/security/audit/audit_worker.c b/sys/security/audit/audit_worker.c index 191d583f4d74..631b29ffb34f 100644 --- a/sys/security/audit/audit_worker.c +++ b/sys/security/audit/audit_worker.c @@ -131,7 +131,7 @@ audit_record_write(struct vnode *vp, struct ucred *cred, void *data, * that we know how we're doing on space. Consider failure of these * operations to indicate a future inability to write to the file. */ - error = VFS_STATFS(vp->v_mount, mnt_stat, curthread); + error = VFS_STATFS(vp->v_mount, mnt_stat); if (error) goto fail; vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); diff --git a/sys/sys/mount.h b/sys/sys/mount.h index 45f21bc87607..ca90b19cc7d2 100644 --- a/sys/sys/mount.h +++ b/sys/sys/mount.h @@ -554,15 +554,12 @@ struct nameidata; struct sysctl_req; struct mntarg; -typedef int vfs_cmount_t(struct mntarg *ma, void *data, int flags, struct thread *td); -typedef int vfs_unmount_t(struct mount *mp, int mntflags, struct thread *td); -typedef int vfs_root_t(struct mount *mp, int flags, struct vnode **vpp, - struct thread *td); -typedef int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, - void *arg, struct thread *td); -typedef int vfs_statfs_t(struct mount *mp, struct statfs *sbp, - struct thread *td); -typedef int vfs_sync_t(struct mount *mp, int waitfor, struct thread *td); +typedef int vfs_cmount_t(struct mntarg *ma, void *data, int flags); +typedef int vfs_unmount_t(struct mount *mp, int mntflags); +typedef int vfs_root_t(struct mount *mp, int flags, struct vnode **vpp); +typedef int vfs_quotactl_t(struct mount *mp, int cmds, uid_t uid, void *arg); +typedef int vfs_statfs_t(struct mount *mp, struct statfs *sbp); +typedef int vfs_sync_t(struct mount *mp, int waitfor); typedef int vfs_vget_t(struct mount *mp, ino_t ino, int flags, struct vnode **vpp); typedef int vfs_fhtovp_t(struct mount *mp, struct fid *fhp, struct vnode **vpp); @@ -573,8 +570,8 @@ typedef int vfs_init_t(struct vfsconf *); typedef int vfs_uninit_t(struct vfsconf *); typedef int vfs_extattrctl_t(struct mount *mp, int cmd, struct vnode *filename_vp, int attrnamespace, - const char *attrname, struct thread *td); -typedef int vfs_mount_t(struct mount *mp, struct thread *td); + const char *attrname); +typedef int vfs_mount_t(struct mount *mp); typedef int vfs_sysctl_t(struct mount *mp, fsctlop_t op, struct sysctl_req *req); typedef void vfs_susp_clean_t(struct mount *mp); @@ -599,21 +596,22 @@ struct vfsops { vfs_statfs_t __vfs_statfs; -#define VFS_MOUNT(MP, P) (*(MP)->mnt_op->vfs_mount)(MP, P) -#define VFS_UNMOUNT(MP, FORCE, P) (*(MP)->mnt_op->vfs_unmount)(MP, FORCE, P) -#define VFS_ROOT(MP, FLAGS, VPP, P) \ - (*(MP)->mnt_op->vfs_root)(MP, FLAGS, VPP, P) -#define VFS_QUOTACTL(MP,C,U,A,P) (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A, P) -#define VFS_STATFS(MP, SBP, P) __vfs_statfs((MP), (SBP), (P)) -#define VFS_SYNC(MP, WAIT, P) (*(MP)->mnt_op->vfs_sync)(MP, WAIT, P) +#define VFS_MOUNT(MP) (*(MP)->mnt_op->vfs_mount)(MP) +#define VFS_UNMOUNT(MP, FORCE) (*(MP)->mnt_op->vfs_unmount)(MP, FORCE) +#define VFS_ROOT(MP, FLAGS, VPP) \ + (*(MP)->mnt_op->vfs_root)(MP, FLAGS, VPP) +#define VFS_QUOTACTL(MP, C, U, A) \ + (*(MP)->mnt_op->vfs_quotactl)(MP, C, U, A) +#define VFS_STATFS(MP, SBP) __vfs_statfs((MP), (SBP)) +#define VFS_SYNC(MP, WAIT) (*(MP)->mnt_op->vfs_sync)(MP, WAIT) #define VFS_VGET(MP, INO, FLAGS, VPP) \ (*(MP)->mnt_op->vfs_vget)(MP, INO, FLAGS, VPP) #define VFS_FHTOVP(MP, FIDP, VPP) \ (*(MP)->mnt_op->vfs_fhtovp)(MP, FIDP, VPP) #define VFS_CHECKEXP(MP, NAM, EXFLG, CRED, NUMSEC, SEC) \ (*(MP)->mnt_op->vfs_checkexp)(MP, NAM, EXFLG, CRED, NUMSEC, SEC) -#define VFS_EXTATTRCTL(MP, C, FN, NS, N, P) \ - (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N, P) +#define VFS_EXTATTRCTL(MP, C, FN, NS, N) \ + (*(MP)->mnt_op->vfs_extattrctl)(MP, C, FN, NS, N) #define VFS_SYSCTL(MP, OP, REQ) \ (*(MP)->mnt_op->vfs_sysctl)(MP, OP, REQ) #define VFS_SUSP_CLEAN(MP) \ diff --git a/sys/sys/param.h b/sys/sys/param.h index 7c77b9370ae4..3aea1012a2f9 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800086 /* Master, propagated to newvers */ +#define __FreeBSD_version 800087 /* Master, propagated to newvers */ #ifndef LOCORE #include diff --git a/sys/ufs/ffs/ffs_vfsops.c b/sys/ufs/ffs/ffs_vfsops.c index 94752c7bc832..c5c13289ba75 100644 --- a/sys/ufs/ffs/ffs_vfsops.c +++ b/sys/ufs/ffs/ffs_vfsops.c @@ -132,9 +132,10 @@ static const char *ffs_opts[] = { "acls", "async", "noatime", "noclusterr", "union", NULL }; static int -ffs_mount(struct mount *mp, struct thread *td) +ffs_mount(struct mount *mp) { struct vnode *devvp; + struct thread *td; struct ufsmount *ump = 0; struct fs *fs; int error, flags; @@ -143,6 +144,7 @@ ffs_mount(struct mount *mp, struct thread *td) struct nameidata ndp; char *fspec; + td = curthread; if (vfs_filteropt(mp->mnt_optnew, ffs_opts)) return (EINVAL); if (uma_inode == NULL) { @@ -213,7 +215,7 @@ ffs_mount(struct mount *mp, struct thread *td) * ignore the suspension to * synchronize on-disk state. */ - curthread->td_pflags |= TDP_IGNSUSP; + td->td_pflags |= TDP_IGNSUSP; break; } MNT_IUNLOCK(mp); @@ -431,7 +433,7 @@ ffs_mount(struct mount *mp, struct thread *td) */ static int -ffs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td) +ffs_cmount(struct mntarg *ma, void *data, int flags) { struct ufs_args args; int error; @@ -1025,11 +1027,11 @@ ffs_oldfscompat_write(fs, ump) * unmount system call */ static int -ffs_unmount(mp, mntflags, td) +ffs_unmount(mp, mntflags) struct mount *mp; int mntflags; - struct thread *td; { + struct thread *td; struct ufsmount *ump = VFSTOUFS(mp); struct fs *fs; int error, flags, susp; @@ -1038,6 +1040,7 @@ ffs_unmount(mp, mntflags, td) #endif flags = 0; + td = curthread; fs = ump->um_fs; if (mntflags & MNT_FORCE) { flags |= FORCECLOSE; @@ -1069,7 +1072,7 @@ ffs_unmount(mp, mntflags, td) MNTK_SUSPEND2); wakeup(&mp->mnt_flag); MNT_IUNLOCK(mp); - curthread->td_pflags |= TDP_IGNSUSP; + td->td_pflags |= TDP_IGNSUSP; break; } MNT_IUNLOCK(mp); @@ -1199,10 +1202,9 @@ ffs_flushfiles(mp, flags, td) * Get filesystem statistics. */ static int -ffs_statfs(mp, sbp, td) +ffs_statfs(mp, sbp) struct mount *mp; struct statfs *sbp; - struct thread *td; { struct ufsmount *ump; struct fs *fs; @@ -1235,12 +1237,12 @@ ffs_statfs(mp, sbp, td) * Note: we are always called with the filesystem marked `MPBUSY'. */ static int -ffs_sync(mp, waitfor, td) +ffs_sync(mp, waitfor) struct mount *mp; int waitfor; - struct thread *td; { struct vnode *mvp, *vp, *devvp; + struct thread *td; struct inode *ip; struct ufsmount *ump = VFSTOUFS(mp); struct fs *fs; @@ -1253,6 +1255,7 @@ ffs_sync(mp, waitfor, td) int softdep_accdeps; struct bufobj *bo; + td = curthread; fs = ump->um_fs; if (fs->fs_fmod != 0 && fs->fs_ronly != 0) { /* XXX */ printf("fs = %s\n", fs->fs_fsmnt); @@ -1698,15 +1701,15 @@ ffs_sbupdate(mp, waitfor, suspended) static int ffs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, - int attrnamespace, const char *attrname, struct thread *td) + int attrnamespace, const char *attrname) { #ifdef UFS_EXTATTR return (ufs_extattrctl(mp, cmd, filename_vp, attrnamespace, - attrname, td)); + attrname)); #else return (vfs_stdextattrctl(mp, cmd, filename_vp, attrnamespace, - attrname, td)); + attrname)); #endif } diff --git a/sys/ufs/ufs/extattr.h b/sys/ufs/ufs/extattr.h index 5d26bf6cd552..3716ec27309a 100644 --- a/sys/ufs/ufs/extattr.h +++ b/sys/ufs/ufs/extattr.h @@ -143,7 +143,7 @@ int ufs_extattr_start(struct mount *mp, struct thread *td); int ufs_extattr_autostart(struct mount *mp, struct thread *td); int ufs_extattr_stop(struct mount *mp, struct thread *td); int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename, - int attrnamespace, const char *attrname, struct thread *td); + int attrnamespace, const char *attrname); int ufs_getextattr(struct vop_getextattr_args *ap); int ufs_deleteextattr(struct vop_deleteextattr_args *ap); int ufs_setextattr(struct vop_setextattr_args *ap); diff --git a/sys/ufs/ufs/ufs_extattr.c b/sys/ufs/ufs/ufs_extattr.c index d034bee1f500..032d9cc34211 100644 --- a/sys/ufs/ufs/ufs_extattr.c +++ b/sys/ufs/ufs/ufs_extattr.c @@ -93,8 +93,10 @@ static int ufs_extattr_set(struct vnode *vp, int attrnamespace, struct thread *td); static int ufs_extattr_rm(struct vnode *vp, int attrnamespace, const char *name, struct ucred *cred, struct thread *td); +#ifdef UFS_EXTATTR_AUTOSTART static int ufs_extattr_autostart_locked(struct mount *mp, struct thread *td); +#endif static int ufs_extattr_start_locked(struct ufsmount *ump, struct thread *td); @@ -478,7 +480,7 @@ ufs_extattr_autostart_locked(struct mount *mp, struct thread *td) * Does UFS_EXTATTR_FSROOTSUBDIR exist off the filesystem root? * If so, automatically start EA's. */ - error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp, td); + error = VFS_ROOT(mp, LK_EXCLUSIVE, &rvp); if (error) { printf("ufs_extattr_autostart.VFS_ROOT() returned %d\n", error); @@ -714,9 +716,10 @@ ufs_extattr_disable(struct ufsmount *ump, int attrnamespace, */ int ufs_extattrctl(struct mount *mp, int cmd, struct vnode *filename_vp, - int attrnamespace, const char *attrname, struct thread *td) + int attrnamespace, const char *attrname) { struct ufsmount *ump = VFSTOUFS(mp); + struct thread *td = curthread; int error; /* diff --git a/sys/ufs/ufs/ufs_vfsops.c b/sys/ufs/ufs/ufs_vfsops.c index ac1fbcf71070..f6b6b1e2ef8c 100644 --- a/sys/ufs/ufs/ufs_vfsops.c +++ b/sys/ufs/ufs/ufs_vfsops.c @@ -66,11 +66,10 @@ MALLOC_DEFINE(M_UFSMNT, "ufs_mount", "UFS mount structure"); * Return the root of a filesystem. */ int -ufs_root(mp, flags, vpp, td) +ufs_root(mp, flags, vpp) struct mount *mp; int flags; struct vnode **vpp; - struct thread *td; { struct vnode *nvp; int error; @@ -86,18 +85,19 @@ ufs_root(mp, flags, vpp, td) * Do operations associated with quotas */ int -ufs_quotactl(mp, cmds, id, arg, td) +ufs_quotactl(mp, cmds, id, arg) struct mount *mp; int cmds; uid_t id; void *arg; - struct thread *td; { #ifndef QUOTA return (EOPNOTSUPP); #else + struct thread *td; int cmd, type, error; + td = curthread; cmd = cmds >> SUBCMDSHIFT; type = cmds & SUBCMDMASK; if (id == -1) { From 22d7ae67d4ea971ca297b7f62036bf4552973952 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 11 May 2009 16:32:58 +0000 Subject: [PATCH 102/544] Fix a kernel compilation error, introduced after r191990, by defining thread with curthread in the AUDIT case. Reported by: dchagin --- sys/kern/vfs_lookup.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 6dbb8d05ad86..a6e663a402a5 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -457,6 +457,9 @@ lookup(struct nameidata *ndp) int dvfslocked; /* VFS Giant state for parent */ int tvfslocked; int lkflags_save; +#ifdef AUDIT + struct thread *td = curthread; +#endif /* * Setup: break out flag bits into variables. From 43af51a2b5e92a4b4a9f345800a929e0dc438737 Mon Sep 17 00:00:00 2001 From: Brian Feldman Date: Mon, 11 May 2009 16:45:53 +0000 Subject: [PATCH 103/544] These are some cosmetic changes to improve the clarity of libthr's fork implementation. --- lib/libthr/thread/thr_fork.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c index afb5a1db19df..529f38f7c356 100644 --- a/lib/libthr/thread/thr_fork.c +++ b/lib/libthr/thread/thr_fork.c @@ -105,7 +105,7 @@ _fork(void) struct pthread_atfork *af; pid_t ret; int errsave; - int unlock_malloc; + int was_threaded; int rtld_locks[MAX_RTLD_LOCKS]; if (!_thr_is_inited()) @@ -122,16 +122,16 @@ _fork(void) } /* - * Try our best to protect memory from being corrupted in - * child process because another thread in malloc code will - * simply be kill by fork(). + * All bets are off as to what should happen soon if the parent + * process was not so kindly as to set up pthread fork hooks to + * relinquish all running threads. */ if (_thr_isthreaded() != 0) { - unlock_malloc = 1; + was_threaded = 1; _malloc_prefork(); _rtld_atfork_pre(rtld_locks); } else { - unlock_malloc = 0; + was_threaded = 0; } /* @@ -159,7 +159,7 @@ _fork(void) _thr_umutex_init(&curthread->lock); _thr_umutex_init(&_thr_atfork_lock); - if (unlock_malloc) + if (was_threaded) _rtld_atfork_post(rtld_locks); _thr_setthreaded(0); @@ -173,7 +173,7 @@ _fork(void) /* Ready to continue, unblock signals. */ _thr_signal_unblock(curthread); - if (unlock_malloc) { + if (was_threaded) { __isthreaded = 1; _malloc_postfork(); __isthreaded = 0; @@ -191,7 +191,7 @@ _fork(void) /* Ready to continue, unblock signals. */ _thr_signal_unblock(curthread); - if (unlock_malloc) { + if (was_threaded) { _rtld_atfork_post(rtld_locks); _malloc_postfork(); } From 75184335fec782660ac61ab2311b01d1430c5c0a Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 11 May 2009 17:05:41 +0000 Subject: [PATCH 104/544] LFS cannot be loaded, compiled, torn, spindled or mutilated in FreeBSD: it was deleted around FreeBSD 3.x... --- share/man/man5/fstab.5 | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/share/man/man5/fstab.5 b/share/man/man5/fstab.5 index 5c7406fed273..df19b9be8af4 100644 --- a/share/man/man5/fstab.5 +++ b/share/man/man5/fstab.5 @@ -80,8 +80,7 @@ Only the root, /usr, and /tmp file systems need be statically compiled into the kernel; everything else will be automatically loaded at mount time. -(Exception: the UFS family - FFS and LFS cannot -currently be demand-loaded.) +(Exception: the FFS cannot currently be demand-loaded.) Some people still prefer to statically compile other file systems as well. .Pp From d83d76df1f28484e61552e8b32f9c01bcdd476f4 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 11 May 2009 17:13:52 +0000 Subject: [PATCH 105/544] Update a few XXX comments Submitted by: ddk ddk ddkprog at yahoo dot com --- sys/dev/bwi/bwimac.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/bwi/bwimac.c b/sys/dev/bwi/bwimac.c index 4b5a20b4316e..c48d9c3a8579 100644 --- a/sys/dev/bwi/bwimac.c +++ b/sys/dev/bwi/bwimac.c @@ -300,7 +300,7 @@ bwi_mac_init(struct bwi_mac *mac) if (error) return error; - /* XXX work around for hardware bugs? */ + /* do timeout fixup */ if (sc->sc_bus_regwin.rw_rev <= 5 && sc->sc_bus_regwin.rw_type != BWI_REGWIN_T_BUSPCIE) { CSR_SETBITS_4(sc, BWI_CONF_LO, @@ -364,7 +364,7 @@ bwi_mac_init(struct bwi_mac *mac) */ bwi_mac_opmode_init(mac); - /* XXX what's these */ + /* set up Beacon interval */ if (mac->mac_rev < 3) { CSR_WRITE_2(sc, 0x60e, 0); CSR_WRITE_2(sc, 0x610, 0x8000); @@ -389,7 +389,7 @@ bwi_mac_init(struct bwi_mac *mac) CSR_WRITE_4(sc, BWI_TXRX_INTR_MASK(i), intrs); } - /* XXX what's this */ + /* allow the MAC to control the PHY clock (dynamic on/off) */ CSR_SETBITS_4(sc, BWI_STATE_LO, 0x100000); /* Setup MAC power up delay */ @@ -441,7 +441,7 @@ bwi_mac_init(struct bwi_mac *mac) } } - /* XXX what's these */ + /* update PRETBTT */ CSR_WRITE_2(sc, 0x612, 0x50); /* Force Pre-TBTT to 80? */ MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x416, 0x50); MOBJ_WRITE_2(mac, BWI_COMM_MOBJ, 0x414, 0x1f4); From 56916f026cf41926e91e2b06f1b14408424e5d33 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 11 May 2009 17:29:11 +0000 Subject: [PATCH 106/544] Always use __null to define NULL for GCC 4+. Use '0' rather than '(void *)0' for NULL for C++ compilers compiling kernel code. Together this makes it easier to build kernel modules using C++. Reviewed by: imp MFC after: 3 days --- sys/sys/_null.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/sys/_null.h b/sys/sys/_null.h index caae78133c9d..b53c1b236983 100644 --- a/sys/sys/_null.h +++ b/sys/sys/_null.h @@ -28,18 +28,18 @@ #ifndef NULL -#if defined(_KERNEL) || !defined(__cplusplus) -#define NULL ((void *)0) -#else #if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4 #define NULL __null #else +#if defined(_KERNEL) && !defined(__cplusplus) +#define NULL ((void *)0) +#else #if defined(__LP64__) #define NULL (0L) #else #define NULL 0 #endif /* __LP64__ */ +#endif /* _KERNEL && !__cplusplus */ #endif /* __GNUG__ */ -#endif /* _KERNEL || !__cplusplus */ #endif From 70839889c667b595faada0bbb777afcf1b3955c8 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 11 May 2009 18:45:04 +0000 Subject: [PATCH 107/544] Modify nfsvno_fhtovp() to ensure that it always sets the credp argument. Returning without credp set could result in a caller doing crfree() on garbage. Reviewed by: kan Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 5dbb21d3e3ab..07cbcdf92f0b 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2422,6 +2422,7 @@ nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam, int error; int numsecflavor, *secflavors; + *credp = NULL; error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); if (nam && !error) { error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp, From 7fb6f68587c6df50b08f7c11a8a56699f41a9f40 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 11 May 2009 18:52:46 +0000 Subject: [PATCH 108/544] Add macros around the sx operations in snp(4). As an experiment, I changed snp(4) to use a mutex instead of an sx lock. We can't enable this right now, because Syscons still picks up Giant. It's nice to already have the framework there. --- sys/dev/snp/snp.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c index 4a480372eba6..52c5a025b577 100644 --- a/sys/dev/snp/snp.c +++ b/sys/dev/snp/snp.c @@ -43,11 +43,22 @@ __FBSDID("$FreeBSD$"); #include static struct cdev *snp_dev; +static MALLOC_DEFINE(M_SNP, "snp", "tty snoop device"); + /* XXX: should be mtx, but TTY can be locked by Giant. */ +#if 0 +static struct mtx snp_register_lock; +MTX_SYSINIT(snp_register_lock, &snp_register_lock, + "tty snoop registration", MTX_DEF); +#define SNP_LOCK() mtx_lock(&snp_register_lock) +#define SNP_UNLOCK() mtx_unlock(&snp_register_lock) +#else static struct sx snp_register_lock; SX_SYSINIT(snp_register_lock, &snp_register_lock, "tty snoop registration"); -static MALLOC_DEFINE(M_SNP, "snp", "tty snoop device"); +#define SNP_LOCK() sx_xlock(&snp_register_lock) +#define SNP_UNLOCK() sx_xunlock(&snp_register_lock) +#endif /* * There is no need to have a big input buffer. In most typical setups, @@ -241,14 +252,14 @@ snp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, switch (cmd) { case SNPSTTY: /* Bind TTY to snoop instance. */ - sx_xlock(&snp_register_lock); + SNP_LOCK(); if (ss->snp_tty != NULL) { - sx_xunlock(&snp_register_lock); + SNP_UNLOCK(); return (EBUSY); } error = ttyhook_register(&ss->snp_tty, td->td_proc, *(int *)data, &snp_hook, ss); - sx_xunlock(&snp_register_lock); + SNP_UNLOCK(); if (error != 0) return (error); From 1c6c0ed9372ac06cdac03c2a1f18559655ecae8b Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 11 May 2009 19:37:05 +0000 Subject: [PATCH 109/544] Change the name of the nfs server addsock structure from nfsd_args to nfsd_addsock_args, so that it is consistent with the one in sys/nfsserver/nfs.h. Approved by: kib (mentor) --- sys/fs/nfs/nfs.h | 2 +- sys/fs/nfsserver/nfs_nfsdport.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 8a341ace2662..b9d030f430f9 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -157,7 +157,7 @@ * Structures for the nfssvc(2) syscall. Not that anyone but nfsd, mount_nfs * and nfsloaduser should ever try and use it. */ -struct nfsd_args { +struct nfsd_addsock_args { int sock; /* Socket to serve */ caddr_t name; /* Client addr for connection based sockets */ int namelen; /* Length of name */ diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 07cbcdf92f0b..ca0e2667ecae 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2866,7 +2866,7 @@ static int nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) { struct file *fp; - struct nfsd_args nfsdarg; + struct nfsd_addsock_args nfsdarg; int error; if (uap->flag & NFSSVC_NFSDADDSOCK) { From 3b616faed5ded69bf68eac48a02371c4b961795e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Mon, 11 May 2009 19:58:03 +0000 Subject: [PATCH 110/544] Prevent overflow of uio_resid. Noted by: jhb MFC after: 3 days --- sys/kern/vfs_syscalls.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 98fbf1fc4dfb..64ca31613197 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -2596,6 +2596,9 @@ kern_readlinkat(struct thread *td, int fd, char *path, enum uio_seg pathseg, struct nameidata nd; int vfslocked; + if (count > INT_MAX) + return (EINVAL); + NDINIT_AT(&nd, LOOKUP, NOFOLLOW | LOCKSHARED | LOCKLEAF | MPSAFE | AUDITVNODE1, pathseg, path, fd, td); From 92919e4a54c1c2df2cca7eab38c96c6916d584e1 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 11 May 2009 21:13:00 +0000 Subject: [PATCH 111/544] *sigh*, while the kernel built, userland C did not. Revert the previous commit and fix it correctly by removing the _KERNEL check entirely. Now the kernel always sees the same value of NULL as userland meaning that it sees __null, 0, or 0L when compiled as C++, and '(void *)0' when compiled as C. --- sys/sys/_null.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/sys/_null.h b/sys/sys/_null.h index b53c1b236983..ed6804ccd10e 100644 --- a/sys/sys/_null.h +++ b/sys/sys/_null.h @@ -28,18 +28,18 @@ #ifndef NULL +#if !defined(__cplusplus) +#define NULL ((void *)0) +#else #if defined(__GNUG__) && defined(__GNUC__) && __GNUC__ >= 4 #define NULL __null #else -#if defined(_KERNEL) && !defined(__cplusplus) -#define NULL ((void *)0) -#else #if defined(__LP64__) #define NULL (0L) #else #define NULL 0 #endif /* __LP64__ */ -#endif /* _KERNEL && !__cplusplus */ #endif /* __GNUG__ */ +#endif /* !__cplusplus */ #endif From 94a24e42409ec994d902a4d95521d6898cb3fb2a Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Mon, 11 May 2009 22:55:49 +0000 Subject: [PATCH 112/544] xen console lock needs to be a spin lock in case it is acquired from an interrupt context --- sys/dev/xen/console/console.c | 6 +++--- sys/dev/xen/console/xencons_ring.c | 4 ++-- sys/dev/xen/console/xencons_ring.h | 11 +++++++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index ac8ebac9edb0..5e14d486b5de 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -76,17 +76,17 @@ static unsigned int wc, wp; /* write_cons, write_prod */ #define XCUNIT(x) (dev2unit(x)) #define ISTTYOPEN(tp) ((tp) && ((tp)->t_state & TS_ISOPEN)) #define CN_LOCK_INIT(x, _name) \ - mtx_init(&x, _name, NULL, MTX_DEF|MTX_RECURSE) + mtx_init(&x, _name, NULL, MTX_SPIN|MTX_RECURSE) #define CN_LOCK(l) \ do { \ if (panicstr == NULL) \ - mtx_lock(&(l)); \ + mtx_lock_spin(&(l)); \ } while (0) #define CN_UNLOCK(l) \ do { \ if (panicstr == NULL) \ - mtx_unlock(&(l)); \ + mtx_unlock_spin(&(l)); \ } while (0) #define CN_LOCK_ASSERT(x) mtx_assert(&x, MA_OWNED) #define CN_LOCK_DESTROY(x) mtx_destroy(&x) diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c index fc9522e4f44b..a86ec5e9c2c4 100644 --- a/sys/dev/xen/console/xencons_ring.c +++ b/sys/dev/xen/console/xencons_ring.c @@ -89,7 +89,7 @@ xencons_handle_input(void *unused) struct xencons_interface *intf; XENCONS_RING_IDX cons, prod; - mtx_lock(&cn_mtx); + CN_LOCK(cn_mtx); intf = xencons_interface(); cons = intf->in_cons; @@ -107,7 +107,7 @@ xencons_handle_input(void *unused) notify_remote_via_evtchn(xen_start_info->console_evtchn); xencons_tx(); - mtx_unlock(&cn_mtx); + CN_UNLOCK(cn_mtx); } void diff --git a/sys/dev/xen/console/xencons_ring.h b/sys/dev/xen/console/xencons_ring.h index fc97d95028e2..7e3a64c9f6ff 100644 --- a/sys/dev/xen/console/xencons_ring.h +++ b/sys/dev/xen/console/xencons_ring.h @@ -5,6 +5,17 @@ #ifndef _XENCONS_RING_H #define _XENCONS_RING_H +#define CN_LOCK(l) \ + do { \ + if (panicstr == NULL) \ + mtx_lock_spin(&(l)); \ + } while (0) +#define CN_UNLOCK(l) \ + do { \ + if (panicstr == NULL) \ + mtx_unlock_spin(&(l)); \ + } while (0) + int xencons_ring_init(void); int xencons_ring_send(const char *data, unsigned len); void xencons_rx(char *buf, unsigned len); From 673d9d33eb50b27551fed81d603dcd2a52fd6f4f Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Mon, 11 May 2009 23:03:15 +0000 Subject: [PATCH 113/544] don't acquire tty lock with console lock held --- sys/dev/xen/console/console.c | 2 ++ sys/dev/xen/console/xencons_ring.c | 4 +++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 5e14d486b5de..5c16b1f5ff29 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -287,8 +287,10 @@ xencons_rx(char *buf, unsigned len) ttydisc_rint_done(tp); tty_unlock(tp); } else { + CN_LOCK(cn_mtx); for (i = 0; i < len; i++) rbuf[RBUF_MASK(rp++)] = buf[i]; + CN_UNLOCK(cn_mtx); } } diff --git a/sys/dev/xen/console/xencons_ring.c b/sys/dev/xen/console/xencons_ring.c index a86ec5e9c2c4..077d286f3fe0 100644 --- a/sys/dev/xen/console/xencons_ring.c +++ b/sys/dev/xen/console/xencons_ring.c @@ -94,7 +94,8 @@ xencons_handle_input(void *unused) cons = intf->in_cons; prod = intf->in_prod; - + CN_UNLOCK(cn_mtx); + /* XXX needs locking */ while (cons != prod) { xencons_rx(intf->in + MASK_XENCONS_IDX(cons, intf->in), 1); @@ -104,6 +105,7 @@ xencons_handle_input(void *unused) mb(); intf->in_cons = cons; + CN_LOCK(cn_mtx); notify_remote_via_evtchn(xen_start_info->console_evtchn); xencons_tx(); From 922f7c5c219449021e36b4185be369a150668911 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Tue, 12 May 2009 02:05:42 +0000 Subject: [PATCH 114/544] Add WUSB54AG and XM142 entries for upgt(4) --- sys/dev/usb/usbdevs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 73def19d63e5..89db645112e3 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1023,6 +1023,7 @@ product CHPRODUCTS FIGHTERSTICK 0x00f3 Fighterstick product CHPRODUCTS FLIGHTYOKE 0x00ff Flight Sim Yoke /* Cisco-Linksys products */ +product CISCOLINKSYS WUSB54AG 0x000c WUSB54AG Wireless Adapter product CISCOLINKSYS WUSB54G 0x000d WUSB54G Wireless Adapter product CISCOLINKSYS WUSB54GP 0x0011 WUSB54GP Wireless Adapter product CISCOLINKSYS USB200MV2 0x0018 USB200M v2 @@ -2516,6 +2517,7 @@ product ZCOM XG703A 0x0008 PrismGT USB 2.0 WLAN product ZCOM ZD1211 0x0011 ZD1211 product ZCOM AR5523 0x0012 AR5523 product ZCOM AR5523_NF 0x0013 AR5523 driver (no firmware) +product ZCOM XM142 0x0015 XM-142 product ZCOM ZD1211B 0x001a ZD1211B /* Zinwell products */ From 231a6377201a0e41d05b706b3a839c51108f0e41 Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Tue, 12 May 2009 02:08:56 +0000 Subject: [PATCH 115/544] connect upgt(4) to the build. It should work on all architectures. --- sys/modules/usb/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/usb/Makefile b/sys/modules/usb/Makefile index 44f55c6cb3a0..f35bb9bbe4ad 100644 --- a/sys/modules/usb/Makefile +++ b/sys/modules/usb/Makefile @@ -28,7 +28,7 @@ SUBDIR = usb #SUBDIR += ubt bluetooth_ng ubtfw SUBDIR += ehci musb ohci uhci uss820dci ${_at91dci} ${_atmegadci} -SUBDIR += rum uath ural zyd +SUBDIR += rum uath upgt ural zyd SUBDIR += uhid ukbd ums udbp ufm SUBDIR += ucom u3g uark ubsa ubser uchcom ucycom ufoma uftdi ugensa uipaq ulpt \ umct umodem umoscom uplcom uslcom uvisor uvscom From 24df53962eeff7790f35bc7669fc2d978cf92f4a Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Tue, 12 May 2009 03:30:25 +0000 Subject: [PATCH 116/544] fix bug introduced by last change Submitted by: Navdeep Parhar --- sys/dev/cxgb/cxgb_multiq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/cxgb/cxgb_multiq.c b/sys/dev/cxgb/cxgb_multiq.c index c55c11118a24..9882ca80bb73 100644 --- a/sys/dev/cxgb/cxgb_multiq.c +++ b/sys/dev/cxgb/cxgb_multiq.c @@ -296,7 +296,7 @@ cxgb_pcpu_start_(struct sge_qset *qs, struct mbuf *immpkt, int tx_flush) } stopped = isset(&qs->txq_stopped, TXQ_ETH); - flush = ((drbr_empty(pi->ifp, txq->txq_mr) + flush = ((!drbr_empty(pi->ifp, txq->txq_mr) && !stopped) || txq->immpkt); max_desc = tx_flush ? TX_ETH_Q_SIZE : TX_START_MAX_DESC; From 12aa4fdca9ea8e0ff4210db4dbef64c9fe5ecb23 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 12 May 2009 05:49:02 +0000 Subject: [PATCH 117/544] Eliminate gratuitous clearing of the page's dirty mask. --- sys/fs/smbfs/smbfs_io.c | 3 ++- sys/nfsclient/nfs_bio.c | 3 ++- sys/vm/vnode_pager.c | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index b0988f6bf0ed..7890f88c185f 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -517,7 +517,8 @@ smbfs_getpages(ap) * Read operation filled an entire page */ m->valid = VM_PAGE_BITS_ALL; - vm_page_undirty(m); + KASSERT(m->dirty == 0, + ("smbfs_getpages: page %p is dirty", m)); } else if (size > toff) { /* * Read operation filled a partial page. diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 0d1f3fa8ec1a..e60a20102b54 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -209,7 +209,8 @@ nfs_getpages(struct vop_getpages_args *ap) * Read operation filled an entire page */ m->valid = VM_PAGE_BITS_ALL; - vm_page_undirty(m); + KASSERT(m->dirty == 0, + ("nfs_getpages: page %p is dirty", m)); } else if (size > toff) { /* * Read operation filled a partial page. diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index 3d6909b29377..cf9dcb101051 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -762,7 +762,8 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage) return VM_PAGER_OK; } else if (reqblock == -1) { pmap_zero_page(m[reqpage]); - vm_page_undirty(m[reqpage]); + KASSERT(m[reqpage]->dirty == 0, + ("vnode_pager_generic_getpages: page %p is dirty", m)); m[reqpage]->valid = VM_PAGE_BITS_ALL; vm_page_lock_queues(); for (i = 0; i < count; i++) From ebc90701ac6c1f814c5bd6f3e19f0113ebe06156 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Tue, 12 May 2009 07:41:20 +0000 Subject: [PATCH 118/544] This patch adds a host route to an interface address (that is assigned to a non loopback/ppp link types) through the loopback interface. Prior to the new L2/L3 rewrite, this host route is implicitly added by the L2 code during RTM_RESOLVE of that interface address. This host route is deleted when that interface is removed. Reviewed by: kmacy --- sys/netinet/in.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 81803265398f..84750a6365b6 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -45,12 +45,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include +#include #include #include @@ -814,6 +817,9 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, INIT_VNET_INET(ifp->if_vnet); register u_long i = ntohl(sin->sin_addr.s_addr); struct sockaddr_in oldaddr; + struct rtentry *rt = NULL; + struct rt_addrinfo info; + static struct sockaddr_dl null_sdl = {sizeof(null_sdl), AF_LINK}; int s = splimp(), flags = RTF_UP, error = 0; oldaddr = ia->ia_addr; @@ -900,6 +906,29 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, if ((error = in_addprefix(ia, flags)) != 0) return (error); + /* + * add a loopback route to self + */ + if (!(ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { + bzero(&info, sizeof(info)); + info.rti_ifp = V_loif; + info.rti_flags = ia->ia_flags | RTF_HOST | RTF_STATIC; + info.rti_info[RTAX_DST] = (struct sockaddr *)&ia->ia_addr; + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; + error = rtrequest1_fib(RTM_ADD, &info, &rt, 0); + + if (error == 0 && rt != NULL) { + RT_LOCK(rt); + ((struct sockaddr_dl *)rt->rt_gateway)->sdl_type = + rt->rt_ifp->if_type; + ((struct sockaddr_dl *)rt->rt_gateway)->sdl_index = + rt->rt_ifp->if_index; + RT_REMREF(rt); + RT_UNLOCK(rt); + } else if (error != 0) + log(LOG_INFO, "in_ifinit: insertion failed\n"); + } + return (error); } @@ -979,10 +1008,28 @@ in_scrubprefix(struct in_ifaddr *target) struct in_ifaddr *ia; struct in_addr prefix, mask, p; int error; + struct rt_addrinfo info; + struct sockaddr_dl null_sdl; if ((target->ia_flags & IFA_ROUTE) == 0) return (0); + if (!(target->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { + bzero(&null_sdl, sizeof(null_sdl)); + null_sdl.sdl_len = sizeof(null_sdl); + null_sdl.sdl_family = AF_LINK; + null_sdl.sdl_type = V_loif->if_type; + null_sdl.sdl_index = V_loif->if_index; + bzero(&info, sizeof(info)); + info.rti_flags = target->ia_flags | RTF_HOST | RTF_STATIC; + info.rti_info[RTAX_DST] = (struct sockaddr *)&target->ia_addr; + info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&null_sdl; + error = rtrequest1_fib(RTM_DELETE, &info, NULL, 0); + + if (error != 0) + log(LOG_INFO, "in_scrubprefix: deletion failed\n"); + } + if (rtinitflags(target)) prefix = target->ia_dstaddr.sin_addr; else { @@ -1136,7 +1183,6 @@ in_purgemaddrs(struct ifnet *ifp) IN_MULTI_UNLOCK(); } -#include #include #include From ada3b6a9eade74051c907b38141ef46a2c178265 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 12 May 2009 09:22:33 +0000 Subject: [PATCH 119/544] Return controlled EINVAL when the fdescfs lookup routine is given string representing too large integer, instead of overflowing and possibly returning a random but valid vnode. Noted by: Jilles Tjoelker MFC after: 3 days --- sys/fs/fdescfs/fdesc_vnops.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 9857d937f67f..4474b1765776 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -265,7 +265,7 @@ fdesc_lookup(ap) struct thread *td = cnp->cn_thread; struct file *fp; int nlen = cnp->cn_namelen; - u_int fd; + u_int fd, fd1; int error; struct vnode *fvp; @@ -297,7 +297,12 @@ fdesc_lookup(ap) error = ENOENT; goto bad; } - fd = 10 * fd + *pname++ - '0'; + fd1 = 10 * fd + *pname++ - '0'; + if (fd1 < fd) { + error = ENOENT; + goto bad; + } + fd = fd1; } if ((error = fget(td, fd, &fp)) != 0) From 3fe65eb8fe59a17f65ff667b8aa30d543d62b221 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Tue, 12 May 2009 09:28:45 +0000 Subject: [PATCH 120/544] Report all fdescfs vnodes as VCHR for stat(2). Fake the unique major/minor numbers of the devices. Pretending that the vnodes are character devices prevents file tree walkers from descending into the directories opened by current process. Also, not doing stat on the filedescriptors prevents the recursive entry into the VFS. Requested by: kientzle Discussed with: Jilles Tjoelker --- sys/fs/fdescfs/fdesc_vnops.c | 85 +++++++++--------------------------- 1 file changed, 20 insertions(+), 65 deletions(-) diff --git a/sys/fs/fdescfs/fdesc_vnops.c b/sys/fs/fdescfs/fdesc_vnops.c index 4474b1765776..07b2547b1757 100644 --- a/sys/fs/fdescfs/fdesc_vnops.c +++ b/sys/fs/fdescfs/fdesc_vnops.c @@ -389,78 +389,34 @@ fdesc_getattr(ap) { struct vnode *vp = ap->a_vp; struct vattr *vap = ap->a_vap; - struct thread *td = curthread; - struct file *fp; - struct stat stb; - u_int fd; - int error = 0; + + vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; + vap->va_fileid = VTOFDESC(vp)->fd_ix; + vap->va_uid = 0; + vap->va_gid = 0; + vap->va_blocksize = DEV_BSIZE; + vap->va_atime.tv_sec = boottime.tv_sec; + vap->va_atime.tv_nsec = 0; + vap->va_mtime = vap->va_atime; + vap->va_ctime = vap->va_mtime; + vap->va_gen = 0; + vap->va_flags = 0; + vap->va_bytes = 0; + vap->va_filerev = 0; switch (VTOFDESC(vp)->fd_type) { case Froot: - vap->va_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; vap->va_type = VDIR; vap->va_nlink = 2; vap->va_size = DEV_BSIZE; - vap->va_fileid = VTOFDESC(vp)->fd_ix; - vap->va_uid = 0; - vap->va_gid = 0; - vap->va_blocksize = DEV_BSIZE; - vap->va_atime.tv_sec = boottime.tv_sec; - vap->va_atime.tv_nsec = 0; - vap->va_mtime = vap->va_atime; - vap->va_ctime = vap->va_mtime; - vap->va_gen = 0; - vap->va_flags = 0; vap->va_rdev = NODEV; - vap->va_bytes = 0; - vap->va_filerev = 0; break; case Fdesc: - fd = VTOFDESC(vp)->fd_fd; - - if ((error = fget(td, fd, &fp)) != 0) - return (error); - - bzero(&stb, sizeof(stb)); - error = fo_stat(fp, &stb, td->td_ucred, td); - fdrop(fp, td); - if (error == 0) { - vap->va_type = IFTOVT(stb.st_mode); - vap->va_mode = stb.st_mode; - if (vap->va_type == VDIR) - vap->va_mode &= ~(S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); - vap->va_nlink = 1; - vap->va_flags = 0; - vap->va_bytes = stb.st_blocks * stb.st_blksize; - vap->va_fileid = VTOFDESC(vp)->fd_ix; - vap->va_size = stb.st_size; - vap->va_blocksize = stb.st_blksize; - vap->va_rdev = stb.st_rdev; - - /* - * If no time data is provided, use the current time. - */ - if (stb.st_atimespec.tv_sec == 0 && - stb.st_atimespec.tv_nsec == 0) - nanotime(&stb.st_atimespec); - - if (stb.st_ctimespec.tv_sec == 0 && - stb.st_ctimespec.tv_nsec == 0) - nanotime(&stb.st_ctimespec); - - if (stb.st_mtimespec.tv_sec == 0 && - stb.st_mtimespec.tv_nsec == 0) - nanotime(&stb.st_mtimespec); - - vap->va_atime = stb.st_atimespec; - vap->va_mtime = stb.st_mtimespec; - vap->va_ctime = stb.st_ctimespec; - vap->va_uid = stb.st_uid; - vap->va_gid = stb.st_gid; - vap->va_gen = 0; - vap->va_filerev = 0; - } + vap->va_type = VCHR; + vap->va_nlink = 1; + vap->va_size = 0; + vap->va_rdev = makedev(0, vap->va_fileid); break; default: @@ -468,9 +424,8 @@ fdesc_getattr(ap) break; } - if (error == 0) - vp->v_type = vap->va_type; - return (error); + vp->v_type = vap->va_type; + return (0); } static int From 0c70e3070b96748fd2fc0ea1319aea4177b45ae8 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 15:03:47 +0000 Subject: [PATCH 121/544] Add missing 'break' statements. Found with: Coverity Prevent(tm) CID: 3936, 3937 Reviewed by: scottl@ --- sys/cam/scsi/scsi_sg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/cam/scsi/scsi_sg.c b/sys/cam/scsi/scsi_sg.c index efaa43e9a8ab..acdb404378c5 100644 --- a/sys/cam/scsi/scsi_sg.c +++ b/sys/cam/scsi/scsi_sg.c @@ -953,6 +953,7 @@ sg_scsiio_status(struct ccb_scsiio *csio, u_short *hoststat, u_short *drvstat) case CAM_SCSI_STATUS_ERROR: *hoststat = DID_ERROR; *drvstat = 0; + break; case CAM_SCSI_BUS_RESET: *hoststat = DID_RESET; *drvstat = 0; @@ -964,6 +965,7 @@ sg_scsiio_status(struct ccb_scsiio *csio, u_short *hoststat, u_short *drvstat) case CAM_SCSI_BUSY: *hoststat = DID_BUS_BUSY; *drvstat = 0; + break; default: *hoststat = DID_ERROR; *drvstat = DRIVER_ERROR; From 9b61a5b95e6f623ca4f7b827a19113095339a36c Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 15:14:37 +0000 Subject: [PATCH 122/544] Add missing free(9) in error case. Found with: Coverity Prevent(tm) CID: 4224 --- sys/cam/cam_periph.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 368d409c03c3..31bb24c3dbb4 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -173,6 +173,7 @@ cam_periph_alloc(periph_ctor_t *periph_ctor, xpt_unlock_buses(); if (*p_drv == NULL) { printf("cam_periph_alloc: invalid periph name '%s'\n", name); + free(periph, M_CAMPERIPH); return (CAM_REQ_INVALID); } From 7e745519569381d6b833e5524589a4ddfae294ee Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 12 May 2009 16:04:51 +0000 Subject: [PATCH 123/544] Modify the experimental nfs server to use the new nfsd_nfsd_args structure for nfsd. Includes a change that clarifies the use of an empty principal name string to indicate AUTH_SYS only. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdkrpc.c | 62 ++++++++++++++------------------- sys/fs/nfsserver/nfs_nfsdport.c | 15 +++++--- 2 files changed, 38 insertions(+), 39 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index 0b8df950326c..d9671c4e5bc5 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -350,20 +350,16 @@ int nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) { #ifdef KGSSAPI - char principal[128]; + char principal[MAXHOSTNAMELEN + 5]; int error; bool_t ret2, ret3, ret4; #endif #ifdef KGSSAPI - if (args != NULL) { - error = copyinstr(args->principal, principal, - sizeof(principal), NULL); - if (error) - return (error); - } else { - snprintf(principal, sizeof(principal), "nfs@%s", hostname); - } + error = copyinstr(args->principal, principal, sizeof (principal), + NULL); + if (error) + return (error); #endif /* @@ -380,40 +376,36 @@ nfsrvd_nfsd(struct thread *td, struct nfsd_nfsd_args *args) NFSD_UNLOCK(); #ifdef KGSSAPI - ret2 = rpc_gss_set_svc_name(principal, "kerberosv5", - GSS_C_INDEFINITE, NFS_PROG, NFS_VER2); - ret3 = rpc_gss_set_svc_name(principal, "kerberosv5", - GSS_C_INDEFINITE, NFS_PROG, NFS_VER3); - ret4 = rpc_gss_set_svc_name(principal, "kerberosv5", - GSS_C_INDEFINITE, NFS_PROG, NFS_VER4); + /* An empty string implies AUTH_SYS only. */ + if (principal[0] != '\0') { + ret2 = rpc_gss_set_svc_name(principal, "kerberosv5", + GSS_C_INDEFINITE, NFS_PROG, NFS_VER2); + ret3 = rpc_gss_set_svc_name(principal, "kerberosv5", + GSS_C_INDEFINITE, NFS_PROG, NFS_VER3); + ret4 = rpc_gss_set_svc_name(principal, "kerberosv5", + GSS_C_INDEFINITE, NFS_PROG, NFS_VER4); - /* - * If the principal name was specified, these should have - * succeeded. - */ - if (args != NULL && principal[0] != '\0' && - (!ret2 || !ret3 || !ret4)) { - NFSD_LOCK(); - newnfs_numnfsd--; - NFSD_UNLOCK(); - return (EAUTH); + if (!ret2 || !ret3 || !ret4) { + NFSD_LOCK(); + newnfs_numnfsd--; + nfsrvd_init(1); + NFSD_UNLOCK(); + return (EAUTH); + } } #endif - if (args != NULL) { - nfsrvd_pool->sp_minthreads = args->minthreads; - nfsrvd_pool->sp_maxthreads = args->maxthreads; - } else { - nfsrvd_pool->sp_minthreads = 4; - nfsrvd_pool->sp_maxthreads = 4; - } + nfsrvd_pool->sp_minthreads = args->minthreads; + nfsrvd_pool->sp_maxthreads = args->maxthreads; svc_run(nfsrvd_pool); #ifdef KGSSAPI - rpc_gss_clear_svc_name(NFS_PROG, NFS_VER2); - rpc_gss_clear_svc_name(NFS_PROG, NFS_VER3); - rpc_gss_clear_svc_name(NFS_PROG, NFS_VER4); + if (principal[0] != '\0') { + rpc_gss_clear_svc_name(NFS_PROG, NFS_VER2); + rpc_gss_clear_svc_name(NFS_PROG, NFS_VER3); + rpc_gss_clear_svc_name(NFS_PROG, NFS_VER4); + } #endif NFSD_LOCK(); diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index ca0e2667ecae..7679eac6ab5d 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2866,14 +2866,15 @@ static int nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) { struct file *fp; - struct nfsd_addsock_args nfsdarg; + struct nfsd_addsock_args sockarg; + struct nfsd_nfsd_args nfsdarg; int error; if (uap->flag & NFSSVC_NFSDADDSOCK) { - error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg)); + error = copyin(uap->argp, (caddr_t)&sockarg, sizeof (sockarg)); if (error) return (error); - if ((error = fget(td, nfsdarg.sock, &fp)) != 0) { + if ((error = fget(td, sockarg.sock, &fp)) != 0) { return (error); } if (fp->f_type != DTYPE_SOCKET) { @@ -2883,7 +2884,13 @@ nfssvc_nfsd(struct thread *td, struct nfssvc_args *uap) error = nfsrvd_addsock(fp); fdrop(fp, td); } else if (uap->flag & NFSSVC_NFSDNFSD) { - error = nfsrvd_nfsd(td, NULL); + if (uap->argp == NULL) + return (EINVAL); + error = copyin(uap->argp, (caddr_t)&nfsdarg, + sizeof (nfsdarg)); + if (error) + return (error); + error = nfsrvd_nfsd(td, &nfsdarg); } else { error = nfssvc_srvcall(td, uap, td->td_ucred); } From ff10bcec5dd9b99da21b8cd42371d17401a56e76 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 12 May 2009 16:07:08 +0000 Subject: [PATCH 124/544] - Implement detach path. - Release memory and DMA resources on stop. - Unload the associated DMA maps after transmit is complete. --- sys/arm/at91/if_ate.c | 227 +++++++++++++++++++++++++++--------------- 1 file changed, 144 insertions(+), 83 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 1b92cc2ac9b5..e0621921cd95 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -23,14 +23,10 @@ * SUCH DAMAGE. */ -/* TODO: (in no order) +/* TODO * - * 8) Need to sync busdma goo in atestop - * 9) atestop should maybe free the mbufs? - * - * 1) detach - * 2) Free dma setup - * 3) Turn on the clock in pmc? Turn off? + * 1) Turn on the clock in pmc? Turn off? + * 2) GPIO initializtion in board setup code. */ #include @@ -152,7 +148,7 @@ static void ate_intr(void *); /* helper routines */ static int ate_activate(device_t dev); -static void ate_deactivate(device_t dev); +static void ate_deactivate(struct ate_softc *sc); static int ate_ifmedia_upd(struct ifnet *ifp); static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); static int ate_get_mac(struct ate_softc *sc, u_char *eaddr); @@ -179,11 +175,33 @@ ate_attach(device_t dev) struct ifnet *ifp = NULL; struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; - int err; u_char eaddr[ETHER_ADDR_LEN]; uint32_t rnd; + int rid, err; sc->dev = dev; + ATE_LOCK_INIT(sc); + + /* + * Allocate resources. + */ + rid = 0; + sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (sc->mem_res == NULL) { + device_printf(dev, "could not allocate memory resources.\n"); + err = ENOMEM; + goto out; + } + rid = 0; + sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (sc->irq_res == NULL) { + device_printf(dev, "could not allocate interrupt resources.\n"); + err = ENOMEM; + goto out; + } + err = ate_activate(dev); if (err) goto out; @@ -197,8 +215,9 @@ ate_attach(device_t dev) CTLFLAG_RD, &sc->use_rmii, 0, "rmii in use"); /* calling atestop before ifp is set is OK */ + ATE_LOCK(sc); atestop(sc); - ATE_LOCK_INIT(sc); + ATE_UNLOCK(sc); callout_init_mtx(&sc->tick_ch, &sc->sc_mtx, 0); if ((err = ate_get_mac(sc, eaddr)) != 0) { @@ -252,26 +271,65 @@ ate_attach(device_t dev) ether_ifattach(ifp, eaddr); /* - * Activate the interrupt + * Activate the interrupt. */ err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_NET | INTR_MPSAFE, NULL, ate_intr, sc, &sc->intrhand); if (err) { + device_printf(dev, "could not establish interrupt handler.\n"); ether_ifdetach(ifp); - ATE_LOCK_DESTROY(sc); + goto out; } -out:; + +out: if (err) - ate_deactivate(dev); - if (err && ifp) - if_free(ifp); + ate_detach(dev); return (err); } static int ate_detach(device_t dev) { - return EBUSY; /* XXX TODO(1) */ + struct ate_softc *sc; + struct ifnet *ifp; + + sc = device_get_softc(dev); + KASSERT(sc != NULL, ("[ate: %d]: sc is NULL", __LINE__)); + ifp = sc->ifp; + if (device_is_attached(dev)) { + ATE_LOCK(sc); + sc->flags |= ATE_FLAG_DETACHING; + atestop(sc); + ATE_UNLOCK(sc); + callout_drain(&sc->tick_ch); + ether_ifdetach(ifp); + } + if (sc->miibus != NULL) { + device_delete_child(dev, sc->miibus); + sc->miibus = NULL; + } + bus_generic_detach(sc->dev); + ate_deactivate(sc); + if (sc->intrhand != NULL) { + bus_teardown_intr(dev, sc->irq_res, sc->intrhand); + sc->intrhand = NULL; + } + if (ifp != NULL) { + if_free(ifp); + sc->ifp = NULL; + } + if (sc->mem_res != NULL) { + bus_release_resource(dev, SYS_RES_IOPORT, + rman_get_rid(sc->mem_res), sc->mem_res); + sc->mem_res = NULL; + } + if (sc->irq_res != NULL) { + bus_release_resource(dev, SYS_RES_IRQ, + rman_get_rid(sc->irq_res), sc->irq_res); + sc->irq_res = NULL; + } + ATE_LOCK_DESTROY(sc); + return (0); } static void @@ -367,20 +425,9 @@ static int ate_activate(device_t dev) { struct ate_softc *sc; - int rid, err, i; + int err, i; sc = device_get_softc(dev); - rid = 0; - sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, - RF_ACTIVE); - if (sc->mem_res == NULL) - goto errout; - rid = 0; - sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, - RF_ACTIVE); - if (sc->irq_res == NULL) - goto errout; - /* * Allocate DMA tags and maps */ @@ -423,7 +470,6 @@ ate_activate(device_t dev) sc->rx_descs, ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), ate_getaddr, sc, 0) != 0) goto errout; - /* XXX TODO(5) Put this in ateinit_locked? */ for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { sc->rx_buf_ptr = i; if (bus_dmamem_alloc(sc->rxtag, (void **)&sc->rx_buf[i], @@ -439,65 +485,69 @@ ate_activate(device_t dev) /* Write the descriptor queue address. */ WR4(sc, ETH_RBQP, sc->rx_desc_phys); return (0); + errout: - ate_deactivate(dev); return (ENOMEM); } static void -ate_deactivate(device_t dev) +ate_deactivate(struct ate_softc *sc) { - struct ate_softc *sc; + int i; - sc = device_get_softc(dev); - /* XXX TODO(2) teardown busdma junk, below from fxp -- customize */ -#if 0 - if (sc->fxp_mtag) { - for (i = 0; i < FXP_NRFABUFS; i++) { - rxp = &sc->fxp_desc.rx_list[i]; - if (rxp->rx_mbuf != NULL) { - bus_dmamap_sync(sc->fxp_mtag, rxp->rx_map, - BUS_DMASYNC_POSTREAD); - bus_dmamap_unload(sc->fxp_mtag, rxp->rx_map); - m_freem(rxp->rx_mbuf); - } - bus_dmamap_destroy(sc->fxp_mtag, rxp->rx_map); - } - bus_dmamap_destroy(sc->fxp_mtag, sc->spare_map); - for (i = 0; i < FXP_NTXCB; i++) { - txp = &sc->fxp_desc.tx_list[i]; - if (txp->tx_mbuf != NULL) { - bus_dmamap_sync(sc->fxp_mtag, txp->tx_map, + KASSERT(sc != NULL, ("[ate, %d]: sc is NULL!", __LINE__)); + if (sc->mtag != NULL) { + for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { + if (sc->sent_mbuf[i] != NULL) { + bus_dmamap_sync(sc->mtag, sc->tx_map[i], BUS_DMASYNC_POSTWRITE); - bus_dmamap_unload(sc->fxp_mtag, txp->tx_map); - m_freem(txp->tx_mbuf); + bus_dmamap_unload(sc->mtag, sc->tx_map[i]); + m_freem(sc->sent_mbuf[i]); } - bus_dmamap_destroy(sc->fxp_mtag, txp->tx_map); + bus_dmamap_destroy(sc->mtag, sc->tx_map[i]); + sc->sent_mbuf[i] = NULL; + sc->tx_map[i] = NULL; } - bus_dma_tag_destroy(sc->fxp_mtag); + bus_dma_tag_destroy(sc->mtag); + } + if (sc->rx_desc_tag != NULL) { + if (sc->rx_descs != NULL) { + if (sc->rx_desc_phys != 0) { + bus_dmamap_sync(sc->rx_desc_tag, + sc->rx_desc_map, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rx_desc_tag, + sc->rx_desc_map); + sc->rx_desc_phys = 0; + } + } + } + if (sc->rxtag != NULL) { + for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { + if (sc->rx_buf[i] != NULL) { + if (sc->rx_descs[i].addr != 0) { + bus_dmamap_sync(sc->rxtag, + sc->rx_map[i], + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->rxtag, + sc->rx_map[i]); + sc->rx_descs[i].addr = 0; + } + bus_dmamem_free(sc->rxtag, sc->rx_buf[i], + sc->rx_map[i]); + sc->rx_buf[i] = NULL; + sc->rx_map[i] = NULL; + } + } + bus_dma_tag_destroy(sc->rxtag); + } + if (sc->rx_desc_tag != NULL) { + if (sc->rx_descs != NULL) + bus_dmamem_free(sc->rx_desc_tag, sc->rx_descs, + sc->rx_desc_map); + bus_dma_tag_destroy(sc->rx_desc_tag); + sc->rx_descs = NULL; + sc->rx_desc_tag = NULL; } - if (sc->fxp_stag) - bus_dma_tag_destroy(sc->fxp_stag); - if (sc->cbl_tag) - bus_dma_tag_destroy(sc->cbl_tag); - if (sc->mcs_tag) - bus_dma_tag_destroy(sc->mcs_tag); -#endif - if (sc->intrhand) - bus_teardown_intr(dev, sc->irq_res, sc->intrhand); - sc->intrhand = 0; - bus_generic_detach(sc->dev); - if (sc->miibus) - device_delete_child(sc->dev, sc->miibus); - if (sc->mem_res) - bus_release_resource(dev, SYS_RES_IOPORT, - rman_get_rid(sc->mem_res), sc->mem_res); - sc->mem_res = 0; - if (sc->irq_res) - bus_release_resource(dev, SYS_RES_IRQ, - rman_get_rid(sc->irq_res), sc->irq_res); - sc->irq_res = 0; - return; } /* @@ -718,6 +768,7 @@ ate_intr(void *xsc) if (sc->sent_mbuf[0]) { bus_dmamap_sync(sc->mtag, sc->tx_map[0], BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->mtag, sc->tx_map[0]); m_freem(sc->sent_mbuf[0]); ifp->if_opackets++; sc->sent_mbuf[0] = NULL; @@ -726,6 +777,7 @@ ate_intr(void *xsc) if (RD4(sc, ETH_TSR) & ETH_TSR_IDLE) { bus_dmamap_sync(sc->mtag, sc->tx_map[1], BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->mtag, sc->tx_map[1]); m_freem(sc->sent_mbuf[1]); ifp->if_opackets++; sc->txcur = 0; @@ -911,8 +963,11 @@ atestart(struct ifnet *ifp) static void atestop(struct ate_softc *sc) { - struct ifnet *ifp = sc->ifp; + struct ifnet *ifp; + int i; + ATE_ASSERT_LOCKED(sc); + ifp = sc->ifp; if (ifp) { ifp->if_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); @@ -948,11 +1003,17 @@ atestop(struct ate_softc *sc) WR4(sc, ETH_RSR, 0xffffffff); /* - * XXX TODO(8) - * need to worry about the busdma resources? Yes, I think we need - * to sync and unload them. We may also need to release the mbufs - * that are assocaited with RX and TX operations. + * Release TX resources. */ + for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) { + if (sc->sent_mbuf[i] != NULL) { + bus_dmamap_sync(sc->mtag, sc->tx_map[i], + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->mtag, sc->tx_map[i]); + m_freem(sc->sent_mbuf[i]); + sc->sent_mbuf[i] = NULL; + } + } /* * XXX we should power down the EMAC if it isn't in use, after From ee857ce73be3dcfe8dfcd959fd7e6260471c6756 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 16:38:32 +0000 Subject: [PATCH 125/544] Remove dead code. Found with: Coverity Prevent(tm) CID: 3667 --- sys/cam/scsi/scsi_pass.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index c60bb92276bd..4e4e48fa4b88 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -179,7 +179,6 @@ passasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) { struct cam_periph *periph; - struct cam_sim *sim; periph = (struct cam_periph *)callback_arg; @@ -198,7 +197,6 @@ passasync(void *callback_arg, u_int32_t code, * this device and start the probe * process. */ - sim = xpt_path_sim(cgd->ccb_h.path); status = cam_periph_alloc(passregister, passoninvalidate, passcleanup, passstart, "pass", CAM_PERIPH_BIO, cgd->ccb_h.path, From f095d54f0196faa1149779e7b01a425679e7a912 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 16:39:43 +0000 Subject: [PATCH 126/544] Remove dead code. Found with: Coverity Prevent(tm) CID: 556 --- sys/dev/ata/atapi-cam.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/dev/ata/atapi-cam.c b/sys/dev/ata/atapi-cam.c index 62e52510381d..50aaf7877c77 100644 --- a/sys/dev/ata/atapi-cam.c +++ b/sys/dev/ata/atapi-cam.c @@ -796,14 +796,10 @@ static void atapi_async(void *callback_arg, u_int32_t code, struct cam_path* path, void *arg) { - struct atapi_xpt_softc *softc; - struct cam_sim *sim; int targ; GIANT_REQUIRED; - sim = (struct cam_sim *) callback_arg; - softc = (struct atapi_xpt_softc *) cam_sim_softc(sim); switch (code) { case AC_LOST_DEVICE: targ = xpt_path_target_id(path); From 916cd41c476878fa42ca8dbeda69eab59ac1f1cd Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 16:59:50 +0000 Subject: [PATCH 127/544] Check return value of gctl_get_asciiparam(). Found with: Coverity Prevent(tm) CID: 1118 --- sys/geom/concat/g_concat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/geom/concat/g_concat.c b/sys/geom/concat/g_concat.c index ad56f43490f8..021c9f56fc00 100644 --- a/sys/geom/concat/g_concat.c +++ b/sys/geom/concat/g_concat.c @@ -753,6 +753,10 @@ g_concat_ctl_create(struct gctl_req *req, struct g_class *mp) for (attached = 0, no = 1; no < *nargs; no++) { snprintf(param, sizeof(param), "arg%u", no); name = gctl_get_asciiparam(req, param); + if (name == NULL) { + gctl_error(req, "No 'arg%d' argument.", no); + return; + } if (strncmp(name, "/dev/", strlen("/dev/")) == 0) name += strlen("/dev/"); pp = g_provider_by_name(name); From e5023dd9f6ec341342e8ad7ce75c8caf600af630 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 12 May 2009 17:05:40 +0000 Subject: [PATCH 128/544] Add missing 'break' statement. Found with: Coverity Prevent(tm) CID: 3919 --- sys/kern/kern_lock.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/kern/kern_lock.c b/sys/kern/kern_lock.c index f19e249a6c2c..f4e5ea9903e2 100644 --- a/sys/kern/kern_lock.c +++ b/sys/kern/kern_lock.c @@ -1067,6 +1067,7 @@ db_show_lockmgr(struct lock_object *lock) switch (lk->lk_lock & LK_ALL_WAITERS) { case LK_SHARED_WAITERS: db_printf("shared\n"); + break; case LK_EXCLUSIVE_WAITERS: db_printf("exclusive\n"); break; From 75c4b82c36133b0fba6f7a82fc0f14a153ac9385 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Tue, 12 May 2009 19:30:46 +0000 Subject: [PATCH 129/544] Remove unused variable. Found with: Coverity Prevent(tm) CID: 550 --- sys/dev/vge/if_vge.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c index d01aabaaffaa..5a56eb1e0662 100644 --- a/sys/dev/vge/if_vge.c +++ b/sys/dev/vge/if_vge.c @@ -651,10 +651,8 @@ vge_probe(dev) device_t dev; { struct vge_type *t; - struct vge_softc *sc; t = vge_devs; - sc = device_get_softc(dev); while (t->vge_name != NULL) { if ((pci_get_vendor(dev) == t->vge_vid) && From 6282e61346e9139947b68673f692fc7f33b7ef9e Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Tue, 12 May 2009 19:33:36 +0000 Subject: [PATCH 130/544] Remove unused variable. Found with: Coverity Prevent(tm) CID: 549 --- sys/dev/lge/if_lge.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/dev/lge/if_lge.c b/sys/dev/lge/if_lge.c index 438a5016bf21..ecae572169b6 100644 --- a/sys/dev/lge/if_lge.c +++ b/sys/dev/lge/if_lge.c @@ -1257,7 +1257,6 @@ lge_init_locked(sc) struct lge_softc *sc; { struct ifnet *ifp = sc->lge_ifp; - struct mii_data *mii; LGE_LOCK_ASSERT(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) @@ -1269,8 +1268,6 @@ lge_init_locked(sc) lge_stop(sc); lge_reset(sc); - mii = device_get_softc(sc->lge_miibus); - /* Set MAC address */ CSR_WRITE_4(sc, LGE_PAR0, *(u_int32_t *)(&IF_LLADDR(sc->lge_ifp)[0])); CSR_WRITE_4(sc, LGE_PAR1, *(u_int32_t *)(&IF_LLADDR(sc->lge_ifp)[4])); From ee3b0f6e2e053c63a22950421e05ff93ebc3cd73 Mon Sep 17 00:00:00 2001 From: Diomidis Spinellis Date: Tue, 12 May 2009 20:42:12 +0000 Subject: [PATCH 131/544] Add -c option to summarize number of calls, errors, and system time. Reviewed by: alfred --- usr.bin/truss/amd64-fbsd.c | 3 +- usr.bin/truss/amd64-fbsd32.c | 3 +- usr.bin/truss/amd64-linux32.c | 2 +- usr.bin/truss/i386-fbsd.c | 3 +- usr.bin/truss/i386-linux.c | 2 +- usr.bin/truss/ia64-fbsd.c | 3 +- usr.bin/truss/main.c | 18 +- usr.bin/truss/powerpc-fbsd.c | 3 +- usr.bin/truss/sparc64-fbsd.c | 3 +- usr.bin/truss/syscall.h | 6 +- usr.bin/truss/syscalls.c | 323 ++++++++++++++++++++-------------- usr.bin/truss/truss.1 | 12 +- usr.bin/truss/truss.h | 11 ++ 13 files changed, 247 insertions(+), 145 deletions(-) diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c index 3a632d637c5e..d43f92912587 100644 --- a/usr.bin/truss/amd64-fbsd.c +++ b/usr.bin/truss/amd64-fbsd.c @@ -323,7 +323,8 @@ amd64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index 64157e30c7b6..4e6458a08920 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -339,7 +339,8 @@ amd64_fbsd32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index 163b1417bd64..7f7390aa7688 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -309,7 +309,7 @@ amd64_linux32_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused } print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - errorp ? i : retval); + errorp ? i : retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index 4f0eabb20622..a65c7dbaa6ec 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -329,7 +329,8 @@ i386_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index 1264439fcef5..de17628c0797 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -309,7 +309,7 @@ i386_linux_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) } print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - errorp ? i : retval); + errorp ? i : retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c index 70140b6b84de..cd8c69eb234a 100644 --- a/usr.bin/truss/ia64-fbsd.c +++ b/usr.bin/truss/ia64-fbsd.c @@ -294,7 +294,8 @@ ia64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + fsc.sc, retval); clear_fsc(); return (retval); diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index 9c1589b2e7e9..4333f2df3076 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$"); #include "truss.h" #include "extern.h" +#include "syscall.h" #define MAXARGS 6 @@ -65,8 +66,8 @@ static void usage(void) { fprintf(stderr, "%s\n%s\n", - "usage: truss [-faedDS] [-o file] [-s strsize] -p pid", - " truss [-faedDS] [-o file] [-s strsize] command [args]"); + "usage: truss [-cfaedDS] [-o file] [-s strsize] -p pid", + " truss [-cfaedDS] [-o file] [-s strsize] command [args]"); exit(1); } @@ -188,7 +189,7 @@ main(int ac, char **av) trussinfo->pr_why = S_NONE; trussinfo->curthread = NULL; SLIST_INIT(&trussinfo->threadlist); - while ((c = getopt(ac, av, "p:o:faedDs:S")) != -1) { + while ((c = getopt(ac, av, "p:o:facedDs:S")) != -1) { switch (c) { case 'p': /* specified pid */ trussinfo->pid = atoi(optarg); @@ -204,6 +205,9 @@ main(int ac, char **av) case 'a': /* Print execve() argument strings. */ trussinfo->flags |= EXECVEARGS; break; + case 'c': /* Count number of system calls and time. */ + trussinfo->flags |= COUNTONLY; + break; case 'e': /* Print execve() environment strings. */ trussinfo->flags |= EXECVEENVS; break; @@ -337,6 +341,8 @@ main(int ac, char **av) free(signame); break; case S_EXIT: + if (trussinfo->flags & COUNTONLY) + break; if (trussinfo->flags & FOLLOWFORKS) fprintf(trussinfo->outfile, "%5d: ", trussinfo->pid); @@ -360,12 +366,16 @@ main(int ac, char **av) break; } } while (trussinfo->pr_why != S_EXIT); - fflush(trussinfo->outfile); if (trussinfo->flags & FOLLOWFORKS) do { childpid = wait(&status); } while (childpid != -1); + if (trussinfo->flags & COUNTONLY) + print_summary(trussinfo); + + fflush(trussinfo->outfile); + return (0); } diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c index 7b4cfb5ba63f..2316740b32f1 100644 --- a/usr.bin/truss/powerpc-fbsd.c +++ b/usr.bin/truss/powerpc-fbsd.c @@ -331,7 +331,8 @@ powerpc_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c index 896bac749395..31e304af977d 100644 --- a/usr.bin/truss/sparc64-fbsd.c +++ b/usr.bin/truss/sparc64-fbsd.c @@ -336,7 +336,8 @@ sparc64_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + retval, fsc.sc); clear_fsc(); return (retval); diff --git a/usr.bin/truss/syscall.h b/usr.bin/truss/syscall.h index 39a796a71370..484bb5d42197 100644 --- a/usr.bin/truss/syscall.h +++ b/usr.bin/truss/syscall.h @@ -57,10 +57,14 @@ struct syscall { int nargs; /* actual number of meaningful arguments */ /* Hopefully, no syscalls with > 10 args */ struct syscall_args args[10]; + struct timespec time; /* Time spent for this call */ + int ncalls; /* Number of calls */ + int nerror; /* Number of calls that returned with error */ }; struct syscall *get_syscall(const char*); char *print_arg(struct syscall_args *, unsigned long*, long, struct trussinfo *); void print_syscall(struct trussinfo *, const char *, int, char **); void print_syscall_ret(struct trussinfo *, const char *, int, char **, int, - long); + long, struct syscall *); +void print_summary(struct trussinfo *trussinfo); diff --git a/usr.bin/truss/syscalls.c b/usr.bin/truss/syscalls.c index d1b390b09d59..d9278156649b 100644 --- a/usr.bin/truss/syscalls.c +++ b/usr.bin/truss/syscalls.c @@ -89,135 +89,162 @@ static const char rcsid[] = /* * This should probably be in its own file, sorted alphabetically. */ - struct syscall syscalls[] = { - { "fcntl", 1, 3, - { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, - { "readlink", 1, 3, - { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 } } }, - { "lseek", 2, 3, - { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, - { "linux_lseek", 2, 3, - { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, - { "mmap", 2, 6, - { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, - { "mprotect", 1, 3, - { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, - { "open", 1, 3, - { { Name | IN, 0 } , { Open, 1 }, { Octal, 2 } } }, - { "mkdir", 1, 2, - { { Name, 0 } , { Octal, 1 } } }, - { "linux_open", 1, 3, - { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, - { "close", 1, 1, - { { Int, 0 } } }, - { "link", 0, 2, - { { Name, 0 }, { Name, 1 } } }, - { "unlink", 0, 1, - { { Name, 0 } } }, - { "chdir", 0, 1, - { { Name, 0 } } }, - { "chroot", 0, 1, - { { Name, 0 } } }, - { "mknod", 0, 3, - { { Name, 0 }, { Octal, 1 }, { Int, 3 } } }, - { "chmod", 0, 2, - { { Name, 0 }, { Octal, 1 } } }, - { "chown", 0, 3, - { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, - { "mount", 0, 4, - { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } }, - { "umount", 0, 2, - { { Name, 0 }, { Int, 2 } } }, - { "fstat", 1, 2, - { { Int, 0 }, { Stat | OUT , 1 } } }, - { "stat", 1, 2, - { { Name | IN, 0 }, { Stat | OUT, 1 } } }, - { "lstat", 1, 2, - { { Name | IN, 0 }, { Stat | OUT, 1 } } }, - { "linux_newstat", 1, 2, - { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, - { "linux_newfstat", 1, 2, - { { Int, 0 }, { Ptr | OUT, 1 } } }, - { "write", 1, 3, - { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 } } }, - { "ioctl", 1, 3, - { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 } } }, - { "break", 1, 1, { { Ptr, 0 } } }, - { "exit", 0, 1, { { Hex, 0 } } }, - { "access", 1, 2, { { Name | IN, 0 }, { Int, 1 } } }, - { "sigaction", 1, 3, - { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } }, - { "accept", 1, 3, - { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, - { "bind", 1, 3, - { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, - { "connect", 1, 3, - { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, - { "getpeername", 1, 3, - { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, - { "getsockname", 1, 3, - { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, - { "recvfrom", 1, 6, - { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } }, - { "sendto", 1, 6, - { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } }, - { "execve", 1, 3, - { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, - { "linux_execve", 1, 3, - { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, - { "kldload", 0, 1, { { Name | IN, 0 } } }, - { "kldunload", 0, 1, { { Int, 0 } } }, - { "kldfind", 0, 1, { { Name | IN, 0 } } }, - { "kldnext", 0, 1, { { Int, 0 } } }, - { "kldstat", 0, 2, { { Int, 0 }, { Ptr, 1 } } }, - { "kldfirstmod", 0, 1, { { Int, 0 } } }, - { "nanosleep", 0, 1, { { Timespec, 0 } } }, - { "select", 1, 5, { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, { Timeval, 4 } } }, - { "poll", 1, 3, { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } }, - { "gettimeofday", 1, 2, { { Timeval | OUT, 0 }, { Ptr, 1 } } }, - { "clock_gettime", 1, 2, { { Int, 0 }, { Timespec | OUT, 1 } } }, - { "getitimer", 1, 2, { { Int, 0 }, { Itimerval | OUT, 2 } } }, - { "setitimer", 1, 3, { { Int, 0 }, { Itimerval, 1 } , { Itimerval | OUT, 2 } } }, - { "kse_release", 0, 1, { { Timespec, 0 } } }, - { "kevent", 0, 6, { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, - { "_umtx_lock", 0, 1, { { Umtx, 0 } } }, - { "_umtx_unlock", 0, 1, { { Umtx, 0 } } }, - { "sigprocmask", 0, 3, { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } }, - { "unmount", 1, 2, { { Name, 0 }, { Int, 1 } } }, - { "socket", 1, 3, { { Sockdomain, 0 }, { Socktype, 1 }, { Int, 2 } } }, - { "getrusage", 1, 2, { { Int, 0 }, { Rusage | OUT, 1 } } }, - { "__getcwd", 1, 2, { { Name | OUT, 0 }, { Int, 1 } } }, - { "shutdown", 1, 2, { { Int, 0 }, { Shutdown, 1 } } }, - { "getrlimit", 1, 2, { { Resource, 0 }, { Rlimit | OUT, 1 } } }, - { "setrlimit", 1, 2, { { Resource, 0 }, { Rlimit | IN, 1 } } }, - { "utimes", 1, 2, - { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, - { "lutimes", 1, 2, - { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, - { "futimes", 1, 2, - { { Int, 0 }, { Timeval | IN, 1 } } }, - { "chflags", 1, 2, - { { Name | IN, 0 }, { Hex, 1 } } }, - { "lchflags", 1, 2, - { { Name | IN, 0 }, { Hex, 1 } } }, - { "pathconf", 1, 2, - { { Name | IN, 0 }, { Pathconf, 1 } } }, - { "truncate", 1, 3, - { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, - { "ftruncate", 1, 3, - { { Int | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, - { "kill", 1, 2, - { { Int | IN, 0 }, { Signal | IN, 1 } } }, - { "munmap", 1, 2, - { { Ptr, 0 }, { Int, 1 } } }, - { "read", 1, 3, - { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, - { "rename", 1, 2, - { { Name , 0 } , { Name, 1 } } }, - { "symlink", 1, 2, - { { Name , 0 } , { Name, 1 } } }, - { 0, 0, 0, { { 0, 0 } } }, + { .name = "fcntl", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 } , { Fcntl, 1 }, { Fcntlflag | OUT, 2 } } }, + { .name = "readlink", .ret_type = 1, .nargs = 3, + .args = { { Name, 0 } , { Readlinkres | OUT, 1 }, { Int, 2 } } }, + { .name = "lseek", .ret_type = 2, .nargs = 3, + .args = { { Int, 0 }, { Quad, 1 + QUAD_ALIGN }, { Whence, 1 + QUAD_SLOTS + QUAD_ALIGN } } }, + { .name = "linux_lseek", .ret_type = 2, .nargs = 3, + .args = { { Int, 0 }, { Int, 1 }, { Whence, 2 } } }, + { .name = "mmap", .ret_type = 2, .nargs = 6, + .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 }, { Mmapflags, 3 }, { Int, 4 }, { Quad, 5 + QUAD_ALIGN } } }, + { .name = "mprotect", .ret_type = 1, .nargs = 3, + .args = { { Ptr, 0 }, { Int, 1 }, { Mprot, 2 } } }, + { .name = "open", .ret_type = 1, .nargs = 3, + .args = { { Name | IN, 0 } , { Open, 1 }, { Octal, 2 } } }, + { .name = "mkdir", .ret_type = 1, .nargs = 2, + .args = { { Name, 0 } , { Octal, 1 } } }, + { .name = "linux_open", .ret_type = 1, .nargs = 3, + .args = { { Name, 0 }, { Hex, 1 }, { Octal, 2 } } }, + { .name = "close", .ret_type = 1, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "link", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Name, 1 } } }, + { .name = "unlink", .ret_type = 0, .nargs = 1, + .args = { { Name, 0 } } }, + { .name = "chdir", .ret_type = 0, .nargs = 1, + .args = { { Name, 0 } } }, + { .name = "chroot", .ret_type = 0, .nargs = 1, + .args = { { Name, 0 } } }, + { .name = "mknod", .ret_type = 0, .nargs = 3, + .args = { { Name, 0 }, { Octal, 1 }, { Int, 3 } } }, + { .name = "chmod", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Octal, 1 } } }, + { .name = "chown", .ret_type = 0, .nargs = 3, + .args = { { Name, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "mount", .ret_type = 0, .nargs = 4, + .args = { { Name, 0 }, { Name, 1 }, { Int, 2 }, { Ptr, 3 } } }, + { .name = "umount", .ret_type = 0, .nargs = 2, + .args = { { Name, 0 }, { Int, 2 } } }, + { .name = "fstat", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Stat | OUT , 1 } } }, + { .name = "stat", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, + { .name = "lstat", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Stat | OUT, 1 } } }, + { .name = "linux_newstat", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Ptr | OUT, 1 } } }, + { .name = "linux_newfstat", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Ptr | OUT, 1 } } }, + { .name = "write", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 } } }, + { .name = "ioctl", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Ioctl, 1 }, { Hex, 2 } } }, + { .name = "break", .ret_type = 1, .nargs = 1, + .args = { { Ptr, 0 } } }, + { .name = "exit", .ret_type = 0, .nargs = 1, + .args = { { Hex, 0 } } }, + { .name = "access", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Int, 1 } } }, + { .name = "sigaction", .ret_type = 1, .nargs = 3, + .args = { { Signal, 0 }, { Sigaction | IN, 1 }, { Sigaction | OUT, 2 } } }, + { .name = "accept", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, + { .name = "bind", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "connect", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Sockaddr | IN, 1 }, { Int, 2 } } }, + { .name = "getpeername", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, + { .name = "getsockname", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Sockaddr | OUT, 1 }, { Ptr | OUT, 2 } } }, + { .name = "recvfrom", .ret_type = 1, .nargs = 6, + .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | OUT, 4 }, { Ptr | OUT, 5 } } }, + { .name = "sendto", .ret_type = 1, .nargs = 6, + .args = { { Int, 0 }, { BinString | IN, 1 }, { Int, 2 }, { Hex, 3 }, { Sockaddr | IN, 4 }, { Ptr | IN, 5 } } }, + { .name = "execve", .ret_type = 1, .nargs = 3, + .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, + { .name = "linux_execve", .ret_type = 1, .nargs = 3, + .args = { { Name | IN, 0 }, { StringArray | IN, 1 }, { StringArray | IN, 2 } } }, + { .name = "kldload", .ret_type = 0, .nargs = 1, + .args = { { Name | IN, 0 } } }, + { .name = "kldunload", .ret_type = 0, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "kldfind", .ret_type = 0, .nargs = 1, + .args = { { Name | IN, 0 } } }, + { .name = "kldnext", .ret_type = 0, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "kldstat", .ret_type = 0, .nargs = 2, + .args = { { Int, 0 }, { Ptr, 1 } } }, + { .name = "kldfirstmod", .ret_type = 0, .nargs = 1, + .args = { { Int, 0 } } }, + { .name = "nanosleep", .ret_type = 0, .nargs = 1, + .args = { { Timespec, 0 } } }, + { .name = "select", .ret_type = 1, .nargs = 5, + .args = { { Int, 0 }, { Fd_set, 1 }, { Fd_set, 2 }, { Fd_set, 3 }, { Timeval, 4 } } }, + { .name = "poll", .ret_type = 1, .nargs = 3, + .args = { { Pollfd, 0 }, { Int, 1 }, { Int, 2 } } }, + { .name = "gettimeofday", .ret_type = 1, .nargs = 2, + .args = { { Timeval | OUT, 0 }, { Ptr, 1 } } }, + { .name = "clock_gettime", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Timespec | OUT, 1 } } }, + { .name = "getitimer", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Itimerval | OUT, 2 } } }, + { .name = "setitimer", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { Itimerval, 1 } , { Itimerval | OUT, 2 } } }, + { .name = "kse_release", .ret_type = 0, .nargs = 1, + .args = { { Timespec, 0 } } }, + { .name = "kevent", .ret_type = 0, .nargs = 6, + .args = { { Int, 0 }, { Kevent, 1 }, { Int, 2 }, { Kevent | OUT, 3 }, { Int, 4 }, { Timespec, 5 } } }, + { .name = "_umtx_lock", .ret_type = 0, .nargs = 1, + .args = { { Umtx, 0 } } }, + { .name = "_umtx_unlock", .ret_type = 0, .nargs = 1, + .args = { { Umtx, 0 } } }, + { .name = "sigprocmask", .ret_type = 0, .nargs = 3, + .args = { { Sigprocmask, 0 }, { Sigset, 1 }, { Sigset | OUT, 2 } } }, + { .name = "unmount", .ret_type = 1, .nargs = 2, + .args = { { Name, 0 }, { Int, 1 } } }, + { .name = "socket", .ret_type = 1, .nargs = 3, + .args = { { Sockdomain, 0 }, { Socktype, 1 }, { Int, 2 } } }, + { .name = "getrusage", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Rusage | OUT, 1 } } }, + { .name = "__getcwd", .ret_type = 1, .nargs = 2, + .args = { { Name | OUT, 0 }, { Int, 1 } } }, + { .name = "shutdown", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Shutdown, 1 } } }, + { .name = "getrlimit", .ret_type = 1, .nargs = 2, + .args = { { Resource, 0 }, { Rlimit | OUT, 1 } } }, + { .name = "setrlimit", .ret_type = 1, .nargs = 2, + .args = { { Resource, 0 }, { Rlimit | IN, 1 } } }, + { .name = "utimes", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, + { .name = "lutimes", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Timeval2 | IN, 1 } } }, + { .name = "futimes", .ret_type = 1, .nargs = 2, + .args = { { Int, 0 }, { Timeval | IN, 1 } } }, + { .name = "chflags", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Hex, 1 } } }, + { .name = "lchflags", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Hex, 1 } } }, + { .name = "pathconf", .ret_type = 1, .nargs = 2, + .args = { { Name | IN, 0 }, { Pathconf, 1 } } }, + { .name = "truncate", .ret_type = 1, .nargs = 3, + .args = { { Name | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, + { .name = "ftruncate", .ret_type = 1, .nargs = 3, + .args = { { Int | IN, 0 }, { Int | IN, 1 }, { Quad | IN, 2 } } }, + { .name = "kill", .ret_type = 1, .nargs = 2, + .args = { { Int | IN, 0 }, { Signal | IN, 1 } } }, + { .name = "munmap", .ret_type = 1, .nargs = 2, + .args = { { Ptr, 0 }, { Int, 1 } } }, + { .name = "read", .ret_type = 1, .nargs = 3, + .args = { { Int, 0 }, { BinString | OUT, 1 }, { Int, 2 } } }, + { .name = "rename", .ret_type = 1, .nargs = 2, + .args = { { Name , 0 } , { Name, 1 } } }, + { .name = "symlink", .ret_type = 1, .nargs = 2, + .args = { { Name , 0 } , { Name, 1 } } }, + { .name = 0 }, }; /* Xlat idea taken from strace */ @@ -1077,8 +1104,21 @@ print_syscall(struct trussinfo *trussinfo, const char *name, int nargs, char **s void print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, - char **s_args, int errorp, long retval) + char **s_args, int errorp, long retval, struct syscall *sc) { + struct timespec timediff; + + if (trussinfo->flags & COUNTONLY) { + if (!sc) + return; + clock_gettime(CLOCK_REALTIME, &trussinfo->after); + timespecsubt(&trussinfo->after, &trussinfo->before, &timediff); + timespecadd(&sc->time, &timediff, &sc->time); + sc->ncalls++; + if (errorp) + sc->nerror++; + return; + } print_syscall(trussinfo, name, nargs, s_args); fflush(trussinfo->outfile); @@ -1088,3 +1128,28 @@ print_syscall_ret(struct trussinfo *trussinfo, const char *name, int nargs, fprintf(trussinfo->outfile, " = %ld (0x%lx)\n", retval, retval); } } + +void +print_summary(struct trussinfo *trussinfo) +{ + struct syscall *sc; + struct timespec total = {0, 0}; + int ncall, nerror; + + fprintf(trussinfo->outfile, "%-20s%15s%8s%8s\n", + "syscall", "seconds", "calls", "errors"); + ncall = nerror = 0; + for (sc = syscalls; sc->name != NULL; sc++) + if (sc->ncalls) { + fprintf(trussinfo->outfile, "%-20s%5d.%09ld%8d%8d\n", + sc->name, sc->time.tv_sec, sc->time.tv_nsec, + sc->ncalls, sc->nerror); + timespecadd(&total, &sc->time, &total); + ncall += sc->ncalls; + nerror += sc->nerror; + } + fprintf(trussinfo->outfile, "%20s%15s%8s%8s\n", + "", "-------------", "-------", "-------"); + fprintf(trussinfo->outfile, "%-20s%5d.%09ld%8d%8d\n", + "", total.tv_sec, total.tv_nsec, ncall, nerror); +} diff --git a/usr.bin/truss/truss.1 b/usr.bin/truss/truss.1 index 28e474e042ea..6a01451a4983 100644 --- a/usr.bin/truss/truss.1 +++ b/usr.bin/truss/truss.1 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd January 22, 2009 +.Dd May 12, 2009 .Dt TRUSS 1 .Os .Sh NAME @@ -8,12 +8,12 @@ .Nd trace system calls .Sh SYNOPSIS .Nm -.Op Fl faedDS +.Op Fl facedDS .Op Fl o Ar file .Op Fl s Ar strsize .Fl p Ar pid .Nm -.Op Fl faedDS +.Op Fl facedDS .Op Fl o Ar file .Op Fl s Ar strsize .Ar command Op Ar args @@ -36,6 +36,12 @@ etc. Show the argument strings that are passed in each .Xr execve 2 system call. +.It Fl c +Do not display individual system calls. +Instead, before exiting, print a summary containing for each system call: +the total system time used, +the number of times the call was invoked, +and the number of times the call returned with an error. .It Fl e Show the environment strings that are passed in each .Xr execve 2 diff --git a/usr.bin/truss/truss.h b/usr.bin/truss/truss.h index 8533fae36ea9..89198c950ce0 100644 --- a/usr.bin/truss/truss.h +++ b/usr.bin/truss/truss.h @@ -33,6 +33,7 @@ #define NOSIGS 0x00000008 #define EXECVEARGS 0x00000010 #define EXECVEENVS 0x00000020 +#define COUNTONLY 0x00000040 struct threadinfo { @@ -70,6 +71,16 @@ struct trussinfo } \ } while (0) +#define timespecadd(tvp, uvp, vvp) \ + do { \ + (vvp)->tv_sec = (tvp)->tv_sec + (uvp)->tv_sec; \ + (vvp)->tv_nsec = (tvp)->tv_nsec + (uvp)->tv_nsec; \ + if ((vvp)->tv_nsec > 1000000000) { \ + (vvp)->tv_sec++; \ + (vvp)->tv_nsec -= 1000000000; \ + } \ + } while (0) + #define S_NONE 0 #define S_SCE 1 #define S_SCX 2 From 08390d3b63f05bbfe16b43c530329dd8c0db3dee Mon Sep 17 00:00:00 2001 From: Marius Strobl Date: Tue, 12 May 2009 20:56:34 +0000 Subject: [PATCH 132/544] Correct r190283 (partially reverting it) as on sparc64 BUS_DMA_NOCACHE actually is only valid for bus_dmamap_load(). MFC after: 3 days --- share/man/man9/bus_dma.9 | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/share/man/man9/bus_dma.9 b/share/man/man9/bus_dma.9 index dc5ae4b3a225..7886b14876f7 100644 --- a/share/man/man9/bus_dma.9 +++ b/share/man/man9/bus_dma.9 @@ -60,7 +60,7 @@ .\" $FreeBSD$ .\" $NetBSD: bus_dma.9,v 1.25 2002/10/14 13:43:16 wiz Exp $ .\" -.Dd November 16, 2008 +.Dd May 12, 2009 .Dt BUS_DMA 9 .Os .Sh NAME @@ -561,6 +561,13 @@ Are as follows: .It Dv BUS_DMA_NOWAIT The load should not be deferred in case of insufficient mapping resources, and instead should return immediately with an appropriate error. +.It Dv BUS_DMA_NOCACHE +The generated transactions to and from the virtual page are non-cacheable. +For +.Fn bus_dmamap_load , +the +.Dv BUS_DMA_NOCACHE +flag is currently implemented on sparc64. .El .El .Pp @@ -780,11 +787,12 @@ Causes the allocated memory to be set to all zeros. The allocated memory will not be cached in the processor caches. All memory accesses appear on the bus and are executed without reordering. -On the amd64 and i386 architectures this flag results in the -Strong Uncacheable PAT to be set for the allocated virtual address range. -The +For +.Fn bus_dmamem_alloc , +the .Dv BUS_DMA_NOCACHE -flag is currently implemented on amd64, i386 and sparc64. +flag is currently implemented on amd64 and i386 where it results in the +Strong Uncacheable PAT to be set for the allocated virtual address range. .El .It Fa mapp Pointer to a From 878722157886100dc9a1190b5129a71f8d828d2d Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 12 May 2009 21:14:36 +0000 Subject: [PATCH 133/544] - Eliminate extra register reads by using a variable to store registers contents. - Use memory barriers to preserve the order of buffer space operations. This might be needed if we'll ever use this driver on architectures where ordering is not guaranteed. --- sys/arm/at91/if_ate.c | 44 +++++++++++++++++++++++++++---------------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index e0621921cd95..967f62e37843 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -118,6 +118,13 @@ WR4(struct ate_softc *sc, bus_size_t off, uint32_t val) bus_write_4(sc->mem_res, off, val); } +static inline void +BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags) +{ + + bus_barrier(sc->mem_res, off, len, flags); +} + #define ATE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define ATE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define ATE_LOCK_INIT(_sc) \ @@ -586,18 +593,19 @@ ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) static void ate_stat_update(struct ate_softc *sc, int active) { + uint32_t reg; + /* * The speed and full/half-duplex state needs to be reflected * in the ETH_CFG register. */ - if (IFM_SUBTYPE(active) == IFM_10_T) - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_SPD); - else - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_SPD); + reg = RD4(sc, ETH_CFG); + reg &= ~(ETH_CFG_SPD | ETH_CFG_FD); + if (IFM_SUBTYPE(active) != IFM_10_T) + reg |= ETH_CFG_SPD; if (active & IFM_FDX) - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_FD); - else - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_FD); + reg |= ETH_CFG_FD; + WR4(sc, ETH_CFG, reg); } static void @@ -709,11 +717,10 @@ ate_intr(void *xsc) { struct ate_softc *sc = xsc; struct ifnet *ifp = sc->ifp; - int status; - int i; - void *bp; struct mbuf *mb; - uint32_t rx_stat; + void *bp; + uint32_t status, reg, rx_stat; + int i; status = RD4(sc, ETH_ISR); if (status == 0) @@ -800,10 +807,11 @@ ate_intr(void *xsc) ATE_UNLOCK(sc); } if (status & ETH_ISR_RBNA) { - printf("RBNA workaround\n"); /* Workaround Errata #11 */ - WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) &~ ETH_CTL_RE); - WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_RE); + reg = RD4(sc, ETH_CTL); + WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE); + BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE); + WR4(sc, ETH_CTL, reg | ETH_CTL_RE); } } @@ -816,6 +824,7 @@ ateinit_locked(void *xsc) struct ate_softc *sc = xsc; struct ifnet *ifp = sc->ifp; struct mii_data *mii; + uint32_t reg; ATE_ASSERT_LOCKED(sc); @@ -834,10 +843,12 @@ ateinit_locked(void *xsc) * to this chip. Select the right one based on a compile-time * option. */ + reg = RD4(sc, ETH_CFG); if (sc->use_rmii) - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_RMII); + reg |= ETH_CFG_RMII; else - WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) & ~ETH_CFG_RMII); + reg &= ~ETH_CFG_RMII; + WR4(sc, ETH_CFG, reg); ate_rxfilter(sc); @@ -926,6 +937,7 @@ atestart_locked(struct ifnet *ifp) * tell the hardware to xmit the packet. */ WR4(sc, ETH_TAR, segs[0].ds_addr); + BARRIER(sc, ETH_TAR, 8, BUS_SPACE_BARRIER_WRITE); WR4(sc, ETH_TCR, segs[0].ds_len); /* From cd2d868fbfe1d2d8af717ddd604ecd6fed01d343 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Tue, 12 May 2009 21:28:41 +0000 Subject: [PATCH 134/544] - Resurrect the debug printf message I accidentally dropped in the previous commit. - Use device_printf instead of printf. - Put all printfs in the interrupt handler under bootverbose. --- sys/arm/at91/if_ate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 967f62e37843..6ccfd63345c2 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -734,7 +734,8 @@ ate_intr(void *xsc) bp = sc->rx_buf[i]; rx_stat = sc->rx_descs[i].status; if ((rx_stat & ETH_LEN_MASK) == 0) { - printf("ignoring bogus 0 len packet\n"); + if (bootverbose) + device_printf(sc->dev, "ignoring bogus zero-length packet\n"); bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); sc->rx_descs[i].addr &= ~ETH_CPU_OWNER; @@ -808,6 +809,8 @@ ate_intr(void *xsc) } if (status & ETH_ISR_RBNA) { /* Workaround Errata #11 */ + if (bootverbose) + device_printf(sc->dev, "RBNA workaround\n"); reg = RD4(sc, ETH_CTL); WR4(sc, ETH_CTL, reg & ~ETH_CTL_RE); BARRIER(sc, ETH_CTL, 4, BUS_SPACE_BARRIER_WRITE); From d1e015bfee904fa191363e26dd0a599edbe29904 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Tue, 12 May 2009 22:11:02 +0000 Subject: [PATCH 135/544] Remove unused variables. Found with: Coverity Prevent(tm) CID: 4285, 4286 --- sys/i386/cpufreq/hwpstate.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/i386/cpufreq/hwpstate.c b/sys/i386/cpufreq/hwpstate.c index cc5d03e6a0df..7e024a396167 100644 --- a/sys/i386/cpufreq/hwpstate.c +++ b/sys/i386/cpufreq/hwpstate.c @@ -161,7 +161,6 @@ DRIVER_MODULE(hwpstate, cpu, hwpstate_driver, hwpstate_devclass, 0, 0); static int hwpstate_goto_pstate(device_t dev, int pstate) { - struct hwpstate_softc *sc; struct pcpu *pc; int i; uint64_t msr; @@ -170,7 +169,6 @@ hwpstate_goto_pstate(device_t dev, int pstate) int id = pstate; int error; - sc = device_get_softc(dev); /* get the current pstate limit */ msr = rdmsr(MSR_AMD_10H_11H_LIMIT); limit = AMD_10H_11H_GET_PSTATE_LIMIT(msr); @@ -299,7 +297,6 @@ hwpstate_type(device_t dev, int *type) static void hwpstate_identify(driver_t *driver, device_t parent) { - device_t child; if (device_find_child(parent, "hwpstate", -1) != NULL) return; @@ -318,7 +315,7 @@ hwpstate_identify(driver_t *driver, device_t parent) if (resource_disabled("hwpstate", 0)) return; - if ((child = BUS_ADD_CHILD(parent, 10, "hwpstate", -1)) == NULL) + if (BUS_ADD_CHILD(parent, 10, "hwpstate", -1) == NULL) device_printf(parent, "hwpstate: add child failed\n"); } From e831cd36d0fada153e43523e0c6b2a2e448a16f8 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Tue, 12 May 2009 23:22:58 +0000 Subject: [PATCH 136/544] Remove unused variables. Found with: Coverity Prevent(tm) CID: 544, 545 --- sys/dev/acpi_support/acpi_ibm.c | 3 --- sys/dev/acpi_support/acpi_sony.c | 5 +---- 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/sys/dev/acpi_support/acpi_ibm.c b/sys/dev/acpi_support/acpi_ibm.c index ccb0c062adb9..ca67716ed8d6 100644 --- a/sys/dev/acpi_support/acpi_ibm.c +++ b/sys/dev/acpi_support/acpi_ibm.c @@ -332,7 +332,6 @@ static int acpi_ibm_attach(device_t dev) { struct acpi_ibm_softc *sc; - struct acpi_softc *acpi_sc; devclass_t ec_devclass; ACPI_FUNCTION_TRACE((char *)(uintptr_t) __func__); @@ -341,8 +340,6 @@ acpi_ibm_attach(device_t dev) sc->dev = dev; sc->handle = acpi_get_handle(dev); - acpi_sc = acpi_device_get_parent_softc(dev); - /* Look for the first embedded controller */ if (!(ec_devclass = devclass_find ("acpi_ec"))) { if (bootverbose) diff --git a/sys/dev/acpi_support/acpi_sony.c b/sys/dev/acpi_support/acpi_sony.c index 808d0da25dce..88195c2d7836 100644 --- a/sys/dev/acpi_support/acpi_sony.c +++ b/sys/dev/acpi_support/acpi_sony.c @@ -102,10 +102,7 @@ static char *sny_id[] = {"SNY5001", NULL}; static int acpi_sony_probe(device_t dev) { - struct acpi_sony_softc *sc; - int ret = ENXIO; - - sc = device_get_softc(dev); + int ret = ENXIO; if (ACPI_ID_PROBE(device_get_parent(dev), dev, sny_id)) { device_set_desc(dev, "Sony notebook controller"); From c5136006b2ebefe77c76b4763513be6243e83a42 Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Wed, 13 May 2009 00:04:08 +0000 Subject: [PATCH 137/544] Eliminate duplicate error messages from "tar c". Reported by: pav@ --- lib/libarchive/archive_read_disk_entry_from_file.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libarchive/archive_read_disk_entry_from_file.c b/lib/libarchive/archive_read_disk_entry_from_file.c index 6e12517b5e58..8f90191352aa 100644 --- a/lib/libarchive/archive_read_disk_entry_from_file.c +++ b/lib/libarchive/archive_read_disk_entry_from_file.c @@ -92,6 +92,7 @@ archive_read_disk_entry_from_file(struct archive *_a, int initial_fd = fd; int r, r1; + archive_clear_error(_a); path = archive_entry_sourcepath(entry); if (path == NULL) path = archive_entry_pathname(entry); From b1f26c738c3a2433f1759099fceb31d741e4f462 Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 13 May 2009 02:26:34 +0000 Subject: [PATCH 138/544] Fix copy-paste bug in NGM_NETFLOW_SETCONFIG argument size verification. PR: kern/134220 Submitted by: Eugene Mychlo MFC after: 1 week --- sys/netgraph/netflow/ng_netflow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netgraph/netflow/ng_netflow.c b/sys/netgraph/netflow/ng_netflow.c index d43c976ba4f9..cacbd724b0dc 100644 --- a/sys/netgraph/netflow/ng_netflow.c +++ b/sys/netgraph/netflow/ng_netflow.c @@ -422,7 +422,7 @@ ng_netflow_rcvmsg (node_p node, item_p item, hook_p lasthook) { struct ng_netflow_setconfig *set; - if (msg->header.arglen != sizeof(struct ng_netflow_settimeouts)) + if (msg->header.arglen != sizeof(struct ng_netflow_setconfig)) ERROUT(EINVAL); set = (struct ng_netflow_setconfig *)msg->data; From 1c1b26f276f85b086bc6e579c452e52231c234ac Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 13 May 2009 05:39:39 +0000 Subject: [PATCH 139/544] Eliminate page queues locking from bufdone_finish() through the following changes: Rename vfs_page_set_valid() to vfs_page_set_validclean() to reflect what this function actually does. Suggested by: tegge Introduce a new version of vfs_page_set_valid() that does no more than what the function's name implies. Specifically, it does not update the page's dirty mask, and thus it does not require the page queues lock to be held. Update two of the three callers to the old vfs_page_set_valid() to call vfs_page_set_validclean() instead because they actually require the page's dirty mask to be cleared. Introduce vm_page_set_valid(). Reviewed by: tegge --- sys/kern/vfs_bio.c | 47 +++++++++++++++++++++++++++++++++++----------- sys/vm/vm_page.c | 45 ++++++++++++++++++++++++++++++++++++++++++++ sys/vm/vm_page.h | 1 + 3 files changed, 82 insertions(+), 11 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 58e349147ba6..2979f61f24ce 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -98,7 +98,8 @@ static void vm_hold_free_pages(struct buf *bp, vm_offset_t from, vm_offset_t to); static void vm_hold_load_pages(struct buf *bp, vm_offset_t from, vm_offset_t to); -static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, +static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, vm_page_t m); +static void vfs_page_set_validclean(struct buf *bp, vm_ooffset_t off, vm_page_t m); static void vfs_clean_pages(struct buf *bp); static void vfs_setdirty(struct buf *bp); @@ -3277,7 +3278,6 @@ bufdone_finish(struct buf *bp) vm_object_t obj; int iosize; struct vnode *vp = bp->b_vp; - boolean_t are_queues_locked; obj = bp->b_bufobj->bo_object; @@ -3314,11 +3314,6 @@ bufdone_finish(struct buf *bp) !(bp->b_ioflags & BIO_ERROR)) { bp->b_flags |= B_CACHE; } - if (bp->b_iocmd == BIO_READ) { - vm_page_lock_queues(); - are_queues_locked = TRUE; - } else - are_queues_locked = FALSE; for (i = 0; i < bp->b_npages; i++) { int bogusflag = 0; int resid; @@ -3354,6 +3349,9 @@ bufdone_finish(struct buf *bp) * only need to do this here in the read case. */ if ((bp->b_iocmd == BIO_READ) && !bogusflag && resid > 0) { + KASSERT((m->dirty & vm_page_bits(foff & + PAGE_MASK, resid)) == 0, ("bufdone_finish:" + " page %p has unexpected dirty bits", m)); vfs_page_set_valid(bp, foff, m); } @@ -3387,8 +3385,6 @@ bufdone_finish(struct buf *bp) foff = (foff + PAGE_SIZE) & ~(off_t)PAGE_MASK; iosize -= resid; } - if (are_queues_locked) - vm_page_unlock_queues(); vm_object_pip_wakeupn(obj, 0); VM_OBJECT_UNLOCK(obj); } @@ -3453,6 +3449,35 @@ vfs_unbusy_pages(struct buf *bp) */ static void vfs_page_set_valid(struct buf *bp, vm_ooffset_t off, vm_page_t m) +{ + vm_ooffset_t eoff; + + /* + * Compute the end offset, eoff, such that [off, eoff) does not span a + * page boundary and eoff is not greater than the end of the buffer. + * The end of the buffer, in this case, is our file EOF, not the + * allocation size of the buffer. + */ + eoff = (off + PAGE_SIZE) & ~(vm_ooffset_t)PAGE_MASK; + if (eoff > bp->b_offset + bp->b_bcount) + eoff = bp->b_offset + bp->b_bcount; + + /* + * Set valid range. This is typically the entire buffer and thus the + * entire page. + */ + if (eoff > off) + vm_page_set_valid(m, off & PAGE_MASK, eoff - off); +} + +/* + * vfs_page_set_validclean: + * + * Set the valid bits and clear the dirty bits in a page based on the + * supplied offset. The range is restricted to the buffer's size. + */ +static void +vfs_page_set_validclean(struct buf *bp, vm_ooffset_t off, vm_page_t m) { vm_ooffset_t soff, eoff; @@ -3545,7 +3570,7 @@ vfs_busy_pages(struct buf *bp, int clear_modify) */ if (clear_modify) { pmap_remove_write(m); - vfs_page_set_valid(bp, foff, m); + vfs_page_set_validclean(bp, foff, m); } else if (m->valid == VM_PAGE_BITS_ALL && (bp->b_flags & B_CACHE) == 0) { bp->b_pages[i] = bogus_page; @@ -3591,7 +3616,7 @@ vfs_clean_pages(struct buf *bp) if (eoff > bp->b_offset + bp->b_bufsize) eoff = bp->b_offset + bp->b_bufsize; - vfs_page_set_valid(bp, foff, m); + vfs_page_set_validclean(bp, foff, m); /* vm_page_clear_dirty(m, foff & PAGE_MASK, eoff - foff); */ foff = noff; } diff --git a/sys/vm/vm_page.c b/sys/vm/vm_page.c index 8befdd56705a..f0f90425a13a 100644 --- a/sys/vm/vm_page.c +++ b/sys/vm/vm_page.c @@ -1851,6 +1851,51 @@ vm_page_bits(int base, int size) return ((2 << last_bit) - (1 << first_bit)); } +/* + * vm_page_set_valid: + * + * Sets portions of a page valid. The arguments are expected + * to be DEV_BSIZE aligned but if they aren't the bitmap is inclusive + * of any partial chunks touched by the range. The invalid portion of + * such chunks will be zeroed. + * + * (base + size) must be less then or equal to PAGE_SIZE. + */ +void +vm_page_set_valid(vm_page_t m, int base, int size) +{ + int endoff, frag; + + VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED); + if (size == 0) /* handle degenerate case */ + return; + + /* + * If the base is not DEV_BSIZE aligned and the valid + * bit is clear, we have to zero out a portion of the + * first block. + */ + if ((frag = base & ~(DEV_BSIZE - 1)) != base && + (m->valid & (1 << (base >> DEV_BSHIFT))) == 0) + pmap_zero_page_area(m, frag, base - frag); + + /* + * If the ending offset is not DEV_BSIZE aligned and the + * valid bit is clear, we have to zero out a portion of + * the last block. + */ + endoff = base + size; + if ((frag = endoff & ~(DEV_BSIZE - 1)) != endoff && + (m->valid & (1 << (endoff >> DEV_BSHIFT))) == 0) + pmap_zero_page_area(m, endoff, + DEV_BSIZE - (endoff & (DEV_BSIZE - 1))); + + /* + * Set valid bits inclusive of any overlap. + */ + m->valid |= vm_page_bits(base, size); +} + /* * vm_page_set_validclean: * diff --git a/sys/vm/vm_page.h b/sys/vm/vm_page.h index 7f996ea9bfab..8bbbaee192f4 100644 --- a/sys/vm/vm_page.h +++ b/sys/vm/vm_page.h @@ -321,6 +321,7 @@ vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t); void vm_page_remove (vm_page_t); void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t); void vm_page_requeue(vm_page_t m); +void vm_page_set_valid(vm_page_t m, int base, int size); void vm_page_sleep(vm_page_t m, const char *msg); vm_page_t vm_page_splay(vm_pindex_t, vm_page_t); vm_offset_t vm_page_startup(vm_offset_t vaddr); From 07a7b85e94c29317f9737c91e4a6a1bc5ccd711c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 13 May 2009 07:42:53 +0000 Subject: [PATCH 140/544] Correct a rare use-after-free error in pmap_copy(). This error was introduced in amd64 revision 1.540 and i386 revision 1.547. However, it had no harmful effects until after a recent change, r189698, on amd64. (In other words, the error is harmless in RELENG_7.) The error is triggered by the failure to allocate a pv entry for the one and only mapping in a page table page. I am addressing the error by changing pmap_copy() to abort if either pv entry allocation or page table page allocation fails. This is appropriate because the creation of mappings by pmap_copy() is optional. They are a (possible) optimization, and not a requirement. Correct a nearby whitespace error in the i386 pmap_copy(). Crash reported by: jeff@ MFC after: 6 weeks --- sys/amd64/amd64/pmap.c | 4 +++- sys/i386/i386/pmap.c | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/sys/amd64/amd64/pmap.c b/sys/amd64/amd64/pmap.c index 883b7edaccb5..e152d3ffea91 100644 --- a/sys/amd64/amd64/pmap.c +++ b/sys/amd64/amd64/pmap.c @@ -3556,7 +3556,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, dstmpte->wire_count++; else if ((dstmpte = pmap_allocpte(dst_pmap, addr, M_NOWAIT)) == NULL) - break; + goto out; dst_pte = (pt_entry_t *) PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpte)); dst_pte = &dst_pte[pmap_pte_index(addr)]; @@ -3579,6 +3579,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, addr); pmap_free_zero_pages(free); } + goto out; } if (dstmpte->wire_count >= srcmpte->wire_count) break; @@ -3587,6 +3588,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, src_pte++; } } +out: vm_page_unlock_queues(); PMAP_UNLOCK(src_pmap); PMAP_UNLOCK(dst_pmap); diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 7f6900dfade3..5f016d5a6f7a 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -3638,7 +3638,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, dstmpte = pmap_allocpte(dst_pmap, addr, M_NOWAIT); if (dstmpte == NULL) - break; + goto out; dst_pte = pmap_pte_quick(dst_pmap, addr); if (*dst_pte == 0 && pmap_try_insert_pv_entry(dst_pmap, addr, @@ -3653,12 +3653,13 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, dst_pmap->pm_stats.resident_count++; } else { free = NULL; - if (pmap_unwire_pte_hold( dst_pmap, + if (pmap_unwire_pte_hold(dst_pmap, dstmpte, &free)) { pmap_invalidate_page(dst_pmap, addr); pmap_free_zero_pages(free); } + goto out; } if (dstmpte->wire_count >= srcmpte->wire_count) break; @@ -3667,6 +3668,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len, src_pte++; } } +out: sched_unpin(); vm_page_unlock_queues(); PMAP_UNLOCK(src_pmap); From c3c1eab368b545209f52cb60b5b452e78aa4007c Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Wed, 13 May 2009 08:50:13 +0000 Subject: [PATCH 141/544] Fix memory leak in an error case. Found with: Coverity Prevent(tm) CID: 371 MFC after: 2 weeks --- sys/compat/ndis/kern_windrv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c index 2824bcd5470a..1d4f76c93f5f 100644 --- a/sys/compat/ndis/kern_windrv.c +++ b/sys/compat/ndis/kern_windrv.c @@ -531,7 +531,10 @@ windrv_bus_attach(drv, name) RtlInitAnsiString(&as, name); if (RtlAnsiStringToUnicodeString(&drv->dro_drivername, &as, TRUE)) + { + free(new, M_DEVBUF); return(ENOMEM); + } /* * Set up a fake image pointer to avoid false matches From b53ae7114c0b73e47240895cf58dc282839b0989 Mon Sep 17 00:00:00 2001 From: Diomidis Spinellis Date: Wed, 13 May 2009 12:43:37 +0000 Subject: [PATCH 142/544] Fix compilation error introduced in r192025. --- usr.bin/truss/mips-fbsd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c index 34137d8d89f7..3e7ebf957469 100644 --- a/usr.bin/truss/mips-fbsd.c +++ b/usr.bin/truss/mips-fbsd.c @@ -338,7 +338,8 @@ mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { * but that complicates things considerably. */ - print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, retval); + print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, + fsc.sc, retval); clear_fsc(); return (retval); From 1de3b2ff030fa938f933046f581a07b123febca4 Mon Sep 17 00:00:00 2001 From: Diomidis Spinellis Date: Wed, 13 May 2009 13:00:52 +0000 Subject: [PATCH 143/544] Fix print_syscall_ret parameter order. --- usr.bin/truss/mips-fbsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c index 3e7ebf957469..bfefdd75bc16 100644 --- a/usr.bin/truss/mips-fbsd.c +++ b/usr.bin/truss/mips-fbsd.c @@ -339,7 +339,7 @@ mips_syscall_exit(struct trussinfo *trussinfo, int syscall_num __unused) { */ print_syscall_ret(trussinfo, fsc.name, fsc.nargs, fsc.s_args, errorp, - fsc.sc, retval); + retval, fsc.sc); clear_fsc(); return (retval); From 0a594d9ecc33f10d0c74dc16ff3cdbc4e509649d Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 13 May 2009 14:25:55 +0000 Subject: [PATCH 144/544] Add a short delay after programming PHY registers to give some time for the engine to catch up. This prevents a machine check exception from illegal memory requests with a BCM4318. --- sys/dev/bwi/bwiphy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c index 2f93c5960454..9fa7a6b719f8 100644 --- a/sys/dev/bwi/bwiphy.c +++ b/sys/dev/bwi/bwiphy.c @@ -664,6 +664,7 @@ bwi_phy_init_11b_rev6(struct bwi_mac *mac) for (ofs = 0xa8; ofs < 0xc8; ++ofs) { PHY_WRITE(mac, ofs, (val & 0x3f3f)); val += 0x202; + DELAY(10); } if (phy->phy_mode == IEEE80211_MODE_11G) { From d47f0d75af4cf9eeeb0fe04ceb6a708bb0670eb3 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 13 May 2009 14:43:26 +0000 Subject: [PATCH 145/544] ifp->if_softc is managed entirely by the driver. We never set it to NULL or change it. We initialize it before we set if_ioctl. It can therefore never be NULL, and most other drivers don't bother with this sanity check. --- sys/dev/ed/if_ed.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/sys/dev/ed/if_ed.c b/sys/dev/ed/if_ed.c index 5a60569ff1ef..f94ec8b76806 100644 --- a/sys/dev/ed/if_ed.c +++ b/sys/dev/ed/if_ed.c @@ -1164,14 +1164,6 @@ ed_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct ifreq *ifr = (struct ifreq *)data; int error = 0; - /* - * XXX really needed? - */ - if (sc == NULL) { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - return (ENXIO); - } - switch (command) { case SIOCSIFFLAGS: /* From 8553eea5ce22b46f348d45c5547a678e5aff88d9 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Wed, 13 May 2009 16:19:05 +0000 Subject: [PATCH 146/544] Add a comment to motivate my last change. Suggested by: sam, imp --- sys/dev/bwi/bwiphy.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c index 9fa7a6b719f8..a0be96df9533 100644 --- a/sys/dev/bwi/bwiphy.c +++ b/sys/dev/bwi/bwiphy.c @@ -664,6 +664,8 @@ bwi_phy_init_11b_rev6(struct bwi_mac *mac) for (ofs = 0xa8; ofs < 0xc8; ++ofs) { PHY_WRITE(mac, ofs, (val & 0x3f3f)); val += 0x202; + + /* XXX: delay 10 us to avoid PCI parity errors with BCM4318 */ DELAY(10); } From c834e61abdeab3b026647e8496e035cdd4db602c Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Wed, 13 May 2009 17:11:25 +0000 Subject: [PATCH 147/544] Garbage collect legacy upgt driver now that it is available in the new USB implementation. Garbage collect legacy USB ethernet framework now that it is unused. --- sys/legacy/dev/usb/if_upgt.c | 2375 ---------------------------- sys/legacy/dev/usb/if_upgtvar.h | 462 ------ sys/legacy/dev/usb/usb_ethersubr.c | 283 ---- sys/legacy/dev/usb/usb_ethersubr.h | 91 -- 4 files changed, 3211 deletions(-) delete mode 100644 sys/legacy/dev/usb/if_upgt.c delete mode 100644 sys/legacy/dev/usb/if_upgtvar.h delete mode 100644 sys/legacy/dev/usb/usb_ethersubr.c delete mode 100644 sys/legacy/dev/usb/usb_ethersubr.h diff --git a/sys/legacy/dev/usb/if_upgt.c b/sys/legacy/dev/usb/if_upgt.c deleted file mode 100644 index 9ab226f2cc5b..000000000000 --- a/sys/legacy/dev/usb/if_upgt.c +++ /dev/null @@ -1,2375 +0,0 @@ -/* $OpenBSD: if_upgt.c,v 1.35 2008/04/16 18:32:15 damien Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 2007 Marcus Glocker - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include "usbdevs.h" -#include - -#include - -/* - * Driver for the USB PrismGT devices. - * - * For now just USB 2.0 devices with the GW3887 chipset are supported. - * The driver has been written based on the firmware version 2.13.1.0_LM87. - * - * TODO's: - * - MONITOR mode test. - * - Add HOSTAP mode. - * - Add IBSS mode. - * - Support the USB 1.0 devices (NET2280, ISL3880, ISL3886 chipsets). - * - * Parts of this driver has been influenced by reading the p54u driver - * written by Jean-Baptiste Note and - * Sebastien Bourdeauducq . - */ - -SYSCTL_NODE(_hw, OID_AUTO, upgt, CTLFLAG_RD, 0, - "USB PrismGT GW3887 driver parameters"); - -/* - * NB: normally `upgt_txbuf' value can be increased to maximum 6, mininum 1. - * However, we're using just 2 txbufs to protect packet losses in some cases - * so the performance was sacrificed that with this value its speed is about - * 2.1Mb/s. - * - * With setting txbuf value as 6, you can get full speed, 3.0Mb/s, of this - * device but sometimes you'd meet some packet losses then retransmision. - */ -static int upgt_txbuf = UPGT_TX_COUNT; /* # tx buffers to allocate */ -SYSCTL_INT(_hw_upgt, OID_AUTO, txbuf, CTLFLAG_RW, &upgt_txbuf, - 0, "tx buffers allocated"); -TUNABLE_INT("hw.upgt.txbuf", &upgt_txbuf); - -#ifdef UPGT_DEBUG -int upgt_debug = 0; -SYSCTL_INT(_hw_upgt, OID_AUTO, debug, CTLFLAG_RW, &upgt_debug, - 0, "control debugging printfs"); -TUNABLE_INT("hw.upgt.debug", &upgt_debug); -enum { - UPGT_DEBUG_XMIT = 0x00000001, /* basic xmit operation */ - UPGT_DEBUG_RECV = 0x00000002, /* basic recv operation */ - UPGT_DEBUG_RESET = 0x00000004, /* reset processing */ - UPGT_DEBUG_INTR = 0x00000008, /* INTR */ - UPGT_DEBUG_TX_PROC = 0x00000010, /* tx ISR proc */ - UPGT_DEBUG_RX_PROC = 0x00000020, /* rx ISR proc */ - UPGT_DEBUG_STATE = 0x00000040, /* 802.11 state transitions */ - UPGT_DEBUG_STAT = 0x00000080, /* statistic */ - UPGT_DEBUG_FW = 0x00000100, /* firmware */ - UPGT_DEBUG_ANY = 0xffffffff -}; -#define DPRINTF(sc, m, fmt, ...) do { \ - if (sc->sc_debug & (m)) \ - printf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, m, fmt, ...) do { \ - (void) sc; \ -} while (0) -#endif - -/* - * Prototypes. - */ -static device_probe_t upgt_match; -static device_attach_t upgt_attach; -static device_detach_t upgt_detach; -static int upgt_alloc_tx(struct upgt_softc *); -static int upgt_alloc_rx(struct upgt_softc *); -static int upgt_alloc_cmd(struct upgt_softc *); -static int upgt_attach_hook(device_t); -static int upgt_device_reset(struct upgt_softc *); -static int upgt_bulk_xmit(struct upgt_softc *, struct upgt_data *, - usbd_pipe_handle, uint32_t *, int); -static int upgt_fw_verify(struct upgt_softc *); -static int upgt_mem_init(struct upgt_softc *); -static int upgt_fw_load(struct upgt_softc *); -static int upgt_fw_copy(const uint8_t *, char *, int); -static uint32_t upgt_crc32_le(const void *, size_t); -static void upgt_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static void upgt_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static int upgt_eeprom_read(struct upgt_softc *); -static int upgt_eeprom_parse(struct upgt_softc *); -static void upgt_eeprom_parse_hwrx(struct upgt_softc *, uint8_t *); -static void upgt_eeprom_parse_freq3(struct upgt_softc *, uint8_t *, int); -static void upgt_eeprom_parse_freq4(struct upgt_softc *, uint8_t *, int); -static void upgt_eeprom_parse_freq6(struct upgt_softc *, uint8_t *, int); -static uint32_t upgt_chksum_le(const uint32_t *, size_t); -static void upgt_tx_done(struct upgt_softc *, uint8_t *); -static void upgt_rx(struct upgt_softc *, uint8_t *, int); -static void upgt_init(void *); -static void upgt_init_locked(struct upgt_softc *); -static int upgt_ioctl(struct ifnet *, u_long, caddr_t); -static void upgt_start(struct ifnet *); -static int upgt_raw_xmit(struct ieee80211_node *, struct mbuf *, - const struct ieee80211_bpf_params *); -static void upgt_scan_start(struct ieee80211com *); -static void upgt_scan_end(struct ieee80211com *); -static void upgt_set_channel(struct ieee80211com *); -static struct ieee80211vap *upgt_vap_create(struct ieee80211com *, - const char name[IFNAMSIZ], int unit, int opmode, - int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]); -static void upgt_vap_delete(struct ieee80211vap *); -static void upgt_update_mcast(struct ifnet *); -static uint8_t upgt_rx_rate(struct upgt_softc *, const int); -static void upgt_set_multi(void *); -static void upgt_stop(struct upgt_softc *, int); -static void upgt_setup_rates(struct ieee80211vap *, struct ieee80211com *); -static int upgt_set_macfilter(struct upgt_softc *, uint8_t); -static int upgt_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static void upgt_task(void *); -static void upgt_scantask(void *); -static void upgt_set_chan(struct upgt_softc *, struct ieee80211_channel *); -static void upgt_set_led(struct upgt_softc *, int); -static void upgt_set_led_blink(void *); -static void upgt_tx_task(void *); -static int upgt_get_stats(struct upgt_softc *); -static void upgt_mem_free(struct upgt_softc *, uint32_t); -static uint32_t upgt_mem_alloc(struct upgt_softc *); -static void upgt_free_tx(struct upgt_softc *); -static void upgt_free_rx(struct upgt_softc *); -static void upgt_free_cmd(struct upgt_softc *); -static void upgt_watchdog(void *); - -static const char *upgt_fwname = "upgt-gw3887"; - -static const struct usb_devno upgt_devs_2[] = { - /* version 2 devices */ - { USB_VENDOR_ACCTON, USB_PRODUCT_ACCTON_PRISM_GT }, - { USB_VENDOR_BELKIN, USB_PRODUCT_BELKIN_F5D7050 }, - { USB_VENDOR_CONCEPTRONIC, USB_PRODUCT_CONCEPTRONIC_PRISM_GT }, - { USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_1 }, - { USB_VENDOR_DELL, USB_PRODUCT_DELL_PRISM_GT_2 }, - { USB_VENDOR_FSC, USB_PRODUCT_FSC_E5400 }, - { USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_1 }, - { USB_VENDOR_GLOBESPAN, USB_PRODUCT_GLOBESPAN_PRISM_GT_2 }, - { USB_VENDOR_INTERSIL, USB_PRODUCT_INTERSIL_PRISM_GT }, - { USB_VENDOR_SMC, USB_PRODUCT_SMC_2862WG }, - { USB_VENDOR_WISTRONNEWEB, USB_PRODUCT_WISTRONNEWEB_UR045G }, - { USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_1 }, - { USB_VENDOR_XYRATEX, USB_PRODUCT_XYRATEX_PRISM_GT_2 }, - { USB_VENDOR_ZCOM, USB_PRODUCT_ZCOM_XG703A } -}; - -static int -upgt_match(device_t dev) -{ - struct usb_attach_arg *uaa = device_get_ivars(dev); - - if (!uaa->iface) - return UMATCH_NONE; - - if (usb_lookup(upgt_devs_2, uaa->vendor, uaa->product) != NULL) - return (UMATCH_VENDOR_PRODUCT); - - return (UMATCH_NONE); -} - -static int -upgt_attach(device_t dev) -{ - int i; - struct upgt_softc *sc = device_get_softc(dev); - struct usb_attach_arg *uaa = device_get_ivars(dev); - usb_endpoint_descriptor_t *ed; - usb_interface_descriptor_t *id; - usbd_status error; - - sc->sc_dev = dev; - sc->sc_udev = uaa->device; -#ifdef UPGT_DEBUG - sc->sc_debug = upgt_debug; -#endif - - /* set configuration number */ - if (usbd_set_config_no(sc->sc_udev, UPGT_CONFIG_NO, 0) != 0) { - device_printf(dev, "could not set configuration no!\n"); - return ENXIO; - } - - /* get the first interface handle */ - error = usbd_device2interface_handle(sc->sc_udev, UPGT_IFACE_INDEX, - &sc->sc_iface); - if (error != 0) { - device_printf(dev, "could not get interface handle!\n"); - return ENXIO; - } - - /* find endpoints */ - id = usbd_get_interface_descriptor(sc->sc_iface); - sc->sc_rx_no = sc->sc_tx_no = -1; - for (i = 0; i < id->bNumEndpoints; i++) { - ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); - if (ed == NULL) { - device_printf(dev, - "no endpoint descriptor for iface %d!\n", i); - return ENXIO; - } - - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_OUT && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_tx_no = ed->bEndpointAddress; - if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN && - UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) - sc->sc_rx_no = ed->bEndpointAddress; - - /* - * 0x01 TX pipe - * 0x81 RX pipe - * - * Deprecated scheme (not used with fw version >2.5.6.x): - * 0x02 TX MGMT pipe - * 0x82 TX MGMT pipe - */ - if (sc->sc_tx_no != -1 && sc->sc_rx_no != -1) - break; - } - if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { - device_printf(dev, "missing endpoint!\n"); - return ENXIO; - } - - /* - * Open TX and RX USB bulk pipes. - */ - error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, - &sc->sc_tx_pipeh); - if (error != 0) { - device_printf(dev, "could not open TX pipe: %s!\n", - usbd_errstr(error)); - goto fail; - } - error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, - &sc->sc_rx_pipeh); - if (error != 0) { - device_printf(dev, "could not open RX pipe: %s!\n", - usbd_errstr(error)); - goto fail; - } - - /* Allocate TX, RX, and CMD xfers. */ - if (upgt_alloc_tx(sc) != 0) - goto fail; - if (upgt_alloc_rx(sc) != 0) - goto fail; - if (upgt_alloc_cmd(sc) != 0) - goto fail; - - /* We need the firmware loaded to complete the attach. */ - return upgt_attach_hook(dev); - -fail: - device_printf(dev, "%s failed!\n", __func__); - return ENXIO; -} - -static int -upgt_attach_hook(device_t dev) -{ - struct ieee80211com *ic; - struct ifnet *ifp; - struct upgt_softc *sc = device_get_softc(dev); - struct upgt_data *data_rx = &sc->rx_data; - uint8_t bands; - usbd_status error; - - ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - return ENXIO; - } - - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - usb_init_task(&sc->sc_mcasttask, upgt_set_multi, sc); - usb_init_task(&sc->sc_scantask, upgt_scantask, sc); - usb_init_task(&sc->sc_task, upgt_task, sc); - usb_init_task(&sc->sc_task_tx, upgt_tx_task, sc); - callout_init(&sc->sc_led_ch, 0); - callout_init(&sc->sc_watchdog_ch, 0); - - /* Initialize the device. */ - if (upgt_device_reset(sc) != 0) - goto fail; - - /* Verify the firmware. */ - if (upgt_fw_verify(sc) != 0) - goto fail; - - /* Calculate device memory space. */ - if (sc->sc_memaddr_frame_start == 0 || sc->sc_memaddr_frame_end == 0) { - device_printf(dev, - "could not find memory space addresses on FW!\n"); - goto fail; - } - sc->sc_memaddr_frame_end -= UPGT_MEMSIZE_RX + 1; - sc->sc_memaddr_rx_start = sc->sc_memaddr_frame_end + 1; - - DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame start=0x%08x\n", - sc->sc_memaddr_frame_start); - DPRINTF(sc, UPGT_DEBUG_FW, "memory address frame end=0x%08x\n", - sc->sc_memaddr_frame_end); - DPRINTF(sc, UPGT_DEBUG_FW, "memory address rx start=0x%08x\n", - sc->sc_memaddr_rx_start); - - upgt_mem_init(sc); - - /* Load the firmware. */ - if (upgt_fw_load(sc) != 0) - goto fail; - - /* Startup the RX pipe. */ - usbd_setup_xfer(data_rx->xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, - MCLBYTES, USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rxeof); - error = usbd_transfer(data_rx->xfer); - if (error != 0 && error != USBD_IN_PROGRESS) { - device_printf(dev, "could not queue RX transfer!\n"); - goto fail; - } - usbd_delay_ms(sc->sc_udev, 100); - - /* Read the whole EEPROM content and parse it. */ - if (upgt_eeprom_read(sc) != 0) - goto fail; - if (upgt_eeprom_parse(sc) != 0) - goto fail; - - /* Setup the 802.11 device. */ - ifp->if_softc = sc; - if_initname(ifp, "upgt", device_get_unit(sc->sc_dev)); - ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | - IFF_NEEDSGIANT; /* USB stack is still under Giant lock */ - ifp->if_init = upgt_init; - ifp->if_ioctl = upgt_ioctl; - ifp->if_start = upgt_start; - IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); - IFQ_SET_READY(&ifp->if_snd); - - ic = ifp->if_l2com; - ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; - /* set device capabilities */ - ic->ic_caps = - IEEE80211_C_STA /* station mode */ - | IEEE80211_C_MONITOR /* monitor mode */ - | IEEE80211_C_SHPREAMBLE /* short preamble supported */ - | IEEE80211_C_SHSLOT /* short slot time supported */ - | IEEE80211_C_BGSCAN /* capable of bg scanning */ - | IEEE80211_C_WPA /* 802.11i */ - ; - - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - ieee80211_init_channels(ic, NULL, &bands); - - ieee80211_ifattach(ic); - ic->ic_raw_xmit = upgt_raw_xmit; - ic->ic_scan_start = upgt_scan_start; - ic->ic_scan_end = upgt_scan_end; - ic->ic_set_channel = upgt_set_channel; - - ic->ic_vap_create = upgt_vap_create; - ic->ic_vap_delete = upgt_vap_delete; - ic->ic_update_mcast = upgt_update_mcast; - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof(sc->sc_rxtap); - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof(sc->sc_txtap); - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT); - - if (bootverbose) - ieee80211_announce(ic); - - usbd_add_drv_event(USB_EVENT_DRIVER_ATTACH, sc->sc_udev, sc->sc_dev); - return 0; -fail: - device_printf(dev, "%s failed!\n", __func__); - mtx_destroy(&sc->sc_mtx); - if_free(ifp); - return ENXIO; -} - -static void -upgt_tx_task(void *arg) -{ - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211_frame *wh; - struct ieee80211_key *k; - struct upgt_data *data_tx; - struct upgt_lmac_mem *mem; - struct upgt_lmac_tx_desc *txdesc; - struct mbuf *m; - uint32_t addr; - int len, i; - usbd_status error; - - upgt_set_led(sc, UPGT_LED_BLINK); - - UPGT_LOCK(sc); - for (i = 0; i < upgt_txbuf; i++) { - data_tx = &sc->tx_data[i]; - if (data_tx->m == NULL) - continue; - - m = data_tx->m; - addr = data_tx->addr + UPGT_MEMSIZE_FRAME_HEAD; - - /* - * Software crypto. - */ - wh = mtod(m, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(data_tx->ni, m); - if (k == NULL) { - device_printf(sc->sc_dev, - "ieee80211_crypto_encap returns NULL.\n"); - goto done; - } - - /* in case packet header moved, reset pointer */ - wh = mtod(m, struct ieee80211_frame *); - } - - /* - * Transmit the URB containing the TX data. - */ - bzero(data_tx->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_tx->buf; - mem->addr = htole32(addr); - - txdesc = (struct upgt_lmac_tx_desc *)(mem + 1); - - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == - IEEE80211_FC0_TYPE_MGT) { - /* mgmt frames */ - txdesc->header1.flags = UPGT_H1_FLAGS_TX_MGMT; - /* always send mgmt frames at lowest rate (DS1) */ - memset(txdesc->rates, 0x10, sizeof(txdesc->rates)); - } else { - /* data frames */ - txdesc->header1.flags = UPGT_H1_FLAGS_TX_DATA; - bcopy(sc->sc_cur_rateset, txdesc->rates, - sizeof(txdesc->rates)); - } - txdesc->header1.type = UPGT_H1_TYPE_TX_DATA; - txdesc->header1.len = htole16(m->m_pkthdr.len); - txdesc->header2.reqid = htole32(data_tx->addr); - txdesc->header2.type = htole16(UPGT_H2_TYPE_TX_ACK_YES); - txdesc->header2.flags = htole16(UPGT_H2_FLAGS_TX_ACK_YES); - txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA); - txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE; - - if (bpf_peers_present(ifp->if_bpf)) { - struct upgt_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = 0; /* XXX where to get from? */ - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); - } - - /* copy frame below our TX descriptor header */ - m_copydata(m, 0, m->m_pkthdr.len, - data_tx->buf + (sizeof(*mem) + sizeof(*txdesc))); - /* calculate frame size */ - len = sizeof(*mem) + sizeof(*txdesc) + m->m_pkthdr.len; - /* we need to align the frame to a 4 byte boundary */ - len = (len + 3) & ~3; - /* calculate frame checksum */ - mem->chksum = upgt_chksum_le((uint32_t *)txdesc, - len - sizeof(*mem)); - /* we do not need the mbuf anymore */ - m_freem(m); - data_tx->m = NULL; - - DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: TX start data sending\n", - __func__); - KASSERT(len <= MCLBYTES, ("mbuf is small for saving data")); - - usbd_setup_xfer(data_tx->xfer, sc->sc_tx_pipeh, data_tx, - data_tx->buf, len, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, - UPGT_USB_TIMEOUT, upgt_txeof); - UPGT_UNLOCK(sc); - mtx_lock(&Giant); - error = usbd_transfer(data_tx->xfer); - mtx_unlock(&Giant); - UPGT_LOCK(sc); - if (error != 0 && error != USBD_IN_PROGRESS) { - device_printf(sc->sc_dev, - "could not transmit TX data URB!\n"); - goto done; - } - - DPRINTF(sc, UPGT_DEBUG_XMIT, "TX sent (%d bytes)\n", len); - } -done: - UPGT_UNLOCK(sc); - /* - * If we don't regulary read the device statistics, the RX queue - * will stall. It's strange, but it works, so we keep reading - * the statistics here. *shrug* - */ - (void)upgt_get_stats(sc); -} - -static void -upgt_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct upgt_data *data_tx = priv; - struct upgt_softc *sc = data_tx->sc; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - if (status == USBD_STALLED) { - usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); - return; - } - - device_printf(sc->sc_dev, "TX warning(%s)\n", - usbd_errstr(status)); - } -} - -static int -upgt_get_stats(struct upgt_softc *sc) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_lmac_mem *mem; - struct upgt_lmac_stats *stats; - int len; - - /* - * Transmit the URB containing the CMD data. - */ - bzero(data_cmd->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_cmd->buf; - mem->addr = htole32(sc->sc_memaddr_frame_start + - UPGT_MEMSIZE_FRAME_HEAD); - - stats = (struct upgt_lmac_stats *)(mem + 1); - - stats->header1.flags = 0; - stats->header1.type = UPGT_H1_TYPE_CTRL; - stats->header1.len = htole16( - sizeof(struct upgt_lmac_stats) - sizeof(struct upgt_lmac_header)); - - stats->header2.reqid = htole32(sc->sc_memaddr_frame_start); - stats->header2.type = htole16(UPGT_H2_TYPE_STATS); - stats->header2.flags = 0; - - len = sizeof(*mem) + sizeof(*stats); - - mem->chksum = upgt_chksum_le((uint32_t *)stats, - len - sizeof(*mem)); - - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not transmit statistics CMD data URB!\n"); - return (EIO); - } - - return (0); -} - -static int -upgt_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct upgt_softc *sc = ifp->if_softc; - struct ieee80211com *ic = ifp->if_l2com; - struct ifreq *ifr = (struct ifreq *) data; - int error = 0, startall = 0; - - switch (cmd) { - case SIOCSIFFLAGS: - mtx_lock(&Giant); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if ((ifp->if_flags ^ sc->sc_if_flags) & - (IFF_ALLMULTI | IFF_PROMISC)) - upgt_set_multi(sc); - } else { - upgt_init(sc); - startall = 1; - } - } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - upgt_stop(sc, 1); - } - sc->sc_if_flags = ifp->if_flags; - if (startall) - ieee80211_start_all(ic); - mtx_unlock(&Giant); - break; - case SIOCGIFMEDIA: - error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); - break; - case SIOCGIFADDR: - error = ether_ioctl(ifp, cmd, data); - break; - default: - error = EINVAL; - break; - } - return error; -} - -static void -upgt_stop(struct upgt_softc *sc, int disable) -{ - struct ifnet *ifp = sc->sc_ifp; - - /* abort and close TX / RX pipes */ - if (sc->sc_tx_pipeh != NULL) - usbd_abort_pipe(sc->sc_tx_pipeh); - if (sc->sc_rx_pipeh != NULL) - usbd_abort_pipe(sc->sc_rx_pipeh); - - /* device down */ - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); -} - -static void -upgt_task(void *arg) -{ - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct upgt_vap *uvp = UPGT_VAP(vap); - - DPRINTF(sc, UPGT_DEBUG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[vap->iv_state], - ieee80211_state_name[sc->sc_state]); - - switch (sc->sc_state) { - case IEEE80211_S_INIT: - /* do not accept any frames if the device is down */ - UPGT_LOCK(sc); - upgt_set_macfilter(sc, sc->sc_state); - UPGT_UNLOCK(sc); - upgt_set_led(sc, UPGT_LED_OFF); - break; - case IEEE80211_S_SCAN: - upgt_set_chan(sc, ic->ic_curchan); - break; - case IEEE80211_S_AUTH: - upgt_set_chan(sc, ic->ic_curchan); - break; - case IEEE80211_S_ASSOC: - break; - case IEEE80211_S_RUN: - UPGT_LOCK(sc); - upgt_set_macfilter(sc, sc->sc_state); - UPGT_UNLOCK(sc); - upgt_set_led(sc, UPGT_LED_ON); - break; - default: - break; - } - - IEEE80211_LOCK(ic); - uvp->newstate(vap, sc->sc_state, sc->sc_arg); - if (vap->iv_newstate_cb != NULL) - vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); - IEEE80211_UNLOCK(ic); -} - -static void -upgt_set_led(struct upgt_softc *sc, int action) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_lmac_mem *mem; - struct upgt_lmac_led *led; - int len; - - /* - * Transmit the URB containing the CMD data. - */ - bzero(data_cmd->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_cmd->buf; - mem->addr = htole32(sc->sc_memaddr_frame_start + - UPGT_MEMSIZE_FRAME_HEAD); - - led = (struct upgt_lmac_led *)(mem + 1); - - led->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; - led->header1.type = UPGT_H1_TYPE_CTRL; - led->header1.len = htole16( - sizeof(struct upgt_lmac_led) - - sizeof(struct upgt_lmac_header)); - - led->header2.reqid = htole32(sc->sc_memaddr_frame_start); - led->header2.type = htole16(UPGT_H2_TYPE_LED); - led->header2.flags = 0; - - switch (action) { - case UPGT_LED_OFF: - led->mode = htole16(UPGT_LED_MODE_SET); - led->action_fix = 0; - led->action_tmp = htole16(UPGT_LED_ACTION_OFF); - led->action_tmp_dur = 0; - break; - case UPGT_LED_ON: - led->mode = htole16(UPGT_LED_MODE_SET); - led->action_fix = 0; - led->action_tmp = htole16(UPGT_LED_ACTION_ON); - led->action_tmp_dur = 0; - break; - case UPGT_LED_BLINK: - if (sc->sc_state != IEEE80211_S_RUN) - return; - if (sc->sc_led_blink) - /* previous blink was not finished */ - return; - led->mode = htole16(UPGT_LED_MODE_SET); - led->action_fix = htole16(UPGT_LED_ACTION_OFF); - led->action_tmp = htole16(UPGT_LED_ACTION_ON); - led->action_tmp_dur = htole16(UPGT_LED_ACTION_TMP_DUR); - /* lock blink */ - sc->sc_led_blink = 1; - callout_reset(&sc->sc_led_ch, hz, upgt_set_led_blink, sc); - break; - default: - return; - } - - len = sizeof(*mem) + sizeof(*led); - - mem->chksum = upgt_chksum_le((uint32_t *)led, - len - sizeof(*mem)); - - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) - device_printf(sc->sc_dev, "could not transmit led CMD URB!\n"); -} - -static void -upgt_set_led_blink(void *arg) -{ - struct upgt_softc *sc = arg; - - /* blink finished, we are ready for a next one */ - sc->sc_led_blink = 0; -} - -static void -upgt_init(void *priv) -{ - struct upgt_softc *sc = priv; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - UPGT_LOCK(sc); - upgt_init_locked(sc); - UPGT_UNLOCK(sc); - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ieee80211_start_all(ic); /* start all vap's */ -} - -static void -upgt_init_locked(struct upgt_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - DPRINTF(sc, UPGT_DEBUG_RESET, "setting MAC address to %s\n", - ether_sprintf(ic->ic_myaddr)); - - upgt_set_macfilter(sc, IEEE80211_S_SCAN); - - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - ifp->if_drv_flags |= IFF_DRV_RUNNING; -} - -static int -upgt_set_macfilter(struct upgt_softc *sc, uint8_t state) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); - struct ieee80211_node *ni = vap->iv_bss; - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_lmac_mem *mem; - struct upgt_lmac_filter *filter; - int len; - uint8_t broadcast[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; - - /* - * Transmit the URB containing the CMD data. - */ - bzero(data_cmd->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_cmd->buf; - mem->addr = htole32(sc->sc_memaddr_frame_start + - UPGT_MEMSIZE_FRAME_HEAD); - - filter = (struct upgt_lmac_filter *)(mem + 1); - - filter->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; - filter->header1.type = UPGT_H1_TYPE_CTRL; - filter->header1.len = htole16( - sizeof(struct upgt_lmac_filter) - - sizeof(struct upgt_lmac_header)); - - filter->header2.reqid = htole32(sc->sc_memaddr_frame_start); - filter->header2.type = htole16(UPGT_H2_TYPE_MACFILTER); - filter->header2.flags = 0; - - switch (state) { - case IEEE80211_S_INIT: - DPRINTF(sc, UPGT_DEBUG_STATE, "%s: set MAC filter to INIT\n", - __func__); - filter->type = htole16(UPGT_FILTER_TYPE_RESET); - break; - case IEEE80211_S_SCAN: - DPRINTF(sc, UPGT_DEBUG_STATE, - "set MAC filter to SCAN (bssid %s)\n", - ether_sprintf(broadcast)); - filter->type = htole16(UPGT_FILTER_TYPE_NONE); - IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr); - IEEE80211_ADDR_COPY(filter->src, broadcast); - filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); - filter->rxaddr = htole32(sc->sc_memaddr_rx_start); - filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2); - filter->rxhw = htole32(sc->sc_eeprom_hwrx); - filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); - break; - case IEEE80211_S_RUN: - /* XXX monitor mode isn't tested yet. */ - if (vap->iv_opmode == IEEE80211_M_MONITOR) { - filter->type = htole16(UPGT_FILTER_TYPE_MONITOR); - IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr); - IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); - filter->unknown1 = htole16(UPGT_FILTER_MONITOR_UNKNOWN1); - filter->rxaddr = htole32(sc->sc_memaddr_rx_start); - filter->unknown2 = htole16(UPGT_FILTER_MONITOR_UNKNOWN2); - filter->rxhw = htole32(sc->sc_eeprom_hwrx); - filter->unknown3 = htole16(UPGT_FILTER_MONITOR_UNKNOWN3); - } else { - DPRINTF(sc, UPGT_DEBUG_STATE, - "set MAC filter to RUN (bssid %s)\n", - ether_sprintf(ni->ni_bssid)); - filter->type = htole16(UPGT_FILTER_TYPE_STA); - IEEE80211_ADDR_COPY(filter->dst, ic->ic_myaddr); - IEEE80211_ADDR_COPY(filter->src, ni->ni_bssid); - filter->unknown1 = htole16(UPGT_FILTER_UNKNOWN1); - filter->rxaddr = htole32(sc->sc_memaddr_rx_start); - filter->unknown2 = htole16(UPGT_FILTER_UNKNOWN2); - filter->rxhw = htole32(sc->sc_eeprom_hwrx); - filter->unknown3 = htole16(UPGT_FILTER_UNKNOWN3); - } - break; - default: - device_printf(sc->sc_dev, - "MAC filter does not know that state!\n"); - break; - } - - len = sizeof(*mem) + sizeof(*filter); - - mem->chksum = upgt_chksum_le((uint32_t *)filter, - len - sizeof(*mem)); - - UPGT_UNLOCK(sc); - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not transmit macfilter CMD data URB!\n"); - UPGT_LOCK(sc); - return (EIO); - } - UPGT_LOCK(sc); - - return (0); -} - -static void -upgt_setup_rates(struct ieee80211vap *vap, struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct upgt_softc *sc = ifp->if_softc; - const struct ieee80211_txparam *tp; - - /* - * 0x01 = OFMD6 0x10 = DS1 - * 0x04 = OFDM9 0x11 = DS2 - * 0x06 = OFDM12 0x12 = DS5 - * 0x07 = OFDM18 0x13 = DS11 - * 0x08 = OFDM24 - * 0x09 = OFDM36 - * 0x0a = OFDM48 - * 0x0b = OFDM54 - */ - const uint8_t rateset_auto_11b[] = - { 0x13, 0x13, 0x12, 0x11, 0x11, 0x10, 0x10, 0x10 }; - const uint8_t rateset_auto_11g[] = - { 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x04, 0x01 }; - const uint8_t rateset_fix_11bg[] = - { 0x10, 0x11, 0x12, 0x13, 0x01, 0x04, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b }; - - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; - - /* XXX */ - if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { - /* - * Automatic rate control is done by the device. - * We just pass the rateset from which the device - * will pickup a rate. - */ - if (ic->ic_curmode == IEEE80211_MODE_11B) - bcopy(rateset_auto_11b, sc->sc_cur_rateset, - sizeof(sc->sc_cur_rateset)); - if (ic->ic_curmode == IEEE80211_MODE_11G || - ic->ic_curmode == IEEE80211_MODE_AUTO) - bcopy(rateset_auto_11g, sc->sc_cur_rateset, - sizeof(sc->sc_cur_rateset)); - } else { - /* set a fixed rate */ - memset(sc->sc_cur_rateset, rateset_fix_11bg[tp->ucastrate], - sizeof(sc->sc_cur_rateset)); - } -} - -static void -upgt_set_multi(void *arg) -{ - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - - if (!(ifp->if_flags & IFF_UP)) - return; - - /* - * XXX don't know how to set a device. Lack of docs. Just try to set - * IFF_ALLMULTI flag here. - */ - IF_ADDR_LOCK(ifp); - ifp->if_flags |= IFF_ALLMULTI; - IF_ADDR_UNLOCK(ifp); -} - -static void -upgt_start(struct ifnet *ifp) -{ - struct upgt_softc *sc = ifp->if_softc; - struct upgt_data *data_tx; - struct ieee80211_node *ni; - struct mbuf *m; - int i; - - UPGT_LOCK(sc); - for (i = 0; i < upgt_txbuf; i++) { - data_tx = &sc->tx_data[i]; - if (data_tx->use == 1) - continue; - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - - ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; - m = ieee80211_encap(ni, m); - if (m == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - - if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) { - device_printf(sc->sc_dev, "no free prism memory!\n"); - UPGT_UNLOCK(sc); - return; - } - data_tx->ni = ni; - data_tx->m = m; - data_tx->use = 1; - sc->tx_queued++; - } - - if (sc->tx_queued > 0) { - DPRINTF(sc, UPGT_DEBUG_XMIT, "tx_queued=%d\n", sc->tx_queued); - - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_tx_timer = 5; - callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); - /* process the TX queue in process context */ - usb_rem_task(sc->sc_udev, &sc->sc_task_tx); - usb_add_task(sc->sc_udev, &sc->sc_task_tx, USB_TASKQ_DRIVER); - } - UPGT_UNLOCK(sc); -} - -static int -upgt_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, - const struct ieee80211_bpf_params *params) -{ - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; - struct upgt_softc *sc = ifp->if_softc; - struct upgt_data *data_tx = NULL; - int i; - - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - m_freem(m); - ieee80211_free_node(ni); - return ENETDOWN; - } - - UPGT_LOCK(sc); - if (sc->tx_queued >= upgt_txbuf) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - m_freem(m); - ieee80211_free_node(ni); - UPGT_UNLOCK(sc); - return ENOBUFS; /* XXX */ - } - - ifp->if_opackets++; - - /* choose a unused buffer. */ - for (i = 0; i < upgt_txbuf; i++) { - data_tx = &sc->tx_data[i]; - if (data_tx->use == 0) - break; - } - KASSERT(data_tx != NULL, ("data_tx is NULL")); - KASSERT(data_tx->use == 0, ("no empty TX queue")); - if ((data_tx->addr = upgt_mem_alloc(sc)) == 0) { - device_printf(sc->sc_dev, "no free prism memory!\n"); - UPGT_UNLOCK(sc); - return ENOBUFS; - } - - if (bpf_peers_present(ifp->if_bpf)) { - struct upgt_tx_radiotap_header *tap = &sc->sc_txtap; - - tap->wt_flags = 0; - tap->wt_rate = 0; /* TODO: where to get from? */ - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); - } - - data_tx->ni = ni; - data_tx->m = m; - data_tx->use = 1; - sc->tx_queued++; - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - UPGT_UNLOCK(sc); - - sc->sc_tx_timer = 5; - callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); - usb_rem_task(sc->sc_udev, &sc->sc_task_tx); - usb_add_task(sc->sc_udev, &sc->sc_task_tx, USB_TASKQ_DRIVER); - - return 0; -} - -static void -upgt_watchdog(void *arg) -{ - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - - if (sc->sc_tx_timer > 0) { - if (--sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "watchdog timeout\n"); - /* upgt_init(ifp); XXX needs a process context ? */ - ifp->if_oerrors++; - return; - } - callout_reset(&sc->sc_watchdog_ch, hz, upgt_watchdog, sc); - } -} - -static uint32_t -upgt_mem_alloc(struct upgt_softc *sc) -{ - int i; - - for (i = 0; i < sc->sc_memory.pages; i++) { - if (sc->sc_memory.page[i].used == 0) { - sc->sc_memory.page[i].used = 1; - return (sc->sc_memory.page[i].addr); - } - } - - return (0); -} - -static void -upgt_scantask(void *arg) -{ - struct upgt_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - switch (sc->sc_scan_action) { - case UPGT_SET_CHANNEL: - upgt_set_chan(sc, ic->ic_curchan); - break; - default: - device_printf(sc->sc_dev, "unknown scan action %d\n", - sc->sc_scan_action); - break; - } -} - -static void -upgt_scan_start(struct ieee80211com *ic) -{ - /* do nothing. */ -} - -static void -upgt_scan_end(struct ieee80211com *ic) -{ - /* do nothing. */ -} - -static void -upgt_set_channel(struct ieee80211com *ic) -{ - struct upgt_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - - /* do it in a process context */ - sc->sc_scan_action = UPGT_SET_CHANNEL; - usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); -} - -static void -upgt_set_chan(struct upgt_softc *sc, struct ieee80211_channel *c) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_lmac_mem *mem; - struct upgt_lmac_channel *chan; - int len, channel; - - channel = ieee80211_chan2ieee(ic, c); - if (channel == 0 || channel == IEEE80211_CHAN_ANY) { - /* XXX should NEVER happen */ - device_printf(sc->sc_dev, - "%s: invalid channel %x\n", __func__, channel); - return; - } - - DPRINTF(sc, UPGT_DEBUG_STATE, "%s: channel %d\n", __func__, channel); - - /* - * Transmit the URB containing the CMD data. - */ - bzero(data_cmd->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_cmd->buf; - mem->addr = htole32(sc->sc_memaddr_frame_start + - UPGT_MEMSIZE_FRAME_HEAD); - - chan = (struct upgt_lmac_channel *)(mem + 1); - - chan->header1.flags = UPGT_H1_FLAGS_TX_NO_CALLBACK; - chan->header1.type = UPGT_H1_TYPE_CTRL; - chan->header1.len = htole16( - sizeof(struct upgt_lmac_channel) - sizeof(struct upgt_lmac_header)); - - chan->header2.reqid = htole32(sc->sc_memaddr_frame_start); - chan->header2.type = htole16(UPGT_H2_TYPE_CHANNEL); - chan->header2.flags = 0; - - chan->unknown1 = htole16(UPGT_CHANNEL_UNKNOWN1); - chan->unknown2 = htole16(UPGT_CHANNEL_UNKNOWN2); - chan->freq6 = sc->sc_eeprom_freq6[channel]; - chan->settings = sc->sc_eeprom_freq6_settings; - chan->unknown3 = UPGT_CHANNEL_UNKNOWN3; - - bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_1, - sizeof(chan->freq3_1)); - bcopy(&sc->sc_eeprom_freq4[channel], chan->freq4, - sizeof(sc->sc_eeprom_freq4[channel])); - bcopy(&sc->sc_eeprom_freq3[channel].data, chan->freq3_2, - sizeof(chan->freq3_2)); - - len = sizeof(*mem) + sizeof(*chan); - - mem->chksum = upgt_chksum_le((uint32_t *)chan, - len - sizeof(*mem)); - - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) - device_printf(sc->sc_dev, - "could not transmit channel CMD data URB!\n"); -} - -static struct ieee80211vap * -upgt_vap_create(struct ieee80211com *ic, - const char name[IFNAMSIZ], int unit, int opmode, int flags, - const uint8_t bssid[IEEE80211_ADDR_LEN], - const uint8_t mac[IEEE80211_ADDR_LEN]) -{ - struct upgt_vap *uvp; - struct ieee80211vap *vap; - - if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ - return NULL; - uvp = (struct upgt_vap *) malloc(sizeof(struct upgt_vap), - M_80211_VAP, M_NOWAIT | M_ZERO); - if (uvp == NULL) - return NULL; - vap = &uvp->vap; - /* enable s/w bmiss handling for sta mode */ - ieee80211_vap_setup(ic, vap, name, unit, opmode, - flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); - - /* override state transition machine */ - uvp->newstate = vap->iv_newstate; - vap->iv_newstate = upgt_newstate; - - /* setup device rates */ - upgt_setup_rates(vap, ic); - - /* complete setup */ - ieee80211_vap_attach(vap, ieee80211_media_change, - ieee80211_media_status); - ic->ic_opmode = opmode; - return vap; -} - -static int -upgt_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) -{ - struct upgt_vap *uvp = UPGT_VAP(vap); - struct ieee80211com *ic = vap->iv_ic; - struct upgt_softc *sc = ic->ic_ifp->if_softc; - - usb_rem_task(sc->sc_udev, &sc->sc_task); - - /* do it in a process context */ - sc->sc_state = nstate; - sc->sc_arg = arg; - - if (nstate == IEEE80211_S_INIT) { - uvp->newstate(vap, nstate, arg); - return 0; - } else { - usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return EINPROGRESS; - } -} - -static void -upgt_vap_delete(struct ieee80211vap *vap) -{ - struct upgt_vap *uvp = UPGT_VAP(vap); - - ieee80211_vap_detach(vap); - free(uvp, M_80211_VAP); -} - -static void -upgt_update_mcast(struct ifnet *ifp) -{ - struct upgt_softc *sc = ifp->if_softc; - - usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER); -} - -static int -upgt_eeprom_parse(struct upgt_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct upgt_eeprom_header *eeprom_header; - struct upgt_eeprom_option *eeprom_option; - uint16_t option_len; - uint16_t option_type; - uint16_t preamble_len; - int option_end = 0; - - /* calculate eeprom options start offset */ - eeprom_header = (struct upgt_eeprom_header *)sc->sc_eeprom; - preamble_len = le16toh(eeprom_header->preamble_len); - eeprom_option = (struct upgt_eeprom_option *)(sc->sc_eeprom + - (sizeof(struct upgt_eeprom_header) + preamble_len)); - - while (!option_end) { - /* the eeprom option length is stored in words */ - option_len = - (le16toh(eeprom_option->len) - 1) * sizeof(uint16_t); - option_type = - le16toh(eeprom_option->type); - - switch (option_type) { - case UPGT_EEPROM_TYPE_NAME: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM name len=%d\n", option_len); - break; - case UPGT_EEPROM_TYPE_SERIAL: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM serial len=%d\n", option_len); - break; - case UPGT_EEPROM_TYPE_MAC: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM mac len=%d\n", option_len); - - IEEE80211_ADDR_COPY(ic->ic_myaddr, eeprom_option->data); - break; - case UPGT_EEPROM_TYPE_HWRX: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM hwrx len=%d\n", option_len); - - upgt_eeprom_parse_hwrx(sc, eeprom_option->data); - break; - case UPGT_EEPROM_TYPE_CHIP: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM chip len=%d\n", option_len); - break; - case UPGT_EEPROM_TYPE_FREQ3: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM freq3 len=%d\n", option_len); - - upgt_eeprom_parse_freq3(sc, eeprom_option->data, - option_len); - break; - case UPGT_EEPROM_TYPE_FREQ4: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM freq4 len=%d\n", option_len); - - upgt_eeprom_parse_freq4(sc, eeprom_option->data, - option_len); - break; - case UPGT_EEPROM_TYPE_FREQ5: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM freq5 len=%d\n", option_len); - break; - case UPGT_EEPROM_TYPE_FREQ6: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM freq6 len=%d\n", option_len); - - upgt_eeprom_parse_freq6(sc, eeprom_option->data, - option_len); - break; - case UPGT_EEPROM_TYPE_END: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM end len=%d\n", option_len); - option_end = 1; - break; - case UPGT_EEPROM_TYPE_OFF: - DPRINTF(sc, UPGT_DEBUG_FW, - "%s: EEPROM off without end option!\n", __func__); - return (EIO); - default: - DPRINTF(sc, UPGT_DEBUG_FW, - "EEPROM unknown type 0x%04x len=%d\n", - option_type, option_len); - break; - } - - /* jump to next EEPROM option */ - eeprom_option = (struct upgt_eeprom_option *) - (eeprom_option->data + option_len); - } - - return (0); -} - -static void -upgt_eeprom_parse_freq3(struct upgt_softc *sc, uint8_t *data, int len) -{ - struct upgt_eeprom_freq3_header *freq3_header; - struct upgt_lmac_freq3 *freq3; - int i, elements, flags; - unsigned channel; - - freq3_header = (struct upgt_eeprom_freq3_header *)data; - freq3 = (struct upgt_lmac_freq3 *)(freq3_header + 1); - - flags = freq3_header->flags; - elements = freq3_header->elements; - - DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d\n", - flags, elements); - - for (i = 0; i < elements; i++) { - channel = ieee80211_mhz2ieee(le16toh(freq3[i].freq), 0); - if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) - continue; - - sc->sc_eeprom_freq3[channel] = freq3[i]; - - DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", - le16toh(sc->sc_eeprom_freq3[channel].freq), channel); - } -} - -void -upgt_eeprom_parse_freq4(struct upgt_softc *sc, uint8_t *data, int len) -{ - struct upgt_eeprom_freq4_header *freq4_header; - struct upgt_eeprom_freq4_1 *freq4_1; - struct upgt_eeprom_freq4_2 *freq4_2; - int i, j, elements, settings, flags; - unsigned channel; - - freq4_header = (struct upgt_eeprom_freq4_header *)data; - freq4_1 = (struct upgt_eeprom_freq4_1 *)(freq4_header + 1); - flags = freq4_header->flags; - elements = freq4_header->elements; - settings = freq4_header->settings; - - /* we need this value later */ - sc->sc_eeprom_freq6_settings = freq4_header->settings; - - DPRINTF(sc, UPGT_DEBUG_FW, "flags=0x%02x elements=%d settings=%d\n", - flags, elements, settings); - - for (i = 0; i < elements; i++) { - channel = ieee80211_mhz2ieee(le16toh(freq4_1[i].freq), 0); - if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) - continue; - - freq4_2 = (struct upgt_eeprom_freq4_2 *)freq4_1[i].data; - for (j = 0; j < settings; j++) { - sc->sc_eeprom_freq4[channel][j].cmd = freq4_2[j]; - sc->sc_eeprom_freq4[channel][j].pad = 0; - } - - DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", - le16toh(freq4_1[i].freq), channel); - } -} - -void -upgt_eeprom_parse_freq6(struct upgt_softc *sc, uint8_t *data, int len) -{ - struct upgt_lmac_freq6 *freq6; - int i, elements; - unsigned channel; - - freq6 = (struct upgt_lmac_freq6 *)data; - elements = len / sizeof(struct upgt_lmac_freq6); - - DPRINTF(sc, UPGT_DEBUG_FW, "elements=%d\n", elements); - - for (i = 0; i < elements; i++) { - channel = ieee80211_mhz2ieee(le16toh(freq6[i].freq), 0); - if (!(channel >= 0 && channel < IEEE80211_CHAN_MAX)) - continue; - - sc->sc_eeprom_freq6[channel] = freq6[i]; - - DPRINTF(sc, UPGT_DEBUG_FW, "frequence=%d, channel=%d\n", - le16toh(sc->sc_eeprom_freq6[channel].freq), channel); - } -} - -static void -upgt_eeprom_parse_hwrx(struct upgt_softc *sc, uint8_t *data) -{ - struct upgt_eeprom_option_hwrx *option_hwrx; - - option_hwrx = (struct upgt_eeprom_option_hwrx *)data; - - sc->sc_eeprom_hwrx = option_hwrx->rxfilter - UPGT_EEPROM_RX_CONST; - - DPRINTF(sc, UPGT_DEBUG_FW, "hwrx option value=0x%04x\n", - sc->sc_eeprom_hwrx); -} - -static int -upgt_eeprom_read(struct upgt_softc *sc) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_lmac_mem *mem; - struct upgt_lmac_eeprom *eeprom; - int offset, block, len; - - offset = 0; - block = UPGT_EEPROM_BLOCK_SIZE; - while (offset < UPGT_EEPROM_SIZE) { - DPRINTF(sc, UPGT_DEBUG_FW, - "request EEPROM block (offset=%d, len=%d)\n", offset, block); - - /* - * Transmit the URB containing the CMD data. - */ - bzero(data_cmd->buf, MCLBYTES); - - mem = (struct upgt_lmac_mem *)data_cmd->buf; - mem->addr = htole32(sc->sc_memaddr_frame_start + - UPGT_MEMSIZE_FRAME_HEAD); - - eeprom = (struct upgt_lmac_eeprom *)(mem + 1); - eeprom->header1.flags = 0; - eeprom->header1.type = UPGT_H1_TYPE_CTRL; - eeprom->header1.len = htole16(( - sizeof(struct upgt_lmac_eeprom) - - sizeof(struct upgt_lmac_header)) + block); - - eeprom->header2.reqid = htole32(sc->sc_memaddr_frame_start); - eeprom->header2.type = htole16(UPGT_H2_TYPE_EEPROM); - eeprom->header2.flags = 0; - - eeprom->offset = htole16(offset); - eeprom->len = htole16(block); - - len = sizeof(*mem) + sizeof(*eeprom) + block; - - mem->chksum = upgt_chksum_le((uint32_t *)eeprom, - len - sizeof(*mem)); - - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, - USBD_FORCE_SHORT_XFER) != 0) { - device_printf(sc->sc_dev, - "could not transmit EEPROM data URB!\n"); - return (EIO); - } - if (tsleep(sc, 0, "eeprom_request", UPGT_USB_TIMEOUT)) { - device_printf(sc->sc_dev, - "timeout while waiting for EEPROM data!\n"); - return (EIO); - } - - offset += block; - if (UPGT_EEPROM_SIZE - offset < block) - block = UPGT_EEPROM_SIZE - offset; - } - - return (0); -} - -/* - * The firmware awaits a checksum for each frame we send to it. - * The algorithm used therefor is uncommon but somehow similar to CRC32. - */ -static uint32_t -upgt_chksum_le(const uint32_t *buf, size_t size) -{ - int i; - uint32_t crc = 0; - - for (i = 0; i < size; i += sizeof(uint32_t)) { - crc = htole32(crc ^ *buf++); - crc = htole32((crc >> 5) ^ (crc << 3)); - } - - return (crc); -} - -static void -upgt_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) -{ - struct upgt_data *data_rx = priv; - struct upgt_softc *sc = data_rx->sc; - int len; - struct upgt_lmac_header *header; - struct upgt_lmac_eeprom *eeprom; - uint8_t h1_type; - uint16_t h2_type; - - if (status != USBD_NORMAL_COMPLETION) { - if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) - return; - if (status == USBD_STALLED) - usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); - goto skip; - } - usbd_get_xfer_status(xfer, NULL, NULL, &len, NULL); - - /* - * Check what type of frame came in. - */ - header = (struct upgt_lmac_header *)(data_rx->buf + 4); - - h1_type = header->header1.type; - h2_type = le16toh(header->header2.type); - - if (h1_type == UPGT_H1_TYPE_CTRL && h2_type == UPGT_H2_TYPE_EEPROM) { - eeprom = (struct upgt_lmac_eeprom *)(data_rx->buf + 4); - uint16_t eeprom_offset = le16toh(eeprom->offset); - uint16_t eeprom_len = le16toh(eeprom->len); - - DPRINTF(sc, UPGT_DEBUG_FW, - "received EEPROM block (offset=%d, len=%d)\n", - eeprom_offset, eeprom_len); - - bcopy(data_rx->buf + sizeof(struct upgt_lmac_eeprom) + 4, - sc->sc_eeprom + eeprom_offset, eeprom_len); - - /* EEPROM data has arrived in time, wakeup tsleep() */ - wakeup(sc); - } else if (h1_type == UPGT_H1_TYPE_CTRL && - h2_type == UPGT_H2_TYPE_TX_DONE) { - DPRINTF(sc, UPGT_DEBUG_XMIT, "%s: received 802.11 TX done\n", - __func__); - upgt_tx_done(sc, data_rx->buf + 4); - } else if (h1_type == UPGT_H1_TYPE_RX_DATA || - h1_type == UPGT_H1_TYPE_RX_DATA_MGMT) { - DPRINTF(sc, UPGT_DEBUG_RECV, "%s: received 802.11 RX data\n", - __func__); - upgt_rx(sc, data_rx->buf + 4, le16toh(header->header1.len)); - } else if (h1_type == UPGT_H1_TYPE_CTRL && - h2_type == UPGT_H2_TYPE_STATS) { - DPRINTF(sc, UPGT_DEBUG_STAT, "%s: received statistic data\n", - __func__); - /* TODO: what could we do with the statistic data? */ - } else { - /* ignore unknown frame types */ - DPRINTF(sc, UPGT_DEBUG_INTR, - "received unknown frame type 0x%02x\n", - header->header1.type); - } - -skip: /* setup new transfer */ - usbd_setup_xfer(xfer, sc->sc_rx_pipeh, data_rx, data_rx->buf, MCLBYTES, - USBD_SHORT_XFER_OK, USBD_NO_TIMEOUT, upgt_rxeof); - (void)usbd_transfer(xfer); -} - -static void -upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct upgt_lmac_rx_desc *rxdesc; - struct ieee80211_node *ni; - struct mbuf *m; - int nf; - - /* - * don't pass packets to the ieee80211 framework if the driver isn't - * RUNNING. - */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; - - /* access RX packet descriptor */ - rxdesc = (struct upgt_lmac_rx_desc *)data; - - /* create mbuf which is suitable for strict alignment archs */ - KASSERT((pkglen + ETHER_ALIGN) < MCLBYTES, - ("A current mbuf storage is small (%d)", pkglen + ETHER_ALIGN)); - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) { - device_printf(sc->sc_dev, "could not create RX mbuf!\n"); - return; - } - m_adj(m, ETHER_ALIGN); - bcopy(rxdesc->data, mtod(m, char *), pkglen); - /* trim FCS */ - m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN; - m->m_pkthdr.rcvif = ifp; - - if (bpf_peers_present(ifp->if_bpf)) { - struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap; - - tap->wr_flags = 0; - tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wr_antsignal = rxdesc->rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); - } - ifp->if_ipackets++; - - nf = -95; /* XXX */ - ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - if (ni != NULL) { - (void)ieee80211_input(ni, m, rxdesc->rssi, nf, 0); - ieee80211_free_node(ni); - } else - (void)ieee80211_input_all(ic, m, rxdesc->rssi, nf, 0); - - DPRINTF(sc, UPGT_DEBUG_RX_PROC, "%s: RX done\n", __func__); -} - -static uint8_t -upgt_rx_rate(struct upgt_softc *sc, const int rate) -{ - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - static const uint8_t cck_upgt2rate[4] = { 2, 4, 11, 22 }; - static const uint8_t ofdm_upgt2rate[12] = - { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 }; - - if (ic->ic_curmode == IEEE80211_MODE_11B && - !(rate < 0 || rate > 3)) - return cck_upgt2rate[rate & 0xf]; - - if (ic->ic_curmode == IEEE80211_MODE_11G && - !(rate < 0 || rate > 11)) - return ofdm_upgt2rate[rate & 0xf]; - - return (0); -} - -static void -upgt_tx_done(struct upgt_softc *sc, uint8_t *data) -{ - struct ifnet *ifp = sc->sc_ifp; - struct upgt_lmac_tx_done_desc *desc; - int i; - - desc = (struct upgt_lmac_tx_done_desc *)data; - - UPGT_LOCK(sc); - for (i = 0; i < upgt_txbuf; i++) { - struct upgt_data *data_tx = &sc->tx_data[i]; - - if (data_tx->addr == le32toh(desc->header2.reqid)) { - upgt_mem_free(sc, data_tx->addr); - ieee80211_free_node(data_tx->ni); - data_tx->ni = NULL; - data_tx->addr = 0; - data_tx->m = NULL; - data_tx->use = 0; - - sc->tx_queued--; - ifp->if_opackets++; - - DPRINTF(sc, UPGT_DEBUG_TX_PROC, - "TX done: memaddr=0x%08x, status=0x%04x, rssi=%d, ", - le32toh(desc->header2.reqid), - le16toh(desc->status), le16toh(desc->rssi)); - DPRINTF(sc, UPGT_DEBUG_TX_PROC, "seq=%d\n", - le16toh(desc->seq)); - break; - } - } - if (sc->tx_queued == 0) { - /* TX queued was processed, continue */ - sc->sc_tx_timer = 0; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - UPGT_UNLOCK(sc); - upgt_start(ifp); - return; - } - UPGT_UNLOCK(sc); -} - -static void -upgt_mem_free(struct upgt_softc *sc, uint32_t addr) -{ - int i; - - for (i = 0; i < sc->sc_memory.pages; i++) { - if (sc->sc_memory.page[i].addr == addr) { - sc->sc_memory.page[i].used = 0; - return; - } - } - - device_printf(sc->sc_dev, - "could not free memory address 0x%08x!\n", addr); -} - -static int -upgt_fw_load(struct upgt_softc *sc) -{ - const struct firmware *fw; - struct upgt_data *data_cmd = &sc->cmd_data; - struct upgt_data *data_rx = &sc->rx_data; - struct upgt_fw_x2_header *x2; - char start_fwload_cmd[] = { 0x3c, 0x0d }; - int error = 0, offset, bsize, n, i, len; - uint32_t crc32; - - fw = firmware_get(upgt_fwname); - if (fw == NULL) { - device_printf(sc->sc_dev, "could not read microcode %s!\n", - upgt_fwname); - return EIO; - } - - /* send firmware start load command */ - len = sizeof(start_fwload_cmd); - bcopy(start_fwload_cmd, data_cmd->buf, len); - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not send start_firmware_load command!\n"); - error = EIO; - goto fail; - } - - /* send X2 header */ - len = sizeof(struct upgt_fw_x2_header); - x2 = (struct upgt_fw_x2_header *)data_cmd->buf; - bcopy(UPGT_X2_SIGNATURE, x2->signature, UPGT_X2_SIGNATURE_SIZE); - x2->startaddr = htole32(UPGT_MEMADDR_FIRMWARE_START); - x2->len = htole32(fw->datasize); - x2->crc = upgt_crc32_le((uint8_t *)data_cmd->buf + - UPGT_X2_SIGNATURE_SIZE, - sizeof(struct upgt_fw_x2_header) - UPGT_X2_SIGNATURE_SIZE - - sizeof(uint32_t)); - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not send firmware X2 header!\n"); - error = EIO; - goto fail; - } - - /* download firmware */ - for (offset = 0; offset < fw->datasize; offset += bsize) { - if (fw->datasize - offset > UPGT_FW_BLOCK_SIZE) - bsize = UPGT_FW_BLOCK_SIZE; - else - bsize = fw->datasize - offset; - - n = upgt_fw_copy((const uint8_t *)fw->data + offset, - data_cmd->buf, bsize); - - DPRINTF(sc, UPGT_DEBUG_FW, "FW offset=%d, read=%d, sent=%d\n", - offset, n, bsize); - - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &bsize, 0) - != 0) { - device_printf(sc->sc_dev, - "error while downloading firmware block!\n"); - error = EIO; - goto fail; - } - - bsize = n; - } - DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware downloaded\n", __func__); - - /* load firmware */ - crc32 = upgt_crc32_le(fw->data, fw->datasize); - *((uint32_t *)(data_cmd->buf) ) = crc32; - *((uint8_t *)(data_cmd->buf) + 4) = 'g'; - *((uint8_t *)(data_cmd->buf) + 5) = '\r'; - len = 6; - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not send load_firmware command!\n"); - error = EIO; - goto fail; - } - - for (i = 0; i < UPGT_FIRMWARE_TIMEOUT; i++) { - len = UPGT_FW_BLOCK_SIZE; - bzero(data_rx->buf, MCLBYTES); - if (upgt_bulk_xmit(sc, data_rx, sc->sc_rx_pipeh, &len, - USBD_SHORT_XFER_OK) != 0) { - device_printf(sc->sc_dev, - "could not read firmware response!\n"); - error = EIO; - goto fail; - } - - if (memcmp(data_rx->buf, "OK", 2) == 0) - break; /* firmware load was successful */ - } - if (i == UPGT_FIRMWARE_TIMEOUT) { - device_printf(sc->sc_dev, "firmware load failed!\n"); - error = EIO; - } - - DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware loaded\n", __func__); -fail: - firmware_put(fw, FIRMWARE_UNLOAD); - return (error); -} - -static uint32_t -upgt_crc32_le(const void *buf, size_t size) -{ - uint32_t crc; - - crc = ether_crc32_le(buf, size); - - /* apply final XOR value as common for CRC-32 */ - crc = htole32(crc ^ 0xffffffffU); - - return (crc); -} - -/* - * While copying the version 2 firmware, we need to replace two characters: - * - * 0x7e -> 0x7d 0x5e - * 0x7d -> 0x7d 0x5d - */ -static int -upgt_fw_copy(const uint8_t *src, char *dst, int size) -{ - int i, j; - - for (i = 0, j = 0; i < size && j < size; i++) { - switch (src[i]) { - case 0x7e: - dst[j] = 0x7d; - j++; - dst[j] = 0x5e; - j++; - break; - case 0x7d: - dst[j] = 0x7d; - j++; - dst[j] = 0x5d; - j++; - break; - default: - dst[j] = src[i]; - j++; - break; - } - } - - return (i); -} - -static int -upgt_mem_init(struct upgt_softc *sc) -{ - int i; - - for (i = 0; i < UPGT_MEMORY_MAX_PAGES; i++) { - sc->sc_memory.page[i].used = 0; - - if (i == 0) { - /* - * The first memory page is always reserved for - * command data. - */ - sc->sc_memory.page[i].addr = - sc->sc_memaddr_frame_start + MCLBYTES; - } else { - sc->sc_memory.page[i].addr = - sc->sc_memory.page[i - 1].addr + MCLBYTES; - } - - if (sc->sc_memory.page[i].addr + MCLBYTES >= - sc->sc_memaddr_frame_end) - break; - - DPRINTF(sc, UPGT_DEBUG_FW, "memory address page %d=0x%08x\n", - i, sc->sc_memory.page[i].addr); - } - - sc->sc_memory.pages = i; - if (upgt_txbuf > sc->sc_memory.pages) - - DPRINTF(sc, UPGT_DEBUG_FW, "memory pages=%d\n", sc->sc_memory.pages); - return (0); -} - -static int -upgt_fw_verify(struct upgt_softc *sc) -{ - const struct firmware *fw; - const struct upgt_fw_bra_option *bra_opt; - const struct upgt_fw_bra_descr *descr; - const uint8_t *p; - const uint32_t *uc; - uint32_t bra_option_type, bra_option_len; - int offset, bra_end = 0, error = 0; - - fw = firmware_get(upgt_fwname); - if (fw == NULL) { - device_printf(sc->sc_dev, "could not read microcode %s!\n", - upgt_fwname); - return EIO; - } - - /* - * Seek to beginning of Boot Record Area (BRA). - */ - for (offset = 0; offset < fw->datasize; offset += sizeof(*uc)) { - uc = (const uint32_t *)((const uint8_t *)fw->data + offset); - if (*uc == 0) - break; - } - for (; offset < fw->datasize; offset += sizeof(*uc)) { - uc = (const uint32_t *)((const uint8_t *)fw->data + offset); - if (*uc != 0) - break; - } - if (offset == fw->datasize) { - device_printf(sc->sc_dev, - "firmware Boot Record Area not found!\n"); - error = EIO; - goto fail; - } - - DPRINTF(sc, UPGT_DEBUG_FW, - "firmware Boot Record Area found at offset %d\n", offset); - - /* - * Parse Boot Record Area (BRA) options. - */ - while (offset < fw->datasize && bra_end == 0) { - /* get current BRA option */ - p = (const uint8_t *)fw->data + offset; - bra_opt = (const struct upgt_fw_bra_option *)p; - bra_option_type = le32toh(bra_opt->type); - bra_option_len = le32toh(bra_opt->len) * sizeof(*uc); - - switch (bra_option_type) { - case UPGT_BRA_TYPE_FW: - DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_FW len=%d\n", - bra_option_len); - - if (bra_option_len != UPGT_BRA_FWTYPE_SIZE) { - device_printf(sc->sc_dev, - "wrong UPGT_BRA_TYPE_FW len!\n"); - error = EIO; - goto fail; - } - if (memcmp(UPGT_BRA_FWTYPE_LM86, bra_opt->data, - bra_option_len) == 0) { - sc->sc_fw_type = UPGT_FWTYPE_LM86; - break; - } - if (memcmp(UPGT_BRA_FWTYPE_LM87, bra_opt->data, - bra_option_len) == 0) { - sc->sc_fw_type = UPGT_FWTYPE_LM87; - break; - } - device_printf(sc->sc_dev, - "unsupported firmware type!\n"); - error = EIO; - goto fail; - case UPGT_BRA_TYPE_VERSION: - DPRINTF(sc, UPGT_DEBUG_FW, - "UPGT_BRA_TYPE_VERSION len=%d\n", bra_option_len); - break; - case UPGT_BRA_TYPE_DEPIF: - DPRINTF(sc, UPGT_DEBUG_FW, - "UPGT_BRA_TYPE_DEPIF len=%d\n", bra_option_len); - break; - case UPGT_BRA_TYPE_EXPIF: - DPRINTF(sc, UPGT_DEBUG_FW, - "UPGT_BRA_TYPE_EXPIF len=%d\n", bra_option_len); - break; - case UPGT_BRA_TYPE_DESCR: - DPRINTF(sc, UPGT_DEBUG_FW, - "UPGT_BRA_TYPE_DESCR len=%d\n", bra_option_len); - - descr = (const struct upgt_fw_bra_descr *)bra_opt->data; - - sc->sc_memaddr_frame_start = - le32toh(descr->memaddr_space_start); - sc->sc_memaddr_frame_end = - le32toh(descr->memaddr_space_end); - - DPRINTF(sc, UPGT_DEBUG_FW, - "memory address space start=0x%08x\n", - sc->sc_memaddr_frame_start); - DPRINTF(sc, UPGT_DEBUG_FW, - "memory address space end=0x%08x\n", - sc->sc_memaddr_frame_end); - break; - case UPGT_BRA_TYPE_END: - DPRINTF(sc, UPGT_DEBUG_FW, "UPGT_BRA_TYPE_END len=%d\n", - bra_option_len); - bra_end = 1; - break; - default: - DPRINTF(sc, UPGT_DEBUG_FW, "unknown BRA option len=%d\n", - bra_option_len); - error = EIO; - goto fail; - } - - /* jump to next BRA option */ - offset += sizeof(struct upgt_fw_bra_option) + bra_option_len; - } - - DPRINTF(sc, UPGT_DEBUG_FW, "%s: firmware verified", __func__); -fail: - firmware_put(fw, FIRMWARE_UNLOAD); - return (error); -} - -static int -upgt_bulk_xmit(struct upgt_softc *sc, struct upgt_data *data, - usbd_pipe_handle pipeh, uint32_t *size, int flags) -{ - usbd_status status; - - mtx_lock(&Giant); - status = usbd_bulk_transfer(data->xfer, pipeh, - USBD_NO_COPY | flags, UPGT_USB_TIMEOUT, data->buf, size, - "upgt_bulk_xmit"); - if (status != USBD_NORMAL_COMPLETION) { - device_printf(sc->sc_dev, "%s: error %s!\n", - __func__, usbd_errstr(status)); - mtx_unlock(&Giant); - return (EIO); - } - mtx_unlock(&Giant); - - return (0); -} - -static int -upgt_device_reset(struct upgt_softc *sc) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - char init_cmd[] = { 0x7e, 0x7e, 0x7e, 0x7e }; - int len; - - len = sizeof(init_cmd); - bcopy(init_cmd, data_cmd->buf, len); - if (upgt_bulk_xmit(sc, data_cmd, sc->sc_tx_pipeh, &len, 0) != 0) { - device_printf(sc->sc_dev, - "could not send device init string!\n"); - return (EIO); - } - usbd_delay_ms(sc->sc_udev, 100); - - DPRINTF(sc, UPGT_DEBUG_FW, "%s: device initialized\n", __func__); - return (0); -} - -static int -upgt_alloc_tx(struct upgt_softc *sc) -{ - int i; - - sc->tx_queued = 0; - - for (i = 0; i < upgt_txbuf; i++) { - struct upgt_data *data_tx = &sc->tx_data[i]; - - data_tx->sc = sc; - data_tx->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_tx->xfer == NULL) { - device_printf(sc->sc_dev, - "could not allocate TX xfer!\n"); - return (ENOMEM); - } - - data_tx->buf = usbd_alloc_buffer(data_tx->xfer, MCLBYTES); - if (data_tx->buf == NULL) { - device_printf(sc->sc_dev, - "could not allocate TX buffer!\n"); - return (ENOMEM); - } - - bzero(data_tx->buf, MCLBYTES); - } - - return (0); -} - -static int -upgt_alloc_rx(struct upgt_softc *sc) -{ - struct upgt_data *data_rx = &sc->rx_data; - - data_rx->sc = sc; - data_rx->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_rx->xfer == NULL) { - device_printf(sc->sc_dev, "could not allocate RX xfer!\n"); - return (ENOMEM); - } - - data_rx->buf = usbd_alloc_buffer(data_rx->xfer, MCLBYTES); - if (data_rx->buf == NULL) { - device_printf(sc->sc_dev, "could not allocate RX buffer!\n"); - return (ENOMEM); - } - - bzero(data_rx->buf, MCLBYTES); - - return (0); -} - -static int -upgt_alloc_cmd(struct upgt_softc *sc) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - - data_cmd->sc = sc; - data_cmd->xfer = usbd_alloc_xfer(sc->sc_udev); - if (data_cmd->xfer == NULL) { - device_printf(sc->sc_dev, "could not allocate RX xfer!\n"); - return (ENOMEM); - } - - data_cmd->buf = usbd_alloc_buffer(data_cmd->xfer, MCLBYTES); - if (data_cmd->buf == NULL) { - device_printf(sc->sc_dev, "could not allocate RX buffer!\n"); - return (ENOMEM); - } - - bzero(data_cmd->buf, MCLBYTES); - - return (0); -} - -static int -upgt_detach(device_t dev) -{ - struct upgt_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - - if (!device_is_attached(dev)) - return 0; - - upgt_stop(sc, 1); - - /* abort and close TX / RX pipes */ - if (sc->sc_tx_pipeh != NULL) - usbd_close_pipe(sc->sc_tx_pipeh); - if (sc->sc_rx_pipeh != NULL) - usbd_close_pipe(sc->sc_rx_pipeh); - - mtx_destroy(&sc->sc_mtx); - usb_rem_task(sc->sc_udev, &sc->sc_mcasttask); - usb_rem_task(sc->sc_udev, &sc->sc_scantask); - usb_rem_task(sc->sc_udev, &sc->sc_task); - usb_rem_task(sc->sc_udev, &sc->sc_task_tx); - callout_stop(&sc->sc_led_ch); - callout_stop(&sc->sc_watchdog_ch); - - /* free xfers */ - upgt_free_tx(sc); - upgt_free_rx(sc); - upgt_free_cmd(sc); - - bpfdetach(ifp); - ieee80211_ifdetach(ic); - if_free(ifp); - - usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); - - return 0; -} - -static void -upgt_free_rx(struct upgt_softc *sc) -{ - struct upgt_data *data_rx = &sc->rx_data; - - if (data_rx->xfer != NULL) { - usbd_free_xfer(data_rx->xfer); - data_rx->xfer = NULL; - } - - data_rx->ni = NULL; -} - -static void -upgt_free_tx(struct upgt_softc *sc) -{ - int i; - - for (i = 0; i < upgt_txbuf; i++) { - struct upgt_data *data_tx = &sc->tx_data[i]; - - if (data_tx->xfer != NULL) { - usbd_free_xfer(data_tx->xfer); - data_tx->xfer = NULL; - } - - data_tx->ni = NULL; - } -} - -static void -upgt_free_cmd(struct upgt_softc *sc) -{ - struct upgt_data *data_cmd = &sc->cmd_data; - - if (data_cmd->xfer != NULL) { - usbd_free_xfer(data_cmd->xfer); - data_cmd->xfer = NULL; - } -} - -static device_method_t upgt_methods[] = { - /* Device interface */ - DEVMETHOD(device_probe, upgt_match), - DEVMETHOD(device_attach, upgt_attach), - DEVMETHOD(device_detach, upgt_detach), - - { 0, 0 } -}; - -static driver_t upgt_driver = { - "upgt", - upgt_methods, - sizeof(struct upgt_softc) -}; - -static devclass_t upgt_devclass; - -DRIVER_MODULE(if_upgt, uhub, upgt_driver, upgt_devclass, usbd_driver_load, 0); -MODULE_VERSION(if_upgt, 1); -MODULE_DEPEND(if_upgt, usb, 1, 1, 1); -MODULE_DEPEND(if_upgt, wlan, 1, 1, 1); -MODULE_DEPEND(if_upgt, upgtfw_fw, 1, 1, 1); diff --git a/sys/legacy/dev/usb/if_upgtvar.h b/sys/legacy/dev/usb/if_upgtvar.h deleted file mode 100644 index 298fb636285a..000000000000 --- a/sys/legacy/dev/usb/if_upgtvar.h +++ /dev/null @@ -1,462 +0,0 @@ -/* $OpenBSD: if_upgtvar.h,v 1.14 2008/02/02 13:48:44 mglocker Exp $ */ -/* $FreeBSD$ */ - -/* - * Copyright (c) 2007 Marcus Glocker - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -struct upgt_softc; - -/* - * General values. - */ -#define UPGT_IFACE_INDEX 0 -#define UPGT_CONFIG_NO 1 -#define UPGT_USB_TIMEOUT 1000 -#define UPGT_FIRMWARE_TIMEOUT 10 - -#define UPGT_MEMADDR_FIRMWARE_START 0x00020000 /* 512 bytes large */ -#define UPGT_MEMSIZE_FRAME_HEAD 0x0070 -#define UPGT_MEMSIZE_RX 0x3500 - -#define UPGT_TX_COUNT 2 - -/* device flags */ -#define UPGT_DEVICE_ATTACHED (1 << 0) - -/* leds */ -#define UPGT_LED_OFF 0 -#define UPGT_LED_ON 1 -#define UPGT_LED_BLINK 2 - -/* - * Firmware. - */ -#define UPGT_FW_BLOCK_SIZE 512 - -#define UPGT_BRA_FWTYPE_SIZE 4 -#define UPGT_BRA_FWTYPE_LM86 "LM86" -#define UPGT_BRA_FWTYPE_LM87 "LM87" -enum upgt_fw_type { - UPGT_FWTYPE_LM86, - UPGT_FWTYPE_LM87 -}; - -#define UPGT_BRA_TYPE_FW 0x80000001 -#define UPGT_BRA_TYPE_VERSION 0x80000002 -#define UPGT_BRA_TYPE_DEPIF 0x80000003 -#define UPGT_BRA_TYPE_EXPIF 0x80000004 -#define UPGT_BRA_TYPE_DESCR 0x80000101 -#define UPGT_BRA_TYPE_END 0xff0000ff -struct upgt_fw_bra_option { - uint32_t type; - uint32_t len; - uint8_t data[]; -} __packed; - -struct upgt_fw_bra_descr { - uint32_t unknown1; - uint32_t memaddr_space_start; - uint32_t memaddr_space_end; - uint32_t unknown2; - uint32_t unknown3; - uint8_t rates[20]; -} __packed; - -#define UPGT_X2_SIGNATURE_SIZE 4 -#define UPGT_X2_SIGNATURE "x2 " -struct upgt_fw_x2_header { - uint8_t signature[4]; - uint32_t startaddr; - uint32_t len; - uint32_t crc; -} __packed; - -/* - * EEPROM. - */ -#define UPGT_EEPROM_SIZE 8192 -#define UPGT_EEPROM_BLOCK_SIZE 1020 - -struct upgt_eeprom_header { - /* 14 bytes */ - uint32_t magic; - uint16_t pad1; - uint16_t preamble_len; - uint32_t pad2; - /* data */ -} __packed; - -#define UPGT_EEPROM_TYPE_END 0x0000 -#define UPGT_EEPROM_TYPE_NAME 0x0001 -#define UPGT_EEPROM_TYPE_SERIAL 0x0003 -#define UPGT_EEPROM_TYPE_MAC 0x0101 -#define UPGT_EEPROM_TYPE_HWRX 0x1001 -#define UPGT_EEPROM_TYPE_CHIP 0x1002 -#define UPGT_EEPROM_TYPE_FREQ3 0x1903 -#define UPGT_EEPROM_TYPE_FREQ4 0x1904 -#define UPGT_EEPROM_TYPE_FREQ5 0x1905 -#define UPGT_EEPROM_TYPE_FREQ6 0x1906 -#define UPGT_EEPROM_TYPE_OFF 0xffff -struct upgt_eeprom_option { - uint16_t len; - uint16_t type; - uint8_t data[]; - /* data */ -} __packed; - -#define UPGT_EEPROM_RX_CONST 0x88 -struct upgt_eeprom_option_hwrx { - uint32_t pad1; - uint8_t rxfilter; - uint8_t pad2[15]; -} __packed; - -struct upgt_eeprom_freq3_header { - uint8_t flags; - uint8_t elements; -} __packed; - -struct upgt_eeprom_freq4_header { - uint8_t flags; - uint8_t elements; - uint8_t settings; - uint8_t type; -} __packed; - -struct upgt_eeprom_freq4_1 { - uint16_t freq; - uint8_t data[50]; -} __packed; - -struct upgt_eeprom_freq4_2 { - uint16_t head; - uint8_t subtails[4]; - uint8_t tail; -} __packed; - -/* - * LMAC protocol. - */ -struct upgt_lmac_mem { - uint32_t addr; - uint32_t chksum; -} __packed; - -#define UPGT_H1_FLAGS_TX_MGMT 0x00 /* for TX: mgmt frame */ -#define UPGT_H1_FLAGS_TX_NO_CALLBACK 0x01 /* for TX: no USB callback */ -#define UPGT_H1_FLAGS_TX_DATA 0x10 /* for TX: data frame */ -#define UPGT_H1_TYPE_RX_DATA 0x00 /* 802.11 RX data frame */ -#define UPGT_H1_TYPE_RX_DATA_MGMT 0x04 /* 802.11 RX mgmt frame */ -#define UPGT_H1_TYPE_TX_DATA 0x40 /* 802.11 TX data frame */ -#define UPGT_H1_TYPE_CTRL 0x80 /* control frame */ -struct upgt_lmac_h1 { - /* 4 bytes */ - uint8_t flags; - uint8_t type; - uint16_t len; -} __packed; - -#define UPGT_H2_TYPE_TX_ACK_NO 0x0000 -#define UPGT_H2_TYPE_TX_ACK_YES 0x0001 -#define UPGT_H2_TYPE_MACFILTER 0x0000 -#define UPGT_H2_TYPE_CHANNEL 0x0001 -#define UPGT_H2_TYPE_TX_DONE 0x0008 -#define UPGT_H2_TYPE_STATS 0x000a -#define UPGT_H2_TYPE_EEPROM 0x000c -#define UPGT_H2_TYPE_LED 0x000d -#define UPGT_H2_FLAGS_TX_ACK_NO 0x0101 -#define UPGT_H2_FLAGS_TX_ACK_YES 0x0707 -struct upgt_lmac_h2 { - /* 8 bytes */ - uint32_t reqid; - uint16_t type; - uint16_t flags; -} __packed; - -struct upgt_lmac_header { - /* 12 bytes */ - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; -} __packed; - -struct upgt_lmac_eeprom { - /* 16 bytes */ - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - uint16_t offset; - uint16_t len; - /* data */ -} __packed; - -#define UPGT_FILTER_TYPE_NONE 0x0000 -#define UPGT_FILTER_TYPE_STA 0x0001 -#define UPGT_FILTER_TYPE_IBSS 0x0002 -#define UPGT_FILTER_TYPE_HOSTAP 0x0004 -#define UPGT_FILTER_TYPE_MONITOR 0x0010 -#define UPGT_FILTER_TYPE_RESET 0x0020 -#define UPGT_FILTER_UNKNOWN1 0x0002 -#define UPGT_FILTER_UNKNOWN2 0x0ca8 -#define UPGT_FILTER_UNKNOWN3 0xffff -#define UPGT_FILTER_MONITOR_UNKNOWN1 0x0000 -#define UPGT_FILTER_MONITOR_UNKNOWN2 0x0000 -#define UPGT_FILTER_MONITOR_UNKNOWN3 0x0000 -struct upgt_lmac_filter { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - /* 32 bytes */ - uint16_t type; - uint8_t dst[IEEE80211_ADDR_LEN]; - uint8_t src[IEEE80211_ADDR_LEN]; - uint16_t unknown1; - uint32_t rxaddr; - uint16_t unknown2; - uint32_t rxhw; - uint16_t unknown3; - uint32_t unknown4; -} __packed; - -/* frequence 3 data */ -struct upgt_lmac_freq3 { - uint16_t freq; - uint8_t data[6]; -} __packed; - -/* frequence 4 data */ -struct upgt_lmac_freq4 { - struct upgt_eeprom_freq4_2 cmd; - uint8_t pad; -}; - -/* frequence 6 data */ -struct upgt_lmac_freq6 { - uint16_t freq; - uint8_t data[8]; -} __packed; - -#define UPGT_CHANNEL_UNKNOWN1 0x0001 -#define UPGT_CHANNEL_UNKNOWN2 0x0000 -#define UPGT_CHANNEL_UNKNOWN3 0x48 -struct upgt_lmac_channel { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - /* 112 bytes */ - uint16_t unknown1; - uint16_t unknown2; - uint8_t pad1[20]; - struct upgt_lmac_freq6 freq6; - uint8_t settings; - uint8_t unknown3; - uint8_t freq3_1[4]; - struct upgt_lmac_freq4 freq4[8]; - uint8_t freq3_2[4]; - uint32_t pad2; -} __packed; - -#define UPGT_LED_MODE_SET 0x0003 -#define UPGT_LED_ACTION_OFF 0x0002 -#define UPGT_LED_ACTION_ON 0x0003 -#define UPGT_LED_ACTION_TMP_DUR 100 /* ms */ -struct upgt_lmac_led { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - uint16_t mode; - uint16_t action_fix; - uint16_t action_tmp; - uint16_t action_tmp_dur; -} __packed; - -struct upgt_lmac_stats { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - uint8_t data[76]; -} __packed; - -struct upgt_lmac_rx_desc { - struct upgt_lmac_h1 header1; - /* 16 bytes */ - uint16_t freq; - uint8_t unknown1; - uint8_t rate; - uint8_t rssi; - uint8_t pad; - uint16_t unknown2; - uint32_t timestamp; - uint32_t unknown3; - uint8_t data[]; -} __packed; - -#define UPGT_TX_DESC_KEY_EXISTS 0x01 -struct upgt_lmac_tx_desc_wep { - uint8_t key_exists; - uint8_t key_len; - uint8_t key_val[16]; -} __packed; - -#define UPGT_TX_DESC_TYPE_BEACON 0x00000000 -#define UPGT_TX_DESC_TYPE_PROBE 0x00000001 -#define UPGT_TX_DESC_TYPE_MGMT 0x00000002 -#define UPGT_TX_DESC_TYPE_DATA 0x00000004 -#define UPGT_TX_DESC_PAD3_SIZE 2 -struct upgt_lmac_tx_desc { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - uint8_t rates[8]; - uint16_t pad1; - struct upgt_lmac_tx_desc_wep wep_key; - uint32_t type; - uint32_t pad2; - uint32_t unknown1; - uint32_t unknown2; - uint8_t pad3[2]; - /* 802.11 frame data */ -} __packed; - -#define UPGT_TX_DONE_DESC_STATUS_OK 0x0001 -struct upgt_lmac_tx_done_desc { - struct upgt_lmac_h1 header1; - struct upgt_lmac_h2 header2; - uint16_t status; - uint16_t rssi; - uint16_t seq; - uint16_t unknown; -} __packed; - -/* - * USB xfers. - */ -struct upgt_data { - struct upgt_softc *sc; - usbd_xfer_handle xfer; - uint8_t *buf; - struct ieee80211_node *ni; - struct mbuf *m; - uint32_t addr; - uint8_t use; -}; - -/* - * Prism memory. - */ -struct upgt_memory_page { - uint8_t used; - uint32_t addr; -} __packed; - -#define UPGT_MEMORY_MAX_PAGES 8 -struct upgt_memory { - uint8_t pages; - struct upgt_memory_page page[UPGT_MEMORY_MAX_PAGES]; -} __packed; - -/* - * BPF - */ -struct upgt_rx_radiotap_header { - struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint8_t wr_rate; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - int8_t wr_antsignal; -} __packed; - -#define UPGT_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) - -struct upgt_tx_radiotap_header { - struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint8_t wt_rate; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; -} __packed; - -#define UPGT_TX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_RATE) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL)) - -struct upgt_vap { - struct ieee80211vap vap; - int (*newstate)(struct ieee80211vap *, - enum ieee80211_state, int); -}; -#define UPGT_VAP(vap) ((struct upgt_vap *)(vap)) - -struct upgt_softc { - device_t sc_dev; - struct ifnet *sc_ifp; - usbd_device_handle sc_udev; - usbd_interface_handle sc_iface; - struct mtx sc_mtx; - int sc_if_flags; - int sc_debug; - - struct usb_task sc_mcasttask; - struct usb_task sc_task; - struct usb_task sc_scantask; -#define UPGT_SET_CHANNEL 2 - int sc_scan_action; - enum ieee80211_state sc_state; - int sc_arg; - int sc_led_blink; - struct callout sc_led_ch; - uint8_t sc_cur_rateset[8]; - - /* watchdog */ - int sc_tx_timer; - struct callout sc_watchdog_ch; - - /* Firmware. */ - int sc_fw_type; - /* memory addresses on device */ - uint32_t sc_memaddr_frame_start; - uint32_t sc_memaddr_frame_end; - uint32_t sc_memaddr_rx_start; - struct upgt_memory sc_memory; - - /* data which we found in the EEPROM */ - uint8_t sc_eeprom[UPGT_EEPROM_SIZE]; - uint16_t sc_eeprom_hwrx; - struct upgt_lmac_freq3 sc_eeprom_freq3[IEEE80211_CHAN_MAX]; - struct upgt_lmac_freq4 sc_eeprom_freq4[IEEE80211_CHAN_MAX][8]; - struct upgt_lmac_freq6 sc_eeprom_freq6[IEEE80211_CHAN_MAX]; - uint8_t sc_eeprom_freq6_settings; - - /* RX/TX */ - int sc_rx_no; - int sc_tx_no; - usbd_pipe_handle sc_rx_pipeh; - usbd_pipe_handle sc_tx_pipeh; - struct upgt_data tx_data[UPGT_TX_COUNT]; - struct upgt_data rx_data; - struct upgt_data cmd_data; - int tx_queued; - struct usb_task sc_task_tx; - - /* BPF */ - struct upgt_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - - struct upgt_tx_radiotap_header sc_txtap; - int sc_txtap_len; -}; - -#define UPGT_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define UPGT_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) diff --git a/sys/legacy/dev/usb/usb_ethersubr.c b/sys/legacy/dev/usb/usb_ethersubr.c deleted file mode 100644 index d0a3b83698c6..000000000000 --- a/sys/legacy/dev/usb/usb_ethersubr.c +++ /dev/null @@ -1,283 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Callbacks in the USB code operate at splusb() (actually splbio() - * in FreeBSD). However adding packets to the input queues has to be - * done at splimp(). It is conceivable that this arrangement could - * trigger a condition where the splimp() is ignored and the input - * queues could get trampled in spite of our best effors to prevent - * it. To work around this, we implement a special input queue for - * USB ethernet adapter drivers. Rather than passing the frames directly - * to ether_input(), we pass them here, then schedule a soft interrupt - * to hand them to ether_input() later, outside of the USB interrupt - * context. - * - * It's questional as to whether this code should be expanded to - * handle other kinds of devices, or handle USB transfer callbacks - * in general. Right now, I need USB network interfaces to work - * properly. - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -static struct ifqueue usbq_rx; -static struct ifqueue usbq_tx; -static int mtx_inited = 0; - -static void usbintr (void); - -static void -usbintr(void) -{ - struct mbuf *m; - struct usb_qdat *q; - struct ifnet *ifp; - - mtx_lock(&Giant); - - /* Check the RX queue */ - while(1) { - IF_DEQUEUE(&usbq_rx, m); - if (m == NULL) - break; - q = (struct usb_qdat *)m->m_pkthdr.rcvif; - ifp = q->ifp; - m->m_pkthdr.rcvif = ifp; - (*ifp->if_input)(ifp, m); - - /* Re-arm the receiver */ - (*q->if_rxstart)(ifp); - if (ifp->if_snd.ifq_head != NULL) - (*ifp->if_start)(ifp); - } - - /* Check the TX queue */ - while(1) { - IF_DEQUEUE(&usbq_tx, m); - if (m == NULL) - break; - ifp = m->m_pkthdr.rcvif; - m_freem(m); - if (ifp->if_snd.ifq_head != NULL) - (*ifp->if_start)(ifp); - } - - mtx_unlock(&Giant); - - return; -} - -void -usb_register_netisr(void) -{ - if (mtx_inited) - return; - netisr_register(NETISR_USB, (netisr_t *)usbintr, NULL, - NETISR_FORCEQUEUE); - mtx_init(&usbq_tx.ifq_mtx, "usbq_tx_mtx", NULL, MTX_DEF); - mtx_init(&usbq_rx.ifq_mtx, "usbq_rx_mtx", NULL, MTX_DEF); - mtx_inited++; - return; -} - -/* - * Must be called at splusb() (actually splbio()). This should be - * the case when called from a transfer callback routine. - */ -void -usb_ether_input(m) - struct mbuf *m; -{ - IF_ENQUEUE(&usbq_rx, m); - schednetisr(NETISR_USB); - - return; -} - -void -usb_tx_done(m) - struct mbuf *m; -{ - IF_ENQUEUE(&usbq_tx, m); - schednetisr(NETISR_USB); - - return; -} - -struct mbuf * -usb_ether_newbuf(void) -{ - struct mbuf *m_new; - - m_new = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m_new == NULL) - return (NULL); - m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; - - m_adj(m_new, ETHER_ALIGN); - return (m_new); -} - -int -usb_ether_rx_list_init(void *sc, struct ue_cdata *cd, - usbd_device_handle ue_udev) -{ - struct ue_chain *c; - int i; - - for (i = 0; i < UE_RX_LIST_CNT; i++) { - c = &cd->ue_rx_chain[i]; - c->ue_sc = sc; - c->ue_idx = i; - c->ue_mbuf = usb_ether_newbuf(); - if (c->ue_mbuf == NULL) - return (ENOBUFS); - if (c->ue_xfer == NULL) { - c->ue_xfer = usbd_alloc_xfer(ue_udev); - if (c->ue_xfer == NULL) - return (ENOBUFS); - c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ); - if (c->ue_buf == NULL) - return (ENOBUFS); - } - } - - return (0); -} - -int -usb_ether_tx_list_init(void *sc, struct ue_cdata *cd, - usbd_device_handle ue_udev) -{ - struct ue_chain *c; - int i; - - for (i = 0; i < UE_TX_LIST_CNT; i++) { - c = &cd->ue_tx_chain[i]; - c->ue_sc = sc; - c->ue_idx = i; - c->ue_mbuf = NULL; - if (c->ue_xfer == NULL) { - c->ue_xfer = usbd_alloc_xfer(ue_udev); - if (c->ue_xfer == NULL) - return (ENOBUFS); - c->ue_buf = usbd_alloc_buffer(c->ue_xfer, UE_BUFSZ); - if (c->ue_buf == NULL) - return (ENOBUFS); - } - } - - return (0); -} - -void -usb_ether_rx_list_free(struct ue_cdata *cd) -{ - int i; - - for (i = 0; i < UE_RX_LIST_CNT; i++) { - if (cd->ue_rx_chain[i].ue_mbuf != NULL) { - m_freem(cd->ue_rx_chain[i].ue_mbuf); - cd->ue_rx_chain[i].ue_mbuf = NULL; - } - if (cd->ue_rx_chain[i].ue_xfer != NULL) { - usbd_free_xfer(cd->ue_rx_chain[i].ue_xfer); - cd->ue_rx_chain[i].ue_xfer = NULL; - } - } -} - -void -usb_ether_tx_list_free(struct ue_cdata *cd) -{ - int i; - - for (i = 0; i < UE_RX_LIST_CNT; i++) { - if (cd->ue_tx_chain[i].ue_mbuf != NULL) { - m_freem(cd->ue_tx_chain[i].ue_mbuf); - cd->ue_tx_chain[i].ue_mbuf = NULL; - } - if (cd->ue_tx_chain[i].ue_xfer != NULL) { - usbd_free_xfer(cd->ue_tx_chain[i].ue_xfer); - cd->ue_tx_chain[i].ue_xfer = NULL; - } - } -} - -void -usb_ether_task_init(device_t dev, int flags, struct usb_taskqueue *tq) -{ - - /* nothing for now. */ -} - -void -usb_ether_task_enqueue(struct usb_taskqueue *tq, struct task *task) -{ - - taskqueue_enqueue(taskqueue_thread, task); -} - -void -usb_ether_task_drain(struct usb_taskqueue *tq, struct task *task) -{ - - taskqueue_drain(taskqueue_thread, task); -} - -void -usb_ether_task_destroy(struct usb_taskqueue *tq) -{ - - /* nothing for now */ - -} diff --git a/sys/legacy/dev/usb/usb_ethersubr.h b/sys/legacy/dev/usb/usb_ethersubr.h deleted file mode 100644 index f3d2e3429b48..000000000000 --- a/sys/legacy/dev/usb/usb_ethersubr.h +++ /dev/null @@ -1,91 +0,0 @@ -/*- - * Copyright (c) 1997, 1998, 1999, 2000 - * Bill Paul . All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Bill Paul. - * 4. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _USB_ETHERSUBR_H_ -#define _USB_ETHERSUBR_H_ - -#include -#include - -#include - -#define UE_TX_LIST_CNT 1 -#define UE_RX_LIST_CNT 1 -#define UE_BUFSZ 1536 - -struct usb_qdat { - struct ifnet *ifp; - void (*if_rxstart) (struct ifnet *); -}; - -struct ue_chain { - void *ue_sc; - usbd_xfer_handle ue_xfer; - char *ue_buf; - struct mbuf *ue_mbuf; - int ue_idx; - usbd_status ue_status; -}; - -struct ue_cdata { - struct ue_chain ue_tx_chain[UE_TX_LIST_CNT]; - struct ue_chain ue_rx_chain[UE_RX_LIST_CNT]; - void *ue_ibuf; - int ue_tx_prod; - int ue_tx_cons; - int ue_tx_cnt; - int ue_rx_prod; -}; - -void usb_register_netisr (void); -void usb_ether_input (struct mbuf *); -void usb_tx_done (struct mbuf *); -struct mbuf *usb_ether_newbuf (void); -int usb_ether_rx_list_init (void *, struct ue_cdata *, - usbd_device_handle); -int usb_ether_tx_list_init (void *, struct ue_cdata *, - usbd_device_handle); -void usb_ether_rx_list_free (struct ue_cdata *); -void usb_ether_tx_list_free (struct ue_cdata *); - -struct usb_taskqueue { - int dummy; -}; - -void usb_ether_task_init(device_t, int, struct usb_taskqueue *); -void usb_ether_task_enqueue(struct usb_taskqueue *, struct task *); -void usb_ether_task_drain(struct usb_taskqueue *, struct task *); -void usb_ether_task_destroy(struct usb_taskqueue *); - -#endif /* _USB_ETHERSUBR_H_ */ From 270b60993586cb846054bbdd8bf3e57e7dff1b9f Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Wed, 13 May 2009 17:17:05 +0000 Subject: [PATCH 148/544] Remove now-unused NETISR_USB. --- sys/net/netisr.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/net/netisr.h b/sys/net/netisr.h index ab1dece7c9de..78a02f72e156 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -53,7 +53,6 @@ #define NETISR_ATALK1 17 /* Appletalk phase 1 */ #define NETISR_ARP 18 /* same as AF_LINK */ #define NETISR_IPX 23 /* same as AF_IPX */ -#define NETISR_USB 25 /* USB soft interrupt */ #define NETISR_PPP 26 /* PPP soft interrupt */ #define NETISR_IPV6 27 #define NETISR_NATM 28 From 2f120c90a7362e49b327675019a8726c3a049a2b Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Wed, 13 May 2009 17:22:33 +0000 Subject: [PATCH 149/544] Garbage collect now-unused NETISR_FORCEQUEUE, which overrode the global direct dispatch policy for specific protocols (NETISR_USB). We leave the additional 'flags' argument to netisr_register() for the time being, even though it is no longer required. --- sys/net/netisr.c | 15 +++++---------- sys/net/netisr.h | 1 - 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/sys/net/netisr.c b/sys/net/netisr.c index efbc1831dae8..eecf315bc3f7 100644 --- a/sys/net/netisr.c +++ b/sys/net/netisr.c @@ -78,8 +78,7 @@ netisr_register(int num, netisr_t *handler, struct ifqueue *inq, int flags) KASSERT(!(num < 0 || num >= (sizeof(netisrs)/sizeof(*netisrs))), ("bad isr %d", num)); - KASSERT(flags == 0 || flags == NETISR_FORCEQUEUE, - ("netisr_register: bad flags 0x%x\n", flags)); + KASSERT(flags == 0, ("netisr_register: bad flags 0x%x\n", flags)); netisrs[num].ni_handler = handler; netisrs[num].ni_queue = inq; netisrs[num].ni_flags = flags; @@ -169,15 +168,11 @@ netisr_dispatch(int num, struct mbuf *m) } /* - * Unless NETISR_FORCEQUEUE is set on the netisr (generally - * indicating that the handler still requires Giant, which cannot be - * acquired in arbitrary order with respect to a caller), directly - * dispatch handling of this packet. Source ordering is maintained - * by virtue of callers consistently calling one of queued or direct - * dispatch, and the forcequeue flag being immutable after - * registration. + * Directly dispatch handling of this packet, if permitted by global + * policy. Source ordering is maintained by virtue of callers + * consistently calling one of queued or direct dispatch. */ - if (netisr_direct && !(ni->ni_flags & NETISR_FORCEQUEUE)) { + if (netisr_direct) { isrstat.isrs_directed++; ni->ni_handler(m); } else { diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 78a02f72e156..1bc7b0c204f8 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -83,7 +83,6 @@ typedef void netisr_t (struct mbuf *); void netisr_dispatch(int, struct mbuf *); int netisr_queue(int, struct mbuf *); -#define NETISR_FORCEQUEUE 0x0002 /* Force queued dispatch. */ void netisr_register(int, netisr_t *, struct ifqueue *, int); void netisr_unregister(int); From 9dc0b3d54f3d673ef95c8dcf4781caf797a2f6ee Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 13 May 2009 17:53:04 +0000 Subject: [PATCH 150/544] Implement simple machine check support for amd64 and i386. - For CPUs that only support MCE (the machine check exception) but not MCA (i.e. Pentium), all this does is print out the value of the machine check registers and then panic when a machine check exception occurs. - For CPUs that support MCA (the machine check architecture), the support is a bit more involved. - First, there is limited support for decoding the CPU-independent MCA error codes in the kernel, and the kernel uses this to output a short description of any machine check events that occur. - When a machine check exception occurs, all of the MCx banks on the current CPU are scanned and any events are reported to the console before panic'ing. - To catch events for correctable errors, a periodic timer kicks off a task which scans the MCx banks on all CPUs. The frequency of these checks is controlled via the "hw.mca.interval" sysctl. - Userland can request an immediate scan of the MCx banks by writing a non-zero value to "hw.mca.force_scan". - If any correctable events are encountered, the appropriate details are stored in a 'struct mca_record' (defined in ). The "hw.mca.count" is a count of such records and each record may be queried via the "hw.mca.records" tree by specifying the record index (0 .. count - 1) as the next name in the MIB similar to using PIDs with the kern.proc.* sysctls. The idea is to export machine check events to userland for more detailed processing. - The periodic timer and hw.mca sysctls are only present if the CPU supports MCA. Discussed with: emaste (briefly) MFC after: 1 month --- sys/amd64/amd64/machdep.c | 2 + sys/amd64/amd64/mca.c | 530 +++++++++++++++++++++++++++++++++ sys/amd64/amd64/mp_machdep.c | 3 + sys/amd64/amd64/trap.c | 7 + sys/amd64/include/mca.h | 48 +++ sys/amd64/include/specialreg.h | 28 ++ sys/conf/files.amd64 | 1 + sys/conf/files.i386 | 1 + sys/i386/i386/machdep.c | 2 + sys/i386/i386/mca.c | 530 +++++++++++++++++++++++++++++++++ sys/i386/i386/mp_machdep.c | 3 + sys/i386/i386/trap.c | 7 + sys/i386/include/mca.h | 48 +++ sys/i386/include/specialreg.h | 28 ++ 14 files changed, 1238 insertions(+) create mode 100644 sys/amd64/amd64/mca.c create mode 100644 sys/amd64/include/mca.h create mode 100644 sys/i386/i386/mca.c create mode 100644 sys/i386/include/mca.h diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 4a5871a74dfd..eb1e72247307 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -109,6 +109,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -274,6 +275,7 @@ cpu_startup(dummy) vm_pager_bufferinit(); cpu_setregs(); + mca_init(); } /* diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c new file mode 100644 index 000000000000..f0cf57232aea --- /dev/null +++ b/sys/amd64/amd64/mca.c @@ -0,0 +1,530 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Support for x86 machine check architecture. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mca_internal { + struct mca_record rec; + int logged; + STAILQ_ENTRY(mca_internal) link; +}; + +static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture"); + +static struct sysctl_oid *mca_sysctl_tree; + +static int mca_count; /* Number of records stored. */ + +static STAILQ_HEAD(, mca_internal) mca_records; +static struct callout mca_timer; +static int mca_ticks = 3600; /* Check hourly by default. */ +static struct task mca_task; +static struct mtx mca_lock; + +static int +sysctl_mca_ticks(SYSCTL_HANDLER_ARGS) +{ + int error, value; + + value = mca_ticks; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error || req->newptr == NULL) + return (error); + if (value <= 0) + return (EINVAL); + mca_ticks = value; + return (0); +} + +static int +sysctl_mca_records(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *)arg1; + u_int namelen = arg2; + struct mca_record record; + struct mca_internal *rec; + int i; + + if (namelen != 1) + return (EINVAL); + + if (name[0] < 0 || name[0] >= mca_count) + return (EINVAL); + + mtx_lock_spin(&mca_lock); + if (name[0] >= mca_count) { + mtx_unlock_spin(&mca_lock); + return (EINVAL); + } + i = 0; + STAILQ_FOREACH(rec, &mca_records, link) { + if (i == name[0]) { + record = rec->rec; + break; + } + i++; + } + mtx_unlock_spin(&mca_lock); + return (SYSCTL_OUT(req, &record, sizeof(record))); +} + +static struct mca_record * +mca_record_entry(int bank) +{ + struct mca_internal *rec; + uint64_t status; + u_int p[4]; + + status = rdmsr(MSR_MC_STATUS(bank)); + if (!(status & MC_STATUS_VAL)) + return (NULL); + + rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT | M_ZERO); + if (rec == NULL) { + printf("MCA: Unable to allocate space for an event.\n"); + return (NULL); + } + + /* Save exception information. */ + rec->rec.mr_status = status; + if (status & MC_STATUS_ADDRV) + rec->rec.mr_addr = rdmsr(MSR_MC_ADDR(bank)); + if (status & MC_STATUS_MISCV) + rec->rec.mr_misc = rdmsr(MSR_MC_MISC(bank)); + rec->rec.mr_tsc = rdtsc(); + rec->rec.mr_apic_id = PCPU_GET(apic_id); + + /* + * Clear machine check. Don't do this for uncorrectable + * errors so that the BIOS can see them. + */ + if (!(rec->rec.mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { + wrmsr(MSR_MC_STATUS(bank), 0); + do_cpuid(0, p); + } + + mtx_lock_spin(&mca_lock); + STAILQ_INSERT_TAIL(&mca_records, rec, link); + mca_count++; + mtx_unlock_spin(&mca_lock); + return (&rec->rec); +} + +static const char * +mca_error_ttype(uint16_t mca_error) +{ + + switch ((mca_error & 0x000c) >> 2) { + case 0: + return ("I"); + case 1: + return ("D"); + case 2: + return ("G"); + } + return ("?"); +} + +static const char * +mca_error_level(uint16_t mca_error) +{ + + switch (mca_error & 0x0003) { + case 0: + return ("L0"); + case 1: + return ("L1"); + case 2: + return ("L2"); + case 3: + return ("LG"); + } + return ("L?"); +} + +static const char * +mca_error_request(uint16_t mca_error) +{ + + switch ((mca_error & 0x00f0) >> 4) { + case 0x0: + return ("ERR"); + case 0x1: + return ("RD"); + case 0x2: + return ("WR"); + case 0x3: + return ("DRD"); + case 0x4: + return ("DWR"); + case 0x5: + return ("IRD"); + case 0x6: + return ("PREFETCH"); + case 0x7: + return ("EVICT"); + case 0x8: + return ("SNOOP"); + } + return ("???"); +} + +/* Dump details about a single machine check. */ +static void +mca_log(struct mca_record *rec) +{ + uint16_t mca_error; + + printf("MCA: CPU %d ", rec->mr_apic_id); + if (rec->mr_status & MC_STATUS_UC) + printf("UNCOR "); + else + printf("COR "); + if (rec->mr_status & MC_STATUS_PCC) + printf("PCC "); + if (rec->mr_status & MC_STATUS_OVER) + printf("OVER "); + mca_error = rec->mr_status & MC_STATUS_MCA_ERROR; + switch (mca_error) { + /* Simple error codes. */ + case 0x0000: + printf("no error"); + break; + case 0x0001: + printf("unclassified error"); + break; + case 0x0002: + printf("ucode ROM parity error"); + break; + case 0x0003: + printf("external error"); + break; + case 0x0004: + printf("FRC error"); + break; + case 0x0400: + printf("internal timer error"); + break; + default: + if ((mca_error & 0xfc00) == 0x0400) { + printf("internal error %x", mca_error & 0x03ff); + break; + } + + /* Compound error codes. */ + + /* Memory hierarchy error. */ + if ((mca_error & 0xeffc) == 0x000c) { + printf("%s memory error", mca_error_level(mca_error)); + break; + } + + /* TLB error. */ + if ((mca_error & 0xeff0) == 0x0010) { + printf("%sTLB %s error", mca_error_ttype(mca_error), + mca_error_level(mca_error)); + break; + } + + /* Cache error. */ + if ((mca_error & 0xef00) == 0x0100) { + printf("%sCACHE %s %s error", + mca_error_ttype(mca_error), + mca_error_level(mca_error), + mca_error_request(mca_error)); + break; + } + + /* Bus and/or Interconnect error. */ + if ((mca_error & 0xe800) == 0x0800) { + printf("BUS%s ", mca_error_level(mca_error)); + switch ((mca_error & 0x0600) >> 9) { + case 0: + printf("Source"); + break; + case 1: + printf("Responder"); + break; + case 2: + printf("Observer"); + break; + default: + printf("???"); + break; + } + printf(" %s ", mca_error_request(mca_error)); + switch ((mca_error & 0x000c) >> 2) { + case 0: + printf("Memory"); + break; + case 2: + printf("I/O"); + break; + case 3: + printf("Other"); + break; + default: + printf("???"); + break; + } + if (mca_error & 0x0100) + printf(" timed out"); + break; + } + + printf("unknown error %x", mca_error); + break; + } + printf("\n"); + if (rec->mr_status & MC_STATUS_ADDRV) + printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr); +} + +/* + * This scans all the machine check banks of the current CPU to see if + * there are any machine checks. Any non-recoverable errors are + * reported immediately via mca_log(). The current thread must be + * pinned when this is called. The 'mcip' parameter indicates if we + * are being called from the MC exception handler. In that case this + * function returns true if the system is restartable. Otherwise, it + * returns a count of the number of valid MC records found. + */ +static int +mca_scan(int mcip) +{ + struct mca_record *rec; + uint64_t mcg_cap, ucmask; + int count, i, recoverable; + + count = 0; + recoverable = 1; + ucmask = MC_STATUS_UC | MC_STATUS_PCC; + + /* When handling a MCE#, treat the OVER flag as non-restartable. */ + if (mcip) + ucmask = MC_STATUS_OVER; + mcg_cap = rdmsr(MSR_MCG_CAP); + for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { + rec = mca_record_entry(i); + if (rec != NULL) { + count++; + if (rec->mr_status & ucmask) { + recoverable = 0; + mca_log(rec); + } + } + } + return (mcip ? recoverable : count); +} + +/* + * Scan the machine check banks on all CPUs by binding to each CPU in + * turn. If any of the CPUs contained new machine check records, log + * them to the console. + */ +static void +mca_scan_cpus(void *context, int pending) +{ + struct mca_internal *mca; + struct thread *td; + int count, cpu; + + td = curthread; + count = 0; + thread_lock(td); + for (cpu = 0; cpu <= mp_maxid; cpu++) { + if (CPU_ABSENT(cpu)) + continue; + sched_bind(td, cpu); + thread_unlock(td); + count += mca_scan(0); + thread_lock(td); + sched_unbind(td); + } + thread_unlock(td); + if (count != 0) { + mtx_lock_spin(&mca_lock); + STAILQ_FOREACH(mca, &mca_records, link) { + if (!mca->logged) { + mca->logged = 1; + mtx_unlock_spin(&mca_lock); + mca_log(&mca->rec); + mtx_lock_spin(&mca_lock); + } + } + mtx_unlock_spin(&mca_lock); + } +} + +static void +mca_periodic_scan(void *arg) +{ + + taskqueue_enqueue(taskqueue_thread, &mca_task); + callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, NULL); +} + +static int +sysctl_mca_scan(SYSCTL_HANDLER_ARGS) +{ + int error, i; + + i = 0; + error = sysctl_handle_int(oidp, &i, 0, req); + if (error) + return (error); + if (i) + taskqueue_enqueue(taskqueue_thread, &mca_task); + return (0); +} + +static void +mca_startup(void *dummy) +{ + + if (!(cpu_feature & CPUID_MCA)) + return; + + callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, + NULL); +} +SYSINIT(mca_startup, SI_SUB_SMP, SI_ORDER_ANY, mca_startup, NULL); + +static void +mca_setup(void) +{ + + mtx_init(&mca_lock, "mca", NULL, MTX_SPIN); + STAILQ_INIT(&mca_records); + TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL); + callout_init(&mca_timer, CALLOUT_MPSAFE); + mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw), + OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container"); + SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "count", CTLFLAG_RD, &mca_count, 0, "Record count"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks, + 0, sysctl_mca_ticks, "I", + "Periodic interval in seconds to scan for machine checks"); + SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, + sysctl_mca_scan, "I", "Force an immediate scan for machine checks"); +} + +/* Must be executed on each CPU. */ +void +mca_init(void) +{ + uint64_t mcg_cap; + int i; + + /* MCE is required. */ + if (!(cpu_feature & CPUID_MCE)) + return; + + if (cpu_feature & CPUID_MCA) { + if (PCPU_GET(cpuid) == 0) + mca_setup(); + + sched_pin(); + mcg_cap = rdmsr(MSR_MCG_CAP); + if (mcg_cap & MCG_CAP_CTL_P) + /* Enable MCA features. */ + wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); + + for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { + /* + * Enable logging of all errors. For P6 + * processors, MC0_CTL is always enabled. + * + * XXX: Better CPU test needed here? + */ + if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) + wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); + + /* XXX: Better CPU test needed here. */ + if ((cpu_id & 0xf00) == 0xf00) + mca_record_entry(i); + + /* Clear all errors. */ + wrmsr(MSR_MC_STATUS(i), 0); + } + sched_unpin(); + } + + load_cr4(rcr4() | CR4_MCE); +} + +/* Called when a machine check exception fires. */ +int +mca_intr(void) +{ + uint64_t mcg_status; + int recoverable; + + if (!(cpu_feature & CPUID_MCA)) { + /* + * Just print the values of the old Pentium registers + * and panic. + */ + printf("MC Type: 0x%lx Address: 0x%lx\n", + rdmsr(MSR_P5_MC_TYPE), rdmsr(MSR_P5_MC_ADDR)); + return (0); + } + + /* Scan the banks and check for any non-recoverable errors. */ + recoverable = mca_scan(1); + mcg_status = rdmsr(MSR_MCG_STATUS); + if (!(mcg_status & MCG_STATUS_RIPV)) + recoverable = 0; + + /* Clear MCIP. */ + wrmsr(MSR_MCG_STATUS, mcg_status & ~MCG_STATUS_MCIP); + return (recoverable); +} diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 7a930237307b..f398a24b20c9 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -60,6 +60,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -667,6 +668,8 @@ init_secondary(void) KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread")); PCPU_SET(curthread, PCPU_GET(idlethread)); + mca_init(); + mtx_lock_spin(&ap_boot_mtx); /* Init local apic for irq's */ diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 467feafcee36..fee3caf6a9da 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -88,6 +88,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #ifdef SMP @@ -266,6 +267,12 @@ trap(struct trapframe *frame) goto out; #endif + if (type == T_MCHK) { + if (!mca_intr()) + trap_fatal(frame, 0); + goto out; + } + #ifdef KDTRACE_HOOKS /* * A trap can occur while DTrace executes a probe. Before diff --git a/sys/amd64/include/mca.h b/sys/amd64/include/mca.h new file mode 100644 index 000000000000..c43d98953e42 --- /dev/null +++ b/sys/amd64/include/mca.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __MACHINE_MCA_H__ +#define __MACHINE_MCA_H__ + +struct mca_record { + uint64_t mr_status; + uint64_t mr_addr; + uint64_t mr_misc; + uint64_t mr_tsc; + int mr_apic_id; +}; + +#ifdef _KERNEL + +void mca_init(void); +int mca_intr(void); + +#endif + +#endif /* !__MACHINE_MCA_H__ */ diff --git a/sys/amd64/include/specialreg.h b/sys/amd64/include/specialreg.h index afc6580ea9ff..88ff734ca114 100644 --- a/sys/amd64/include/specialreg.h +++ b/sys/amd64/include/specialreg.h @@ -345,6 +345,34 @@ #define DIR0 0xfe #define DIR1 0xff +/* + * Machine Check register constants. + */ +#define MCG_CAP_COUNT 0x000000ff +#define MCG_CAP_CTL_P 0x00000100 +#define MCG_CAP_EXT_P 0x00000200 +#define MCG_CAP_TES_P 0x00000800 +#define MCG_CAP_EXT_CNT 0x00ff0000 +#define MCG_STATUS_RIPV 0x00000001 +#define MCG_STATUS_EIPV 0x00000002 +#define MCG_STATUS_MCIP 0x00000004 +#define MCG_CTL_ENABLE 0xffffffffffffffffUL +#define MCG_CTL_DISABLE 0x0000000000000000UL +#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4) +#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4) +#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4) +#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4) +#define MC_STATUS_MCA_ERROR 0x000000000000ffffUL +#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000UL +#define MC_STATUS_OTHER_INFO 0x01ffffff00000000UL +#define MC_STATUS_PCC 0x0200000000000000UL +#define MC_STATUS_ADDRV 0x0400000000000000UL +#define MC_STATUS_MISCV 0x0800000000000000UL +#define MC_STATUS_EN 0x1000000000000000UL +#define MC_STATUS_UC 0x2000000000000000UL +#define MC_STATUS_OVER 0x4000000000000000UL +#define MC_STATUS_VAL 0x8000000000000000UL + /* * The following four 3-byte registers control the non-cacheable regions. * These registers must be written as three separate bytes. diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 56e17d15712d..602d7e04ae77 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -110,6 +110,7 @@ amd64/amd64/legacy.c standard amd64/amd64/local_apic.c standard amd64/amd64/locore.S standard no-obj amd64/amd64/machdep.c standard +amd64/amd64/mca.c standard amd64/amd64/mem.c optional mem amd64/amd64/minidump_machdep.c standard amd64/amd64/mp_machdep.c optional smp diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index d88be047be8a..5a1ed9185882 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -278,6 +278,7 @@ i386/xen/locore.s optional xen no-obj i386/i386/longrun.c optional cpu_enable_longrun i386/i386/machdep.c standard i386/xen/xen_machdep.c optional xen +i386/i386/mca.c standard i386/i386/mem.c optional mem i386/i386/minidump_machdep.c standard i386/i386/mp_clock.c optional smp diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 3987907f94b1..a74db11cdc2c 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -113,6 +113,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -320,6 +321,7 @@ cpu_startup(dummy) #ifndef XEN cpu_setregs(); #endif + mca_init(); } /* diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c new file mode 100644 index 000000000000..63317ee34025 --- /dev/null +++ b/sys/i386/i386/mca.c @@ -0,0 +1,530 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * Support for x86 machine check architecture. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mca_internal { + struct mca_record rec; + int logged; + STAILQ_ENTRY(mca_internal) link; +}; + +static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture"); + +static struct sysctl_oid *mca_sysctl_tree; + +static int mca_count; /* Number of records stored. */ + +static STAILQ_HEAD(, mca_internal) mca_records; +static struct callout mca_timer; +static int mca_ticks = 3600; /* Check hourly by default. */ +static struct task mca_task; +static struct mtx mca_lock; + +static int +sysctl_mca_ticks(SYSCTL_HANDLER_ARGS) +{ + int error, value; + + value = mca_ticks; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error || req->newptr == NULL) + return (error); + if (value <= 0) + return (EINVAL); + mca_ticks = value; + return (0); +} + +static int +sysctl_mca_records(SYSCTL_HANDLER_ARGS) +{ + int *name = (int *)arg1; + u_int namelen = arg2; + struct mca_record record; + struct mca_internal *rec; + int i; + + if (namelen != 1) + return (EINVAL); + + if (name[0] < 0 || name[0] >= mca_count) + return (EINVAL); + + mtx_lock_spin(&mca_lock); + if (name[0] >= mca_count) { + mtx_unlock_spin(&mca_lock); + return (EINVAL); + } + i = 0; + STAILQ_FOREACH(rec, &mca_records, link) { + if (i == name[0]) { + record = rec->rec; + break; + } + i++; + } + mtx_unlock_spin(&mca_lock); + return (SYSCTL_OUT(req, &record, sizeof(record))); +} + +static struct mca_record * +mca_record_entry(int bank) +{ + struct mca_internal *rec; + uint64_t status; + u_int p[4]; + + status = rdmsr(MSR_MC_STATUS(bank)); + if (!(status & MC_STATUS_VAL)) + return (NULL); + + rec = malloc(sizeof(*rec), M_MCA, M_NOWAIT | M_ZERO); + if (rec == NULL) { + printf("MCA: Unable to allocate space for an event.\n"); + return (NULL); + } + + /* Save exception information. */ + rec->rec.mr_status = status; + if (status & MC_STATUS_ADDRV) + rec->rec.mr_addr = rdmsr(MSR_MC_ADDR(bank)); + if (status & MC_STATUS_MISCV) + rec->rec.mr_misc = rdmsr(MSR_MC_MISC(bank)); + rec->rec.mr_tsc = rdtsc(); + rec->rec.mr_apic_id = PCPU_GET(apic_id); + + /* + * Clear machine check. Don't do this for uncorrectable + * errors so that the BIOS can see them. + */ + if (!(rec->rec.mr_status & (MC_STATUS_PCC | MC_STATUS_UC))) { + wrmsr(MSR_MC_STATUS(bank), 0); + do_cpuid(0, p); + } + + mtx_lock_spin(&mca_lock); + STAILQ_INSERT_TAIL(&mca_records, rec, link); + mca_count++; + mtx_unlock_spin(&mca_lock); + return (&rec->rec); +} + +static const char * +mca_error_ttype(uint16_t mca_error) +{ + + switch ((mca_error & 0x000c) >> 2) { + case 0: + return ("I"); + case 1: + return ("D"); + case 2: + return ("G"); + } + return ("?"); +} + +static const char * +mca_error_level(uint16_t mca_error) +{ + + switch (mca_error & 0x0003) { + case 0: + return ("L0"); + case 1: + return ("L1"); + case 2: + return ("L2"); + case 3: + return ("LG"); + } + return ("L?"); +} + +static const char * +mca_error_request(uint16_t mca_error) +{ + + switch ((mca_error & 0x00f0) >> 4) { + case 0x0: + return ("ERR"); + case 0x1: + return ("RD"); + case 0x2: + return ("WR"); + case 0x3: + return ("DRD"); + case 0x4: + return ("DWR"); + case 0x5: + return ("IRD"); + case 0x6: + return ("PREFETCH"); + case 0x7: + return ("EVICT"); + case 0x8: + return ("SNOOP"); + } + return ("???"); +} + +/* Dump details about a single machine check. */ +static void +mca_log(struct mca_record *rec) +{ + uint16_t mca_error; + + printf("MCA: CPU %d ", rec->mr_apic_id); + if (rec->mr_status & MC_STATUS_UC) + printf("UNCOR "); + else + printf("COR "); + if (rec->mr_status & MC_STATUS_PCC) + printf("PCC "); + if (rec->mr_status & MC_STATUS_OVER) + printf("OVER "); + mca_error = rec->mr_status & MC_STATUS_MCA_ERROR; + switch (mca_error) { + /* Simple error codes. */ + case 0x0000: + printf("no error"); + break; + case 0x0001: + printf("unclassified error"); + break; + case 0x0002: + printf("ucode ROM parity error"); + break; + case 0x0003: + printf("external error"); + break; + case 0x0004: + printf("FRC error"); + break; + case 0x0400: + printf("internal timer error"); + break; + default: + if ((mca_error & 0xfc00) == 0x0400) { + printf("internal error %x", mca_error & 0x03ff); + break; + } + + /* Compound error codes. */ + + /* Memory hierarchy error. */ + if ((mca_error & 0xeffc) == 0x000c) { + printf("%s memory error", mca_error_level(mca_error)); + break; + } + + /* TLB error. */ + if ((mca_error & 0xeff0) == 0x0010) { + printf("%sTLB %s error", mca_error_ttype(mca_error), + mca_error_level(mca_error)); + break; + } + + /* Cache error. */ + if ((mca_error & 0xef00) == 0x0100) { + printf("%sCACHE %s %s error", + mca_error_ttype(mca_error), + mca_error_level(mca_error), + mca_error_request(mca_error)); + break; + } + + /* Bus and/or Interconnect error. */ + if ((mca_error & 0xe800) == 0x0800) { + printf("BUS%s ", mca_error_level(mca_error)); + switch ((mca_error & 0x0600) >> 9) { + case 0: + printf("Source"); + break; + case 1: + printf("Responder"); + break; + case 2: + printf("Observer"); + break; + default: + printf("???"); + break; + } + printf(" %s ", mca_error_request(mca_error)); + switch ((mca_error & 0x000c) >> 2) { + case 0: + printf("Memory"); + break; + case 2: + printf("I/O"); + break; + case 3: + printf("Other"); + break; + default: + printf("???"); + break; + } + if (mca_error & 0x0100) + printf(" timed out"); + break; + } + + printf("unknown error %x", mca_error); + break; + } + printf("\n"); + if (rec->mr_status & MC_STATUS_ADDRV) + printf("MCA: Address 0x%llx\n", (long long)rec->mr_addr); +} + +/* + * This scans all the machine check banks of the current CPU to see if + * there are any machine checks. Any non-recoverable errors are + * reported immediately via mca_log(). The current thread must be + * pinned when this is called. The 'mcip' parameter indicates if we + * are being called from the MC exception handler. In that case this + * function returns true if the system is restartable. Otherwise, it + * returns a count of the number of valid MC records found. + */ +static int +mca_scan(int mcip) +{ + struct mca_record *rec; + uint64_t mcg_cap, ucmask; + int count, i, recoverable; + + count = 0; + recoverable = 1; + ucmask = MC_STATUS_UC | MC_STATUS_PCC; + + /* When handling a MCE#, treat the OVER flag as non-restartable. */ + if (mcip) + ucmask = MC_STATUS_OVER; + mcg_cap = rdmsr(MSR_MCG_CAP); + for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { + rec = mca_record_entry(i); + if (rec != NULL) { + count++; + if (rec->mr_status & ucmask) { + recoverable = 0; + mca_log(rec); + } + } + } + return (mcip ? recoverable : count); +} + +/* + * Scan the machine check banks on all CPUs by binding to each CPU in + * turn. If any of the CPUs contained new machine check records, log + * them to the console. + */ +static void +mca_scan_cpus(void *context, int pending) +{ + struct mca_internal *mca; + struct thread *td; + int count, cpu; + + td = curthread; + count = 0; + thread_lock(td); + for (cpu = 0; cpu <= mp_maxid; cpu++) { + if (CPU_ABSENT(cpu)) + continue; + sched_bind(td, cpu); + thread_unlock(td); + count += mca_scan(0); + thread_lock(td); + sched_unbind(td); + } + thread_unlock(td); + if (count != 0) { + mtx_lock_spin(&mca_lock); + STAILQ_FOREACH(mca, &mca_records, link) { + if (!mca->logged) { + mca->logged = 1; + mtx_unlock_spin(&mca_lock); + mca_log(&mca->rec); + mtx_lock_spin(&mca_lock); + } + } + mtx_unlock_spin(&mca_lock); + } +} + +static void +mca_periodic_scan(void *arg) +{ + + taskqueue_enqueue(taskqueue_thread, &mca_task); + callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, NULL); +} + +static int +sysctl_mca_scan(SYSCTL_HANDLER_ARGS) +{ + int error, i; + + i = 0; + error = sysctl_handle_int(oidp, &i, 0, req); + if (error) + return (error); + if (i) + taskqueue_enqueue(taskqueue_thread, &mca_task); + return (0); +} + +static void +mca_startup(void *dummy) +{ + + if (!(cpu_feature & CPUID_MCA)) + return; + + callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, + NULL); +} +SYSINIT(mca_startup, SI_SUB_SMP, SI_ORDER_ANY, mca_startup, NULL); + +static void +mca_setup(void) +{ + + mtx_init(&mca_lock, "mca", NULL, MTX_SPIN); + STAILQ_INIT(&mca_records); + TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL); + callout_init(&mca_timer, CALLOUT_MPSAFE); + mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw), + OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container"); + SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "count", CTLFLAG_RD, &mca_count, 0, "Record count"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks, + 0, sysctl_mca_ticks, "I", + "Periodic interval in seconds to scan for machine checks"); + SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records"); + SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, + sysctl_mca_scan, "I", "Force an immediate scan for machine checks"); +} + +/* Must be executed on each CPU. */ +void +mca_init(void) +{ + uint64_t mcg_cap; + int i; + + /* MCE is required. */ + if (!(cpu_feature & CPUID_MCE)) + return; + + if (cpu_feature & CPUID_MCA) { + if (PCPU_GET(cpuid) == 0) + mca_setup(); + + sched_pin(); + mcg_cap = rdmsr(MSR_MCG_CAP); + if (mcg_cap & MCG_CAP_CTL_P) + /* Enable MCA features. */ + wrmsr(MSR_MCG_CTL, MCG_CTL_ENABLE); + + for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { + /* + * Enable logging of all errors. For P6 + * processors, MC0_CTL is always enabled. + * + * XXX: Better CPU test needed here? + */ + if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) + wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); + + /* XXX: Better CPU test needed here. */ + if ((cpu_id & 0xf00) == 0xf00) + mca_record_entry(i); + + /* Clear all errors. */ + wrmsr(MSR_MC_STATUS(i), 0); + } + sched_unpin(); + } + + load_cr4(rcr4() | CR4_MCE); +} + +/* Called when a machine check exception fires. */ +int +mca_intr(void) +{ + uint64_t mcg_status; + int recoverable; + + if (!(cpu_feature & CPUID_MCA)) { + /* + * Just print the values of the old Pentium registers + * and panic. + */ + printf("MC Type: 0x%llx Address: 0x%llx\n", + rdmsr(MSR_P5_MC_TYPE), rdmsr(MSR_P5_MC_ADDR)); + return (0); + } + + /* Scan the banks and check for any non-recoverable errors. */ + recoverable = mca_scan(1); + mcg_status = rdmsr(MSR_MCG_STATUS); + if (!(mcg_status & MCG_STATUS_RIPV)) + recoverable = 0; + + /* Clear MCIP. */ + wrmsr(MSR_MCG_STATUS, mcg_status & ~MCG_STATUS_MCIP); + return (recoverable); +} diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 69fa35583e0a..4495a5735311 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -74,6 +74,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -704,6 +705,8 @@ init_secondary(void) KASSERT(PCPU_GET(idlethread) != NULL, ("no idle thread")); PCPU_SET(curthread, PCPU_GET(idlethread)); + mca_init(); + mtx_lock_spin(&ap_boot_mtx); /* Init local apic for irq's */ diff --git a/sys/i386/i386/trap.c b/sys/i386/i386/trap.c index 95e33e30b7c7..e9671046060c 100644 --- a/sys/i386/i386/trap.c +++ b/sys/i386/i386/trap.c @@ -90,6 +90,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #ifdef SMP @@ -239,6 +240,12 @@ trap(struct trapframe *frame) goto out; #endif + if (type == T_MCHK) { + if (!mca_intr()) + trap_fatal(frame, 0); + goto out; + } + #ifdef KDTRACE_HOOKS /* * A trap can occur while DTrace executes a probe. Before diff --git a/sys/i386/include/mca.h b/sys/i386/include/mca.h new file mode 100644 index 000000000000..c43d98953e42 --- /dev/null +++ b/sys/i386/include/mca.h @@ -0,0 +1,48 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: John H. Baldwin + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __MACHINE_MCA_H__ +#define __MACHINE_MCA_H__ + +struct mca_record { + uint64_t mr_status; + uint64_t mr_addr; + uint64_t mr_misc; + uint64_t mr_tsc; + int mr_apic_id; +}; + +#ifdef _KERNEL + +void mca_init(void); +int mca_intr(void); + +#endif + +#endif /* !__MACHINE_MCA_H__ */ diff --git a/sys/i386/include/specialreg.h b/sys/i386/include/specialreg.h index fa9cf8143bef..67283e44c580 100644 --- a/sys/i386/include/specialreg.h +++ b/sys/i386/include/specialreg.h @@ -414,6 +414,34 @@ #define DIR0 0xfe #define DIR1 0xff +/* + * Machine Check register constants. + */ +#define MCG_CAP_COUNT 0x000000ff +#define MCG_CAP_CTL_P 0x00000100 +#define MCG_CAP_EXT_P 0x00000200 +#define MCG_CAP_TES_P 0x00000800 +#define MCG_CAP_EXT_CNT 0x00ff0000 +#define MCG_STATUS_RIPV 0x00000001 +#define MCG_STATUS_EIPV 0x00000002 +#define MCG_STATUS_MCIP 0x00000004 +#define MCG_CTL_ENABLE 0xffffffffffffffffUL +#define MCG_CTL_DISABLE 0x0000000000000000UL +#define MSR_MC_CTL(x) (MSR_MC0_CTL + (x) * 4) +#define MSR_MC_STATUS(x) (MSR_MC0_STATUS + (x) * 4) +#define MSR_MC_ADDR(x) (MSR_MC0_ADDR + (x) * 4) +#define MSR_MC_MISC(x) (MSR_MC0_MISC + (x) * 4) +#define MC_STATUS_MCA_ERROR 0x000000000000ffffUL +#define MC_STATUS_MODEL_ERROR 0x00000000ffff0000UL +#define MC_STATUS_OTHER_INFO 0x01ffffff00000000UL +#define MC_STATUS_PCC 0x0200000000000000UL +#define MC_STATUS_ADDRV 0x0400000000000000UL +#define MC_STATUS_MISCV 0x0800000000000000UL +#define MC_STATUS_EN 0x1000000000000000UL +#define MC_STATUS_UC 0x2000000000000000UL +#define MC_STATUS_OVER 0x4000000000000000UL +#define MC_STATUS_VAL 0x8000000000000000UL + /* * The following four 3-byte registers control the non-cacheable regions. * These registers must be written as three separate bytes. From f1f8840814846a633225fd805f157774209ba919 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 17:58:37 +0000 Subject: [PATCH 151/544] The transfer must return USB_ERR_CANCELLED when the device is gone due to the way usb drivers work. Submitted by: Hans Petter Selasky --- sys/dev/usb/usb_transfer.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index b0aba0f6c2f8..d3c289645616 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -1439,7 +1439,11 @@ usb2_start_hardware(struct usb2_xfer *xfer) /* Check if the device is still alive */ if (info->udev->state < USB_STATE_POWERED) { USB_BUS_LOCK(bus); - usb2_transfer_done(xfer, USB_ERR_NOT_CONFIGURED); + /* + * Must return cancelled error code else + * device drivers can hang. + */ + usb2_transfer_done(xfer, USB_ERR_CANCELLED); USB_BUS_UNLOCK(bus); return; } From 3a67e914306cf61a28b937f7cf09bf2df4584eeb Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:03:23 +0000 Subject: [PATCH 152/544] Sync to P4 Add umass quirks for Alcor AU6390, Cypress PATA 6830XX and MPMan MPF400. Submitted by: Hans Petter Selasky --- sys/dev/usb/storage/umass.c | 147 ++++++++++++++++++++---------------- sys/dev/usb/usbdevs | 7 ++ 2 files changed, 90 insertions(+), 64 deletions(-) diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index 2f2a163523fc..bca5d998e554 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -309,6 +309,7 @@ struct umass_devdescr { /* wire and command protocol */ uint16_t proto; +#define UMASS_PROTO_DEFAULT 0x0000 /* use protocol indicated by USB descriptors */ #define UMASS_PROTO_BBB 0x0001 /* USB wire protocol */ #define UMASS_PROTO_CBI 0x0002 #define UMASS_PROTO_CBI_I 0x0004 @@ -372,7 +373,7 @@ struct umass_devdescr { static const struct umass_devdescr umass_devdescr[] = { {USB_VENDOR_ASAHIOPTICAL, PID_WILDCARD, RID_WILDCARD, - UMASS_PROTO_ATAPI | UMASS_PROTO_CBI_I, + UMASS_PROTO_DEFAULT, RS_NO_CLEAR_UA }, {USB_VENDOR_ADDON, USB_PRODUCT_ADDON_ATTACHE, RID_WILDCARD, @@ -395,6 +396,10 @@ static const struct umass_devdescr umass_devdescr[] = { UMASS_PROTO_SCSI | UMASS_PROTO_BBB, NO_QUIRKS }, + {USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_AU6390, RID_WILDCARD, + UMASS_PROTO_DEFAULT, + NO_SYNCHRONIZE_CACHE + }, {USB_VENDOR_ALCOR, USB_PRODUCT_ALCOR_UMCR_9361, RID_WILDCARD, UMASS_PROTO_SCSI | UMASS_PROTO_BBB, NO_GETMAXLUN @@ -427,6 +432,10 @@ static const struct umass_devdescr umass_devdescr[] = { UMASS_PROTO_SCSI | UMASS_PROTO_BBB, FORCE_SHORT_INQUIRY | NO_START_STOP | IGNORE_RESIDUE }, + {USB_VENDOR_CYPRESS, USB_PRODUCT_CYPRESS_XX6830XX, RID_WILDCARD, + UMASS_PROTO_DEFAULT, + NO_GETMAXLUN | NO_SYNCHRONIZE_CACHE + }, {USB_VENDOR_DESKNOTE, USB_PRODUCT_DESKNOTE_UCR_61S2B, RID_WILDCARD, UMASS_PROTO_SCSI | UMASS_PROTO_BBB, NO_QUIRKS @@ -600,6 +609,10 @@ static const struct umass_devdescr umass_devdescr[] = { UMASS_PROTO_SCSI | UMASS_PROTO_BBB, FORCE_SHORT_INQUIRY | NO_INQUIRY_EVPD | NO_GETMAXLUN }, + {USB_VENDOR_MPMAN, PID_WILDCARD, RID_WILDCARD, + UMASS_PROTO_DEFAULT, + NO_SYNCHRONIZE_CACHE + }, {USB_VENDOR_MSYSTEMS, USB_PRODUCT_MSYSTEMS_DISKONKEY, RID_WILDCARD, UMASS_PROTO_SCSI | UMASS_PROTO_BBB, IGNORE_RESIDUE | NO_GETMAXLUN | RS_NO_CLEAR_UA @@ -609,11 +622,11 @@ static const struct umass_devdescr umass_devdescr[] = { NO_QUIRKS }, {USB_VENDOR_MYSON, USB_PRODUCT_MYSON_HEDEN, RID_WILDCARD, - UMASS_PROTO_SCSI | UMASS_PROTO_BBB, + UMASS_PROTO_DEFAULT, IGNORE_RESIDUE | NO_SYNCHRONIZE_CACHE }, {USB_VENDOR_MYSON, USB_PRODUCT_MYSON_STARREADER, RID_WILDCARD, - UMASS_PROTO_SCSI | UMASS_PROTO_BBB, + UMASS_PROTO_DEFAULT, NO_SYNCHRONIZE_CACHE }, {USB_VENDOR_NEODIO, USB_PRODUCT_NEODIO_ND3260, RID_WILDCARD, @@ -849,7 +862,7 @@ static const struct umass_devdescr umass_devdescr[] = { NO_QUIRKS }, {USB_VENDOR_SUPERTOP, USB_PRODUCT_SUPERTOP_IDE, RID_WILDCARD, - UMASS_PROTO_SCSI | UMASS_PROTO_BBB, + UMASS_PROTO_DEFAULT, IGNORE_RESIDUE | NO_SYNCHRONIZE_CACHE }, {USB_VENDOR_TAUGA, USB_PRODUCT_TAUGA_CAMERAMATE, RID_WILDCARD, @@ -1281,6 +1294,58 @@ MODULE_DEPEND(umass, cam, 1, 1, 1); * USB device probe/attach/detach */ +static uint16_t +umass_get_proto(struct usb2_interface *iface) +{ + struct usb2_interface_descriptor *id; + uint16_t retval; + + retval = 0; + + /* Check for a standards compliant device */ + id = usb2_get_interface_descriptor(iface); + if ((id == NULL) || + (id->bInterfaceClass != UICLASS_MASS)) { + goto done; + } + switch (id->bInterfaceSubClass) { + case UISUBCLASS_SCSI: + retval |= UMASS_PROTO_SCSI; + break; + case UISUBCLASS_UFI: + retval |= UMASS_PROTO_UFI; + break; + case UISUBCLASS_RBC: + retval |= UMASS_PROTO_RBC; + break; + case UISUBCLASS_SFF8020I: + case UISUBCLASS_SFF8070I: + retval |= UMASS_PROTO_ATAPI; + break; + default: + retval = 0; + goto done; + } + + switch (id->bInterfaceProtocol) { + case UIPROTO_MASS_CBI: + retval |= UMASS_PROTO_CBI; + break; + case UIPROTO_MASS_CBI_I: + retval |= UMASS_PROTO_CBI_I; + break; + case UIPROTO_MASS_BBB_OLD: + case UIPROTO_MASS_BBB: + retval |= UMASS_PROTO_BBB; + break; + default: + retval = 0; + goto done; + } +done: + return (retval); +} + /* * Match the device we are seeing with the * devices supported. @@ -1289,10 +1354,9 @@ static struct umass_probe_proto umass_probe_proto(device_t dev, struct usb2_attach_arg *uaa) { const struct umass_devdescr *udd = umass_devdescr; - struct usb2_interface_descriptor *id; struct umass_probe_proto ret; - bzero(&ret, sizeof(ret)); + memset(&ret, 0, sizeof(ret)); /* * An entry specifically for Y-E Data devices as they don't fit in @@ -1319,7 +1383,6 @@ umass_probe_proto(device_t dev, struct usb2_attach_arg *uaa) ret.quirks |= NO_TEST_UNIT_READY; } ret.quirks |= RS_NO_CLEAR_UA | FLOPPY_SPEED; - ret.error = 0; goto done; } /* @@ -1327,13 +1390,6 @@ umass_probe_proto(device_t dev, struct usb2_attach_arg *uaa) * check for wildcarded and fully matched. First match wins. */ for (; udd->vid != VID_EOT; udd++) { - if ((udd->vid == VID_WILDCARD) && - (udd->pid == PID_WILDCARD) && - (udd->rid == RID_WILDCARD)) { - device_printf(dev, "ignoring invalid " - "wildcard quirk\n"); - continue; - } if (((udd->vid == uaa->info.idVendor) || (udd->vid == VID_WILDCARD)) && ((udd->pid == uaa->info.idProduct) || @@ -1341,64 +1397,27 @@ umass_probe_proto(device_t dev, struct usb2_attach_arg *uaa) if (udd->rid == RID_WILDCARD) { ret.proto = udd->proto; ret.quirks = udd->quirks; - ret.error = 0; - goto done; + if (ret.proto == UMASS_PROTO_DEFAULT) + goto default_proto; + else + goto done; } else if (udd->rid == uaa->info.bcdDevice) { ret.proto = udd->proto; ret.quirks = udd->quirks; - ret.error = 0; - goto done; + if (ret.proto == UMASS_PROTO_DEFAULT) + goto default_proto; + else + goto done; } /* else RID does not match */ } } - /* Check for a standards compliant device */ - id = usb2_get_interface_descriptor(uaa->iface); - if ((id == NULL) || - (id->bInterfaceClass != UICLASS_MASS)) { +default_proto: + ret.proto = umass_get_proto(uaa->iface); + if (ret.proto == 0) ret.error = ENXIO; - goto done; - } - switch (id->bInterfaceSubClass) { - case UISUBCLASS_SCSI: - ret.proto |= UMASS_PROTO_SCSI; - break; - case UISUBCLASS_UFI: - ret.proto |= UMASS_PROTO_UFI; - break; - case UISUBCLASS_RBC: - ret.proto |= UMASS_PROTO_RBC; - break; - case UISUBCLASS_SFF8020I: - case UISUBCLASS_SFF8070I: - ret.proto |= UMASS_PROTO_ATAPI; - break; - default: - device_printf(dev, "unsupported command " - "protocol %d\n", id->bInterfaceSubClass); - ret.error = ENXIO; - goto done; - } - - switch (id->bInterfaceProtocol) { - case UIPROTO_MASS_CBI: - ret.proto |= UMASS_PROTO_CBI; - break; - case UIPROTO_MASS_CBI_I: - ret.proto |= UMASS_PROTO_CBI_I; - break; - case UIPROTO_MASS_BBB_OLD: - case UIPROTO_MASS_BBB: - ret.proto |= UMASS_PROTO_BBB; - break; - default: - device_printf(dev, "unsupported wire " - "protocol %d\n", id->bInterfaceProtocol); - ret.error = ENXIO; - goto done; - } - - ret.error = 0; + else + ret.error = 0; done: return (ret); } diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 89db645112e3..0e567476bd63 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -624,6 +624,7 @@ vendor QCOM 0x18e8 Qcom vendor LINKSYS3 0x1915 Linksys vendor QUALCOMMINC 0x19d2 Qualcomm, Incorporated vendor STELERA 0x1a8d Stelera Wireless +vendor MPMAN 0x1cae MpMan vendor DRESDENELEKTRONIK 0x1cf1 dresden elektronik vendor DLINK 0x2001 D-Link vendor PLANEX2 0x2019 Planex Communications @@ -817,6 +818,7 @@ product ALCOR AU9814 0x9215 AU9814 Hub product ALCOR UMCR_9361 0x9361 USB Multimedia Card Reader product ALCOR SM_KBD 0x9410 MicroConnectors/StrongMan Keyboard product ALCOR NEC_KBD_HUB 0x9472 NEC Kbd Hub +product ALCOR AU6390 0x6390 AU6390 USB-IDE converter /* Altec Lansing products */ product ALTEC ADA70 0x0070 ADA70 Speakers @@ -1107,6 +1109,7 @@ product CYPRESS KBDHUB 0x0101 Keyboard/Hub product CYPRESS FMRADIO 0x1002 FM Radio product CYPRESS USBRS232 0x5500 USB-RS232 Interface product CYPRESS SLIM_HUB 0x6560 Slim Hub +product CYPRESS XX6830XX 0x6830 PATA Storage Device /* Daisy Technology products */ product DAISY DMC 0x6901 USB MultiMedia Reader @@ -2297,6 +2300,10 @@ product SPHAIRON UB801R 0x0110 UB801R product STELERA ZEROCD 0x1000 Zerocd Installer product STELERA C105 0x1002 Stelera/Bandrish C105 USB +/* MpMan products */ +product MPMAN MPF400_1 0x36d0 MPF400 Music Player 1Go +product MPMAN MPF400_2 0x25a8 MPF400 Music Player 2Go + /* STMicroelectronics products */ product STMICRO BIOCPU 0x2016 Biometric Coprocessor product STMICRO COMMUNICATOR 0x7554 USB Communicator From c773c254197bd5775b1d0efe5254727d3f2a8481 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:04:51 +0000 Subject: [PATCH 153/544] Add debug lines for fullspeed and highspeed xfer completion. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/ehci.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 74539f575043..9bb9304ab2d6 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -2028,6 +2028,8 @@ ehci_isoc_fs_done(ehci_softc_t *sc, struct usb2_xfer *xfer) len = EHCI_SITD_GET_LEN(status); + DPRINTFN(2, "status=0x%08x, rem=%u\n", status, len); + if (*plen >= len) { len = *plen - len; } else { @@ -2081,6 +2083,8 @@ ehci_isoc_hs_done(ehci_softc_t *sc, struct usb2_xfer *xfer) len = EHCI_ITD_GET_LEN(status); + DPRINTFN(2, "status=0x%08x, len=%u\n", status, len); + if (*plen >= len) { /* * The length is valid. NOTE: The complete From 07532e4997866496e5466f4e9414dcac2fc03c25 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:05:40 +0000 Subject: [PATCH 154/544] Check the correct variable for IO_NDELAY. Submitted by: Hans Petter Selasky --- sys/dev/usb/usb_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index d9d81e0800d0..33c536373668 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -1203,7 +1203,7 @@ usb2_read(struct cdev *dev, struct uio *uio, int ioflag) (f->methods->f_start_read) (f); - if (fflags & IO_NDELAY) { + if (ioflag & IO_NDELAY) { if (tr_data) { /* return length before error */ break; @@ -1326,7 +1326,7 @@ usb2_write(struct cdev *dev, struct uio *uio, int ioflag) if (m == NULL) { - if (fflags & IO_NDELAY) { + if (ioflag & IO_NDELAY) { if (tr_data) { /* return length before error */ break; From ecf65ed434edcf8a40e904b5cc6713b64596fcb5 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:06:52 +0000 Subject: [PATCH 155/544] Make sure collections have the usage field set. Submitted by: Hans Petter Selasky --- sys/dev/usb/usb_hid.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c index 555d324ded43..cfec2096c669 100644 --- a/sys/dev/usb/usb_hid.c +++ b/sys/dev/usb/usb_hid.c @@ -309,6 +309,7 @@ hid_get_item(struct hid_data *s, struct hid_item *h) c->kind = hid_collection; c->collection = dval; c->collevel++; + c->usage = s->usage_last; *h = *c; return (1); case 11: /* Feature */ @@ -408,6 +409,9 @@ hid_get_item(struct hid_data *s, struct hid_item *h) if (bSize != 4) dval = (dval & mask) | c->_usage_page; + /* set last usage, in case of a collection */ + s->usage_last = dval; + if (s->nusage < MAXUSAGE) { s->usages_min[s->nusage] = dval; s->usages_max[s->nusage] = dval; @@ -630,9 +634,11 @@ hid_is_collection(const void *desc, usb2_size_t size, uint32_t usage) if (hd == NULL) return (0); - err = hid_get_item(hd, &hi) && - hi.kind == hid_collection && - hi.usage == usage; + while ((err = hid_get_item(hd, &hi))) { + if (hi.kind == hid_collection && + hi.usage == usage) + break; + } hid_end_parse(hd); return (err); } From 8ea86e467f15ef8303f878ff95b756fd573dcdde Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:25:14 +0000 Subject: [PATCH 156/544] Add parenthesis around the xfer macro argument. Submitted by: Hans Petter Selasky --- sys/dev/usb/usb_core.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index a9fc6bcf9a7c..7a1c1e93c8de 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -233,9 +233,9 @@ * The following macro will tell if an USB transfer is currently * receiving or transferring data. */ -#define USB_GET_DATA_ISREAD(xfer) (((xfer)->flags_int.usb2_mode == \ - USB_MODE_DEVICE) ? ((xfer->endpoint & UE_DIR_IN) ? 0 : 1) : \ - ((xfer->endpoint & UE_DIR_IN) ? 1 : 0)) +#define USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb2_mode == \ + USB_MODE_DEVICE ? (((xfer)->endpoint & UE_DIR_IN) ? 0 : 1) : \ + (((xfer)->endpoint & UE_DIR_IN) ? 1 : 0)) /* * The following macros are used used to convert milliseconds into From 7261357fbc5a00a7f6b858ada367d4dd44a5cef3 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 13 May 2009 18:26:55 +0000 Subject: [PATCH 157/544] Ensure the bmRequestType is the right type for the incoming control request. Submitted by: Hans Petter Selasky --- sys/dev/usb/storage/ustorage_fs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/storage/ustorage_fs.c b/sys/dev/usb/storage/ustorage_fs.c index c810c2e0f190..8e8a50981a41 100644 --- a/sys/dev/usb/storage/ustorage_fs.c +++ b/sys/dev/usb/storage/ustorage_fs.c @@ -466,7 +466,8 @@ ustorage_fs_handle_request(device_t dev, const struct usb2_device_request *req = preq; if (!is_complete) { - if (req->bRequest == UR_BBB_RESET) { + if ((req->bmRequestType == UT_WRITE_CLASS_INTERFACE) && + (req->bRequest == UR_BBB_RESET)) { *plen = 0; mtx_lock(&sc->sc_mtx); ustorage_fs_transfer_stop(sc); @@ -475,7 +476,8 @@ ustorage_fs_handle_request(device_t dev, USTORAGE_FS_T_BBB_COMMAND); mtx_unlock(&sc->sc_mtx); return (0); - } else if (req->bRequest == UR_BBB_GET_MAX_LUN) { + } else if ((req->bmRequestType == UT_READ_CLASS_INTERFACE) && + (req->bRequest == UR_BBB_GET_MAX_LUN)) { if (offset == 0) { *plen = 1; *pptr = &sc->sc_last_lun; From ab88d607a5a22790df716068da86ce8c5d8017b4 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 13 May 2009 18:31:28 +0000 Subject: [PATCH 158/544] - Remove nonexistent header file from includes list --- sys/dev/flash/at45d.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/dev/flash/at45d.c b/sys/dev/flash/at45d.c index 13e26bcac5ac..21a2056c43ca 100644 --- a/sys/dev/flash/at45d.c +++ b/sys/dev/flash/at45d.c @@ -30,7 +30,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include From ecd616333853888f75b5076cc66102c4625c91c9 Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Wed, 13 May 2009 18:42:49 +0000 Subject: [PATCH 159/544] - Make SPI bus bridge be non-arch dependent by using more generic name Reviewed by: imp --- sys/arm/at91/at91_spi.c | 2 +- sys/dev/spibus/spibus.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/arm/at91/at91_spi.c b/sys/arm/at91/at91_spi.c index 53c33807ee5f..2252f00c8d25 100644 --- a/sys/arm/at91/at91_spi.c +++ b/sys/arm/at91/at91_spi.c @@ -297,7 +297,7 @@ static device_method_t at91_spi_methods[] = { }; static driver_t at91_spi_driver = { - "at91_spi", + "spi", at91_spi_methods, sizeof(struct at91_spi_softc), }; diff --git a/sys/dev/spibus/spibus.c b/sys/dev/spibus/spibus.c index 76b4a8cc3c72..33205ea64f1d 100644 --- a/sys/dev/spibus/spibus.c +++ b/sys/dev/spibus/spibus.c @@ -194,5 +194,5 @@ static driver_t spibus_driver = { devclass_t spibus_devclass; -DRIVER_MODULE(spibus, at91_spi, spibus_driver, spibus_devclass, 0, 0); +DRIVER_MODULE(spibus, spi, spibus_driver, spibus_devclass, 0, 0); MODULE_VERSION(spibus, 1); From aa16f86ca5cd03da24ba042731c67b0c7778c68f Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Wed, 13 May 2009 19:29:50 +0000 Subject: [PATCH 160/544] Keep this line shorter than 80 columns. --- sys/dev/snp/snp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c index 52c5a025b577..fcc70a5d84f3 100644 --- a/sys/dev/snp/snp.c +++ b/sys/dev/snp/snp.c @@ -257,8 +257,8 @@ snp_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flags, SNP_UNLOCK(); return (EBUSY); } - error = ttyhook_register(&ss->snp_tty, td->td_proc, *(int *)data, - &snp_hook, ss); + error = ttyhook_register(&ss->snp_tty, td->td_proc, + *(int *)data, &snp_hook, ss); SNP_UNLOCK(); if (error != 0) return (error); From 24756cad5de2da821e7f5bce63aeaf549fbdb9a9 Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Wed, 13 May 2009 20:29:53 +0000 Subject: [PATCH 161/544] - Style(9) and consistency nitpicking. Reviewed by: imp --- sys/arm/at91/if_ate.c | 160 +++++++++++++++++++++++------------------- 1 file changed, 88 insertions(+), 72 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 6ccfd63345c2..12fbb7a03ffd 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -69,8 +69,8 @@ __FBSDID("$FreeBSD$"); #include "miibus_if.h" -#define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */ -#define ATE_MAX_RX_BUFFERS 64 +#define ATE_MAX_TX_BUFFERS 2 /* We have ping-pong tx buffers */ +#define ATE_MAX_RX_BUFFERS 64 /* * Driver-specific flags. @@ -80,41 +80,43 @@ __FBSDID("$FreeBSD$"); struct ate_softc { - struct ifnet *ifp; /* ifnet pointer */ - struct mtx sc_mtx; /* basically a perimeter lock */ - device_t dev; /* Myself */ - device_t miibus; /* My child miibus */ - void *intrhand; /* Interrupt handle */ - struct resource *irq_res; /* IRQ resource */ + struct ifnet *ifp; /* ifnet pointer */ + struct mtx sc_mtx; /* Basically a perimeter lock */ + device_t dev; /* Myself */ + device_t miibus; /* My child miibus */ + struct resource *irq_res; /* IRQ resource */ struct resource *mem_res; /* Memory resource */ - struct callout tick_ch; /* Tick callout */ - bus_dma_tag_t mtag; /* bus dma tag for mbufs */ - bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS]; - struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */ - bus_dma_tag_t rxtag; - bus_dmamap_t rx_map[ATE_MAX_RX_BUFFERS]; - void *rx_buf[ATE_MAX_RX_BUFFERS]; /* RX buffer space */ - int rx_buf_ptr; - bus_dma_tag_t rx_desc_tag; - bus_dmamap_t rx_desc_map; - int txcur; /* current tx map pointer */ - bus_addr_t rx_desc_phys; - eth_rx_desc_t *rx_descs; - int use_rmii; - struct ifmib_iso_8802_3 mibdata; /* stuff for network mgmt */ - int flags; - int if_flags; + struct callout tick_ch; /* Tick callout */ + struct ifmib_iso_8802_3 mibdata; /* Stuff for network mgmt */ + struct mbuf *sent_mbuf[ATE_MAX_TX_BUFFERS]; /* Sent mbufs */ + bus_dma_tag_t mtag; /* bus dma tag for mbufs */ + bus_dma_tag_t rxtag; + bus_dma_tag_t rx_desc_tag; + bus_dmamap_t rx_desc_map; + bus_dmamap_t rx_map[ATE_MAX_RX_BUFFERS]; + bus_dmamap_t tx_map[ATE_MAX_TX_BUFFERS]; + bus_addr_t rx_desc_phys; + eth_rx_desc_t *rx_descs; + void *rx_buf[ATE_MAX_RX_BUFFERS]; /* RX buffer space */ + void *intrhand; /* Interrupt handle */ + int flags; + int if_flags; + int rx_buf_ptr; + int txcur; /* Current TX map pointer */ + int use_rmii; }; static inline uint32_t RD4(struct ate_softc *sc, bus_size_t off) { - return bus_read_4(sc->mem_res, off); + + return (bus_read_4(sc->mem_res, off)); } static inline void WR4(struct ate_softc *sc, bus_size_t off, uint32_t val) { + bus_write_4(sc->mem_res, off, val); } @@ -125,41 +127,45 @@ BARRIER(struct ate_softc *sc, bus_size_t off, bus_size_t len, int flags) bus_barrier(sc->mem_res, off, len, flags); } -#define ATE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) +#define ATE_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define ATE_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) -#define ATE_LOCK_INIT(_sc) \ - mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ +#define ATE_LOCK_INIT(_sc) \ + mtx_init(&_sc->sc_mtx, device_get_nameunit(_sc->dev), \ MTX_NETWORK_LOCK, MTX_DEF) -#define ATE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); -#define ATE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); -#define ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); +#define ATE_LOCK_DESTROY(_sc) mtx_destroy(&_sc->sc_mtx); +#define ATE_ASSERT_LOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED); +#define ATE_ASSERT_UNLOCKED(_sc) mtx_assert(&_sc->sc_mtx, MA_NOTOWNED); static devclass_t ate_devclass; -/* ifnet entry points */ +/* + * ifnet entry points. + */ +static void ateinit_locked(void *); +static void atestart_locked(struct ifnet *); -static void ateinit_locked(void *); -static void atestart_locked(struct ifnet *); +static void ateinit(void *); +static void atestart(struct ifnet *); +static void atestop(struct ate_softc *); +static int ateioctl(struct ifnet * ifp, u_long, caddr_t); -static void ateinit(void *); -static void atestart(struct ifnet *); -static void atestop(struct ate_softc *); -static int ateioctl(struct ifnet * ifp, u_long, caddr_t); +/* + * Bus entry points. + */ +static int ate_probe(device_t dev); +static int ate_attach(device_t dev); +static int ate_detach(device_t dev); +static void ate_intr(void *); -/* bus entry points */ - -static int ate_probe(device_t dev); -static int ate_attach(device_t dev); -static int ate_detach(device_t dev); -static void ate_intr(void *); - -/* helper routines */ -static int ate_activate(device_t dev); -static void ate_deactivate(struct ate_softc *sc); -static int ate_ifmedia_upd(struct ifnet *ifp); -static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); -static int ate_get_mac(struct ate_softc *sc, u_char *eaddr); -static void ate_set_mac(struct ate_softc *sc, u_char *eaddr); +/* + * Helper routines. + */ +static int ate_activate(device_t dev); +static void ate_deactivate(struct ate_softc *sc); +static int ate_ifmedia_upd(struct ifnet *ifp); +static void ate_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr); +static int ate_get_mac(struct ate_softc *sc, u_char *eaddr); +static void ate_set_mac(struct ate_softc *sc, u_char *eaddr); static void ate_rxfilter(struct ate_softc *sc); /* @@ -171,6 +177,7 @@ static void ate_rxfilter(struct ate_softc *sc); static int ate_probe(device_t dev) { + device_set_desc(dev, "EMAC"); return (0); } @@ -178,7 +185,7 @@ ate_probe(device_t dev) static int ate_attach(device_t dev) { - struct ate_softc *sc = device_get_softc(dev); + struct ate_softc *sc; struct ifnet *ifp = NULL; struct sysctl_ctx_list *sctx; struct sysctl_oid *soid; @@ -186,6 +193,7 @@ ate_attach(device_t dev) uint32_t rnd; int rid, err; + sc = device_get_softc(dev); sc->dev = dev; ATE_LOCK_INIT(sc); @@ -221,7 +229,7 @@ ate_attach(device_t dev) SYSCTL_ADD_UINT(sctx, SYSCTL_CHILDREN(soid), OID_AUTO, "rmii", CTLFLAG_RD, &sc->use_rmii, 0, "rmii in use"); - /* calling atestop before ifp is set is OK */ + /* Calling atestop before ifp is set is OK. */ ATE_LOCK(sc); atestop(sc); ATE_UNLOCK(sc); @@ -261,7 +269,7 @@ ate_attach(device_t dev) if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_capabilities |= IFCAP_VLAN_MTU; - ifp->if_capenable |= IFCAP_VLAN_MTU; /* the hw bits already set */ + ifp->if_capenable |= IFCAP_VLAN_MTU; /* The hw bits already set. */ ifp->if_start = atestart; ifp->if_ioctl = ateioctl; ifp->if_init = ateinit; @@ -435,8 +443,9 @@ ate_activate(device_t dev) int err, i; sc = device_get_softc(dev); + /* - * Allocate DMA tags and maps + * Allocate DMA tags and maps. */ err = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES, @@ -448,11 +457,7 @@ ate_activate(device_t dev) if (err != 0) goto errout; } - /* - * Allocate our Rx buffers. This chip has a rx structure that's filled - * in - */ - + /* * Allocate DMA tags and maps for RX. */ @@ -462,7 +467,9 @@ ate_activate(device_t dev) if (err != 0) goto errout; - /* Dma TAG and MAP for the rx descriptors. */ + /* + * DMA tag and map for the RX descriptors. + */ err = bus_dma_tag_create(bus_get_dma_tag(dev), sizeof(eth_rx_desc_t), 0, BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), 1, @@ -477,6 +484,11 @@ ate_activate(device_t dev) sc->rx_descs, ATE_MAX_RX_BUFFERS * sizeof(eth_rx_desc_t), ate_getaddr, sc, 0) != 0) goto errout; + + /* + * Allocate our RX buffers. This chip has a RX structure that's filled + * in. + */ for (i = 0; i < ATE_MAX_RX_BUFFERS; i++) { sc->rx_buf_ptr = i; if (bus_dmamem_alloc(sc->rxtag, (void **)&sc->rx_buf[i], @@ -487,7 +499,7 @@ ate_activate(device_t dev) goto errout; } sc->rx_buf_ptr = 0; - /* Flush the memory for the EMAC rx descriptor */ + /* Flush the memory for the EMAC rx descriptor. */ bus_dmamap_sync(sc->rx_desc_tag, sc->rx_desc_map, BUS_DMASYNC_PREWRITE); /* Write the descriptor queue address. */ WR4(sc, ETH_RBQP, sc->rx_desc_phys); @@ -662,8 +674,9 @@ ate_tick(void *xsc) sc->mibdata.dot3StatsCarrierSenseErrors += RD4(sc, ETH_CSE); sc->mibdata.dot3StatsFrameTooLongs += RD4(sc, ETH_ELR); sc->mibdata.dot3StatsInternalMacReceiveErrors += RD4(sc, ETH_DRFC); + /* - * not sure where to lump these, so count them against the errors + * Not sure where to lump these, so count them against the errors * for the interface. */ sc->ifp->if_oerrors += RD4(sc, ETH_TUE); @@ -679,6 +692,7 @@ ate_tick(void *xsc) static void ate_set_mac(struct ate_softc *sc, u_char *eaddr) { + WR4(sc, ETH_SA1L, (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) | eaddr[0]); WR4(sc, ETH_SA1H, (eaddr[5] << 8) | (eaddr[4])); @@ -819,7 +833,7 @@ ate_intr(void *xsc) } /* - * Reset and initialize the chip + * Reset and initialize the chip. */ static void ateinit_locked(void *xsc) @@ -868,12 +882,12 @@ ateinit_locked(void *xsc) * swapping to do. Again, if we need it (which I don't think we do). */ - /* enable big packets */ + /* Enable big packets. */ WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); /* * Set 'running' flag, and clear output active flag - * and attempt to start the output + * and attempt to start the output. */ ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -887,7 +901,7 @@ ateinit_locked(void *xsc) } /* - * dequeu packets and transmit + * Dequeue packets and transmit. */ static void atestart_locked(struct ifnet *ifp) @@ -903,7 +917,7 @@ atestart_locked(struct ifnet *ifp) while (sc->txcur < ATE_MAX_TX_BUFFERS) { /* - * check to see if there's room to put another packet into the + * Check to see if there's room to put another packet into the * xmit queue. The EMAC chip has a ping-pong buffer for xmit * packets. We use OACTIVE to indicate "we can stuff more into * our buffers (clear) or not (set)." @@ -937,7 +951,7 @@ atestart_locked(struct ifnet *ifp) BUS_DMASYNC_PREWRITE); /* - * tell the hardware to xmit the packet. + * Tell the hardware to xmit the packet. */ WR4(sc, ETH_TAR, segs[0].ds_addr); BARRIER(sc, ETH_TAR, 8, BUS_SPACE_BARRIER_WRITE); @@ -957,6 +971,7 @@ static void ateinit(void *xsc) { struct ate_softc *sc = xsc; + ATE_LOCK(sc); ateinit_locked(sc); ATE_UNLOCK(sc); @@ -966,13 +981,14 @@ static void atestart(struct ifnet *ifp) { struct ate_softc *sc = ifp->if_softc; + ATE_LOCK(sc); atestart_locked(ifp); ATE_UNLOCK(sc); } /* - * Turn off interrupts, and stop the nic. Can be called with sc->ifp NULL + * Turn off interrupts, and stop the NIC. Can be called with sc->ifp NULL, * so be careful. */ static void From 18f799c8fdc4fad92dab7d1eaeb7542df3dbed4e Mon Sep 17 00:00:00 2001 From: Stanislav Sedov Date: Wed, 13 May 2009 21:01:10 +0000 Subject: [PATCH 162/544] - Set MAC address in ateinit, so it can be changed later. --- sys/arm/at91/if_ate.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c index 12fbb7a03ffd..36400a9074bf 100644 --- a/sys/arm/at91/if_ate.c +++ b/sys/arm/at91/if_ate.c @@ -256,7 +256,6 @@ ate_attach(device_t dev) eaddr[4] = (rnd >> 8) & 0xff; eaddr[5] = rnd & 0xff; } - ate_set_mac(sc, eaddr); sc->ifp = ifp = if_alloc(IFT_ETHER); if (mii_phy_probe(dev, &sc->miibus, ate_ifmedia_upd, ate_ifmedia_sts)) { @@ -841,6 +840,7 @@ ateinit_locked(void *xsc) struct ate_softc *sc = xsc; struct ifnet *ifp = sc->ifp; struct mii_data *mii; + uint8_t eaddr[ETHER_ADDR_LEN]; uint32_t reg; ATE_ASSERT_LOCKED(sc); @@ -869,19 +869,18 @@ ateinit_locked(void *xsc) ate_rxfilter(sc); + /* + * Set the chip MAC address. + */ + bcopy(IF_LLADDR(ifp), eaddr, ETHER_ADDR_LEN); + ate_set_mac(sc, eaddr); + /* * Turn on MACs and interrupt processing. */ WR4(sc, ETH_CTL, RD4(sc, ETH_CTL) | ETH_CTL_TE | ETH_CTL_RE); WR4(sc, ETH_IER, ETH_ISR_RCOM | ETH_ISR_TCOM | ETH_ISR_RBNA); - /* - * Boot loader fills in MAC address. If that's not the case, then - * we should set SA1L and SA1H here to the appropriate value. Note: - * the byte order is big endian, not little endian, so we have some - * swapping to do. Again, if we need it (which I don't think we do). - */ - /* Enable big packets. */ WR4(sc, ETH_CFG, RD4(sc, ETH_CFG) | ETH_CFG_BIG); From a770e183dd865c0541553ada1aea9e2813cc587b Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 13 May 2009 21:18:34 +0000 Subject: [PATCH 163/544] Apply a one line change to nfs_clbio.c (which is largely a copy of sys/nfsclient/nfs_bio.c) to track the change recently committed by acl for nfs_bio.c. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clbio.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index bae44edee046..0eb30f990d48 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -306,7 +306,8 @@ ncl_getpages(struct vop_getpages_args *ap) * Read operation filled an entire page */ m->valid = VM_PAGE_BITS_ALL; - vm_page_undirty(m); + KASSERT(m->dirty == 0, + ("nfs_getpages: page %p is dirty", m)); } else if (size > toff) { /* * Read operation filled a partial page. From e872228f518e5d0e6a5511d0229c98f3403daf21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Wed, 13 May 2009 22:31:25 +0000 Subject: [PATCH 164/544] Snip redundant assignment. Approved by: scottl MFC after: 2 weeks Coverity ID: 3863 --- sys/dev/aic/aic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/aic/aic.c b/sys/dev/aic/aic.c index f2d3203fab15..4d5b5c3e3b23 100644 --- a/sys/dev/aic/aic.c +++ b/sys/dev/aic/aic.c @@ -168,7 +168,7 @@ aic_action(struct cam_sim *sim, union ccb *ccb) } case XPT_SET_TRAN_SETTINGS: { - struct ccb_trans_settings *cts = cts = &ccb->cts; + struct ccb_trans_settings *cts = &ccb->cts; struct aic_tinfo *ti = &aic->tinfo[ccb->ccb_h.target_id]; struct ccb_trans_settings_scsi *scsi = &cts->proto_specific.scsi; From b40ce02a2f1b6b59ee7616a769e36cc3d3258971 Mon Sep 17 00:00:00 2001 From: Nathan Whitehorn Date: Thu, 14 May 2009 00:34:26 +0000 Subject: [PATCH 165/544] Factor out platform dependent things unrelated to device drivers into a new platform module. These are probed in early boot, and have the responsibility of determining the layout of physical memory, determining the CPU timebase frequency, and handling the zoo of SMP mechanisms found on PowerPC. Reviewed by: marcel, raj Book-E parts by: raj --- sys/conf/files.powerpc | 4 + sys/powerpc/aim/clock.c | 47 ++-- sys/powerpc/aim/machdep.c | 15 +- sys/powerpc/aim/mmu_oea.c | 2 +- sys/powerpc/aim/mmu_oea64.c | 2 +- sys/powerpc/aim/mp_cpudep.c | 113 --------- sys/powerpc/aim/ofw_machdep.c | 4 +- sys/powerpc/aim/platform_chrp.c | 236 ++++++++++++++++++ sys/powerpc/aim/vm_machdep.c | 1 - sys/powerpc/booke/clock.c | 29 ++- sys/powerpc/booke/machdep.c | 33 +-- sys/powerpc/booke/platform_bare.c | 185 ++++++++++++++ sys/powerpc/booke/pmap.c | 13 +- sys/powerpc/booke/vm_machdep.c | 2 +- sys/powerpc/include/md_var.h | 1 - sys/powerpc/include/ofw_machdep.h | 6 + sys/powerpc/include/{powerpc.h => platform.h} | 33 ++- sys/powerpc/include/platformvar.h | 88 +++++++ sys/powerpc/include/pmap.h | 1 - sys/powerpc/include/smp.h | 5 - sys/powerpc/include/spr.h | 1 + sys/powerpc/powerpc/mp_machdep.c | 13 +- sys/powerpc/powerpc/platform.c | 177 +++++++++++++ sys/powerpc/powerpc/platform_if.m | 163 ++++++++++++ sys/powerpc/powerpc/pmap_dispatch.c | 2 +- 25 files changed, 945 insertions(+), 231 deletions(-) create mode 100644 sys/powerpc/aim/platform_chrp.c create mode 100644 sys/powerpc/booke/platform_bare.c rename sys/powerpc/include/{powerpc.h => platform.h} (80%) create mode 100644 sys/powerpc/include/platformvar.h create mode 100644 sys/powerpc/powerpc/platform.c create mode 100644 sys/powerpc/powerpc/platform_if.m diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index 389d62eaf845..d1707054abcf 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -81,6 +81,7 @@ powerpc/aim/mp_cpudep.c optional aim smp powerpc/aim/nexus.c optional aim powerpc/aim/ofw_machdep.c optional aim powerpc/aim/ofwmagic.S optional aim +powerpc/aim/platform_chrp.c optional aim powerpc/aim/swtch.S optional aim powerpc/aim/trap.c optional aim powerpc/aim/uma_machdep.c optional aim @@ -90,6 +91,7 @@ powerpc/booke/copyinout.c optional e500 powerpc/booke/interrupt.c optional e500 powerpc/booke/locore.S optional e500 no-obj powerpc/booke/machdep.c optional e500 +powerpc/booke/platform_bare.c optional mpc85xx powerpc/booke/pmap.c optional e500 powerpc/booke/swtch.S optional e500 powerpc/booke/trap.c optional e500 @@ -155,6 +157,8 @@ powerpc/powerpc/mp_machdep.c optional smp powerpc/powerpc/openpic.c standard powerpc/powerpc/pic_if.m standard powerpc/powerpc/pmap_dispatch.c standard +powerpc/powerpc/platform.c standard +powerpc/powerpc/platform_if.m standard powerpc/powerpc/sc_machdep.c optional sc powerpc/powerpc/setjmp.S standard powerpc/powerpc/sigcode.S standard diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c index ac6aa2de9583..2d3eb6049566 100644 --- a/sys/powerpc/aim/clock.c +++ b/sys/powerpc/aim/clock.c @@ -125,44 +125,27 @@ decr_intr(struct trapframe *frame) void decr_init(void) { - int qhandle, phandle; - char name[32]; - unsigned int msr; - - phandle = 0; + struct cpuref cpu; + register_t msr; /* - * Get this info during autoconf? XXX + * Check the BSP's timebase frequency. Sometimes we can't find the BSP, so fall + * back to the first CPU in this case. */ - for (qhandle = OF_peer(0); qhandle; qhandle = phandle) { - if (OF_getprop(qhandle, "device_type", name, sizeof name) >= 0 - && !strcmp(name, "cpu") - && OF_getprop(qhandle, "timebase-frequency", - &ticks_per_sec, sizeof ticks_per_sec) >= 0) { - /* - * Should check for correct CPU here? XXX - */ - msr = mfmsr(); - mtmsr(msr & ~PSL_EE); - ns_per_tick = 1000000000 / ticks_per_sec; - ticks_per_intr = ticks_per_sec / hz; - mtdec(ticks_per_intr); + if (platform_smp_get_bsp(&cpu) != 0) + platform_smp_first_cpu(&cpu); - mtmsr(msr); + ticks_per_sec = platform_timebase_freq(&cpu); - break; - } - if ((phandle = OF_child(qhandle))) - continue; - while (qhandle) { - if ((phandle = OF_peer(qhandle))) - break; - qhandle = OF_parent(qhandle); - } - } - if (!phandle) - panic("no cpu node"); + msr = mfmsr(); + mtmsr(msr & ~PSL_EE); + + ns_per_tick = 1000000000 / ticks_per_sec; + ticks_per_intr = ticks_per_sec / hz; + mtdec(ticks_per_intr); + + mtmsr(msr); } void diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 4e8909fc1563..590741ce4cbe 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -114,7 +114,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include @@ -472,14 +471,22 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp) */ mtmsr(msr); isync(); + + /* + * Choose a platform module so we can get the physical memory map. + */ + + platform_probe_and_attach(); /* - * Initialise virtual memory. + * Initialise virtual memory. Use BUS_PROBE_GENERIC priority + * in case the platform module had a better idea of what we + * should do. */ if (ppc64) - pmap_mmu_install(MMU_TYPE_G5, 0); + pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC); else - pmap_mmu_install(MMU_TYPE_OEA, 0); + pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC); pmap_bootstrap(startkernel, endkernel); mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI); diff --git a/sys/powerpc/aim/mmu_oea.c b/sys/powerpc/aim/mmu_oea.c index 71947fa062dc..7eb4beb255f6 100644 --- a/sys/powerpc/aim/mmu_oea.c +++ b/sys/powerpc/aim/mmu_oea.c @@ -141,7 +141,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include #include diff --git a/sys/powerpc/aim/mmu_oea64.c b/sys/powerpc/aim/mmu_oea64.c index 64e8c7563ba9..4590363053d5 100644 --- a/sys/powerpc/aim/mmu_oea64.c +++ b/sys/powerpc/aim/mmu_oea64.c @@ -143,7 +143,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #include #include diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c index e226d3b522ea..1dc9525c0eee 100644 --- a/sys/powerpc/aim/mp_cpudep.c +++ b/sys/powerpc/aim/mp_cpudep.c @@ -54,91 +54,6 @@ extern register_t l3cr_config; void *ap_pcpu; -static int -powerpc_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) -{ - int cpuid, res; - - cpuref->cr_hwref = cpu; - res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); - if (res < 0) - return (ENOENT); - - cpuref->cr_cpuid = cpuid & 0xff; - return (0); -} - -int -powerpc_smp_first_cpu(struct cpuref *cpuref) -{ - char buf[8]; - phandle_t cpu, dev, root; - int res; - - root = OF_peer(0); - - dev = OF_child(root); - while (dev != 0) { - res = OF_getprop(dev, "name", buf, sizeof(buf)); - if (res > 0 && strcmp(buf, "cpus") == 0) - break; - dev = OF_peer(dev); - } - if (dev == 0) - return (ENOENT); - - cpu = OF_child(dev); - while (cpu != 0) { - res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); - if (res > 0 && strcmp(buf, "cpu") == 0) - break; - cpu = OF_peer(cpu); - } - if (cpu == 0) - return (ENOENT); - - return (powerpc_smp_fill_cpuref(cpuref, cpu)); -} - -int -powerpc_smp_next_cpu(struct cpuref *cpuref) -{ - char buf[8]; - phandle_t cpu; - int res; - - cpu = OF_peer(cpuref->cr_hwref); - while (cpu != 0) { - res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); - if (res > 0 && strcmp(buf, "cpu") == 0) - break; - cpu = OF_peer(cpu); - } - if (cpu == 0) - return (ENOENT); - - return (powerpc_smp_fill_cpuref(cpuref, cpu)); -} - -int -powerpc_smp_get_bsp(struct cpuref *cpuref) -{ - ihandle_t inst; - phandle_t bsp, chosen; - int res; - - chosen = OF_finddevice("/chosen"); - if (chosen == 0) - return (ENXIO); - - res = OF_getprop(chosen, "cpu", &inst, sizeof(inst)); - if (res < 0) - return (ENXIO); - - bsp = OF_instance_to_package(inst); - return (powerpc_smp_fill_cpuref(cpuref, bsp)); -} - static register_t l2_enable(void) { @@ -269,31 +184,3 @@ cpudep_ap_bootstrap(void) return (sp); } -int -powerpc_smp_start_cpu(struct pcpu *pc) -{ - phandle_t cpu; - volatile uint8_t *rstvec; - int res, reset, timeout; - - cpu = pc->pc_hwref; - res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset)); - if (res < 0) - return (ENXIO); - - ap_pcpu = pc; - - rstvec = (uint8_t *)(0x80000000 + reset); - - *rstvec = 4; - powerpc_sync(); - DELAY(1); - *rstvec = 0; - powerpc_sync(); - - timeout = 1000; - while (!pc->pc_awake && timeout--) - DELAY(100); - - return ((pc->pc_awake) ? 0 : EBUSY); -} diff --git a/sys/powerpc/aim/ofw_machdep.c b/sys/powerpc/aim/ofw_machdep.c index 977f81a63540..773d229d3a27 100644 --- a/sys/powerpc/aim/ofw_machdep.c +++ b/sys/powerpc/aim/ofw_machdep.c @@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$"); #include #include -#include +#include #include #define OFMEM_REGIONS 32 @@ -144,7 +144,7 @@ memr_merge(struct mem_region *from, struct mem_region *to) * to provide space for two additional entry beyond the terminating one. */ void -mem_regions(struct mem_region **memp, int *memsz, +ofw_mem_regions(struct mem_region **memp, int *memsz, struct mem_region **availp, int *availsz) { phandle_t phandle; diff --git a/sys/powerpc/aim/platform_chrp.c b/sys/powerpc/aim/platform_chrp.c new file mode 100644 index 000000000000..48c7a9138915 --- /dev/null +++ b/sys/powerpc/aim/platform_chrp.c @@ -0,0 +1,236 @@ +/*- + * Copyright (c) 2008 Marcel Moolenaar + * Copyright (c) 2009 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "platform_if.h" + +#ifdef SMP +extern void *ap_pcpu; +#endif + +static int chrp_probe(platform_t); +void chrp_mem_regions(platform_t, struct mem_region **phys, int *physsz, + struct mem_region **avail, int *availsz); +static u_long chrp_timebase_freq(platform_t, struct cpuref *cpuref); +static int chrp_smp_first_cpu(platform_t, struct cpuref *cpuref); +static int chrp_smp_next_cpu(platform_t, struct cpuref *cpuref); +static int chrp_smp_get_bsp(platform_t, struct cpuref *cpuref); +static int chrp_smp_start_cpu(platform_t, struct pcpu *cpu); + +static platform_method_t chrp_methods[] = { + PLATFORMMETHOD(platform_probe, chrp_probe), + PLATFORMMETHOD(platform_mem_regions, chrp_mem_regions), + PLATFORMMETHOD(platform_timebase_freq, chrp_timebase_freq), + + PLATFORMMETHOD(platform_smp_first_cpu, chrp_smp_first_cpu), + PLATFORMMETHOD(platform_smp_next_cpu, chrp_smp_next_cpu), + PLATFORMMETHOD(platform_smp_get_bsp, chrp_smp_get_bsp), + PLATFORMMETHOD(platform_smp_start_cpu, chrp_smp_start_cpu), + + { 0, 0 } +}; + +static platform_def_t chrp_platform = { + "chrp", + chrp_methods, + 0 +}; + +PLATFORM_DEF(chrp_platform); + +static int +chrp_probe(platform_t plat) +{ + if (OF_finddevice("/memory") != -1) + return (BUS_PROBE_GENERIC); + + return (ENXIO); +} + +void +chrp_mem_regions(platform_t plat, struct mem_region **phys, int *physsz, + struct mem_region **avail, int *availsz) +{ + ofw_mem_regions(phys,physsz,avail,availsz); +} + +static u_long +chrp_timebase_freq(platform_t plat, struct cpuref *cpuref) +{ + phandle_t phandle; + u_long ticks = -1; + + phandle = cpuref->cr_hwref; + + OF_getprop(phandle, "timebase-frequency", &ticks, sizeof(ticks)); + + if (ticks <= 0) + panic("Unable to determine timebase frequency!"); + + return (ticks); +} + + +static int +chrp_smp_fill_cpuref(struct cpuref *cpuref, phandle_t cpu) +{ + int cpuid, res; + + cpuref->cr_hwref = cpu; + res = OF_getprop(cpu, "reg", &cpuid, sizeof(cpuid)); + if (res < 0) + return (ENOENT); + + cpuref->cr_cpuid = cpuid & 0xff; + return (0); +} + +static int +chrp_smp_first_cpu(platform_t plat, struct cpuref *cpuref) +{ + char buf[8]; + phandle_t cpu, dev, root; + int res; + + root = OF_peer(0); + + dev = OF_child(root); + while (dev != 0) { + res = OF_getprop(dev, "name", buf, sizeof(buf)); + if (res > 0 && strcmp(buf, "cpus") == 0) + break; + dev = OF_peer(dev); + } + if (dev == 0) + return (ENOENT); + + cpu = OF_child(dev); + while (cpu != 0) { + res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); + if (res > 0 && strcmp(buf, "cpu") == 0) + break; + cpu = OF_peer(cpu); + } + if (cpu == 0) + return (ENOENT); + + return (chrp_smp_fill_cpuref(cpuref, cpu)); +} + +static int +chrp_smp_next_cpu(platform_t plat, struct cpuref *cpuref) +{ + char buf[8]; + phandle_t cpu; + int res; + + cpu = OF_peer(cpuref->cr_hwref); + while (cpu != 0) { + res = OF_getprop(cpu, "device_type", buf, sizeof(buf)); + if (res > 0 && strcmp(buf, "cpu") == 0) + break; + cpu = OF_peer(cpu); + } + if (cpu == 0) + return (ENOENT); + + return (chrp_smp_fill_cpuref(cpuref, cpu)); +} + +static int +chrp_smp_get_bsp(platform_t plat, struct cpuref *cpuref) +{ + ihandle_t inst; + phandle_t bsp, chosen; + int res; + + chosen = OF_finddevice("/chosen"); + if (chosen == 0) + return (ENXIO); + + res = OF_getprop(chosen, "cpu", &inst, sizeof(inst)); + if (res < 0) + return (ENXIO); + + bsp = OF_instance_to_package(inst); + return (chrp_smp_fill_cpuref(cpuref, bsp)); +} + +static int +chrp_smp_start_cpu(platform_t plat, struct pcpu *pc) +{ +#ifdef SMP + phandle_t cpu; + volatile uint8_t *rstvec; + int res, reset, timeout; + + cpu = pc->pc_hwref; + res = OF_getprop(cpu, "soft-reset", &reset, sizeof(reset)); + if (res < 0) + return (ENXIO); + + ap_pcpu = pc; + + rstvec = (uint8_t *)(0x80000000 + reset); + + *rstvec = 4; + powerpc_sync(); + DELAY(1); + *rstvec = 0; + powerpc_sync(); + + timeout = 1000; + while (!pc->pc_awake && timeout--) + DELAY(100); + + return ((pc->pc_awake) ? 0 : EBUSY); +#else + /* No SMP support */ + return (ENXIO); +#endif +} + diff --git a/sys/powerpc/aim/vm_machdep.c b/sys/powerpc/aim/vm_machdep.c index e20ba7b99077..af83854e3b5f 100644 --- a/sys/powerpc/aim/vm_machdep.c +++ b/sys/powerpc/aim/vm_machdep.c @@ -89,7 +89,6 @@ #include #include #include -#include #include diff --git a/sys/powerpc/booke/clock.c b/sys/powerpc/booke/clock.c index 707016121e54..6c8874122ce1 100644 --- a/sys/powerpc/booke/clock.c +++ b/sys/powerpc/booke/clock.c @@ -67,6 +67,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -123,29 +124,22 @@ void cpu_initclocks(void) { - return; -} - -void -decr_config (unsigned long freq) -{ - ticks_per_sec = freq; - decr_timecounter.tc_frequency = freq; + decr_tc_init(); } void decr_init (void) { + struct cpuref cpu; unsigned int msr; - /* - * Should check for correct CPU here? XXX - */ + if (platform_smp_get_bsp(&cpu) != 0) + platform_smp_first_cpu(&cpu); + ticks_per_sec = platform_timebase_freq(&cpu); + msr = mfmsr(); mtmsr(msr & ~(PSL_EE)); - tc_init(&decr_timecounter); - ns_per_tick = 1000000000 / ticks_per_sec; ticks_per_intr = ticks_per_sec / hz; @@ -173,6 +167,15 @@ mftb (void) return tb; } +void +decr_tc_init(void) +{ + + decr_timecounter.tc_frequency = ticks_per_sec; + tc_init(&decr_timecounter); +} + + static unsigned decr_get_timecount(struct timecounter *tc) { diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 35cc64f60c41..3d3dcadc6749 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -127,11 +127,10 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include #include #include -#include +#include #include #include @@ -157,9 +156,6 @@ extern unsigned char __sbss_start[]; extern unsigned char __sbss_end[]; extern unsigned char _end[]; -extern struct mem_region availmem_regions[]; -extern int availmem_regions_sz; - extern void dcache_enable(void); extern void dcache_inval(void); extern void icache_enable(void); @@ -339,9 +335,7 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) struct pcpu *pc; void *kmdp; vm_offset_t end; - struct bi_mem_region *mr; uint32_t csr; - int i; kmdp = NULL; @@ -381,31 +375,9 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) while(1); } - /* Initialize memory regions table */ - mr = bootinfo_mr(); - for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) { - if (i == MEM_REGIONS) - break; - if (mr->mem_base < 1048576) { - availmem_regions[i].mr_start = 1048576; - availmem_regions[i].mr_size = mr->mem_size - - (1048576 - mr->mem_base); - } else { - availmem_regions[i].mr_start = mr->mem_base; - availmem_regions[i].mr_size = mr->mem_size; - } - } - availmem_regions_sz = i; - /* Initialize TLB1 handling */ tlb1_init(bootinfo->bi_bar_base); - /* - * Time Base and Decrementer are updated every 8 CCB bus clocks. - * HID0[SEL_TBCLK] = 0 - */ - decr_config(bootinfo->bi_bus_clk / 8); - /* Init params/tunables that can be overridden by the loader. */ init_param1(); @@ -450,6 +422,9 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif + /* Initialise platform module */ + platform_probe_and_attach(); + /* Initialise virtual memory. */ pmap_mmu_install(MMU_TYPE_BOOKE, 0); pmap_bootstrap(startkernel, end); diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c new file mode 100644 index 000000000000..8f0be7e471d5 --- /dev/null +++ b/sys/powerpc/booke/platform_bare.c @@ -0,0 +1,185 @@ +/*- + * Copyright (c) 2008-2009 Semihalf, Rafal Jaworowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "platform_if.h" + +static int cpu; + +static int bare_probe(platform_t); +static void bare_mem_regions(platform_t, struct mem_region **phys, int *physsz, + struct mem_region **avail, int *availsz); +static u_long bare_timebase_freq(platform_t, struct cpuref *cpuref); +static int bare_smp_first_cpu(platform_t, struct cpuref *cpuref); +static int bare_smp_next_cpu(platform_t, struct cpuref *cpuref); +static int bare_smp_get_bsp(platform_t, struct cpuref *cpuref); +static int bare_smp_start_cpu(platform_t, struct pcpu *cpu); + +static platform_method_t bare_methods[] = { + PLATFORMMETHOD(platform_probe, bare_probe), + PLATFORMMETHOD(platform_mem_regions, bare_mem_regions), + PLATFORMMETHOD(platform_timebase_freq, bare_timebase_freq), + + PLATFORMMETHOD(platform_smp_first_cpu, bare_smp_first_cpu), + PLATFORMMETHOD(platform_smp_next_cpu, bare_smp_next_cpu), + PLATFORMMETHOD(platform_smp_get_bsp, bare_smp_get_bsp), + PLATFORMMETHOD(platform_smp_start_cpu, bare_smp_start_cpu), + + { 0, 0 } +}; + +static platform_def_t bare_platform = { + "bare metal", + bare_methods, + 0 +}; + +PLATFORM_DEF(bare_platform); + +static int +bare_probe(platform_t plat) +{ + + return (BUS_PROBE_GENERIC); +} + +#define MEM_REGIONS 8 +static struct mem_region avail_regions[MEM_REGIONS]; + +void +bare_mem_regions(platform_t plat, struct mem_region **phys, int *physsz, + struct mem_region **avail, int *availsz) +{ + struct bi_mem_region *mr; + int i; + + /* Initialize memory regions table */ + mr = bootinfo_mr(); + for (i = 0; i < bootinfo->bi_mem_reg_no; i++, mr++) { + if (i == MEM_REGIONS) + break; + if (mr->mem_base < 1048576) { + avail_regions[i].mr_start = 1048576; + avail_regions[i].mr_size = mr->mem_size - + (1048576 - mr->mem_base); + } else { + avail_regions[i].mr_start = mr->mem_base; + avail_regions[i].mr_size = mr->mem_size; + } + } + *availsz = i; + *avail = avail_regions; + + /* On the bare metal platform phys == avail memory */ + *physsz = *availsz; + *phys = *avail; +} + +static u_long +bare_timebase_freq(platform_t plat, struct cpuref *cpuref) +{ + u_long ticks = -1; + + /* + * Time Base and Decrementer are updated every 8 CCB bus clocks. + * HID0[SEL_TBCLK] = 0 + */ + ticks = bootinfo->bi_bus_clk / 8; + if (ticks <= 0) + panic("Unable to determine timebase frequency!"); + + return (ticks); +} + +static int +bare_smp_first_cpu(platform_t plat, struct cpuref *cpuref) +{ + + cpu = 0; + cpuref->cr_cpuid = cpu; + cpuref->cr_hwref = cpuref->cr_cpuid; + if (bootverbose) + printf("powerpc_smp_first_cpu: cpuid %d\n", cpuref->cr_cpuid); + cpu++; + + return (0); +} + +static int +bare_smp_next_cpu(platform_t plat, struct cpuref *cpuref) +{ + + if (cpu >= MAXCPU) + return (ENOENT); + + cpuref->cr_cpuid = cpu++; + cpuref->cr_hwref = cpuref->cr_cpuid; + if (bootverbose) + printf("powerpc_smp_next_cpu: cpuid %d\n", cpuref->cr_cpuid); + + return (0); +} + +static int +bare_smp_get_bsp(platform_t plat, struct cpuref *cpuref) +{ + + cpuref->cr_cpuid = mfspr(SPR_PIR); + cpuref->cr_hwref = cpuref->cr_cpuid; + + return (0); +} + +static int +bare_smp_start_cpu(platform_t plat, struct pcpu *pc) +{ + + /* No SMP support */ + return (ENXIO); +} diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 6dedf4f9642b..7089764c633a 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -79,7 +79,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include @@ -122,8 +122,11 @@ vm_size_t kernsize; static vm_offset_t data_start; static vm_size_t data_end; -struct mem_region availmem_regions[MEM_REGIONS]; -int availmem_regions_sz; +/* Phys/avail memory regions. */ +static struct mem_region *availmem_regions; +static int availmem_regions_sz; +static struct mem_region *physmem_regions; +static int physmem_regions_sz; /* Reserved KVA space and mutex for mmu_booke_zero_page. */ static vm_offset_t zero_page_va; @@ -1013,6 +1016,10 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend) * align all regions. Non-page aligned memory isn't very interesting * to us. Also, sort the entries for ascending addresses. */ + + /* Retrieve phys/avail mem regions */ + mem_regions(&physmem_regions, &physmem_regions_sz, + &availmem_regions, &availmem_regions_sz); sz = 0; cnt = availmem_regions_sz; debugf("processing avail regions:\n"); diff --git a/sys/powerpc/booke/vm_machdep.c b/sys/powerpc/booke/vm_machdep.c index 53596cb93a58..e8fff023f3de 100644 --- a/sys/powerpc/booke/vm_machdep.c +++ b/sys/powerpc/booke/vm_machdep.c @@ -124,7 +124,7 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include +#include #include #include diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index 709e4a9a0c0e..ec81e6cd2360 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -55,7 +55,6 @@ void busdma_swi(void); int is_physical_memory(vm_offset_t addr); int mem_valid(vm_offset_t addr, int len); -void decr_config(unsigned long); void decr_init(void); void decr_tc_init(void); diff --git a/sys/powerpc/include/ofw_machdep.h b/sys/powerpc/include/ofw_machdep.h index 1dd2027d077f..bf79224795c5 100644 --- a/sys/powerpc/include/ofw_machdep.h +++ b/sys/powerpc/include/ofw_machdep.h @@ -33,6 +33,7 @@ #include #include #include +#include typedef uint32_t cell_t; @@ -42,4 +43,9 @@ void OF_getetheraddr(device_t dev, u_char *addr); void OF_initial_setup(void *fdt_ptr, void *junk, int (*openfirm)(void *)); boolean_t OF_bootstrap(void); +void OF_halt(void); +void OF_reboot(void); + +void ofw_mem_regions(struct mem_region **, int *, struct mem_region **, int *); + #endif /* _MACHINE_OFW_MACHDEP_H_ */ diff --git a/sys/powerpc/include/powerpc.h b/sys/powerpc/include/platform.h similarity index 80% rename from sys/powerpc/include/powerpc.h rename to sys/powerpc/include/platform.h index 3de078899dd3..cfa7a0d0890c 100644 --- a/sys/powerpc/include/powerpc.h +++ b/sys/powerpc/include/platform.h @@ -32,8 +32,11 @@ * $FreeBSD$ */ -#ifndef _MACHINE_POWERPC_H_ -#define _MACHINE_POWERPC_H_ +#ifndef _MACHINE_PLATFORM_H_ +#define _MACHINE_PLATFORM_H_ + +#include +#include struct mem_region { vm_offset_t mr_start; @@ -42,18 +45,14 @@ struct mem_region { void mem_regions(struct mem_region **, int *, struct mem_region **, int *); -/* - * These two functions get used solely in boot() in machdep.c. - * - * Not sure whether boot itself should be implementation dependent instead. XXX - */ -void OF_halt(void); -void OF_reboot(void); - -int dk_match(char *name); - -void ofrootfound(void); - -extern int booted_partition; - -#endif /* _MACHINE_POWERPC_H_ */ +u_long platform_timebase_freq(struct cpuref *); + +int platform_smp_first_cpu(struct cpuref *); +int platform_smp_next_cpu(struct cpuref *); +int platform_smp_get_bsp(struct cpuref *); +int platform_smp_start_cpu(struct pcpu *); + +const char *installed_platform(void); +void platform_probe_and_attach(void); + +#endif /* _MACHINE_PLATFORM_H_ */ diff --git a/sys/powerpc/include/platformvar.h b/sys/powerpc/include/platformvar.h new file mode 100644 index 000000000000..b7c011d39850 --- /dev/null +++ b/sys/powerpc/include/platformvar.h @@ -0,0 +1,88 @@ +/*- + * Copyright (c) 2005 Peter Grehan + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _MACHINE_PLATFORMVAR_H_ +#define _MACHINE_PLATFORMVAR_H_ + +/* + * A PowerPC platform implementation is declared with a kernel object and + * an associated method table, similar to a device driver. + * + * e.g. + * + * static platform_method_t chrp_methods[] = { + * PLATFORMMETHOD(platform_probe, chrp_probe), + * PLATFORMMETHOD(platform_mem_regions, ofw_mem_regions), + * ... + * PLATFORMMETHOD(platform_smp_first_cpu, chrp_smp_first_cpu), + * { 0, 0 } + * }; + * + * static platform_def_t chrp_platform = { + * "chrp", + * chrp_methods, + * sizeof(chrp_platform_softc), // or 0 if no softc + * }; + * + * PLATFORM_DEF(chrp_platform); + */ + +#include + +struct platform_kobj { + /* + * A platform instance is a kernel object + */ + KOBJ_FIELDS; + + /* + * Utility elements that an instance may use + */ + struct mtx platform_mtx; /* available for instance use */ + void *platform_iptr; /* instance data pointer */ + + /* + * Opaque data that can be overlaid with an instance-private + * structure. Platform code can test that this is large enough at + * compile time with a sizeof() test againt it's softc. There + * is also a run-time test when the platform kernel object is + * registered. + */ +#define PLATFORM_OPAQUESZ 64 + u_int platform_opaque[PLATFORM_OPAQUESZ]; +}; + +typedef struct platform_kobj *platform_t; +typedef struct kobj_class platform_def_t; +#define platform_method_t kobj_method_t + +#define PLATFORMMETHOD KOBJMETHOD + +#define PLATFORM_DEF(name) DATA_SET(platform_set, name) + +#endif /* _MACHINE_PLATFORMVAR_H_ */ diff --git a/sys/powerpc/include/pmap.h b/sys/powerpc/include/pmap.h index 5e6d9c649820..42bc4099526e 100644 --- a/sys/powerpc/include/pmap.h +++ b/sys/powerpc/include/pmap.h @@ -143,7 +143,6 @@ struct md_page { TAILQ_HEAD(, pv_entry) pv_list; }; -#define MEM_REGIONS 8 #define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list)) #endif /* AIM */ diff --git a/sys/powerpc/include/smp.h b/sys/powerpc/include/smp.h index 2b054c5fde53..3929b8c7e7e5 100644 --- a/sys/powerpc/include/smp.h +++ b/sys/powerpc/include/smp.h @@ -46,11 +46,6 @@ struct cpuref { u_int cr_cpuid; }; -int powerpc_smp_first_cpu(struct cpuref *); -int powerpc_smp_get_bsp(struct cpuref *); -int powerpc_smp_next_cpu(struct cpuref *); -int powerpc_smp_start_cpu(struct pcpu *); - void pmap_cpu_bootstrap(int); uint32_t cpudep_ap_bootstrap(void); void machdep_ap_bootstrap(void); diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 84fab0dcbcba..82f734b4646f 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -419,6 +419,7 @@ #define SPR_DAC2 0x3f7 /* 4.. Data Address Compare 2 */ #define SPR_PIR 0x3ff /* .6. Processor Identification Register */ #elif defined(E500) +#define SPR_PIR 0x11e /* ..8 Processor Identification Register */ #define SPR_DBSR 0x130 /* ..8 Debug Status Register */ #define DBSR_IDE 0x80000000 /* Imprecise debug event. */ #define DBSR_UDE 0x40000000 /* Unconditional debug event. */ diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 5d05fd158101..cbaa400130a0 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -39,6 +39,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "pic_if.h" @@ -88,10 +89,10 @@ cpu_mp_setmaxid(void) int error; mp_ncpus = 0; - error = powerpc_smp_first_cpu(&cpuref); + error = platform_smp_first_cpu(&cpuref); while (!error) { mp_ncpus++; - error = powerpc_smp_next_cpu(&cpuref); + error = platform_smp_next_cpu(&cpuref); } /* Sanity. */ if (mp_ncpus == 0) @@ -121,11 +122,11 @@ cpu_mp_start(void) struct pcpu *pc; int error; - error = powerpc_smp_get_bsp(&bsp); + error = platform_smp_get_bsp(&bsp); KASSERT(error == 0, ("Don't know BSP")); KASSERT(bsp.cr_cpuid == 0, ("%s: cpuid != 0", __func__)); - error = powerpc_smp_first_cpu(&cpu); + error = platform_smp_first_cpu(&cpu); while (!error) { if (cpu.cr_cpuid >= MAXCPU) { printf("SMP: cpu%d: skipped -- ID out of range\n", @@ -150,7 +151,7 @@ cpu_mp_start(void) all_cpus |= pc->pc_cpumask; next: - error = powerpc_smp_next_cpu(&cpu); + error = platform_smp_next_cpu(&cpu); } } @@ -188,7 +189,7 @@ cpu_mp_unleash(void *dummy) if (!pc->pc_bsp) { printf("Waking up CPU %d (dev=%x)\n", pc->pc_cpuid, pc->pc_hwref); - powerpc_smp_start_cpu(pc); + platform_smp_start_cpu(pc); } else { __asm __volatile("mfspr %0,1023" : "=r"(pc->pc_pir)); pc->pc_awake = 1; diff --git a/sys/powerpc/powerpc/platform.c b/sys/powerpc/powerpc/platform.c new file mode 100644 index 000000000000..400856375db7 --- /dev/null +++ b/sys/powerpc/powerpc/platform.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2005 Peter Grehan + * Copyright (c) 2009 Nathan Whitehorn + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * Dispatch platform calls to the appropriate platform implementation + * through a previously registered kernel object. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "platform_if.h" + +static platform_def_t *plat_def_impl; +static platform_t plat_obj; +static struct kobj_ops plat_kernel_kops; +static struct platform_kobj plat_kernel_obj; + +static char plat_name[64] = ""; +SYSCTL_STRING(_hw, OID_AUTO, platform, CTLFLAG_RD | CTLFLAG_TUN, + plat_name, 0, "Platform currently in use"); + +void +mem_regions(struct mem_region **phys, int *physsz, struct mem_region **avail, + int *availsz) +{ + PLATFORM_MEM_REGIONS(plat_obj, phys, physsz, avail, availsz); +} + +const char * +installed_platform() +{ + return (plat_def_impl->name); +} + +u_long +platform_timebase_freq(struct cpuref *cpu) +{ + return (PLATFORM_TIMEBASE_FREQ(plat_obj, cpu)); +} + +int +platform_smp_first_cpu(struct cpuref *cpu) +{ + return (PLATFORM_SMP_FIRST_CPU(plat_obj, cpu)); +} + +int +platform_smp_next_cpu(struct cpuref *cpu) +{ + return (PLATFORM_SMP_NEXT_CPU(plat_obj, cpu)); +} + +int +platform_smp_get_bsp(struct cpuref *cpu) +{ + return (PLATFORM_SMP_GET_BSP(plat_obj, cpu)); +} + +int +platform_smp_start_cpu(struct pcpu *cpu) +{ + return (PLATFORM_SMP_START_CPU(plat_obj, cpu)); +} + +/* + * Platform install routines. Highest priority wins, using the same + * algorithm as bus attachment. + */ +SET_DECLARE(platform_set, platform_def_t); + +void +platform_probe_and_attach() +{ + platform_def_t **platpp, *platp; + int prio, best_prio; + + plat_obj = &plat_kernel_obj; + best_prio = 0; + + /* + * Try to locate the best platform kobj + */ + SET_FOREACH(platpp, platform_set) { + platp = *platpp; + + /* + * Take care of compiling the selected class, and + * then statically initialise the MMU object + */ + kobj_class_compile_static(platp, &plat_kernel_kops); + kobj_init((kobj_t)plat_obj, platp); + + prio = PLATFORM_PROBE(plat_obj); + + /* Check for errors */ + if (prio > 0) + continue; + + /* + * Check if this module was specifically requested through + * the loader tunable we provide. + */ + if (strcmp(platp->name,plat_name) == 0) { + plat_def_impl = platp; + break; + } + + /* Otherwise, see if it is better than our current best */ + if (plat_def_impl == NULL || prio > best_prio) { + best_prio = prio; + plat_def_impl = platp; + } + + /* + * We can't free the KOBJ, since it is static. Luckily, + * this has no ill effects since it gets reset every time. + */ + } + + if (plat_def_impl == NULL) + panic("No platform module found!"); + + /* + * Recompile to make sure we ended with the + * correct one, and then attach. + */ + + kobj_class_compile_static(plat_def_impl, &plat_kernel_kops); + kobj_init((kobj_t)plat_obj, plat_def_impl); + + strlcpy(plat_name,plat_def_impl->name,sizeof(plat_name)); + + PLATFORM_ATTACH(plat_obj); +} + diff --git a/sys/powerpc/powerpc/platform_if.m b/sys/powerpc/powerpc/platform_if.m new file mode 100644 index 000000000000..600d14656a58 --- /dev/null +++ b/sys/powerpc/powerpc/platform_if.m @@ -0,0 +1,163 @@ +#- +# Copyright (c) 2009 Nathan Whitehorn +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ +# + +#include +#include +#include +#include + +#include +#include +#include + +/** + * @defgroup PLATFORM platform - KObj methods for PowerPC platform + * implementations + * @brief A set of methods required by all platform implementations. + * These are used to bring up secondary CPUs, supply the physical memory + * map, etc. + *@{ + */ + +INTERFACE platform; + +# +# Default implementations +# +CODE { + static void platform_null_attach(platform_t plat) + { + return; + } + static int platform_null_smp_first_cpu(platform_t plat, + struct cpuref *cpuref) + { + cpuref->cr_hwref = -1; + cpuref->cr_cpuid = 0; + return (0); + } + static int platform_null_smp_next_cpu(platform_t plat, + struct cpuref *_cpuref) + { + return (ENOENT); + } +}; + +/** + * @brief Probe for whether we are on this platform, returning the standard + * newbus probe codes. If we have Open Firmware or a flattened device tree, + * it is guaranteed to be available at this point. + */ +METHOD int probe { + platform_t _plat; +}; + + +/** + * @brief Attach this platform module. This happens before the MMU is online, + * so the platform module can install its own high-priority MMU module at + * this point. + */ +METHOD int attach { + platform_t _plat; +} DEFAULT platform_null_attach; + + +/** + * @brief Return the system's physical memory map. + * + * It shall provide the total and the available regions of RAM. + * The available regions need not take the kernel into account. + * + * @param _memp Array of physical memory chunks + * @param _memsz Number of physical memory chunks + * @param _availp Array of available physical memory chunks + * @param _availsz Number of available physical memory chunks + */ + +METHOD void mem_regions { + platform_t _plat; + struct mem_region **_memp; + int *_memsz; + struct mem_region **_availp; + int *_availsz; +}; + +/** + * @brief Get the CPU's timebase frequency, in ticks per second. + * + * @param _cpu CPU whose timebase to query + */ + +METHOD u_long timebase_freq { + platform_t _plat; + struct cpuref *_cpu; +}; + +# SMP bits + +/** + * @brief Fill the first CPU's cpuref + * + * @param _cpuref CPU + */ +METHOD int smp_first_cpu { + platform_t _plat; + struct cpuref *_cpuref; +} DEFAULT platform_null_smp_first_cpu; + +/** + * @brief Fill the next CPU's cpuref + * + * @param _cpuref CPU + */ +METHOD int smp_next_cpu { + platform_t _plat; + struct cpuref *_cpuref; +} DEFAULT platform_null_smp_next_cpu; + +/** + * @brief Find the boot processor + * + * @param _cpuref CPU + */ +METHOD int smp_get_bsp { + platform_t _plat; + struct cpuref *_cpuref; +} DEFAULT platform_null_smp_first_cpu; + +/** + * @brief Start a CPU + * + * @param _cpuref CPU + */ +METHOD int smp_start_cpu { + platform_t _plat; + struct pcpu *_cpu; +}; + diff --git a/sys/powerpc/powerpc/pmap_dispatch.c b/sys/powerpc/powerpc/pmap_dispatch.c index af657d4e527c..b34c7ebbb9f0 100644 --- a/sys/powerpc/powerpc/pmap_dispatch.c +++ b/sys/powerpc/powerpc/pmap_dispatch.c @@ -509,7 +509,7 @@ pmap_mmu_install(char *name, int prio) if (mmup->name && !strcmp(mmup->name, name) && - prio >= curr_prio) { + (prio >= curr_prio || mmu_def_impl == NULL)) { curr_prio = prio; mmu_def_impl = mmup; return (TRUE); From bf422e5f2745758eff9dd4abc89935e403c761de Mon Sep 17 00:00:00 2001 From: Jeff Roberson Date: Thu, 14 May 2009 03:24:22 +0000 Subject: [PATCH 166/544] - Implement a lockless file descriptor lookup algorithm in fget_unlocked(). - Save old file descriptor tables created on expansion until the entire descriptor table is freed so that pointers may be followed without regard for expanders. - Mark the file zone as NOFREE so we may attempt to reference potentially freed files. - Convert several fget_locked() users to fget_unlocked(). This requires us to manage reference counts explicitly but reduces locking overhead in the common case. --- sys/kern/kern_descrip.c | 121 ++++++++++++++++++++++++++++----------- sys/kern/sys_generic.c | 14 ++--- sys/kern/tty.c | 11 ++-- sys/kern/uipc_syscalls.c | 25 +++----- sys/kern/vfs_syscalls.c | 19 ++---- sys/sys/filedesc.h | 4 ++ 6 files changed, 117 insertions(+), 77 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index 2f4630775767..f29b0ebdc82d 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -124,12 +124,24 @@ static void fdused(struct filedesc *fdp, int fd); */ #define OFILESIZE (sizeof(struct file *) + sizeof(char)) +/* + * Storage to hold unused ofiles that need to be reclaimed. + */ +struct freetable { + struct file **ft_table; + SLIST_ENTRY(freetable) ft_next; +}; + /* * Basic allocation of descriptors: * one of the above, plus arrays for NDFILE descriptors. */ struct filedesc0 { struct filedesc fd_fd; + /* + * ofiles which need to be reclaimed on free. + */ + SLIST_HEAD(,freetable) fd_free; /* * These arrays are used when the number of open files is * <= NDFILE, and are then pointed to by the pointers above. @@ -1268,7 +1280,10 @@ fpathconf(struct thread *td, struct fpathconf_args *uap) static void fdgrowtable(struct filedesc *fdp, int nfd) { + struct filedesc0 *fdp0; + struct freetable *fo; struct file **ntable; + struct file **otable; char *nfileflags; int nnfiles, onfiles; NDSLOTTYPE *nmap; @@ -1287,7 +1302,7 @@ fdgrowtable(struct filedesc *fdp, int nfd) /* allocate a new table and (if required) new bitmaps */ FILEDESC_XUNLOCK(fdp); - ntable = malloc(nnfiles * OFILESIZE, + ntable = malloc((nnfiles * OFILESIZE) + sizeof(struct freetable), M_FILEDESC, M_ZERO | M_WAITOK); nfileflags = (char *)&ntable[nnfiles]; if (NDSLOTS(nnfiles) > NDSLOTS(onfiles)) @@ -1311,10 +1326,20 @@ fdgrowtable(struct filedesc *fdp, int nfd) } bcopy(fdp->fd_ofiles, ntable, onfiles * sizeof(*ntable)); bcopy(fdp->fd_ofileflags, nfileflags, onfiles); - if (onfiles > NDFILE) - free(fdp->fd_ofiles, M_FILEDESC); - fdp->fd_ofiles = ntable; + otable = fdp->fd_ofiles; fdp->fd_ofileflags = nfileflags; + fdp->fd_ofiles = ntable; + /* + * We must preserve ofiles until the process exits because we can't + * be certain that no threads have references to the old table via + * _fget(). + */ + if (onfiles > NDFILE) { + fo = (struct freetable *)&otable[onfiles]; + fdp0 = (struct filedesc0 *)fdp; + fo->ft_table = otable; + SLIST_INSERT_HEAD(&fdp0->fd_free, fo, ft_next); + } if (NDSLOTS(nnfiles) > NDSLOTS(onfiles)) { bcopy(fdp->fd_map, nmap, NDSLOTS(onfiles) * sizeof(*nmap)); if (NDSLOTS(onfiles) > NDSLOTS(NDFILE)) @@ -1512,6 +1537,8 @@ fdhold(struct proc *p) static void fddrop(struct filedesc *fdp) { + struct filedesc0 *fdp0; + struct freetable *ft; int i; mtx_lock(&fdesc_mtx); @@ -1521,6 +1548,11 @@ fddrop(struct filedesc *fdp) return; FILEDESC_LOCK_DESTROY(fdp); + fdp0 = (struct filedesc0 *)fdp; + while ((ft = SLIST_FIRST(&fdp0->fd_free)) != NULL) { + SLIST_REMOVE_HEAD(&fdp0->fd_free, ft_next); + free(ft->ft_table, M_FILEDESC); + } free(fdp, M_FILEDESC); } @@ -2022,6 +2054,38 @@ finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) atomic_store_rel_ptr((volatile uintptr_t *)&fp->f_ops, (uintptr_t)ops); } +struct file * +fget_unlocked(struct filedesc *fdp, int fd) +{ + struct file *fp; + u_int count; + + if (fd < 0 || fd >= fdp->fd_nfiles) + return (NULL); + /* + * Fetch the descriptor locklessly. We avoid fdrop() races by + * never raising a refcount above 0. To accomplish this we have + * to use a cmpset loop rather than an atomic_add. The descriptor + * must be re-verified once we acquire a reference to be certain + * that the identity is still correct and we did not lose a race + * due to preemption. + */ + for (;;) { + fp = fdp->fd_ofiles[fd]; + if (fp == NULL) + break; + count = fp->f_count; + if (count == 0) + continue; + if (atomic_cmpset_int(&fp->f_count, count, count + 1) != 1) + continue; + if (fp == ((struct file *volatile*)fdp->fd_ofiles)[fd]) + break; + fdrop(fp, curthread); + } + + return (fp); +} /* * Extract the file pointer associated with the specified descriptor for the @@ -2030,16 +2094,12 @@ finit(struct file *fp, u_int flag, short type, void *data, struct fileops *ops) * If the descriptor doesn't exist or doesn't match 'flags', EBADF is * returned. * - * If 'hold' is set (non-zero) the file's refcount will be bumped on return. - * It should be dropped with fdrop(). If it is not set, then the refcount - * will not be bumped however the thread's filedesc struct will be returned - * locked (for fgetsock). - * * If an error occured the non-zero error is returned and *fpp is set to - * NULL. Otherwise *fpp is set and zero is returned. + * NULL. Otherwise *fpp is held and set and zero is returned. Caller is + * responsible for fdrop(). */ static __inline int -_fget(struct thread *td, int fd, struct file **fpp, int flags, int hold) +_fget(struct thread *td, int fd, struct file **fpp, int flags) { struct filedesc *fdp; struct file *fp; @@ -2047,29 +2107,22 @@ _fget(struct thread *td, int fd, struct file **fpp, int flags, int hold) *fpp = NULL; if (td == NULL || (fdp = td->td_proc->p_fd) == NULL) return (EBADF); - FILEDESC_SLOCK(fdp); - if ((fp = fget_locked(fdp, fd)) == NULL || fp->f_ops == &badfileops) { - FILEDESC_SUNLOCK(fdp); + if ((fp = fget_unlocked(fdp, fd)) == NULL) + return (EBADF); + if (fp->f_ops == &badfileops) { + fdrop(fp, td); return (EBADF); } - /* * FREAD and FWRITE failure return EBADF as per POSIX. * * Only one flag, or 0, may be specified. */ - if (flags == FREAD && (fp->f_flag & FREAD) == 0) { - FILEDESC_SUNLOCK(fdp); + if ((flags == FREAD && (fp->f_flag & FREAD) == 0) || + (flags == FWRITE && (fp->f_flag & FWRITE) == 0)) { + fdrop(fp, td); return (EBADF); } - if (flags == FWRITE && (fp->f_flag & FWRITE) == 0) { - FILEDESC_SUNLOCK(fdp); - return (EBADF); - } - if (hold) { - fhold(fp); - FILEDESC_SUNLOCK(fdp); - } *fpp = fp; return (0); } @@ -2078,21 +2131,21 @@ int fget(struct thread *td, int fd, struct file **fpp) { - return(_fget(td, fd, fpp, 0, 1)); + return(_fget(td, fd, fpp, 0)); } int fget_read(struct thread *td, int fd, struct file **fpp) { - return(_fget(td, fd, fpp, FREAD, 1)); + return(_fget(td, fd, fpp, FREAD)); } int fget_write(struct thread *td, int fd, struct file **fpp) { - return(_fget(td, fd, fpp, FWRITE, 1)); + return(_fget(td, fd, fpp, FWRITE)); } /* @@ -2109,7 +2162,7 @@ _fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags) int error; *vpp = NULL; - if ((error = _fget(td, fd, &fp, flags, 0)) != 0) + if ((error = _fget(td, fd, &fp, flags)) != 0) return (error); if (fp->f_vnode == NULL) { error = EINVAL; @@ -2117,7 +2170,8 @@ _fgetvp(struct thread *td, int fd, struct vnode **vpp, int flags) *vpp = fp->f_vnode; vref(*vpp); } - FILEDESC_SUNLOCK(td->td_proc->p_fd); + fdrop(fp, td); + return (error); } @@ -2164,7 +2218,7 @@ fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp) *spp = NULL; if (fflagp != NULL) *fflagp = 0; - if ((error = _fget(td, fd, &fp, 0, 0)) != 0) + if ((error = _fget(td, fd, &fp, 0)) != 0) return (error); if (fp->f_type != DTYPE_SOCKET) { error = ENOTSOCK; @@ -2176,7 +2230,8 @@ fgetsock(struct thread *td, int fd, struct socket **spp, u_int *fflagp) soref(*spp); SOCK_UNLOCK(*spp); } - FILEDESC_SUNLOCK(td->td_proc->p_fd); + fdrop(fp, td); + return (error); } @@ -3147,7 +3202,7 @@ filelistinit(void *dummy) { file_zone = uma_zcreate("Files", sizeof(struct file), NULL, NULL, - NULL, NULL, UMA_ALIGN_PTR, 0); + NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); mtx_init(&sigio_lock, "sigio lock", NULL, MTX_DEF); mtx_init(&fdesc_mtx, "fdesc", NULL, MTX_DEF); } diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index d4af4cb28991..616c5b79e11f 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -988,7 +988,6 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits) fdp = td->td_proc->p_fd; stp = td->td_sel; n = 0; - FILEDESC_SLOCK(fdp); STAILQ_FOREACH_SAFE(sfp, &stp->st_selq, sf_link, sfn) { fd = (int)(uintptr_t)sfp->sf_cookie; si = sfp->sf_si; @@ -996,17 +995,15 @@ selrescan(struct thread *td, fd_mask **ibits, fd_mask **obits) /* If the selinfo wasn't cleared the event didn't fire. */ if (si != NULL) continue; - if ((fp = fget_locked(fdp, fd)) == NULL) { - FILEDESC_SUNLOCK(fdp); + if ((fp = fget_unlocked(fdp, fd)) == NULL) return (EBADF); - } idx = fd / NFDBITS; bit = (fd_mask)1 << (fd % NFDBITS); ev = fo_poll(fp, selflags(ibits, idx, bit), td->td_ucred, td); + fdrop(fp, td); if (ev != 0) n += selsetbits(ibits, obits, idx, bit, ev); } - FILEDESC_SUNLOCK(fdp); stp->st_flags = 0; td->td_retval[0] = n; return (0); @@ -1030,7 +1027,6 @@ selscan(td, ibits, obits, nfd) fdp = td->td_proc->p_fd; n = 0; - FILEDESC_SLOCK(fdp); for (idx = 0, fd = 0; fd < nfd; idx++) { end = imin(fd + NFDBITS, nfd); for (bit = 1; fd < end; bit <<= 1, fd++) { @@ -1038,18 +1034,16 @@ selscan(td, ibits, obits, nfd) flags = selflags(ibits, idx, bit); if (flags == 0) continue; - if ((fp = fget_locked(fdp, fd)) == NULL) { - FILEDESC_SUNLOCK(fdp); + if ((fp = fget_unlocked(fdp, fd)) == NULL) return (EBADF); - } selfdalloc(td, (void *)(uintptr_t)fd); ev = fo_poll(fp, flags, td->td_ucred, td); + fdrop(fp, td); if (ev != 0) n += selsetbits(ibits, obits, idx, bit, ev); } } - FILEDESC_SUNLOCK(fdp); td->td_retval[0] = n; return (0); } diff --git a/sys/kern/tty.c b/sys/kern/tty.c index d6ffdd7374d4..2468e8859381 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -1720,10 +1720,13 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, /* Validate the file descriptor. */ if ((fdp = p->p_fd) == NULL) return (EBADF); - FILEDESC_SLOCK(fdp); - if ((fp = fget_locked(fdp, fd)) == NULL || fp->f_ops == &badfileops) { - FILEDESC_SUNLOCK(fdp); + + fp = fget_unlocked(fdp, fd); + if (fp == NULL) return (EBADF); + if (fp->f_ops == &badfileops) { + error = EBADF; + goto done1; } /* Make sure the vnode is bound to a character device. */ @@ -1763,7 +1766,7 @@ ttyhook_register(struct tty **rtp, struct proc *p, int fd, done3: tty_unlock(tp); done2: dev_relthread(dev); -done1: FILEDESC_SUNLOCK(fdp); +done1: fdrop(fp, curthread); return (error); } diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c index f86e65747a9f..9adbbc67b55e 100644 --- a/sys/kern/uipc_syscalls.c +++ b/sys/kern/uipc_syscalls.c @@ -122,23 +122,16 @@ getsock(struct filedesc *fdp, int fd, struct file **fpp, u_int *fflagp) int error; fp = NULL; - if (fdp == NULL) + if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) { error = EBADF; - else { - FILEDESC_SLOCK(fdp); - fp = fget_locked(fdp, fd); - if (fp == NULL) - error = EBADF; - else if (fp->f_type != DTYPE_SOCKET) { - fp = NULL; - error = ENOTSOCK; - } else { - fhold(fp); - if (fflagp != NULL) - *fflagp = fp->f_flag; - error = 0; - } - FILEDESC_SUNLOCK(fdp); + } else if (fp->f_type != DTYPE_SOCKET) { + fdrop(fp, curthread); + fp = NULL; + error = ENOTSOCK; + } else { + if (fflagp != NULL) + *fflagp = fp->f_flag; + error = 0; } *fpp = fp; return (error); diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c index 64ca31613197..ae3904df22bb 100644 --- a/sys/kern/vfs_syscalls.c +++ b/sys/kern/vfs_syscalls.c @@ -4235,22 +4235,13 @@ getvnode(fdp, fd, fpp) int error; struct file *fp; + error = 0; fp = NULL; - if (fdp == NULL) + if (fdp == NULL || (fp = fget_unlocked(fdp, fd)) == NULL) error = EBADF; - else { - FILEDESC_SLOCK(fdp); - if ((u_int)fd >= fdp->fd_nfiles || - (fp = fdp->fd_ofiles[fd]) == NULL) - error = EBADF; - else if (fp->f_vnode == NULL) { - fp = NULL; - error = EINVAL; - } else { - fhold(fp); - error = 0; - } - FILEDESC_SUNLOCK(fdp); + else if (fp->f_vnode == NULL) { + error = EINVAL; + fdrop(fp, curthread); } *fpp = fp; return (error); diff --git a/sys/sys/filedesc.h b/sys/sys/filedesc.h index da4a87cc3c85..dd97d4435fc7 100644 --- a/sys/sys/filedesc.h +++ b/sys/sys/filedesc.h @@ -129,6 +129,10 @@ int getvnode(struct filedesc *fdp, int fd, struct file **fpp); void mountcheckdirs(struct vnode *olddp, struct vnode *newdp); void setugidsafety(struct thread *td); +/* Return a referenced file from an unlocked descriptor. */ +struct file *fget_unlocked(struct filedesc *fdp, int fd); + +/* Requires a FILEDESC_{S,X}LOCK held and returns without a ref. */ static __inline struct file * fget_locked(struct filedesc *fdp, int fd) { From 8222d237cba35e6c64d4e5016202e4b54d5fb93b Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Thu, 14 May 2009 03:33:04 +0000 Subject: [PATCH 167/544] Call drbr_stats_update to update ifp stats directly when we bypass the buf_ring on transmit --- sys/dev/e1000/if_em.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index cf13fbbc465a..0883018c84d2 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -1006,14 +1006,17 @@ em_transmit_locked(struct ifnet *ifp, struct mbuf *m) || (!adapter->link_active)) { error = drbr_enqueue(ifp, adapter->br, m); return (error); - } - - if (ADAPTER_RING_EMPTY(adapter) && + } else if (ADAPTER_RING_EMPTY(adapter) && (adapter->num_tx_desc_avail > EM_TX_OP_THRESHOLD)) { if (em_xmit(adapter, &m)) { if (m && (error = drbr_enqueue(ifp, adapter->br, m)) != 0) return (error); } else { + /* + * We've bypassed the buf ring so we need to update + * ifp directly + */ + drbr_stats_update(ifp, m->m_pkthdr.len, m->m_flags); /* ** Send a copy of the frame to the BPF ** listener and set the watchdog on. From 92fac994774b4bd416167ce4c712b637a1df6e76 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Thu, 14 May 2009 05:27:09 +0000 Subject: [PATCH 168/544] Ignore the INADDR_ANY address inserted/deleted by DHCP when installing a loopback route to the interface address. --- sys/netinet/in.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 84750a6365b6..5bc78273aeb5 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -906,6 +906,9 @@ in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, if ((error = in_addprefix(ia, flags)) != 0) return (error); + if (ia->ia_addr.sin_addr.s_addr == INADDR_ANY) + return (0); + /* * add a loopback route to self */ @@ -1014,7 +1017,8 @@ in_scrubprefix(struct in_ifaddr *target) if ((target->ia_flags & IFA_ROUTE) == 0) return (0); - if (!(target->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { + if ((target->ia_addr.sin_addr.s_addr != INADDR_ANY) && + !(target->ia_ifp->if_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) { bzero(&null_sdl, sizeof(null_sdl)); null_sdl.sdl_len = sizeof(null_sdl); null_sdl.sdl_family = AF_LINK; From 3f7dc796e8810353f154dc715d9d146a485b7755 Mon Sep 17 00:00:00 2001 From: Craig Rodrigues Date: Thu, 14 May 2009 08:26:20 +0000 Subject: [PATCH 169/544] Set crashinfo_enable to "YES" by default. During bootup, if /etc/rc.d/savecore detects a core dump file on the dump device, the core file will be saved, and the crashinfo script will be run to generate a human-readable report. This will make it easier for end-users to provide feedback to developers about kernel crashes. Reviewed by: jhb --- etc/defaults/rc.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index c7740a1ee234..f1c37999727d 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -543,7 +543,7 @@ chkprintcap_flags="-d" # Create missing directories by default. dumpdev="AUTO" # Device to crashdump to (device name, AUTO, or NO). dumpdir="/var/crash" # Directory where crash dumps are to be stored savecore_flags="" # Used if dumpdev is enabled above, and present. -crashinfo_enable="NO" # Automatically generate crash dump summary. +crashinfo_enable="YES" # Automatically generate crash dump summary. crashinfo_program="/usr/sbin/crashinfo" # Script to generate crash dump summary. quota_enable="NO" # turn on quotas on startup (or NO). check_quotas="YES" # Check quotas on startup (or NO). From bf1593783333e0d5cda879bd690ae511377de6ec Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 14 May 2009 09:28:02 +0000 Subject: [PATCH 170/544] Remove an unused variable. Found with: Coverity Prevent(tm) CID: 1167 --- sys/compat/ndis/subr_ndis.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index f67401347cbb..f7f9c673e436 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -2390,11 +2390,9 @@ NdisMDeregisterInterrupt(intr) ndis_miniport_interrupt *intr; { ndis_miniport_block *block; - struct ndis_softc *sc; uint8_t irql; block = intr->ni_block; - sc = device_get_softc(block->nmb_physdeviceobj->do_devext); /* Should really be KeSynchronizeExecution() */ From e401a6a54ec5a3fc23315312d286d9181f3aa369 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Thu, 14 May 2009 10:54:57 +0000 Subject: [PATCH 171/544] Do not advance req->oldidx when sysctl_old_user returning an error due to copyout failure or short buffer. The later breaks the usermode iterators of the sysctl results that pack arbitrary number of variable-sized structures. Iterator expects that kernel filled exactly oldlen bytes, and tries to interpret half-filled or garbage structure at the end of the buffer. In particular, kinfo_getfile(3) segfaulted. Reported and tested by: pho MFC after: 3 weeks --- sys/kern/kern_sysctl.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index b69ac8f95ed5..89fbb9ab3ee0 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1221,9 +1221,9 @@ sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) if (i > 0) bcopy(p, (char *)req->oldptr + req->oldidx, i); } - req->oldidx += l; if (req->oldptr && i != l) return (ENOMEM); + req->oldidx += l; return (0); } @@ -1320,9 +1320,10 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) size_t i, len, origidx; origidx = req->oldidx; - req->oldidx += l; - if (req->oldptr == NULL) + if (req->oldptr == NULL) { + req->oldidx += l; return (0); + } /* * If we have not wired the user supplied buffer and we are currently * holding locks, drop a witness warning, as it's possible that @@ -1344,6 +1345,7 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) return (error); if (i < l) return (ENOMEM); + req->oldidx += l; return (0); } From 54d83191b0208450d8cff148cf093d229a698953 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 14 May 2009 12:39:22 +0000 Subject: [PATCH 172/544] Remove usb_ethersubr.c missed reference -- we don't build ousb with LINT, so the tinderbox didn't pick this up. --- sys/conf/files | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/conf/files b/sys/conf/files index 9301a3db1389..0d3339e53896 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -1535,7 +1535,6 @@ legacy/dev/usb/ums.c optional oums legacy/dev/usb/uplcom.c optional ouplcom legacy/dev/usb/urio.c optional ourio legacy/dev/usb/usb.c optional ousb -legacy/dev/usb/usb_ethersubr.c optional ousb legacy/dev/usb/usb_if.m optional ousb legacy/dev/usb/usb_mem.c optional ousb legacy/dev/usb/usb_quirks.c optional ousb From 3af3ff479b5731a6bd0b47468c57404b9bf17066 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 14 May 2009 13:32:33 +0000 Subject: [PATCH 173/544] Compare the correct variable against NULL. Reviewed by: scottl Found with: Coverity Prevent(tm) CID: 821 MFC after: 2 weeks --- sys/dev/iir/iir_pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/iir/iir_pci.c b/sys/dev/iir/iir_pci.c index 528b7d71ef95..c75f084b796e 100644 --- a/sys/dev/iir/iir_pci.c +++ b/sys/dev/iir/iir_pci.c @@ -202,7 +202,7 @@ iir_pci_attach(device_t dev) rid = 0; irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_ACTIVE | RF_SHAREABLE); - if (io == NULL) { + if (irq == NULL) { device_printf(dev, "can't find IRQ value\n"); error = ENOMEM; goto err; From bb2aebf3ad252165a58525e2f972f955de04d46f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 14 May 2009 14:57:13 +0000 Subject: [PATCH 174/544] - Add a void pointer to the ata-pci controller softc to allow chipset-specific code to attach chipset-specific data. - Use chipset-specific data in the acard and promise chipsets rather than changing the ivars of ATA PCI devices. ivars are reserved for use by the parent bus driver and are _not_ available for use by devices directly. This fixes a panic during sysctl -a with certain Promise controllers with ACPI enabled. Reviewed by: mav Tested by: Magnus Kling (kingfon @ gmail) (on 7) MFC after: 3 days --- sys/dev/ata/ata-pci.h | 1 + sys/dev/ata/chipsets/ata-acard.c | 38 +++++++++++++++++------------- sys/dev/ata/chipsets/ata-promise.c | 8 +++---- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index b1f3eb70504e..b6c1fd8b364e 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -66,6 +66,7 @@ struct ata_pci_controller { void (*function)(void *); void *argument; } interrupt[8]; /* XXX SOS max ch# for now */ + void *chipset_data; }; /* defines for known chipset PCI id's */ diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c index be6043882fde..552c00b6f7c1 100644 --- a/sys/dev/ata/chipsets/ata-acard.c +++ b/sys/dev/ata/chipsets/ata-acard.c @@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include +struct ata_serialize { + struct mtx locked_mtx; + int locked_ch; + int restart_ch; +}; + /* local prototypes */ static int ata_acard_chipinit(device_t dev); static int ata_acard_ch_attach(device_t dev); @@ -58,6 +64,7 @@ static int ata_acard_status(device_t dev); static void ata_acard_850_setmode(device_t dev, int mode); static void ata_acard_86X_setmode(device_t dev, int mode); static int ata_serialize(device_t dev, int flags); +static void ata_serialize_init(struct ata_serialize *serial); /* misc defines */ #define ATP_OLD 1 @@ -93,6 +100,7 @@ static int ata_acard_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); + struct ata_serialize *serial; if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; @@ -102,6 +110,10 @@ ata_acard_chipinit(device_t dev) if (ctlr->chip->cfg1 == ATP_OLD) { ctlr->setmode = ata_acard_850_setmode; ctlr->locking = ata_serialize; + serial = malloc(sizeof(struct ata_serialize), + M_TEMP, M_WAITOK | M_ZERO); + ata_serialize_init(serial); + ctlr->chipset_data = serial; } else ctlr->setmode = ata_acard_86X_setmode; @@ -225,11 +237,14 @@ ata_acard_86X_setmode(device_t dev, int mode) /* we could set PIO mode timings, but we assume the BIOS did that */ } -struct ata_serialize { - struct mtx locked_mtx; - int locked_ch; - int restart_ch; -}; +static void +ata_serialize_init(struct ata_serialize *serial) +{ + + mtx_init(&serial->locked_mtx, "ATA serialize lock", NULL, MTX_DEF); + serial->locked_ch = -1; + serial->restart_ch = -1; +} static int ata_serialize(device_t dev, int flags) @@ -237,20 +252,9 @@ ata_serialize(device_t dev, int flags) struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); struct ata_serialize *serial; - static int inited = 0; int res; - if (!inited) { - serial = malloc(sizeof(struct ata_serialize), - M_TEMP, M_NOWAIT | M_ZERO); - mtx_init(&serial->locked_mtx, "ATA serialize lock", NULL, MTX_DEF); - serial->locked_ch = -1; - serial->restart_ch = -1; - device_set_ivars(ctlr->dev, serial); - inited = 1; - } - else - serial = device_get_ivars(ctlr->dev); + serial = ctlr->chipset_data; mtx_lock(&serial->locked_mtx); switch (flags) { diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 6b34596fa01d..4577ee642a9a 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -283,7 +283,7 @@ ata_promise_chipinit(device_t dev) mtx_init(&hpkt->mtx, "ATA promise HPKT lock", NULL, MTX_DEF); TAILQ_INIT(&hpkt->queue); hpkt->busy = 0; - device_set_ivars(dev, hpkt); + ctlr->chipset_data = hpkt; ctlr->ch_attach = ata_promise_mio_ch_attach; ctlr->ch_detach = ata_promise_mio_ch_detach; ctlr->reset = ata_promise_mio_reset; @@ -730,7 +730,7 @@ ata_promise_mio_reset(device_t dev) case PR_SX4X: /* softreset channel ATA module */ - hpktp = device_get_ivars(ctlr->dev); + hpktp = ctlr->chipset_data; ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1); ata_udelay(1000); ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), @@ -1208,7 +1208,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request) static void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) { - struct ata_promise_sx4 *hpktp = device_get_ivars(ctlr->dev); + struct ata_promise_sx4 *hpktp = ctlr->chipset_data; mtx_lock(&hpktp->mtx); if (hpktp->busy) { @@ -1227,7 +1227,7 @@ ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) static void ata_promise_next_hpkt(struct ata_pci_controller *ctlr) { - struct ata_promise_sx4 *hpktp = device_get_ivars(ctlr->dev); + struct ata_promise_sx4 *hpktp = ctlr->chipset_data; struct host_packet *hp; mtx_lock(&hpktp->mtx); From 85d12e2316c26a7e02bcce78a0e5cc575c221ac0 Mon Sep 17 00:00:00 2001 From: Yoshihiro Takahashi Date: Thu, 14 May 2009 16:01:29 +0000 Subject: [PATCH 175/544] MFi386: revision 192050 Implement simple machine check support. --- sys/conf/files.pc98 | 1 + sys/pc98/include/mca.h | 6 ++++++ sys/pc98/pc98/machdep.c | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 sys/pc98/include/mca.h diff --git a/sys/conf/files.pc98 b/sys/conf/files.pc98 index 4e7e43fa5701..7aedb38517a3 100644 --- a/sys/conf/files.pc98 +++ b/sys/conf/files.pc98 @@ -150,6 +150,7 @@ i386/i386/k6_mem.c optional mem i386/i386/legacy.c standard i386/i386/local_apic.c optional apic i386/i386/locore.s standard no-obj +i386/i386/mca.c standard i386/i386/mem.c optional mem i386/i386/minidump_machdep.c standard i386/i386/mp_clock.c optional smp diff --git a/sys/pc98/include/mca.h b/sys/pc98/include/mca.h new file mode 100644 index 000000000000..a047f87c48c4 --- /dev/null +++ b/sys/pc98/include/mca.h @@ -0,0 +1,6 @@ +/*- + * This file is in the public domain. + */ +/* $FreeBSD$ */ + +#include diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index a42b9032edb0..ba3d04796c62 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -111,6 +111,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -256,6 +257,8 @@ cpu_startup(dummy) vm_pager_bufferinit(); cpu_setregs(); + + mca_init(); } /* From 70ca3d6a9fcd809b8e2984ada02f6e3c64d255e5 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 14 May 2009 16:23:24 +0000 Subject: [PATCH 176/544] correct handling of ctl frames: the sender's address is always i_addr2 for frames we should expect to process (old code was trying to handle frames we should never see--like ACK) Reviewed by: thompsa, cbzimmer --- sys/net80211/ieee80211_node.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index 483af2d201c7..c23a09258bdb 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -1439,12 +1439,6 @@ ieee80211_add_neighbor(struct ieee80211vap *vap, return ni; } -#define IS_CTL(wh) \ - ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) -#define IS_PSPOLL(wh) \ - ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_PS_POLL) -#define IS_BAR(wh) \ - ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == IEEE80211_FC0_SUBTYPE_BAR) #define IS_PROBEREQ(wh) \ ((wh->i_fc[0] & (IEEE80211_FC0_TYPE_MASK|IEEE80211_FC0_SUBTYPE_MASK)) \ == (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_REQ)) @@ -1456,9 +1450,6 @@ static __inline struct ieee80211_node * _find_rxnode(struct ieee80211_node_table *nt, const struct ieee80211_frame_min *wh) { - /* XXX 4-address frames? */ - if (IS_CTL(wh) && !IS_PSPOLL(wh) && !IS_BAR(wh) /*&& !IS_RTS(ah)*/) - return ieee80211_find_node_locked(nt, wh->i_addr1); if (IS_BCAST_PROBEREQ(wh)) return NULL; /* spam bcast probe req to all vap's */ return ieee80211_find_node_locked(nt, wh->i_addr2); @@ -1547,9 +1538,6 @@ ieee80211_find_rxnode_withkey(struct ieee80211com *ic, } #undef IS_BCAST_PROBEREQ #undef IS_PROBEREQ -#undef IS_BAR -#undef IS_PSPOLL -#undef IS_CTL /* * Return a reference to the appropriate node for sending From 95b0b37cfc26fab590fcadcbfe88d1df4d105079 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 14 May 2009 16:25:57 +0000 Subject: [PATCH 177/544] add missing type for SYSCTL_PROC items; w/o a type you can view the value but not change it --- sys/net80211/ieee80211_freebsd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index e2d42a6cce1d..e96e71d3d40b 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -175,27 +175,27 @@ ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS) #ifdef IEEE80211_AMPDU_AGE extern int ieee80211_ampdu_age; -SYSCTL_PROC(_net_wlan, OID_AUTO, ampdu_age, CTLFLAG_RW, +SYSCTL_PROC(_net_wlan, OID_AUTO, ampdu_age, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_ampdu_age, 0, ieee80211_sysctl_msecs_ticks, "I", "AMPDU max reorder age (ms)"); #endif extern int ieee80211_addba_timeout; -SYSCTL_PROC(_net_wlan, OID_AUTO, addba_timeout, CTLFLAG_RW, +SYSCTL_PROC(_net_wlan, OID_AUTO, addba_timeout, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_addba_timeout, 0, ieee80211_sysctl_msecs_ticks, "I", "ADDBA request timeout (ms)"); extern int ieee80211_addba_backoff; -SYSCTL_PROC(_net_wlan, OID_AUTO, addba_backoff, CTLFLAG_RW, +SYSCTL_PROC(_net_wlan, OID_AUTO, addba_backoff, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_addba_backoff, 0, ieee80211_sysctl_msecs_ticks, "I", "ADDBA request backoff (ms)"); extern int ieee80211_addba_maxtries; -SYSCTL_INT(_net_wlan, OID_AUTO, addba_maxtries, CTLFLAG_RW, +SYSCTL_INT(_net_wlan, OID_AUTO, addba_maxtries, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_addba_maxtries, 0, "max ADDBA requests sent before backoff"); #ifdef IEEE80211_SUPPORT_SUPERG extern int ieee80211_ffppsmin; -SYSCTL_INT(_net_wlan, OID_AUTO, ffppsmin, CTLFLAG_RW, +SYSCTL_INT(_net_wlan, OID_AUTO, ffppsmin, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_ffppsmin, 0, "min packet rate before fast-frame staging"); extern int ieee80211_ffagemax; -SYSCTL_PROC(_net_wlan, OID_AUTO, ffagemax, CTLFLAG_RW, +SYSCTL_PROC(_net_wlan, OID_AUTO, ffagemax, CTLTYPE_INT | CTLFLAG_RW, &ieee80211_ffagemax, 0, ieee80211_sysctl_msecs_ticks, "I", "max hold time for fast-frame staging (ms)"); #endif /* IEEE80211_SUPPORT_SUPERG */ From 7ad9c533ef2daf7150841d32dd40bf75a0fb37ae Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 14 May 2009 16:48:25 +0000 Subject: [PATCH 178/544] PowerPC common SMP startup and time base rework. - make mftb() shared, rewrite in C, provide complementary mttb() - adjust SMP startup per the above, additional comments, minor naming changes - eliminate redundant TB defines, other minor cosmetics Reviewed by: marcel, nwhitehorn Obtained from: Freescale, Semihalf --- sys/powerpc/aim/clock.c | 19 ++++----- sys/powerpc/booke/clock.c | 16 -------- sys/powerpc/include/cpufunc.h | 26 +++++++++++- sys/powerpc/include/md_var.h | 3 +- sys/powerpc/include/spr.h | 2 - sys/powerpc/powerpc/mp_machdep.c | 68 ++++++++++++++++++++------------ 6 files changed, 77 insertions(+), 57 deletions(-) diff --git a/sys/powerpc/aim/clock.c b/sys/powerpc/aim/clock.c index 2d3eb6049566..0a5391f7424b 100644 --- a/sys/powerpc/aim/clock.c +++ b/sys/powerpc/aim/clock.c @@ -148,6 +148,14 @@ decr_init(void) mtmsr(msr); } +#ifdef SMP +void +decr_ap_init(void) +{ + +} +#endif + void decr_tc_init(void) { @@ -155,17 +163,6 @@ decr_tc_init(void) tc_init(&decr_timecounter); } -static __inline u_quad_t -mftb(void) -{ - u_long scratch; - u_quad_t tb; - - __asm ("1: mftbu %0; mftb %0+1; mftbu %1; cmpw 0,%0,%1; bne 1b" - : "=r"(tb), "=r"(scratch)); - return tb; -} - static unsigned decr_get_timecount(struct timecounter *tc) { diff --git a/sys/powerpc/booke/clock.c b/sys/powerpc/booke/clock.c index 6c8874122ce1..7f9848e6d977 100644 --- a/sys/powerpc/booke/clock.c +++ b/sys/powerpc/booke/clock.c @@ -151,22 +151,6 @@ decr_init (void) mtmsr(msr); } -static __inline u_quad_t -mftb (void) -{ - u_long scratch; - u_quad_t tb; - - __asm__ __volatile__( - "1: mftbu %0;" - " mftb %0+1;" - " mftbu %1;" - " cmpw 0,%0,%1;" - " bne 1b" - : "=r"(tb), "=r"(scratch)); - return tb; -} - void decr_tc_init(void) { diff --git a/sys/powerpc/include/cpufunc.h b/sys/powerpc/include/cpufunc.h index 66b5df38ad6f..9cdaba028319 100644 --- a/sys/powerpc/include/cpufunc.h +++ b/sys/powerpc/include/cpufunc.h @@ -115,13 +115,37 @@ mfdec(void) static __inline register_t mfpvr(void) { - register_t value; + register_t value; __asm __volatile ("mfpvr %0" : "=r"(value)); return (value); } +static __inline u_quad_t +mftb(void) +{ + u_quad_t tb; + uint32_t *tbup = (uint32_t *)&tb; + uint32_t *tblp = tbup + 1; + + do { + *tbup = mfspr(TBR_TBU); + *tblp = mfspr(TBR_TBL); + } while (*tbup != mfspr(TBR_TBU)); + + return (tb); +} + +static __inline void +mttb(u_quad_t time) +{ + + mtspr(TBR_TBWL, 0); + mtspr(TBR_TBWU, (uint32_t)(time >> 32)); + mtspr(TBR_TBWL, (uint32_t)(time & 0xffffffff)); +} + static __inline void eieio(void) { diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h index ec81e6cd2360..d1785adfbe0f 100644 --- a/sys/powerpc/include/md_var.h +++ b/sys/powerpc/include/md_var.h @@ -56,11 +56,12 @@ int is_physical_memory(vm_offset_t addr); int mem_valid(vm_offset_t addr, int len); void decr_init(void); +void decr_ap_init(void); void decr_tc_init(void); void cpu_setup(u_int); -struct trapframe; +struct trapframe; void powerpc_interrupt(struct trapframe *); #endif /* !_MACHINE_MD_VAR_H_ */ diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 82f734b4646f..098c78c352db 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -129,8 +129,6 @@ #define SPR_SPRG7 0x117 /* 4.. SPR General 7 */ #define SPR_ASR 0x118 /* ... Address Space Register (PPC64) */ #define SPR_EAR 0x11a /* .68 External Access Register */ -#define SPR_TBL 0x11c /* 468 Time Base Lower */ -#define SPR_TBU 0x11d /* 468 Time Base Upper */ #define SPR_PVR 0x11f /* 468 Processor Version Register */ #define MPC601 0x0001 #define MPC603 0x0003 diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index cbaa400130a0..0dbbced06cdd 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -40,6 +41,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include "pic_if.h" @@ -47,30 +49,35 @@ __FBSDID("$FreeBSD$"); extern struct pcpu __pcpu[MAXCPU]; volatile static int ap_awake; -volatile static u_int ap_state; +volatile static u_int ap_letgo; volatile static uint32_t ap_decr; -volatile static uint32_t ap_tbl; +volatile static u_quad_t ap_timebase; +static u_int ipi_msg_cnt[32]; void machdep_ap_bootstrap(void) { - pcpup->pc_awake = 1; + PCPU_SET(pir, mfspr(SPR_PIR)); + PCPU_SET(awake, 1); + __asm __volatile("msync; isync"); - while (ap_state == 0) + while (ap_letgo == 0) ; - mtspr(SPR_TBL, 0); - mtspr(SPR_TBU, 0); - mtspr(SPR_TBL, ap_tbl); + /* Initialize DEC and TB, sync with the BSP values */ + decr_ap_init(); + mttb(ap_timebase); __asm __volatile("mtdec %0" :: "r"(ap_decr)); - ap_awake++; + atomic_add_int(&ap_awake, 1); + CTR1(KTR_SMP, "SMP: AP CPU%d launched", PCPU_GET(cpuid)); - /* Initialize curthread. */ + /* Initialize curthread */ PCPU_SET(curthread, PCPU_GET(idlethread)); PCPU_SET(curpcb, curthread->td_pcb); + /* Let the DEC and external interrupts go */ mtmsr(mfmsr() | PSL_EE); sched_throw(NULL); } @@ -149,8 +156,7 @@ cpu_mp_start(void) pc->pc_cpumask = 1 << pc->pc_cpuid; pc->pc_hwref = cpu.cr_hwref; all_cpus |= pc->pc_cpumask; - - next: +next: error = platform_smp_next_cpu(&cpu); } } @@ -176,7 +182,7 @@ static void cpu_mp_unleash(void *dummy) { struct pcpu *pc; - int cpus; + int cpus, timeout; if (mp_ncpus <= 1) return; @@ -187,35 +193,47 @@ cpu_mp_unleash(void *dummy) cpus++; pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask; if (!pc->pc_bsp) { - printf("Waking up CPU %d (dev=%x)\n", pc->pc_cpuid, - pc->pc_hwref); + if (bootverbose) + printf("Waking up CPU %d (dev=%x)\n", + pc->pc_cpuid, pc->pc_hwref); + platform_smp_start_cpu(pc); + + timeout = 2000; /* wait 2sec for the AP */ + while (!pc->pc_awake && --timeout > 0) + DELAY(1000); + } else { - __asm __volatile("mfspr %0,1023" : "=r"(pc->pc_pir)); + PCPU_SET(pir, mfspr(SPR_PIR)); pc->pc_awake = 1; } - if (pc->pc_awake) + if (pc->pc_awake) { + if (bootverbose) + printf("Adding CPU %d, pir=%x, awake=%x\n", + pc->pc_cpuid, pc->pc_pir, pc->pc_awake); smp_cpus++; + } else + stopped_cpus |= (1 << pc->pc_cpuid); } ap_awake = 1; - __asm __volatile("mftb %0" : "=r"(ap_tbl)); - ap_tbl += 10; + /* Provide our current DEC and TB values for APs */ __asm __volatile("mfdec %0" : "=r"(ap_decr)); - ap_state++; - powerpc_sync(); + ap_timebase = mftb() + 10; + __asm __volatile("msync; isync"); + + /* Let APs continue */ + atomic_store_rel_int(&ap_letgo, 1); - mtspr(SPR_TBL, 0); - mtspr(SPR_TBU, 0); - mtspr(SPR_TBL, ap_tbl); + mttb(ap_timebase); while (ap_awake < smp_cpus) ; if (smp_cpus != cpus || cpus != mp_ncpus) { printf("SMP: %d CPUs found; %d CPUs usable; %d CPUs woken\n", - mp_ncpus, cpus, smp_cpus); + mp_ncpus, cpus, smp_cpus); } smp_active = 1; @@ -224,8 +242,6 @@ cpu_mp_unleash(void *dummy) SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, cpu_mp_unleash, NULL); -static u_int ipi_msg_cnt[32]; - int powerpc_ipi_handler(void *arg) { From a72778d6faa695b2762f6bfeb3f067b24a916fb7 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 14 May 2009 16:56:56 +0000 Subject: [PATCH 179/544] Improve style(9) --- sys/powerpc/include/cpufunc.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/powerpc/include/cpufunc.h b/sys/powerpc/include/cpufunc.h index 9cdaba028319..2bf1161a29f9 100644 --- a/sys/powerpc/include/cpufunc.h +++ b/sys/powerpc/include/cpufunc.h @@ -71,7 +71,7 @@ mtmsr(register_t value) static __inline register_t mfmsr(void) { - register_t value; + register_t value; __asm __volatile ("mfmsr %0" : "=r"(value)); @@ -88,7 +88,7 @@ mtsrin(vm_offset_t va, register_t value) static __inline register_t mfsrin(vm_offset_t va) { - register_t value; + register_t value; __asm __volatile ("mfsrin %0,%1" : "=r"(value) : "r"(va)); @@ -105,7 +105,7 @@ mtdec(register_t value) static __inline register_t mfdec(void) { - register_t value; + register_t value; __asm __volatile ("mfdec %0" : "=r"(value)); @@ -170,7 +170,7 @@ powerpc_sync(void) static __inline register_t intr_disable(void) { - register_t msr; + register_t msr; msr = mfmsr(); mtmsr(msr & ~PSL_EE); @@ -187,11 +187,11 @@ intr_restore(register_t msr) static __inline struct pcpu * powerpc_get_pcpup(void) { - struct pcpu *ret; + struct pcpu *ret; __asm __volatile("mfsprg %0, 0" : "=r"(ret)); - return(ret); + return (ret); } #endif /* _KERNEL */ From b7ced94c8cd5fe9e1a73a2c0dec3e1e469a71259 Mon Sep 17 00:00:00 2001 From: Maksim Yevmenkin Date: Thu, 14 May 2009 17:10:19 +0000 Subject: [PATCH 180/544] Avoid floating point arithmetic while calculating iquiry length. Submitted by: Iain Hibbert < plunky -at- rya-online -dot- net > MFC after: 1 week --- lib/libbluetooth/hci.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/lib/libbluetooth/hci.c b/lib/libbluetooth/hci.c index 74c3e632ea8f..1ae6ff963d7b 100644 --- a/lib/libbluetooth/hci.c +++ b/lib/libbluetooth/hci.c @@ -410,7 +410,6 @@ bt_devinquiry(char const *devname, time_t length, int num_rsp, ng_hci_inquiry_response *ir; struct bt_devinquiry *i; int s, n; - time_t to; if (ii == NULL) { errno = EINVAL; @@ -452,16 +451,20 @@ bt_devinquiry(char const *devname, time_t length, int num_rsp, cp->lap[1] = 0x8b; cp->lap[2] = 0x9e; - /* Calculate inquire length in 1.28 second units */ - to = (time_t) ((double) length / 1.28); - if (to <= 0) - cp->inquiry_length = 4; /* 5.12 seconds */ - else if (to > 254) - cp->inquiry_length = 255; /* 326.40 seconds */ - else - cp->inquiry_length = to + 1; + /* + * Calculate inquire length in 1.28 second units + * v2.x specification says that 1.28 -> 61.44 seconds + * range is acceptable + */ - to = (time_t)((double) cp->inquiry_length * 1.28) + 1; + if (length <= 0) + length = 5; + else if (length == 1) + length = 2; + else if (length > 62) + length = 62; + + cp->inquiry_length = (uint8_t)((length * 100) / 128); if (num_rsp <= 0 || num_rsp > 255) num_rsp = 8; @@ -484,7 +487,7 @@ bt_devinquiry(char const *devname, time_t length, int num_rsp, wait_for_more: - n = bt_devrecv(s, buf, sizeof(buf), to); + n = bt_devrecv(s, buf, sizeof(buf), length); if (n < 0) { free(i); bt_devclose(s); From 120b18d86f71999b83e520b8dc4e089a6bfcca38 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Thu, 14 May 2009 17:43:00 +0000 Subject: [PATCH 181/544] FreeBSD right now support 32 CPUs on all the architectures at least. With the arrival of 128+ cores it is necessary to handle more than that. One of the first thing to change is the support for cpumask_t that needs to handle more than 32 bits masking (which happens now). Some places, however, still assume that cpumask_t is a 32 bits mask. Fix that situation by using always correctly cpumask_t when needed. While here, remove the part under STOP_NMI for the Xen support as it is broken in any case. Additively make ipi_nmi_pending as static. Reviewed by: jhb, kmacy Tested by: Giovanni Trematerra --- sys/amd64/amd64/mp_machdep.c | 20 ++++---- sys/amd64/include/smp.h | 8 ++-- sys/gnu/fs/xfs/FreeBSD/support/debug.h | 1 - sys/i386/i386/mp_machdep.c | 18 +++---- sys/i386/i386/pmap.c | 9 ++-- sys/i386/include/smp.h | 6 +-- sys/i386/xen/mp_machdep.c | 66 ++------------------------ 7 files changed, 35 insertions(+), 93 deletions(-) diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index f398a24b20c9..a989d10b7ec1 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -114,9 +114,9 @@ volatile int smp_tlb_wait; extern inthand_t IDTVEC(fast_syscall), IDTVEC(fast_syscall32); #ifdef STOP_NMI -volatile cpumask_t ipi_nmi_pending; +static volatile cpumask_t ipi_nmi_pending; -static void ipi_nmi_selected(u_int32_t cpus); +static void ipi_nmi_selected(cpumask_t cpus); #endif /* @@ -1016,7 +1016,7 @@ smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) } static void -smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) +smp_targeted_tlb_shootdown(cpumask_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) { int ncpu, othercpus; @@ -1090,7 +1090,7 @@ smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2) } void -smp_masked_invltlb(u_int mask) +smp_masked_invltlb(cpumask_t mask) { if (smp_started) { @@ -1099,7 +1099,7 @@ smp_masked_invltlb(u_int mask) } void -smp_masked_invlpg(u_int mask, vm_offset_t addr) +smp_masked_invlpg(cpumask_t mask, vm_offset_t addr) { if (smp_started) { @@ -1108,7 +1108,7 @@ smp_masked_invlpg(u_int mask, vm_offset_t addr) } void -smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2) +smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2) { if (smp_started) { @@ -1143,7 +1143,7 @@ ipi_bitmap_handler(struct trapframe frame) * send an IPI to a set of cpus. */ void -ipi_selected(u_int32_t cpus, u_int ipi) +ipi_selected(cpumask_t cpus, u_int ipi) { int cpu; u_int bitmap = 0; @@ -1206,8 +1206,8 @@ ipi_all_but_self(u_int ipi) #define BEFORE_SPIN 1000000 -void -ipi_nmi_selected(u_int32_t cpus) +static void +ipi_nmi_selected(cpumask_t cpus) { int cpu; register_t icrlo; @@ -1331,7 +1331,7 @@ SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); static int sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) { - u_int mask; + cpumask_t mask; int error; mask = hlt_cpus_mask; diff --git a/sys/amd64/include/smp.h b/sys/amd64/include/smp.h index 0a0e510a6a5d..d29571580275 100644 --- a/sys/amd64/include/smp.h +++ b/sys/amd64/include/smp.h @@ -52,19 +52,19 @@ void cpu_add(u_int apic_id, char boot_cpu); void cpustop_handler(void); void cpususpend_handler(void); void init_secondary(void); -void ipi_selected(u_int cpus, u_int ipi); +void ipi_selected(cpumask_t cpus, u_int ipi); void ipi_all_but_self(u_int ipi); void ipi_bitmap_handler(struct trapframe frame); u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); void smp_cache_flush(void); void smp_invlpg(vm_offset_t addr); -void smp_masked_invlpg(u_int mask, vm_offset_t addr); +void smp_masked_invlpg(cpumask_t mask, vm_offset_t addr); void smp_invlpg_range(vm_offset_t startva, vm_offset_t endva); -void smp_masked_invlpg_range(u_int mask, vm_offset_t startva, +void smp_masked_invlpg_range(cpumask_t mask, vm_offset_t startva, vm_offset_t endva); void smp_invltlb(void); -void smp_masked_invltlb(u_int mask); +void smp_masked_invltlb(cpumask_t mask); #ifdef STOP_NMI int ipi_nmi_handler(void); diff --git a/sys/gnu/fs/xfs/FreeBSD/support/debug.h b/sys/gnu/fs/xfs/FreeBSD/support/debug.h index d35b14fe6d4e..816a717c1345 100644 --- a/sys/gnu/fs/xfs/FreeBSD/support/debug.h +++ b/sys/gnu/fs/xfs/FreeBSD/support/debug.h @@ -75,6 +75,5 @@ extern int get_thread_id(void); #endif #define ASSERT_ALWAYS(EX) ((EX)?((void)0):assfail(#EX, __FILE__, __LINE__)) -#define debug_stop_all_cpus(param) /* param is "cpumask_t *" */ #endif /* __XFS_SUPPORT_DEBUG_H__ */ diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c index 4495a5735311..c233f2547dd4 100644 --- a/sys/i386/i386/mp_machdep.c +++ b/sys/i386/i386/mp_machdep.c @@ -155,9 +155,9 @@ vm_offset_t smp_tlb_addr2; volatile int smp_tlb_wait; #ifdef STOP_NMI -volatile cpumask_t ipi_nmi_pending; +static volatile cpumask_t ipi_nmi_pending; -static void ipi_nmi_selected(u_int32_t cpus); +static void ipi_nmi_selected(cpumask_t cpus); #endif #ifdef COUNT_IPIS @@ -1146,7 +1146,7 @@ smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) } static void -smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) +smp_targeted_tlb_shootdown(cpumask_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) { int ncpu, othercpus; @@ -1231,7 +1231,7 @@ smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2) } void -smp_masked_invltlb(u_int mask) +smp_masked_invltlb(cpumask_t mask) { if (smp_started) { @@ -1243,7 +1243,7 @@ smp_masked_invltlb(u_int mask) } void -smp_masked_invlpg(u_int mask, vm_offset_t addr) +smp_masked_invlpg(cpumask_t mask, vm_offset_t addr) { if (smp_started) { @@ -1255,7 +1255,7 @@ smp_masked_invlpg(u_int mask, vm_offset_t addr) } void -smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2) +smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2) { if (smp_started) { @@ -1303,7 +1303,7 @@ ipi_bitmap_handler(struct trapframe frame) * send an IPI to a set of cpus. */ void -ipi_selected(u_int32_t cpus, u_int ipi) +ipi_selected(cpumask_t cpus, u_int ipi) { int cpu; u_int bitmap = 0; @@ -1367,7 +1367,7 @@ ipi_all_but_self(u_int ipi) #define BEFORE_SPIN 1000000 void -ipi_nmi_selected(u_int32_t cpus) +ipi_nmi_selected(cpumask_t cpus) { int cpu; register_t icrlo; @@ -1456,7 +1456,7 @@ SYSINIT(start_aps, SI_SUB_SMP, SI_ORDER_FIRST, release_aps, NULL); static int sysctl_hlt_cpus(SYSCTL_HANDLER_ARGS) { - u_int mask; + cpumask_t mask; int error; mask = hlt_cpus_mask; diff --git a/sys/i386/i386/pmap.c b/sys/i386/i386/pmap.c index 5f016d5a6f7a..5d7dc979a9cd 100644 --- a/sys/i386/i386/pmap.c +++ b/sys/i386/i386/pmap.c @@ -1624,7 +1624,7 @@ pmap_allocpte(pmap_t pmap, vm_offset_t va, int flags) * Deal with a SMP shootdown of other users of the pmap that we are * trying to dispose of. This can be a bit hairy. */ -static u_int *lazymask; +static cpumask_t *lazymask; static u_int lazyptd; static volatile u_int lazywait; @@ -1633,7 +1633,7 @@ void pmap_lazyfix_action(void); void pmap_lazyfix_action(void) { - u_int mymask = PCPU_GET(cpumask); + cpumask_t mymask = PCPU_GET(cpumask); #ifdef COUNT_IPIS (*ipi_lazypmap_counts[PCPU_GET(cpuid)])++; @@ -1645,7 +1645,7 @@ pmap_lazyfix_action(void) } static void -pmap_lazyfix_self(u_int mymask) +pmap_lazyfix_self(cpumask_t mymask) { if (rcr3() == lazyptd) @@ -1657,8 +1657,7 @@ pmap_lazyfix_self(u_int mymask) static void pmap_lazyfix(pmap_t pmap) { - u_int mymask; - u_int mask; + cpumask_t mymask, mask; u_int spins; while ((mask = pmap->pm_active) != 0) { diff --git a/sys/i386/include/smp.h b/sys/i386/include/smp.h index 33739ccf7c93..917c2851eee1 100644 --- a/sys/i386/include/smp.h +++ b/sys/i386/include/smp.h @@ -69,12 +69,12 @@ u_int mp_bootaddress(u_int); int mp_grab_cpu_hlt(void); void smp_cache_flush(void); void smp_invlpg(vm_offset_t addr); -void smp_masked_invlpg(u_int mask, vm_offset_t addr); +void smp_masked_invlpg(cpumask_t mask, vm_offset_t addr); void smp_invlpg_range(vm_offset_t startva, vm_offset_t endva); -void smp_masked_invlpg_range(u_int mask, vm_offset_t startva, +void smp_masked_invlpg_range(cpumask_t mask, vm_offset_t startva, vm_offset_t endva); void smp_invltlb(void); -void smp_masked_invltlb(u_int mask); +void smp_masked_invltlb(cpumask_t mask); #ifdef STOP_NMI int ipi_nmi_handler(void); diff --git a/sys/i386/xen/mp_machdep.c b/sys/i386/xen/mp_machdep.c index 7af4437f2472..d8e1eea1a1ae 100644 --- a/sys/i386/xen/mp_machdep.c +++ b/sys/i386/xen/mp_machdep.c @@ -993,7 +993,7 @@ smp_tlb_shootdown(u_int vector, vm_offset_t addr1, vm_offset_t addr2) } static void -smp_targeted_tlb_shootdown(u_int mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) +smp_targeted_tlb_shootdown(cpumask_t mask, u_int vector, vm_offset_t addr1, vm_offset_t addr2) { int ncpu, othercpus; struct _call_data data; @@ -1072,7 +1072,7 @@ smp_invlpg_range(vm_offset_t addr1, vm_offset_t addr2) } void -smp_masked_invltlb(u_int mask) +smp_masked_invltlb(cpumask_t mask) { if (smp_started) { @@ -1081,7 +1081,7 @@ smp_masked_invltlb(u_int mask) } void -smp_masked_invlpg(u_int mask, vm_offset_t addr) +smp_masked_invlpg(cpumask_t mask, vm_offset_t addr) { if (smp_started) { @@ -1090,7 +1090,7 @@ smp_masked_invlpg(u_int mask, vm_offset_t addr) } void -smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2) +smp_masked_invlpg_range(cpumask_t mask, vm_offset_t addr1, vm_offset_t addr2) { if (smp_started) { @@ -1102,7 +1102,7 @@ smp_masked_invlpg_range(u_int mask, vm_offset_t addr1, vm_offset_t addr2) * send an IPI to a set of cpus. */ void -ipi_selected(uint32_t cpus, u_int ipi) +ipi_selected(cpumask_t cpus, u_int ipi) { int cpu; u_int bitmap = 0; @@ -1114,12 +1114,6 @@ ipi_selected(uint32_t cpus, u_int ipi) ipi = IPI_BITMAP_VECTOR; } -#ifdef STOP_NMI - if (ipi == IPI_STOP && stop_cpus_with_nmi) { - ipi_nmi_selected(cpus); - return; - } -#endif CTR3(KTR_SMP, "%s: cpus: %x ipi: %x", __func__, cpus, ipi); while ((cpu = ffs(cpus)) != 0) { cpu--; @@ -1160,56 +1154,6 @@ ipi_all_but_self(u_int ipi) ipi_selected(PCPU_GET(other_cpus), ipi); } -#ifdef STOP_NMI -/* - * send NMI IPI to selected CPUs - */ - -#define BEFORE_SPIN 1000000 - -void -ipi_nmi_selected(u_int32_t cpus) -{ - int cpu; - register_t icrlo; - - icrlo = APIC_DELMODE_NMI | APIC_DESTMODE_PHY | APIC_LEVEL_ASSERT - | APIC_TRIGMOD_EDGE; - - CTR2(KTR_SMP, "%s: cpus: %x nmi", __func__, cpus); - - atomic_set_int(&ipi_nmi_pending, cpus); - - while ((cpu = ffs(cpus)) != 0) { - cpu--; - cpus &= ~(1 << cpu); - - KASSERT(cpu_apic_ids[cpu] != -1, - ("IPI NMI to non-existent CPU %d", cpu)); - - /* Wait for an earlier IPI to finish. */ - if (!lapic_ipi_wait(BEFORE_SPIN)) - panic("ipi_nmi_selected: previous IPI has not cleared"); - - lapic_ipi_raw(icrlo, cpu_apic_ids[cpu]); - } -} - -int -ipi_nmi_handler(void) -{ - int cpumask = PCPU_GET(cpumask); - - if (!(ipi_nmi_pending & cpumask)) - return 1; - - atomic_clear_int(&ipi_nmi_pending, cpumask); - cpustop_handler(); - return 0; -} - -#endif /* STOP_NMI */ - /* * Handle an IPI_STOP by saving our current context and spinning until we * are resumed. From cec6336717d79eeb368b4305de55f7a330ea9396 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 14 May 2009 20:39:09 +0000 Subject: [PATCH 182/544] Change the file names in the comments in sys/fs/nfs/nfs_var.h so that they are the names used in FreeBSD-CURRENT. Also shuffled a few entries around, so that they under the correct comment. Approved by: kib (mentor) --- sys/fs/nfs/nfs_var.h | 64 +++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index b41e0a679009..0f545a31f89f 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -85,7 +85,7 @@ NFS_LOOKUP_ARGS; NFS_READDIR_ARGS; #endif -/* nfsd_srvstate.c */ +/* nfs_nfsdstate.c */ int nfsrv_setclient(struct nfsrv_descript *, struct nfsclient **, nfsquad_t *, nfsquad_t *, NFSPROC_T *); int nfsrv_getclient(nfsquad_t, int, struct nfsclient **, nfsquad_t, @@ -125,7 +125,7 @@ int nfsrv_checkgetattr(struct nfsrv_descript *, vnode_t, int nfsrv_nfsuserdport(u_short, NFSPROC_T *); void nfsrv_nfsuserddelport(void); -/* nfsd_serv.c */ +/* nfs_nfsdserv.c */ int nfsrvd_access(struct nfsrv_descript *, int, vnode_t, NFSPROC_T *, struct nfsexstuff *); int nfsrvd_getattr(struct nfsrv_descript *, int, @@ -209,23 +209,11 @@ int nfsrvd_releaselckown(struct nfsrv_descript *, int, int nfsrvd_pathconf(struct nfsrv_descript *, int, vnode_t, NFSPROC_T *, struct nfsexstuff *); -/* newnfs_socket.c */ -int newnfs_request(struct nfsrv_descript *, struct nfsmount *, - struct nfsclient *, struct nfssockreq *, vnode_t, NFSPROC_T *, - struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *); -int newnfs_connect(struct nfsmount *, struct nfssockreq *, - struct ucred *, NFSPROC_T *, int); -void newnfs_disconnect(struct nfssockreq *); -void newnfs_timer(void *); -int newnfs_sigintr(struct nfsmount *, NFSPROC_T *); -int newnfs_sndlock(int *); -void newnfs_sndunlock(int *); - -/* nfsd_srvsocket.c */ +/* nfs_nfsdsocket.c */ void nfsrvd_rephead(struct nfsrv_descript *); void nfsrvd_dorpc(struct nfsrv_descript *, int, NFSPROC_T *); -/* nfs_srvcache.c */ +/* nfs_nfsdcache.c */ void nfsrvd_initcache(void); int nfsrvd_getcache(struct nfsrv_descript *, struct socket *); struct nfsrvcache *nfsrvd_updatecache(struct nfsrv_descript *, @@ -236,7 +224,7 @@ void nfsrvd_refcache(struct nfsrvcache *); void nfsrvd_derefcache(struct nfsrvcache *); void nfsrvd_delcache(struct nfsrvcache *); -/* newnfs_subs.c */ +/* nfs_commonsubs.c */ void newnfs_init(void); int nfsaddr_match(int, union nethostaddr *, NFSSOCKADDR_T); int nfsaddr2_match(NFSSOCKADDR_T, NFSSOCKADDR_T); @@ -265,8 +253,10 @@ void nfsv4_relref(struct nfsv4lock *); void nfsv4_getref(struct nfsv4lock *, int *, void *); int nfsrv_mtostr(struct nfsrv_descript *, char *, int); int nfsrv_checkutf8(u_int8_t *, int); +int newnfs_sndlock(int *); +void newnfs_sndunlock(int *); -/* nfscl_subs.c */ +/* nfs_clcomsubs.c */ void nfsm_uiombuf(struct nfsrv_descript *, struct uio *, int); void nfscl_reqstart(struct nfsrv_descript *, int, struct nfsmount *, u_int8_t *, int, u_int32_t **); @@ -286,7 +276,7 @@ int nfscl_request(struct nfsrv_descript *, vnode_t, NFSPROC_T *, struct ucred *, void *); void nfsm_stateidtom(struct nfsrv_descript *, nfsv4stateid_t *, int); -/* nfsd_srvsubs.c */ +/* nfs_nfsdsubs.c */ void nfsd_fhtovp(struct nfsrv_descript *, struct nfsrvfh *, vnode_t *, struct nfsexstuff *, mount_t *, int, NFSPROC_T *); @@ -315,13 +305,11 @@ int nfsrv_putreferralattr(struct nfsrv_descript *, nfsattrbit_t *, struct nfsreferral *, int, int *); int nfsrv_parsename(struct nfsrv_descript *, char *, u_long *, NFSPATHLEN_T *); - -/* nfs_srvsyscalls.c */ void nfsd_init(void); -/* nfs_vfsops.c */ +/* nfs_clvfsops.c */ -/* newnfs_port.c */ +/* nfs_commonport.c */ int nfsrv_checksockseqnum(struct socket *, tcp_seq); int nfsrv_getsockseqnum(struct socket *, tcp_seq *); int nfsrv_getsocksndseq(struct socket *, tcp_seq *, tcp_seq *); @@ -335,8 +323,9 @@ void newnfs_setroot(struct ucred *); int nfs_catnap(int, const char *); struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t); int nfsrv_atroot(vnode_t, long *); +void newnfs_timer(void *); -/* newnfs_acl.c */ +/* nfs_commonacl.c */ int nfsrv_dissectace(struct nfsrv_descript *, struct acl_entry *, int *, int *, NFSPROC_T *); #ifdef NFS4_ACL_EXTATTR_NAME @@ -349,7 +338,7 @@ int nfsrv_setacl(vnode_t, NFSACL_T *, struct ucred *, int nfsrv_compareacl(NFSACL_T *, NFSACL_T *); #endif -/* nfscl_rpcops.c */ +/* nfs_clrpcops.c */ int nfsrpc_null(vnode_t, struct ucred *, NFSPROC_T *); int nfsrpc_access(vnode_t, int, struct ucred *, NFSPROC_T *, struct nfsvattr *, int *); @@ -436,7 +425,7 @@ int nfsrpc_delegreturn(struct nfscldeleg *, struct ucred *, int nfsrpc_getacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *); int nfsrpc_setacl(vnode_t, struct ucred *, NFSPROC_T *, NFSACL_T *, void *); -/* nfscl_state.c */ +/* nfs_clstate.c */ int nfscl_open(vnode_t, u_int8_t *, int, u_int32_t, int, struct ucred *, NFSPROC_T *, struct nfsclowner **, struct nfsclopen **, int *, int *, int); @@ -494,7 +483,7 @@ int nfscl_tryclose(struct nfsclopen *, struct ucred *, struct nfsmount *, NFSPROC_T *); void nfscl_cleanup(NFSPROC_T *); -/* nfscl_port.c */ +/* nfs_clport.c */ int nfscl_nget(mount_t, vnode_t, struct nfsfh *, struct componentname *, NFSPROC_T *, struct nfsnode **, void *); NFSPROC_T *nfscl_getparent(NFSPROC_T *); @@ -510,16 +499,16 @@ int nfscl_ngetreopen(mount_t, u_int8_t *, int, NFSPROC_T *, int nfscl_procdoesntexist(u_int8_t *); int nfscl_maperr(NFSPROC_T *, int, uid_t, gid_t); -/* nfsclient/ncl_subs.c */ +/* nfs_clsubs.c */ void nfscl_init(void); -/* nfsclient/ncl_bio.c */ +/* nfs_clbio.c */ int ncl_flush(vnode_t, int, struct ucred *, NFSPROC_T *, int); -/* nfsclient/ncl_node.c */ +/* nfs_clnode.c */ void ncl_invalcaches(vnode_t); -/* nfsd/nfsd_port.c */ +/* nfs_nfsdport.c */ int nfsvno_getattr(vnode_t, struct nfsvattr *, struct ucred *, NFSPROC_T *); int nfsvno_setattr(vnode_t, struct nfsvattr *, struct ucred *, @@ -587,18 +576,25 @@ void nfsvno_unlockvfs(mount_t); int nfsvno_lockvfs(mount_t); int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *); -/* newnfs_krpc.c */ +/* nfs_commonkrpc.c */ int newnfs_nmcancelreqs(struct nfsmount *); void newnfs_set_sigmask(struct thread *, sigset_t *); void newnfs_restore_sigmask(struct thread *, sigset_t *); int newnfs_msleep(struct thread *, void *, struct mtx *, int, char *, int); +int newnfs_request(struct nfsrv_descript *, struct nfsmount *, + struct nfsclient *, struct nfssockreq *, vnode_t, NFSPROC_T *, + struct ucred *, u_int32_t, u_int32_t, u_char *, int, u_int64_t *); +int newnfs_connect(struct nfsmount *, struct nfssockreq *, + struct ucred *, NFSPROC_T *, int); +void newnfs_disconnect(struct nfssockreq *); +int newnfs_sigintr(struct nfsmount *, NFSPROC_T *); -/* nfsd_srvkrpc.c */ +/* nfs_nfsdkrpc.c */ int nfsrvd_addsock(struct file *); int nfsrvd_nfsd(NFSPROC_T *, struct nfsd_nfsd_args *); void nfsrvd_init(int); -/* nfscl_srvkrpc.c */ +/* nfs_clkrpc.c */ int nfscbd_addsock(struct file *); int nfscbd_nfsd(NFSPROC_T *, struct nfsd_nfscbd_args *); From 6d888973c8773d11a5e4f90e090b086b3534aaaf Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 14 May 2009 20:59:36 +0000 Subject: [PATCH 183/544] Staticize two functions not used outside of in_pcb.c: in_pcbremlists() and db_print_inpcb(). MFC after: 1 month --- sys/netinet/in_pcb.c | 6 ++++-- sys/netinet/in_pcb.h | 7 ------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index dbc5ca844fba..94460bb0fc14 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -120,6 +120,8 @@ int ipport_tcplastcount; if ((var) < (min)) { (var) = (min); } \ else if ((var) > (max)) { (var) = (max); } +static void in_pcbremlists(struct inpcb *inp); + static int sysctl_net_ipport_check(SYSCTL_HANDLER_ARGS) { @@ -1512,7 +1514,7 @@ in_pcbrehash(struct inpcb *inp) /* * Remove PCB from various lists. */ -void +static void in_pcbremlists(struct inpcb *inp) { struct inpcbinfo *pcbinfo = inp->inp_pcbinfo; @@ -1878,7 +1880,7 @@ db_print_inpvflag(u_char inp_vflag) } } -void +static void db_print_inpcb(struct inpcb *inp, const char *name, int indent) { diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index c86f1abc318d..aa30e43d7460 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -501,14 +501,7 @@ int in_getsockaddr(struct socket *so, struct sockaddr **nam); struct sockaddr * in_sockaddr(in_port_t port, struct in_addr *addr); void in_pcbsosetlabel(struct socket *so); -void in_pcbremlists(struct inpcb *inp); void ipport_tick(void *xtp); - -/* - * Debugging routines compiled in when DDB is present. - */ -void db_print_inpcb(struct inpcb *inp, const char *name, int indent); - #endif /* _KERNEL */ #endif /* !_NETINET_IN_PCB_H_ */ From 98ad44534ecd62815018d265ce490657755c98dc Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 14 May 2009 21:39:08 +0000 Subject: [PATCH 184/544] Apply changes to the experimental nfs server so that it uses the security flavors as exported in FreeBSD-CURRENT. This allows it to use a slightly modified mountd.c instead of a different utility. Approved by: kib (mentor) --- sys/fs/nfs/nfs.h | 13 ++-- sys/fs/nfs/nfs_var.h | 2 + sys/fs/nfs/nfsdport.h | 8 +- sys/fs/nfs/nfsport.h | 5 -- sys/fs/nfsclient/nfs_clkrpc.c | 6 +- sys/fs/nfsserver/nfs_nfsdkrpc.c | 19 ++++- sys/fs/nfsserver/nfs_nfsdport.c | 124 ++++++++++++++++++++++-------- sys/fs/nfsserver/nfs_nfsdserv.c | 52 +++++++++---- sys/fs/nfsserver/nfs_nfsdsocket.c | 3 +- sys/fs/nfsserver/nfs_nfsdsubs.c | 22 ++++++ 10 files changed, 180 insertions(+), 74 deletions(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index b9d030f430f9..14656a5e69ee 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -580,7 +580,6 @@ struct nfsrv_descript { u_int64_t nd_compref; /* Compound RPC ref# */ time_t nd_tcpconntime; /* Time TCP connection est. */ nfsquad_t nd_clientid; /* Implied clientid */ - int nd_credflavor; /* credential flavor */ int nd_gssnamelen; /* principal name length */ char *nd_gssname; /* principal name */ }; @@ -608,8 +607,11 @@ struct nfsrv_descript { #define ND_V4WCCATTR 0x00010000 #define ND_NFSCB 0x00020000 #define ND_AUTHNONE 0x00040000 -#define ND_EXGSSONLY 0x00080000 -#define ND_INCRSEQID 0x00100000 +#define ND_EXAUTHSYS 0x00080000 +#define ND_EXGSS 0x00100000 +#define ND_EXGSSINTEGRITY 0x00200000 +#define ND_EXGSSPRIVACY 0x00400000 +#define ND_INCRSEQID 0x00800000 /* * ND_GSS should be the "or" of all GSS type authentications. @@ -630,11 +632,6 @@ struct nfsv4_opflag { #define NFSRVSEQID_LAST 0x02 #define NFSRVSEQID_OPEN 0x04 -/* - * MNT_EXGSSONLY is the Or of all the EXGSS bits. - */ -#define MNT_EXGSSONLY MNT_EXGSSKRB5 - /* * assign a doubly linked list to a new head * and prepend one list into another. diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 0f545a31f89f..27465e83dfff 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -306,6 +306,7 @@ int nfsrv_putreferralattr(struct nfsrv_descript *, nfsattrbit_t *, int nfsrv_parsename(struct nfsrv_descript *, char *, u_long *, NFSPATHLEN_T *); void nfsd_init(void); +int nfsd_checkrootexp(struct nfsrv_descript *); /* nfs_clvfsops.c */ @@ -575,6 +576,7 @@ int nfsvno_advlock(vnode_t, int, u_int64_t, u_int64_t, NFSPROC_T *); void nfsvno_unlockvfs(mount_t); int nfsvno_lockvfs(mount_t); int nfsrv_v4rootexport(void *, struct ucred *, NFSPROC_T *); +int nfsvno_testexp(struct nfsrv_descript *, struct nfsexstuff *); /* nfs_commonkrpc.c */ int newnfs_nmcancelreqs(struct nfsmount *); diff --git a/sys/fs/nfs/nfsdport.h b/sys/fs/nfs/nfsdport.h index f8ee44585b6b..42dbe082f98e 100644 --- a/sys/fs/nfs/nfsdport.h +++ b/sys/fs/nfs/nfsdport.h @@ -52,8 +52,10 @@ * needs to be returned by nfsd_fhtovp(). */ struct nfsexstuff { - int nes_vfslocked; /* required for all ports */ - int nes_exflag; + int nes_vfslocked; /* required for all ports */ + int nes_exflag; /* export flags */ + int nes_numsecflavor; /* # of security flavors */ + int nes_secflavors[MAXSECFLAVORS]; /* and the flavors */ }; #define NFSVNO_EXINIT(e) ((e)->nes_exflag = 0) @@ -61,11 +63,9 @@ struct nfsexstuff { #define NFSVNO_EXRDONLY(e) ((e)->nes_exflag & MNT_EXRDONLY) #define NFSVNO_EXPORTANON(e) ((e)->nes_exflag & MNT_EXPORTANON) #define NFSVNO_EXSTRICTACCESS(e) ((e)->nes_exflag & MNT_EXSTRICTACCESS) -#define NFSVNO_EXGSSONLY(e) ((e)->nes_exflag & MNT_EXGSSONLY) #define NFSVNO_EXV4ONLY(e) ((e)->nes_exflag & MNT_EXV4ONLY) #define NFSVNO_SETEXRDONLY(e) ((e)->nes_exflag = (MNT_EXPORTED|MNT_EXRDONLY)) -#define NFSVNO_SETEXGSSONLY(e) ((e)->nes_exflag |= MNT_EXGSSONLY) #define NFSVNO_CMPFH(f1, f2) \ ((f1)->fh_fsid.val[0] == (f2)->fh_fsid.val[0] && \ diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index c1c93a59c9c3..5faade90c702 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -644,11 +644,6 @@ struct nfsex_args { struct export_args export; }; -/* - * Define these here, so they don't have to be in mount.h, for now. - */ -#define MNT_EXGSSKRB5 MNT_EXKERB - /* * These export flags should be defined, but there are no bits left. * Maybe a separate mnt_exflag field could be added or the mnt_flag diff --git a/sys/fs/nfsclient/nfs_clkrpc.c b/sys/fs/nfsclient/nfs_clkrpc.c index 7cc2a60b70f3..37e6d58d6f3d 100644 --- a/sys/fs/nfsclient/nfs_clkrpc.c +++ b/sys/fs/nfsclient/nfs_clkrpc.c @@ -66,7 +66,7 @@ static void nfscb_program(struct svc_req *rqst, SVCXPRT *xprt) { struct nfsrv_descript nd; - int cacherep; + int cacherep, credflavor; memset(&nd, 0, sizeof(nd)); if (rqst->rq_proc != NFSPROC_NULL && @@ -94,12 +94,14 @@ nfscb_program(struct svc_req *rqst, SVCXPRT *xprt) nd.nd_cred = NULL; if (nd.nd_procnum != NFSPROC_NULL) { - if (!svc_getcred(rqst, &nd.nd_cred, &nd.nd_credflavor)) { + if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) { svcerr_weakauth(rqst); svc_freereq(rqst); m_freem(nd.nd_mrep); return; } + + /* For now, I don't care what credential flavor was used. */ #ifdef notyet #ifdef MAC mac_cred_associate_nfsd(nd.nd_cred); diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index d9671c4e5bc5..18b6d6d797ed 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -97,7 +97,7 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) { struct nfsrv_descript nd; struct nfsrvcache *rp = NULL; - int cacherep; + int cacherep, credflavor; memset(&nd, 0, sizeof(nd)); if (rqst->rq_vers == NFS_VER2) { @@ -186,12 +186,27 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) } if (nd.nd_procnum != NFSPROC_NULL) { - if (!svc_getcred(rqst, &nd.nd_cred, &nd.nd_credflavor)) { + if (!svc_getcred(rqst, &nd.nd_cred, &credflavor)) { svcerr_weakauth(rqst); svc_freereq(rqst); m_freem(nd.nd_mrep); return; } + + /* Set the flag based on credflavor */ + if (credflavor == RPCSEC_GSS_KRB5) { + nd.nd_flag |= ND_GSS; + } else if (credflavor == RPCSEC_GSS_KRB5I) { + nd.nd_flag |= (ND_GSS | ND_GSSINTEGRITY); + } else if (credflavor == RPCSEC_GSS_KRB5P) { + nd.nd_flag |= (ND_GSS | ND_GSSPRIVACY); + } else if (credflavor != AUTH_SYS) { + svcerr_weakauth(rqst); + svc_freereq(rqst); + m_freem(nd.nd_mrep); + return; + } + #ifdef MAC mac_cred_associate_nfsd(nd.nd_cred); #endif diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 7679eac6ab5d..3a031250dda5 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2352,14 +2352,16 @@ nfsd_excred(struct nfsrv_descript *nd, struct nfsexstuff *exp, * Check/setup credentials. */ if (nd->nd_flag & ND_GSS) - exp->nes_exflag &= ~(MNT_EXGSSONLY | MNT_EXPORTANON); + exp->nes_exflag &= ~MNT_EXPORTANON; /* - * For AUTH_SYS, check to see if it is allowed. + * Check to see if the operation is allowed for this security flavor. * RFC2623 suggests that the NFSv3 Fsinfo RPC be allowed to * AUTH_NONE or AUTH_SYS for file systems requiring RPCSEC_GSS. + * Also, allow Secinfo, so that it can acquire the correct flavor(s). */ - if (NFSVNO_EXGSSONLY(exp) && + if (nfsvno_testexp(nd, exp) && + nd->nd_procnum != NFSV4OP_SECINFO && nd->nd_procnum != NFSPROC_FSINFO) { if (nd->nd_flag & ND_NFSV4) error = NFSERR_WRONGSEC; @@ -2400,14 +2402,20 @@ int nfsvno_checkexp(struct mount *mp, struct sockaddr *nam, struct nfsexstuff *exp, struct ucred **credp) { - int error; - int numsecflavor, *secflavors; + int i, error, *secflavors; error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp, - &numsecflavor, &secflavors); - if (error && nfs_rootfhset) { - exp->nes_exflag = 0; - error = 0; + &exp->nes_numsecflavor, &secflavors); + if (error) { + if (nfs_rootfhset) { + exp->nes_exflag = 0; + exp->nes_numsecflavor = 0; + error = 0; + } + } else { + /* Copy the security flavors. */ + for (i = 0; i < exp->nes_numsecflavor; i++) + exp->nes_secflavors[i] = secflavors[i]; } return (error); } @@ -2419,21 +2427,26 @@ int nfsvno_fhtovp(struct mount *mp, fhandle_t *fhp, struct sockaddr *nam, struct vnode **vpp, struct nfsexstuff *exp, struct ucred **credp) { - int error; - int numsecflavor, *secflavors; + int i, error, *secflavors; *credp = NULL; + exp->nes_numsecflavor = 0; error = VFS_FHTOVP(mp, &fhp->fh_fid, vpp); if (nam && !error) { error = VFS_CHECKEXP(mp, nam, &exp->nes_exflag, credp, - &numsecflavor, &secflavors); + &exp->nes_numsecflavor, &secflavors); if (error) { if (nfs_rootfhset) { exp->nes_exflag = 0; + exp->nes_numsecflavor = 0; error = 0; } else { vput(*vpp); } + } else { + /* Copy the security flavors. */ + for (i = 0; i < exp->nes_numsecflavor; i++) + exp->nes_secflavors[i] = secflavors[i]; } } return (error); @@ -2539,18 +2552,19 @@ nfsd_fhtovp(struct nfsrv_descript *nd, struct nfsrvfh *nfp, */ #ifdef NFS_REQRSVPORT if (!nd->nd_repstat) { - struct sockaddr_in *saddr; - struct sockaddr_in6 *saddr6; - saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *); - saddr6 = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in6 *); - if (!(nd->nd_flag & ND_NFSV4) && - ((saddr->sin_family == AF_INET && - ntohs(saddr->sin_port) >= IPPORT_RESERVED) || - (saddr6->sin6_family == AF_INET6 && - ntohs(saddr6->sin6_port) >= IPPORT_RESERVED))) { - vput(*vpp); - nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK); - } + struct sockaddr_in *saddr; + struct sockaddr_in6 *saddr6; + + saddr = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in *); + saddr6 = NFSSOCKADDR(nd->nd_nam, struct sockaddr_in6 *); + if (!(nd->nd_flag & ND_NFSV4) && + ((saddr->sin_family == AF_INET && + ntohs(saddr->sin_port) >= IPPORT_RESERVED) || + (saddr6->sin6_family == AF_INET6 && + ntohs(saddr6->sin6_port) >= IPPORT_RESERVED))) { + vput(*vpp); + nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK); + } } #endif /* NFS_REQRSVPORT */ @@ -2598,7 +2612,7 @@ fp_getfvp(struct thread *p, int fd, struct file **fpp, struct vnode **vpp) } /* - * Called from newnfssvc() to update the exports list. Just call + * Called from nfssvc() to update the exports list. Just call * vfs_export(). This has to be done, since the v4 root fake fs isn't * in the mount list. */ @@ -2610,11 +2624,6 @@ nfsrv_v4rootexport(void *argp, struct ucred *cred, struct thread *p) struct nameidata nd; fhandle_t fh; - /* - * Until newmountd is using the secflavor fields, just make - * sure it's 0. - */ - nfsexargp->export.ex_numsecflavors = 0; error = vfs_export(&nfsv4root_mnt, &nfsexargp->export); if ((nfsexargp->export.ex_flags & MNT_DELEXPORT)) { nfs_rootfhset = 0; @@ -2843,16 +2852,24 @@ int nfsvno_v4rootexport(struct nfsrv_descript *nd) { struct ucred *credanon; - int exflags, error; + int exflags, error, numsecflavor, *secflavors, i; error = vfs_stdcheckexp(&nfsv4root_mnt, nd->nd_nam, &exflags, - &credanon, NULL, NULL); + &credanon, &numsecflavor, &secflavors); if (error) return (NFSERR_PROGUNAVAIL); - if ((exflags & MNT_EXGSSONLY)) - nd->nd_flag |= ND_EXGSSONLY; if (credanon != NULL) crfree(credanon); + for (i = 0; i < numsecflavor; i++) { + if (secflavors[i] == AUTH_SYS) + nd->nd_flag |= ND_EXAUTHSYS; + else if (secflavors[i] == RPCSEC_GSS_KRB5) + nd->nd_flag |= ND_EXGSS; + else if (secflavors[i] == RPCSEC_GSS_KRB5I) + nd->nd_flag |= ND_EXGSSINTEGRITY; + else if (secflavors[i] == RPCSEC_GSS_KRB5P) + nd->nd_flag |= ND_EXGSSPRIVACY; + } return (0); } @@ -2985,6 +3002,45 @@ nfssvc_srvcall(struct thread *p, struct nfssvc_args *uap, struct ucred *cred) return (error); } +/* + * Check exports. + * Returns 0 if ok, 1 otherwise. + */ +int +nfsvno_testexp(struct nfsrv_descript *nd, struct nfsexstuff *exp) +{ + int i; + + /* + * This seems odd, but allow the case where the security flavor + * list is empty. This happens when NFSv4 is traversing non-exported + * file systems. Exported file systems should always have a non-empty + * security flavor list. + */ + if (exp->nes_numsecflavor == 0) + return (0); + + for (i = 0; i < exp->nes_numsecflavor; i++) { + /* + * The tests for privacy and integrity must be first, + * since ND_GSS is set for everything but AUTH_SYS. + */ + if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5P && + (nd->nd_flag & ND_GSSPRIVACY)) + return (0); + if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5I && + (nd->nd_flag & ND_GSSINTEGRITY)) + return (0); + if (exp->nes_secflavors[i] == RPCSEC_GSS_KRB5 && + (nd->nd_flag & ND_GSS)) + return (0); + if (exp->nes_secflavors[i] == AUTH_SYS && + (nd->nd_flag & ND_GSS) == 0) + return (0); + } + return (1); +} + extern int (*nfsd_call_nfsd)(struct thread *, struct nfssvc_args *); /* diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index 61c646c32f69..f58de7a6b328 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -3090,7 +3090,6 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram, retnes.nes_vfslocked = exp->nes_vfslocked; vput(vp); savflag = nd->nd_flag; - nd->nd_flag |= ND_GSS; /* so nfsd_fhtovp() won't reply Wrongsec */ if (!nd->nd_repstat) { nfsd_fhtovp(nd, &fh, &vp, &retnes, &mp, 0, p); if (vp) @@ -3106,20 +3105,39 @@ nfsrvd_secinfo(struct nfsrv_descript *nd, int isdgram, */ len = 0; NFSM_BUILD(sizp, u_int32_t *, NFSX_UNSIGNED); - if (!NFSVNO_EXGSSONLY(&retnes)) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(RPCAUTH_UNIX); - len++; - } - for (i = RPCAUTHGSS_SVCNONE; i <= RPCAUTHGSS_SVCPRIVACY; i++) { - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl++ = txdr_unsigned(RPCAUTH_GSS); - (void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str, - nfsgss_mechlist[KERBV_MECH].len); - NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); - *tl++ = txdr_unsigned(GSS_KERBV_QOP); - *tl = txdr_unsigned(i); - len++; + for (i = 0; i < retnes.nes_numsecflavor; i++) { + if (retnes.nes_secflavors[i] == AUTH_SYS) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = txdr_unsigned(RPCAUTH_UNIX); + len++; + } else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl++ = txdr_unsigned(RPCAUTH_GSS); + (void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str, + nfsgss_mechlist[KERBV_MECH].len); + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(GSS_KERBV_QOP); + *tl = txdr_unsigned(RPCAUTHGSS_SVCNONE); + len++; + } else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5I) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl++ = txdr_unsigned(RPCAUTH_GSS); + (void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str, + nfsgss_mechlist[KERBV_MECH].len); + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(GSS_KERBV_QOP); + *tl = txdr_unsigned(RPCAUTHGSS_SVCINTEGRITY); + len++; + } else if (retnes.nes_secflavors[i] == RPCSEC_GSS_KRB5P) { + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl++ = txdr_unsigned(RPCAUTH_GSS); + (void) nfsm_strtom(nd, nfsgss_mechlist[KERBV_MECH].str, + nfsgss_mechlist[KERBV_MECH].len); + NFSM_BUILD(tl, u_int32_t *, 2 * NFSX_UNSIGNED); + *tl++ = txdr_unsigned(GSS_KERBV_QOP); + *tl = txdr_unsigned(RPCAUTHGSS_SVCPRIVACY); + len++; + } } *sizp = txdr_unsigned(len); return (0); @@ -3141,7 +3159,7 @@ nfsrvd_setclientid(struct nfsrv_descript *nd, __unused int isdgram, nfsquad_t clientid, confirm; if ((!nfs_rootfhset && !nfsv4root_set) || - (nd->nd_flag & (ND_GSS | ND_EXGSSONLY)) == ND_EXGSSONLY) { + nfsd_checkrootexp(nd)) { nd->nd_repstat = NFSERR_WRONGSEC; return (0); } @@ -3250,7 +3268,7 @@ nfsrvd_setclientidcfrm(struct nfsrv_descript *nd, nfsquad_t clientid, confirm; if ((!nfs_rootfhset && !nfsv4root_set) || - (nd->nd_flag & (ND_GSS | ND_EXGSSONLY)) == ND_EXGSSONLY) { + nfsd_checkrootexp(nd)) { nd->nd_repstat = NFSERR_WRONGSEC; return (0); } diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index a9c7e8031cd5..54307bc38e43 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -819,8 +819,7 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, op != NFSV4OP_GETFH && op != NFSV4OP_SECINFO) nd->nd_repstat = NFSERR_NOFILEHANDLE; - else if (NFSVNO_EXGSSONLY(&vpnes) && - !(nd->nd_flag & ND_GSS) && + else if (nfsvno_testexp(nd, &vpnes) && op != NFSV4OP_LOOKUP && op != NFSV4OP_GETFH && op != NFSV4OP_GETATTR && diff --git a/sys/fs/nfsserver/nfs_nfsdsubs.c b/sys/fs/nfsserver/nfs_nfsdsubs.c index 51f367a2053d..252eb0d6cba8 100644 --- a/sys/fs/nfsserver/nfs_nfsdsubs.c +++ b/sys/fs/nfsserver/nfs_nfsdsubs.c @@ -2019,3 +2019,25 @@ nfsd_init(void) NFSBZERO(nfs_v2pubfh, NFSX_V2FH); } +/* + * Check the v4 root exports. + * Return 0 if ok, 1 otherwise. + */ +int +nfsd_checkrootexp(struct nfsrv_descript *nd) +{ + + if ((nd->nd_flag & (ND_GSS | ND_EXAUTHSYS)) == ND_EXAUTHSYS) + return (0); + if ((nd->nd_flag & (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) == + (ND_GSSINTEGRITY | ND_EXGSSINTEGRITY)) + return (0); + if ((nd->nd_flag & (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) == + (ND_GSSPRIVACY | ND_EXGSSPRIVACY)) + return (0); + if ((nd->nd_flag & (ND_GSS | ND_GSSINTEGRITY | ND_GSSPRIVACY | + ND_EXGSS)) == (ND_GSS | ND_EXGSS)) + return (0); + return (1); +} + From 76dae094490974235d4b9c8fa6d2a1ccad5904a7 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 14 May 2009 21:53:35 +0000 Subject: [PATCH 185/544] Trim the default set of device hints on i386 and amd64: - Remove vga0 and the disabled uart2/uart3 hints from both platforms. - Remove hints for ISA adv0, bt0, aha0, aic0, ed0, cs0, sn0, ie0, fe0, and le0 from i386. All these hints were marked 'disabled' and thus already did not work "out of the box". Discussed with: imp --- sys/amd64/conf/GENERIC.hints | 9 -------- sys/i386/conf/GENERIC.hints | 42 ------------------------------------ 2 files changed, 51 deletions(-) diff --git a/sys/amd64/conf/GENERIC.hints b/sys/amd64/conf/GENERIC.hints index a6b7196d55ce..d91029ddda7a 100644 --- a/sys/amd64/conf/GENERIC.hints +++ b/sys/amd64/conf/GENERIC.hints @@ -13,7 +13,6 @@ hint.atkbd.0.at="atkbdc" hint.atkbd.0.irq="1" hint.psm.0.at="atkbdc" hint.psm.0.irq="12" -hint.vga.0.at="isa" hint.sc.0.at="isa" hint.sc.0.flags="0x100" hint.uart.0.at="isa" @@ -23,13 +22,5 @@ hint.uart.0.irq="4" hint.uart.1.at="isa" hint.uart.1.port="0x2F8" hint.uart.1.irq="3" -hint.uart.2.at="isa" -hint.uart.2.disabled="1" -hint.uart.2.port="0x3E8" -hint.uart.2.irq="5" -hint.uart.3.at="isa" -hint.uart.3.disabled="1" -hint.uart.3.port="0x2E8" -hint.uart.3.irq="9" hint.ppc.0.at="isa" hint.ppc.0.irq="7" diff --git a/sys/i386/conf/GENERIC.hints b/sys/i386/conf/GENERIC.hints index 4c908882c3ce..8e37ff136838 100644 --- a/sys/i386/conf/GENERIC.hints +++ b/sys/i386/conf/GENERIC.hints @@ -13,21 +13,12 @@ hint.ata.0.irq="14" hint.ata.1.at="isa" hint.ata.1.port="0x170" hint.ata.1.irq="15" -hint.adv.0.at="isa" -hint.adv.0.disabled="1" -hint.bt.0.at="isa" -hint.bt.0.disabled="1" -hint.aha.0.at="isa" -hint.aha.0.disabled="1" -hint.aic.0.at="isa" -hint.aic.0.disabled="1" hint.atkbdc.0.at="isa" hint.atkbdc.0.port="0x060" hint.atkbd.0.at="atkbdc" hint.atkbd.0.irq="1" hint.psm.0.at="atkbdc" hint.psm.0.irq="12" -hint.vga.0.at="isa" hint.sc.0.at="isa" hint.sc.0.flags="0x100" hint.apm.0.disabled="1" @@ -39,41 +30,8 @@ hint.uart.0.irq="4" hint.uart.1.at="isa" hint.uart.1.port="0x2F8" hint.uart.1.irq="3" -hint.uart.2.at="isa" -hint.uart.2.disabled="1" -hint.uart.2.port="0x3E8" -hint.uart.2.irq="5" -hint.uart.3.at="isa" -hint.uart.3.disabled="1" -hint.uart.3.port="0x2E8" -hint.uart.3.irq="9" hint.ppc.0.at="isa" hint.ppc.0.irq="7" -hint.ed.0.at="isa" -hint.ed.0.disabled="1" -hint.ed.0.port="0x280" -hint.ed.0.irq="10" -hint.ed.0.maddr="0xd8000" -hint.cs.0.at="isa" -hint.cs.0.disabled="1" -hint.cs.0.port="0x300" -hint.sn.0.at="isa" -hint.sn.0.disabled="1" -hint.sn.0.port="0x300" -hint.sn.0.irq="10" -hint.ie.0.at="isa" -hint.ie.0.disabled="1" -hint.ie.0.port="0x300" -hint.ie.0.irq="10" -hint.ie.0.maddr="0xd0000" -hint.fe.0.at="isa" -hint.fe.0.disabled="1" -hint.fe.0.port="0x300" -hint.le.0.at="isa" -hint.le.0.disabled="1" -hint.le.0.port="0x280" -hint.le.0.irq="10" -hint.le.0.drq="0" hint.atrtc.0.at="isa" hint.atrtc.0.port="0x70" hint.atrtc.0.irq="8" From 3e829b18d6d3f8b4290538c7c76dc34212603852 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 14 May 2009 22:01:32 +0000 Subject: [PATCH 186/544] - Use a separate sx lock to try to limit the number of concurrent userland sysctl requests to avoid wiring too much user memory. Only grab this lock if the user's old buffer is larger than a page as a tradeoff to allow more concurrency for common small requests. - Just use a shared lock on the sysctl tree for user sysctl requests now. MFC after: 1 week --- sys/kern/kern_sysctl.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 89fbb9ab3ee0..bf539bea3bc7 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -77,11 +77,12 @@ static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer"); * API rather than using the dynamic API. Use of the dynamic API is * strongly encouraged for most code. * - * This lock is also used to serialize userland sysctl requests. Some - * sysctls wire user memory, and serializing the requests limits the - * amount of wired user memory in use. + * The sysctlmemlock is used to limit the amount of user memory wired for + * sysctl requests. This is implemented by serializing any userland + * sysctl requests larger than a single page via an exclusive lock. */ static struct sx sysctllock; +static struct sx sysctlmemlock; #define SYSCTL_SLOCK() sx_slock(&sysctllock) #define SYSCTL_SUNLOCK() sx_sunlock(&sysctllock) @@ -543,6 +544,7 @@ sysctl_register_all(void *arg) { struct sysctl_oid **oidp; + sx_init(&sysctlmemlock, "sysctl mem"); SYSCTL_INIT(); SYSCTL_XLOCK(); SET_FOREACH(oidp, sysctl_set) @@ -1565,7 +1567,7 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, size_t *oldlenp, int inkernel, void *new, size_t newlen, size_t *retval, int flags) { - int error = 0; + int error = 0, memlocked; struct sysctl_req req; bzero(&req, sizeof req); @@ -1605,14 +1607,20 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, if (KTRPOINT(curthread, KTR_SYSCTL)) ktrsysctl(name, namelen); #endif - - SYSCTL_XLOCK(); + + if (req.oldlen > PAGE_SIZE) { + memlocked = 1; + sx_xlock(&sysctlmemlock); + } else + memlocked = 0; CURVNET_SET(TD_TO_VNET(curthread)); for (;;) { req.oldidx = 0; req.newidx = 0; + SYSCTL_SLOCK(); error = sysctl_root(0, name, namelen, &req); + SYSCTL_SUNLOCK(); if (error != EAGAIN) break; uio_yield(); @@ -1622,7 +1630,8 @@ userland_sysctl(struct thread *td, int *name, u_int namelen, void *old, if (req.lock == REQ_WIRED && req.validlen > 0) vsunlock(req.oldptr, req.validlen); - SYSCTL_XUNLOCK(); + if (memlocked) + sx_xunlock(&sysctlmemlock); if (error && error != ENOMEM) return (error); From 25e13e689511f12a2e4d5d202cadc51b7cf23f30 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 14 May 2009 22:33:37 +0000 Subject: [PATCH 187/544] Try to workaround a race where bge_stop() may sneak in when bge_rxeof() drops and re-grabs the softc mutex in the middle, resulting in kernel trap 12. This may happen when a lot of traffic is being hammered on one bge(4) interface while the system is shutting down. Reported by: Alexander Sack PR: kern/134548 MFC After: 2 weeks --- sys/dev/bge/if_bge.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 1bfd509d7646..869ded5e4cb6 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -3193,6 +3193,9 @@ bge_rxeof(struct bge_softc *sc) BGE_UNLOCK(sc); (*ifp->if_input)(ifp, m); BGE_LOCK(sc); + + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + return; } if (stdcnt > 0) @@ -3301,6 +3304,10 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) sc->rxcycles = count; bge_rxeof(sc); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + BGE_UNLOCK(sc); + return; + } bge_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) bge_start_locked(ifp); @@ -3370,7 +3377,9 @@ bge_intr(void *xsc) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* Check RX return ring producer/consumer. */ bge_rxeof(sc); + } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { /* Check TX ring producer/consumer. */ bge_txeof(sc); } From 9fe569d8f96e06bca0ca3d21c16c2a714b31a858 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 14 May 2009 22:36:56 +0000 Subject: [PATCH 188/544] Some comment/space changes (FALLTHRU -> FALLTHROUGH, space after while). --- sys/dev/bge/if_bge.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index 869ded5e4cb6..fbda2ba400a7 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -2441,14 +2441,14 @@ bge_attach(device_t dev) case BGE_ASICREV_BCM5780: case BGE_ASICREV_BCM5714: sc->bge_flags |= BGE_FLAG_5714_FAMILY /* | BGE_FLAG_JUMBO */; - /* FALLTHRU */ + /* FALLTHROUGH */ case BGE_ASICREV_BCM5750: case BGE_ASICREV_BCM5752: case BGE_ASICREV_BCM5755: case BGE_ASICREV_BCM5787: case BGE_ASICREV_BCM5906: sc->bge_flags |= BGE_FLAG_575X_PLUS; - /* FALLTHRU */ + /* FALLTHROUGH */ case BGE_ASICREV_BCM5705: sc->bge_flags |= BGE_FLAG_5705_PLUS; break; @@ -3073,7 +3073,7 @@ bge_rxeof(struct bge_softc *sc) bus_dmamap_sync(sc->bge_cdata.bge_rx_jumbo_ring_tag, sc->bge_cdata.bge_rx_jumbo_ring_map, BUS_DMASYNC_POSTREAD); - while(sc->bge_rx_saved_considx != + while (sc->bge_rx_saved_considx != sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) { struct bge_rx_bd *cur_rx; uint32_t rxidx; From 718d3b2852771dc978d19eb0875988d375003e4b Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 14 May 2009 23:09:33 +0000 Subject: [PATCH 189/544] As the comment says, close() frees the variable, record. So we obtain the length by evaluating the value from the copy, cbuf instead. This fixes a crash caused by previous commit (use-after-free) Submitted by: Dimitry Andric Pointy hat to: delphij --- lib/libc/gen/getcap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libc/gen/getcap.c b/lib/libc/gen/getcap.c index d0e4a7bcb748..32d66d484f5f 100644 --- a/lib/libc/gen/getcap.c +++ b/lib/libc/gen/getcap.c @@ -260,7 +260,7 @@ getent(char **cap, u_int *len, char **db_array, int fd, const char *name, errno = ENOMEM; return (-2); } - *len = strlen(record); + *len = strlen(cbuf); *cap = cbuf; return (retval); } else { From 6262c79b70d81b64bca776b77a91aa0aca1e916e Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Fri, 15 May 2009 00:18:31 +0000 Subject: [PATCH 190/544] Allow a comma-separated list of network interfaces to be specified via the netDev option in install.cfg. Submitted by: randi MFC after: 1 week --- usr.sbin/sysinstall/tcpip.c | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/usr.sbin/sysinstall/tcpip.c b/usr.sbin/sysinstall/tcpip.c index 18849fcb1c1b..f505a0581c0d 100644 --- a/usr.sbin/sysinstall/tcpip.c +++ b/usr.sbin/sysinstall/tcpip.c @@ -642,11 +642,26 @@ tcpDeviceSelect(void) { DMenu *menu; Device **devs, *rval; + char *dev, *network_dev; int cnt; + rval = NULL; + + if (variable_get(VAR_NONINTERACTIVE) && variable_get(VAR_NETWORK_DEVICE)) { + network_dev = variable_get(VAR_NETWORK_DEVICE); + + while ((dev = strsep(&network_dev, ",")) != NULL) { + devs = deviceFind(dev, DEVICE_TYPE_NETWORK); + cnt = deviceCount(devs); + if (cnt) { + if (DITEM_STATUS(tcpOpenDialog(devs[0]) == DITEM_SUCCESS)) + return(devs[0]); + } + } + } + devs = deviceFind(variable_get(VAR_NETWORK_DEVICE), DEVICE_TYPE_NETWORK); cnt = deviceCount(devs); - rval = NULL; if (!cnt) { msgConfirm("No network devices available!"); @@ -660,14 +675,6 @@ tcpDeviceSelect(void) if (DITEM_STATUS(tcpOpenDialog(devs[0]) == DITEM_SUCCESS)) rval = devs[0]; } - else if (variable_get(VAR_NONINTERACTIVE) && variable_get(VAR_NETWORK_DEVICE)) { - devs = deviceFind(variable_get(VAR_NETWORK_DEVICE), DEVICE_TYPE_NETWORK); - cnt = deviceCount(devs); - if (cnt) { - if (DITEM_STATUS(tcpOpenDialog(devs[0]) == DITEM_SUCCESS)) - rval = devs[0]; - } - } else { int status; From 42eb41087c96fbfcdcb887c706caf9ab6e689d8f Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 15 May 2009 04:33:35 +0000 Subject: [PATCH 191/544] Eliminate unnecessary clearing of the page's dirty mask from various getpages functions. Eliminate a stale comment. --- sys/fs/smbfs/smbfs_io.c | 4 +++- sys/nfsclient/nfs_bio.c | 4 +++- sys/vm/vnode_pager.c | 11 ++++++----- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/fs/smbfs/smbfs_io.c b/sys/fs/smbfs/smbfs_io.c index 7890f88c185f..4ea192b14f60 100644 --- a/sys/fs/smbfs/smbfs_io.c +++ b/sys/fs/smbfs/smbfs_io.c @@ -524,7 +524,9 @@ smbfs_getpages(ap) * Read operation filled a partial page. */ m->valid = 0; - vm_page_set_validclean(m, 0, size - toff); + vm_page_set_valid(m, 0, size - toff); + KASSERT((m->dirty & vm_page_bits(0, size - toff)) == 0, + ("smbfs_getpages: page %p is dirty", m)); } else { /* * Read operation was short. If no error occured diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index e60a20102b54..6c468fbe6046 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -216,7 +216,9 @@ nfs_getpages(struct vop_getpages_args *ap) * Read operation filled a partial page. */ m->valid = 0; - vm_page_set_validclean(m, 0, size - toff); + vm_page_set_valid(m, 0, size - toff); + KASSERT((m->dirty & vm_page_bits(0, size - toff)) == 0, + ("nfs_getpages: page %p is dirty", m)); } else { /* * Read operation was short. If no error occured diff --git a/sys/vm/vnode_pager.c b/sys/vm/vnode_pager.c index cf9dcb101051..ed09044b3bfa 100644 --- a/sys/vm/vnode_pager.c +++ b/sys/vm/vnode_pager.c @@ -939,17 +939,18 @@ vnode_pager_generic_getpages(vp, m, bytecount, reqpage) mt)); } else { /* - * Read did not fill up entire page. Since this - * is getpages, the page may be mapped, so we have - * to zero the invalid portions of the page even - * though we aren't setting them valid. + * Read did not fill up entire page. * * Currently we do not set the entire page valid, * we just try to clear the piece that we couldn't * read. */ - vm_page_set_validclean(mt, 0, + vm_page_set_valid(mt, 0, object->un_pager.vnp.vnp_size - tfoff); + KASSERT((mt->dirty & vm_page_bits(0, + object->un_pager.vnp.vnp_size - tfoff)) == 0, + ("vnode_pager_generic_getpages: page %p is dirty", + mt)); } if (i != reqpage) { From 940672949e8f17861246f7e3172629eceb4dfa8b Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 15 May 2009 04:49:20 +0000 Subject: [PATCH 192/544] Fix name for driver to assign to the SPI device. --- sys/arm/at91/at91.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/arm/at91/at91.c b/sys/arm/at91/at91.c index 17e466e216b6..222fce062d0d 100644 --- a/sys/arm/at91/at91.c +++ b/sys/arm/at91/at91.c @@ -409,7 +409,7 @@ struct cpu_devs at91rm9200_devs[] = AT91RM92_IRQ_SSC2 }, { - "at91_spi", 0, + "spi", 0, AT91RM92_BASE + AT91RM92_SPI_BASE, AT91RM92_SPI_SIZE, AT91RM92_IRQ_SPI }, From ca23ba6e2e454e90b81af15749b237e2613e22e9 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 15 May 2009 10:06:33 +0000 Subject: [PATCH 193/544] Sort SEE ALSO section, remove trailing dot. --- share/man/man4/ath.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4 index 5b7b356f21a6..19171fff2c40 100644 --- a/share/man/man4/ath.4 +++ b/share/man/man4/ath.4 @@ -266,8 +266,8 @@ This should not happen. .El .Sh SEE ALSO .Xr ath_hal 4 , -.Xr intro 4 , .Xr cardbus 4 , +.Xr intro 4 , .Xr pcic 4 , .Xr wlan 4 , .Xr wlan_ccmp 4 , @@ -276,7 +276,7 @@ This should not happen. .Xr wlan_xauth 4 , .Xr hostapd 8 , .Xr ifconfig 8 , -.Xr wpa_supplicant 8 . +.Xr wpa_supplicant 8 .Sh HISTORY The .Nm From 7042d357827be20541b09ab1233cc9b1552f1fb6 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 15 May 2009 10:11:54 +0000 Subject: [PATCH 194/544] Xref missing wlan drivers. --- share/man/man4/wlan.4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/man/man4/wlan.4 b/share/man/man4/wlan.4 index 93d18ec09947..dffefabc4563 100644 --- a/share/man/man4/wlan.4 +++ b/share/man/man4/wlan.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 26, 2009 +.Dd May 15, 2009 .Dt WLAN 4 .Os .Sh NAME @@ -164,6 +164,7 @@ was used to be compatible with .Sh SEE ALSO .Xr an 4 , .Xr ath 4 , +.Xr bwi 4 , .Xr ipw 4 , .Xr iwi 4 , .Xr iwn 4 , @@ -171,7 +172,10 @@ was used to be compatible with .Xr netintro 4 , .Xr ral 4 , .Xr rum 4 , +.Xr uath 4 , +.Xr upgt 4 , .Xr ural 4 , +.Xr urtw 4 , .Xr wi 4 , .Xr wlan_acl 4 , .Xr wlan_ccmp 4 , From a9754a7538f0db267c50c8354263dab12ae5666b Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 15 May 2009 13:26:54 +0000 Subject: [PATCH 195/544] This driver can be loaded as a module now. MFC after: 3 days --- share/man/man4/uchcom.4 | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/share/man/man4/uchcom.4 b/share/man/man4/uchcom.4 index 6b127ae3a2a2..456833964364 100644 --- a/share/man/man4/uchcom.4 +++ b/share/man/man4/uchcom.4 @@ -36,7 +36,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 1, 2008 +.Dd May 15, 2009 .Dt UCHCOM 4 .Os .Sh NAME @@ -50,13 +50,13 @@ kernel configuration file: .Cd "device uchcom" .Cd "device ucom" .Ed -.\".Pp -.\"Alternatively, to load the driver as a -.\"module at boot time, place the following line in -.\".Xr loader.conf 5 : -.\".Bd -literal -offset indent -.\"uchcom_load="YES" -.\".Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +uchcom_load="YES" +.Ed .Sh DESCRIPTION The .Nm From 983d12f39bb7be63481ca7137b3a5b72b619cc23 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Fri, 15 May 2009 14:30:37 +0000 Subject: [PATCH 196/544] Turn consolectl into a simple device node, not a TTY. Apart from the 16 virtual terminals, Syscons allocates two device nodes that should not really be TTYs, even though they are. One of them is consolectl. In RELENG_7 and before, these device nodes are used in single user mode. After I simplified input path, we only use this device node to call ioctl() on (moused, Xorg, vidcontrol). When you call ioctl() on consolectl, it will behave the same as being called on the first window. --- sys/dev/syscons/syscons.c | 46 ++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c index 77f4e61fed9a..0ba7d7dcac89 100644 --- a/sys/dev/syscons/syscons.c +++ b/sys/dev/syscons/syscons.c @@ -207,7 +207,7 @@ static int save_kbd_state(scr_stat *scp); static int update_kbd_state(scr_stat *scp, int state, int mask); static int update_kbd_leds(scr_stat *scp, int which); static timeout_t blink_screen; -static struct tty *sc_alloc_tty(int, const char *, ...) __printflike(2, 3); +static struct tty *sc_alloc_tty(int, int); static cn_probe_t sc_cnprobe; static cn_init_t sc_cninit; @@ -224,11 +224,6 @@ static tsw_ioctl_t sctty_ioctl; static tsw_mmap_t sctty_mmap; static struct ttydevsw sc_ttydevsw = { - /* - * XXX: we should use the prefix, but this doesn't work for - * consolectl. - */ - .tsw_flags = TF_NOPREFIX, .tsw_open = sctty_open, .tsw_close = sctty_close, .tsw_outwakeup = sctty_outwakeup, @@ -236,6 +231,15 @@ static struct ttydevsw sc_ttydevsw = { .tsw_mmap = sctty_mmap, }; +static d_ioctl_t consolectl_ioctl; + +static struct cdevsw consolectl_devsw = { + .d_version = D_VERSION, + .d_flags = D_NEEDGIANT, + .d_ioctl = consolectl_ioctl, + .d_name = "consolectl", +}; + int sc_probe_unit(int unit, int flags) { @@ -321,14 +325,10 @@ sctty_outwakeup(struct tty *tp) } static struct tty * -sc_alloc_tty(int index, const char *fmt, ...) +sc_alloc_tty(int index, int devnum) { - va_list ap; struct sc_ttysoftc *stc; struct tty *tp; - char name[11]; /* "consolectl" */ - - va_start(ap, fmt); /* Allocate TTY object and softc to store unit number. */ stc = malloc(sizeof(struct sc_ttysoftc), M_DEVBUF, M_WAITOK); @@ -337,10 +337,7 @@ sc_alloc_tty(int index, const char *fmt, ...) tp = tty_alloc(&sc_ttydevsw, stc, &Giant); /* Create device node. */ - va_start(ap, fmt); - vsnrprintf(name, sizeof name, 32, fmt, ap); - va_end(ap); - tty_makedev(tp, NULL, "%s", name); + tty_makedev(tp, NULL, "v%r", devnum); return (tp); } @@ -354,7 +351,7 @@ sc_attach_unit(int unit, int flags) video_info_t info; #endif int vc; - struct tty *tp; + struct cdev *dev; flags &= ~SC_KERNEL_CONSOLE; @@ -425,7 +422,7 @@ sc_attach_unit(int unit, int flags) for (vc = 0; vc < sc->vtys; vc++) { if (sc->dev[vc] == NULL) { - sc->dev[vc] = sc_alloc_tty(vc, "ttyv%r", vc + unit * MAXCONS); + sc->dev[vc] = sc_alloc_tty(vc, vc + unit * MAXCONS); if (vc == 0 && sc->dev == main_devs) SC_STAT(sc->dev[0]) = &main_console; } @@ -436,8 +433,9 @@ sc_attach_unit(int unit, int flags) */ } - tp = sc_alloc_tty(0, "consolectl"); - SC_STAT(tp) = sc_console; + dev = make_dev(&consolectl_devsw, 0, UID_ROOT, GID_WHEEL, 0600, + "consolectl"); + dev->si_drv1 = sc->dev[0]; return 0; } @@ -1428,6 +1426,14 @@ sctty_ioctl(struct tty *tp, u_long cmd, caddr_t data, struct thread *td) return (ENOIOCTL); } +static int +consolectl_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, + struct thread *td) +{ + + return sctty_ioctl(dev->si_drv1, cmd, data, td); +} + static void sc_cnprobe(struct consdev *cp) { @@ -2728,7 +2734,7 @@ scinit(int unit, int flags) /* assert(sc_malloc) */ sc->dev = malloc(sizeof(struct tty *)*sc->vtys, M_DEVBUF, M_WAITOK|M_ZERO); - sc->dev[0] = sc_alloc_tty(0, "ttyv%r", unit * MAXCONS); + sc->dev[0] = sc_alloc_tty(0, unit * MAXCONS); scp = alloc_scp(sc, sc->first_vty); SC_STAT(sc->dev[0]) = scp; } From 6b72d8db472fe8165857b08b4b3f790cadfcc083 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 15 May 2009 14:41:44 +0000 Subject: [PATCH 197/544] Revert r192094. The revision caused problems for sysctl(3) consumers that expect that oldlen is filled with required buffer length even when supplied buffer is too short and returned error is ENOMEM. Redo the fix for kern.proc.filedesc, by reverting the req->oldidx when remaining buffer space is too short for the current kinfo_file structure. Also, only ignore ENOMEM. We have to convert ENOMEM to no error condition to keep existing interface for the sysctl, though. Reported by: ed, Florian Smeets Tested by: pho --- sys/kern/kern_descrip.c | 17 +++++++++++++++-- sys/kern/kern_sysctl.c | 8 +++----- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index f29b0ebdc82d..e0008e666421 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -2883,6 +2883,7 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) struct proc *p; struct tty *tp; int vfslocked; + size_t oldidx; name = (int *)arg1; if ((p = pfind((pid_t)name[0])) == NULL) @@ -3061,14 +3062,26 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS) strlen(kif->kf_path) + 1; kif->kf_structsize = roundup(kif->kf_structsize, sizeof(uint64_t)); + oldidx = req->oldidx; error = SYSCTL_OUT(req, kif, kif->kf_structsize); - if (error) + if (error) { + if (error == ENOMEM) { + /* + * The hack to keep the ABI of sysctl + * kern.proc.filedesc intact, but not + * to account a partially copied + * kinfo_file into the oldidx. + */ + req->oldidx = oldidx; + error = 0; + } break; + } } FILEDESC_SUNLOCK(fdp); fddrop(fdp); free(kif, M_TEMP); - return (0); + return (error); } static SYSCTL_NODE(_kern_proc, KERN_PROC_FILEDESC, filedesc, CTLFLAG_RD, diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index bf539bea3bc7..0a8a096f0a49 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1223,9 +1223,9 @@ sysctl_old_kernel(struct sysctl_req *req, const void *p, size_t l) if (i > 0) bcopy(p, (char *)req->oldptr + req->oldidx, i); } + req->oldidx += l; if (req->oldptr && i != l) return (ENOMEM); - req->oldidx += l; return (0); } @@ -1322,10 +1322,9 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) size_t i, len, origidx; origidx = req->oldidx; - if (req->oldptr == NULL) { - req->oldidx += l; + req->oldidx += l; + if (req->oldptr == NULL) return (0); - } /* * If we have not wired the user supplied buffer and we are currently * holding locks, drop a witness warning, as it's possible that @@ -1347,7 +1346,6 @@ sysctl_old_user(struct sysctl_req *req, const void *p, size_t l) return (error); if (i < l) return (ENOMEM); - req->oldidx += l; return (0); } From d34b41c9c27cd381be7188dbad68658b3b1e7ccd Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 15 May 2009 16:03:11 +0000 Subject: [PATCH 198/544] Modify the diskless booting code in sys/fs/nfsclient to be compatible with what is in sys/nfsclient, so that it will at least build now. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs.h | 2 +- sys/fs/nfsclient/nfs_clvfsops.c | 61 +++++++++++++++++++-------------- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/sys/fs/nfsclient/nfs.h b/sys/fs/nfsclient/nfs.h index d011ffb2ca42..8029a00c2db6 100644 --- a/sys/fs/nfsclient/nfs.h +++ b/sys/fs/nfsclient/nfs.h @@ -87,7 +87,7 @@ int ncl_fsinfo(struct nfsmount *, struct vnode *, struct ucred *, struct thread *); int ncl_init(struct vfsconf *); int ncl_uninit(struct vfsconf *); -int ncl_mountroot(struct mount *, struct thread *); +int ncl_mountroot(struct mount *); int ncl_nfsiodnew(void); #endif /* _KERNEL */ diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 66ea55b8c9ee..992a7644a410 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -135,14 +135,15 @@ struct nfsv3_diskless newnfsv3_diskless = { { { 0 } } }; int newnfs_diskless_valid = 0; SYSCTL_INT(_vfs_newnfs, OID_AUTO, diskless_valid, CTLFLAG_RD, - &newnfs_diskless_valid, 0, ""); + &newnfs_diskless_valid, 0, + "Has the diskless struct been filled correctly"); SYSCTL_STRING(_vfs_newnfs, OID_AUTO, diskless_rootpath, CTLFLAG_RD, - newnfsv3_diskless.root_hostnam, 0, ""); + newnfsv3_diskless.root_hostnam, 0, "Path to nfs root"); SYSCTL_OPAQUE(_vfs_newnfs, OID_AUTO, diskless_rootaddr, CTLFLAG_RD, - &newnfsv3_diskless.root_saddr, sizeof newnfsv3_diskless.root_saddr, - "%Ssockaddr_in", ""); + &newnfsv3_diskless.root_saddr, sizeof newnfsv3_diskless.root_saddr, + "%Ssockaddr_in", "Diskless root nfs address"); void newnfsargs_ntoh(struct nfs_args *); @@ -220,23 +221,27 @@ nfs_convert_diskless(void) { bcopy(&newnfs_diskless.myif, &newnfsv3_diskless.myif, - sizeof(struct ifaliasreq)); + sizeof (struct ifaliasreq)); bcopy(&newnfs_diskless.mygateway, &newnfsv3_diskless.mygateway, - sizeof(struct sockaddr_in)); - nfs_convert_oargs(&newnfsv3_diskless.root_args,&newnfs_diskless.root_args); + sizeof (struct sockaddr_in)); + nfs_convert_oargs(&newnfsv3_diskless.root_args, + &newnfs_diskless.root_args); if (newnfsv3_diskless.root_args.flags & NFSMNT_NFSV3) { newnfsv3_diskless.root_fhsize = NFSX_MYFH; - bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh, NFSX_MYFH); + bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh, + NFSX_MYFH); } else { newnfsv3_diskless.root_fhsize = NFSX_V2FH; - bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh, NFSX_V2FH); + bcopy(newnfs_diskless.root_fh, newnfsv3_diskless.root_fh, + NFSX_V2FH); } bcopy(&newnfs_diskless.root_saddr,&newnfsv3_diskless.root_saddr, - sizeof(struct sockaddr_in)); - bcopy(newnfs_diskless.root_hostnam, newnfsv3_diskless.root_hostnam, MNAMELEN); + sizeof(struct sockaddr_in)); + bcopy(newnfs_diskless.root_hostnam, newnfsv3_diskless.root_hostnam, + MNAMELEN); newnfsv3_diskless.root_time = newnfs_diskless.root_time; bcopy(newnfs_diskless.my_hostnam, newnfsv3_diskless.my_hostnam, - MAXHOSTNAMELEN); + MAXHOSTNAMELEN); newnfs_diskless_valid = 3; } @@ -355,12 +360,14 @@ ncl_fsinfo(struct nfsmount *nmp, struct vnode *vp, struct ucred *cred, * * It is assumed to be safe to read, modify, and write the nfsv3_diskless * structure, as well as other global NFS client variables here, as - * ncl_mountroot() will be called once in the boot before any other NFS + * nfs_mountroot() will be called once in the boot before any other NFS * client activity occurs. */ int -ncl_mountroot(struct mount *mp, struct thread *td) +ncl_mountroot(struct mount *mp) { + struct thread *td = curthread; + INIT_VPROCG(TD_TO_VPROCG(td)); struct nfsv3_diskless *nd = &newnfsv3_diskless; struct socket *so; struct vnode *vp; @@ -371,13 +378,11 @@ ncl_mountroot(struct mount *mp, struct thread *td) char *cp; #if defined(BOOTP_NFSROOT) && defined(BOOTP) - bootpc_init(); /* use bootp to get newnfs_diskless filled in */ + bootpc_init(); /* use bootp to get nfs_diskless filled in */ #elif defined(NFS_ROOT) nfs_setup_diskless(); #endif - nfscl_init(); - if (newnfs_diskless_valid == 0) return (-1); if (newnfs_diskless_valid == 1) @@ -395,7 +400,7 @@ ncl_mountroot(struct mount *mp, struct thread *td) error = socreate(nd->myif.ifra_addr.sa_family, &so, nd->root_args.sotype, 0, td->td_ucred, td); if (error) - panic("ncl_mountroot: socreate(%04x): %d", + panic("nfs_mountroot: socreate(%04x): %d", nd->myif.ifra_addr.sa_family, error); #if 0 /* XXX Bad idea */ @@ -416,14 +421,14 @@ ncl_mountroot(struct mount *mp, struct thread *td) #endif error = ifioctl(so, SIOCAIFADDR, (caddr_t)&nd->myif, td); if (error) - panic("ncl_mountroot: SIOCAIFADDR: %d", error); + panic("nfs_mountroot: SIOCAIFADDR: %d", error); if ((cp = getenv("boot.netif.mtu")) != NULL) { ir.ifr_mtu = strtol(cp, NULL, 10); bcopy(nd->myif.ifra_name, ir.ifr_name, IFNAMSIZ); freeenv(cp); error = ifioctl(so, SIOCSIFMTU, (caddr_t)&ir, td); if (error) - printf("ncl_mountroot: SIOCSIFMTU: %d", error); + printf("nfs_mountroot: SIOCSIFMTU: %d", error); } soclose(so); @@ -441,12 +446,13 @@ ncl_mountroot(struct mount *mp, struct thread *td) sin = mask; sin.sin_family = AF_INET; sin.sin_len = sizeof(sin); + /* XXX MRT use table 0 for this sort of thing */ error = rtrequest(RTM_ADD, (struct sockaddr *)&sin, (struct sockaddr *)&nd->mygateway, (struct sockaddr *)&mask, RTF_UP | RTF_GATEWAY, NULL); if (error) - panic("ncl_mountroot: RTM_ADD: %d", error); + panic("nfs_mountroot: RTM_ADD: %d", error); } /* @@ -459,6 +465,7 @@ ncl_mountroot(struct mount *mp, struct thread *td) (l >> 24) & 0xff, (l >> 16) & 0xff, (l >> 8) & 0xff, (l >> 0) & 0xff, nd->root_hostnam); printf("NFS ROOT: %s\n", buf); + nd->root_args.hostname = buf; if ((error = nfs_mountdiskless(buf, &nd->root_saddr, &nd->root_args, td, &vp, mp)) != 0) { return (error); @@ -469,11 +476,13 @@ ncl_mountroot(struct mount *mp, struct thread *td) * set hostname here and then let the "/etc/rc.xxx" files * mount the right /var based upon its preset value. */ - bcopy(nd->my_hostnam, hostname, MAXHOSTNAMELEN); - hostname[MAXHOSTNAMELEN - 1] = '\0'; + mtx_lock(&hostname_mtx); + bcopy(nd->my_hostnam, V_hostname, MAXHOSTNAMELEN); + V_hostname[MAXHOSTNAMELEN - 1] = '\0'; for (i = 0; i < MAXHOSTNAMELEN; i++) - if (hostname[i] == '\0') + if (V_hostname[i] == '\0') break; + mtx_unlock(&hostname_mtx); inittodr(ntohl(nd->root_time)); return (0); } @@ -492,7 +501,7 @@ nfs_mountdiskless(char *path, nam = sodupsockaddr((struct sockaddr *)sin, M_WAITOK); if ((error = mountnfs(args, mp, nam, path, NULL, NULL, NULL, vpp, td->td_ucred, td)) != 0) { - printf("ncl_mountroot: mount %s on /: %d\n", path, error); + printf("nfs_mountroot: mount %s on /: %d\n", path, error); return (error); } return (0); @@ -704,7 +713,7 @@ nfs_mount(struct mount *mp) td = curthread; if ((mp->mnt_flag & (MNT_ROOTFS | MNT_UPDATE)) == MNT_ROOTFS) { - error = ncl_mountroot(mp, td); + error = ncl_mountroot(mp); goto out; } From 16dcc9ce7716276be635a083dc39385890d29a8d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 15 May 2009 16:38:42 +0000 Subject: [PATCH 199/544] Cleanup module declarations: Use "bwi" consistently No need to have separate cardbus attachment No need to declare a module version --- sys/dev/bwi/if_bwi_pci.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c index 20696f737c2b..91b8229ae671 100644 --- a/sys/dev/bwi/if_bwi_pci.c +++ b/sys/dev/bwi/if_bwi_pci.c @@ -245,9 +245,7 @@ static driver_t bwi_driver = { sizeof (struct bwi_pci_softc) }; static devclass_t bwi_devclass; -DRIVER_MODULE(if_bwi, pci, bwi_driver, bwi_devclass, 0, 0); -DRIVER_MODULE(bwi, cardbus, bwi_driver, bwi_devclass, 0, 0); -MODULE_VERSION(if_bwi, 1); -MODULE_DEPEND(if_bwi, wlan, 1, 1, 1); /* 802.11 media layer */ -MODULE_DEPEND(if_bwi, firmware, 1, 1, 1); /* firmware support */ -MODULE_DEPEND(if_bwi, wlan_amrr, 1, 1, 1); +DRIVER_MODULE(bwi, pci, bwi_driver, bwi_devclass, 0, 0); +MODULE_DEPEND(bwi, wlan, 1, 1, 1); /* 802.11 media layer */ +MODULE_DEPEND(bwi, firmware, 1, 1, 1); /* firmware support */ +MODULE_DEPEND(bwi, wlan_amrr, 1, 1, 1); From b8f5836a3c1b98b09ea5a101147530d3855cb602 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Fri, 15 May 2009 17:02:11 +0000 Subject: [PATCH 200/544] The module name convention is foo, not if_foo. --- sys/dev/ath/if_ath_pci.c | 6 +++--- sys/dev/ixgb/if_ixgb.c | 6 +++--- sys/dev/lmc/if_lmc.c | 10 +++++----- sys/dev/malo/if_malo_pci.c | 8 ++++---- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c index 8b3e52e2d169..44d398db1b79 100644 --- a/sys/dev/ath/if_ath_pci.c +++ b/sys/dev/ath/if_ath_pci.c @@ -250,6 +250,6 @@ static driver_t ath_pci_driver = { sizeof (struct ath_pci_softc) }; static devclass_t ath_devclass; -DRIVER_MODULE(if_ath, pci, ath_pci_driver, ath_devclass, 0, 0); -MODULE_VERSION(if_ath, 1); -MODULE_DEPEND(if_ath, wlan, 1, 1, 1); /* 802.11 media layer */ +DRIVER_MODULE(ath, pci, ath_pci_driver, ath_devclass, 0, 0); +MODULE_VERSION(ath, 1); +MODULE_DEPEND(ath, wlan, 1, 1, 1); /* 802.11 media layer */ diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c index c1d68582479a..1fb35445552a 100644 --- a/sys/dev/ixgb/if_ixgb.c +++ b/sys/dev/ixgb/if_ixgb.c @@ -167,10 +167,10 @@ static driver_t ixgb_driver = { }; static devclass_t ixgb_devclass; -DRIVER_MODULE(if_ixgb, pci, ixgb_driver, ixgb_devclass, 0, 0); +DRIVER_MODULE(ixgb, pci, ixgb_driver, ixgb_devclass, 0, 0); -MODULE_DEPEND(if_ixgb, pci, 1, 1, 1); -MODULE_DEPEND(if_ixgb, ether, 1, 1, 1); +MODULE_DEPEND(ixgb, pci, 1, 1, 1); +MODULE_DEPEND(ixgb, ether, 1, 1, 1); /* some defines for controlling descriptor fetches in h/w */ #define RXDCTL_PTHRESH_DEFAULT 128 /* chip considers prefech below this */ diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c index 3d1c9d5af616..c97bdfa6c99c 100644 --- a/sys/dev/lmc/if_lmc.c +++ b/sys/dev/lmc/if_lmc.c @@ -5751,14 +5751,14 @@ static driver_t driver = static devclass_t devclass; -DRIVER_MODULE(if_lmc, pci, driver, devclass, 0, 0); -MODULE_VERSION(if_lmc, 2); -MODULE_DEPEND(if_lmc, pci, 1, 1, 1); +DRIVER_MODULE(lmc, pci, driver, devclass, 0, 0); +MODULE_VERSION(lmc, 2); +MODULE_DEPEND(lmc, pci, 1, 1, 1); # if NETGRAPH -MODULE_DEPEND(if_lmc, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); +MODULE_DEPEND(lmc, netgraph, NG_ABI_VERSION, NG_ABI_VERSION, NG_ABI_VERSION); # endif # if NSPPP -MODULE_DEPEND(if_lmc, sppp, 1, 1, 1); +MODULE_DEPEND(lmc, sppp, 1, 1, 1); # endif #endif /* __FreeBSD__ */ diff --git a/sys/dev/malo/if_malo_pci.c b/sys/dev/malo/if_malo_pci.c index 2df6dd19f325..fbad5ab4c172 100644 --- a/sys/dev/malo/if_malo_pci.c +++ b/sys/dev/malo/if_malo_pci.c @@ -368,7 +368,7 @@ static driver_t malo_pci_driver = { }; static devclass_t malo_devclass; -DRIVER_MODULE(if_malo, pci, malo_pci_driver, malo_devclass, 0, 0); -MODULE_VERSION(if_malo, 1); -MODULE_DEPEND(if_malo, wlan, 1, 1, 1); /* 802.11 media layer */ -MODULE_DEPEND(if_malo, malofw_fw, 1, 1, 1); +DRIVER_MODULE(malo, pci, malo_pci_driver, malo_devclass, 0, 0); +MODULE_VERSION(malo, 1); +MODULE_DEPEND(malo, wlan, 1, 1, 1); /* 802.11 media layer */ +MODULE_DEPEND(malo, malofw_fw, 1, 1, 1); From 7293f0e67cc6b53547f67f277d06fd9683d15e5d Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Fri, 15 May 2009 18:25:44 +0000 Subject: [PATCH 201/544] Update the KVM backend for malloc stats to catch up to the internal structure BI change from the addition of DTrace malloc(9) probes. Submitted by: Ben Kelly ben of wanderview dot com --- lib/libmemstat/memstat_malloc.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/libmemstat/memstat_malloc.c b/lib/libmemstat/memstat_malloc.c index 70320f5861d1..28a48c660546 100644 --- a/lib/libmemstat/memstat_malloc.c +++ b/lib/libmemstat/memstat_malloc.c @@ -296,6 +296,7 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle) int hint_dontsearch, j, mp_maxcpus, ret; char name[MEMTYPE_MAXNAME]; struct malloc_type_stats mts[MEMSTAT_MAXCPU], *mtsp; + struct malloc_type_internal *mtip; struct malloc_type type, *typep; kvm_t *kvm; @@ -349,13 +350,11 @@ memstat_kvm_malloc(struct memory_type_list *list, void *kvm_handle) } /* - * Take advantage of explicit knowledge that - * malloc_type_internal is simply an array of statistics - * structures of number MAXCPU. Since our compile-time - * value for MAXCPU may differ from the kernel's, we - * populate our own array. + * Since our compile-time value for MAXCPU may differ from the + * kernel's, we populate our own array. */ - ret = kread(kvm, type.ks_handle, mts, mp_maxcpus * + mtip = type.ks_handle; + ret = kread(kvm, mtip->mti_stats, mts, mp_maxcpus * sizeof(struct malloc_type_stats), 0); if (ret != 0) { _memstat_mtl_empty(list); From 0e9bd89d7ddf23148bcdcfc2249cd711fe76fbaa Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Fri, 15 May 2009 19:23:05 +0000 Subject: [PATCH 202/544] Devfs replaces file ops vector with devfs-specific one in devfs_open(), before the struct file is fully initialized in vn_open(), in particular, fp->f_vnode is NULL. Other thread calling file operation before f_vnode is set results in NULL pointer dereference in devvn_refthread(). Initialize f_vnode before calling d_fdopen() cdevsw method, that might set file ops too. Reported and tested by: Chris Timmons (RELENG_7 version) MFC after: 3 days --- sys/fs/devfs/devfs_vnops.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c index ece95597375e..c637ea8900e9 100644 --- a/sys/fs/devfs/devfs_vnops.c +++ b/sys/fs/devfs/devfs_vnops.c @@ -942,8 +942,10 @@ devfs_open(struct vop_open_args *ap) fpop = td->td_fpop; td->td_fpop = fp; - if (fp != NULL) + if (fp != NULL) { fp->f_data = dev; + fp->f_vnode = vp; + } if (dsw->d_fdopen != NULL) error = dsw->d_fdopen(dev, ap->a_mode, td, fp); else From 0c794c5db14615933588c4c3a0c777a1e5a89475 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 15 May 2009 19:33:59 +0000 Subject: [PATCH 203/544] Move the nfsstat structure and proc/op number definitions on the experimental nfs subsystem from sys/fs/nfs/nfs.h and sys/fs/nfs/nfsproto.h to sys/fs/nfs/nfsport.h and rename nfsstat to ext_nfsstat. This was done so that src/usr.bin/nfsstat.c could use it alongside the regular nfs include files and struct nfsstat. Approved by: kib (mentor) --- sys/fs/nfs/nfs.h | 55 ------------- sys/fs/nfs/nfsport.h | 176 ++++++++++++++++++++++++++++++++++++++++++ sys/fs/nfs/nfsproto.h | 98 +---------------------- 3 files changed, 177 insertions(+), 152 deletions(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 14656a5e69ee..250ce1a58db8 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -324,61 +324,6 @@ struct nfsreferral { #define NFSID_ADDGROUPNAME 0x0080 #define NFSID_DELGROUPNAME 0x0100 -/* - * Stats structure - */ -struct nfsstats { - int attrcache_hits; - int attrcache_misses; - int lookupcache_hits; - int lookupcache_misses; - int direofcache_hits; - int direofcache_misses; - int accesscache_hits; - int accesscache_misses; - int biocache_reads; - int read_bios; - int read_physios; - int biocache_writes; - int write_bios; - int write_physios; - int biocache_readlinks; - int readlink_bios; - int biocache_readdirs; - int readdir_bios; - int rpccnt[NFS_NPROCS]; - int rpcretries; - int srvrpccnt[NFSV4OP_NOPS + NFSV4OP_FAKENOPS]; - int srvrpc_errs; - int srv_errs; - int rpcrequests; - int rpctimeouts; - int rpcunexpected; - int rpcinvalid; - int srvcache_inproghits; - int srvcache_idemdonehits; - int srvcache_nonidemdonehits; - int srvcache_misses; - int srvcache_tcppeak; - int srvcache_size; - int srvclients; - int srvopenowners; - int srvopens; - int srvlockowners; - int srvlocks; - int srvdelegates; - int cbrpccnt[NFSV4OP_CBNOPS]; - int clopenowners; - int clopens; - int cllockowners; - int cllocks; - int cldelegates; - int cllocalopenowners; - int cllocalopens; - int cllocallockowners; - int cllocallocks; -}; - /* * fs.nfs sysctl(3) identifiers */ diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 5faade90c702..5be658799360 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -186,6 +186,182 @@ */ #define NFSMUTEX_T struct mtx +#endif /* _KERNEL */ + +/* + * NFSv4 Operation numbers. + */ +#define NFSV4OP_ACCESS 3 +#define NFSV4OP_CLOSE 4 +#define NFSV4OP_COMMIT 5 +#define NFSV4OP_CREATE 6 +#define NFSV4OP_DELEGPURGE 7 +#define NFSV4OP_DELEGRETURN 8 +#define NFSV4OP_GETATTR 9 +#define NFSV4OP_GETFH 10 +#define NFSV4OP_LINK 11 +#define NFSV4OP_LOCK 12 +#define NFSV4OP_LOCKT 13 +#define NFSV4OP_LOCKU 14 +#define NFSV4OP_LOOKUP 15 +#define NFSV4OP_LOOKUPP 16 +#define NFSV4OP_NVERIFY 17 +#define NFSV4OP_OPEN 18 +#define NFSV4OP_OPENATTR 19 +#define NFSV4OP_OPENCONFIRM 20 +#define NFSV4OP_OPENDOWNGRADE 21 +#define NFSV4OP_PUTFH 22 +#define NFSV4OP_PUTPUBFH 23 +#define NFSV4OP_PUTROOTFH 24 +#define NFSV4OP_READ 25 +#define NFSV4OP_READDIR 26 +#define NFSV4OP_READLINK 27 +#define NFSV4OP_REMOVE 28 +#define NFSV4OP_RENAME 29 +#define NFSV4OP_RENEW 30 +#define NFSV4OP_RESTOREFH 31 +#define NFSV4OP_SAVEFH 32 +#define NFSV4OP_SECINFO 33 +#define NFSV4OP_SETATTR 34 +#define NFSV4OP_SETCLIENTID 35 +#define NFSV4OP_SETCLIENTIDCFRM 36 +#define NFSV4OP_VERIFY 37 +#define NFSV4OP_WRITE 38 +#define NFSV4OP_RELEASELCKOWN 39 + +/* + * Must be one greater than the last Operation#. + */ +#define NFSV4OP_NOPS 40 + +/* + * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV4OP_NOPS. + */ +#define NFSV4OP_SYMLINK (NFSV4OP_NOPS) +#define NFSV4OP_MKDIR (NFSV4OP_NOPS + 1) +#define NFSV4OP_RMDIR (NFSV4OP_NOPS + 2) +#define NFSV4OP_READDIRPLUS (NFSV4OP_NOPS + 3) +#define NFSV4OP_MKNOD (NFSV4OP_NOPS + 4) +#define NFSV4OP_FSSTAT (NFSV4OP_NOPS + 5) +#define NFSV4OP_FSINFO (NFSV4OP_NOPS + 6) +#define NFSV4OP_PATHCONF (NFSV4OP_NOPS + 7) +#define NFSV4OP_V3CREATE (NFSV4OP_NOPS + 8) + +/* + * This is the count of the fake operations listed above. + */ +#define NFSV4OP_FAKENOPS 9 + +/* + * and the Callback OPs + */ +#define NFSV4OP_CBGETATTR 3 +#define NFSV4OP_CBRECALL 4 + +/* + * Must be one greater than the last Callback Operation#. + */ +#define NFSV4OP_CBNOPS 5 + +/* + * The lower numbers -> 21 are used by NFSv2 and v3. These define higher + * numbers used by NFSv4. + * NFS_V3NPROCS is one greater than the last V3 op and NFS_NPROCS is + * one greater than the last number. + */ +#define NFS_V3NPROCS 22 + +#define NFSPROC_LOOKUPP 22 +#define NFSPROC_SETCLIENTID 23 +#define NFSPROC_SETCLIENTIDCFRM 24 +#define NFSPROC_LOCK 25 +#define NFSPROC_LOCKU 26 +#define NFSPROC_OPEN 27 +#define NFSPROC_CLOSE 28 +#define NFSPROC_OPENCONFIRM 29 +#define NFSPROC_LOCKT 30 +#define NFSPROC_OPENDOWNGRADE 31 +#define NFSPROC_RENEW 32 +#define NFSPROC_PUTROOTFH 33 +#define NFSPROC_RELEASELCKOWN 34 +#define NFSPROC_DELEGRETURN 35 +#define NFSPROC_RETDELEGREMOVE 36 +#define NFSPROC_RETDELEGRENAME1 37 +#define NFSPROC_RETDELEGRENAME2 38 +#define NFSPROC_GETACL 39 +#define NFSPROC_SETACL 40 + +/* + * Must be defined as one higher than the last Proc# above. + */ +#define NFSV4_NPROCS 41 + +/* + * Stats structure + */ +struct ext_nfsstats { + int attrcache_hits; + int attrcache_misses; + int lookupcache_hits; + int lookupcache_misses; + int direofcache_hits; + int direofcache_misses; + int accesscache_hits; + int accesscache_misses; + int biocache_reads; + int read_bios; + int read_physios; + int biocache_writes; + int write_bios; + int write_physios; + int biocache_readlinks; + int readlink_bios; + int biocache_readdirs; + int readdir_bios; + int rpccnt[NFSV4_NPROCS]; + int rpcretries; + int srvrpccnt[NFSV4OP_NOPS + NFSV4OP_FAKENOPS]; + int srvrpc_errs; + int srv_errs; + int rpcrequests; + int rpctimeouts; + int rpcunexpected; + int rpcinvalid; + int srvcache_inproghits; + int srvcache_idemdonehits; + int srvcache_nonidemdonehits; + int srvcache_misses; + int srvcache_tcppeak; + int srvcache_size; + int srvclients; + int srvopenowners; + int srvopens; + int srvlockowners; + int srvlocks; + int srvdelegates; + int cbrpccnt[NFSV4OP_CBNOPS]; + int clopenowners; + int clopens; + int cllockowners; + int cllocks; + int cldelegates; + int cllocalopenowners; + int cllocalopens; + int cllocallockowners; + int cllocallocks; +}; + +#ifdef _KERNEL +/* + * Define the ext_nfsstats as nfsstats for the kernel code. + */ +#define nfsstats ext_nfsstats + +/* + * Define NFS_NPROCS as NFSV4_NPROCS for the experimental kernel code. + */ +#define NFS_NPROCS NFSV4_NPROCS + #include #include #include diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index a0927909f827..f007b70db687 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -217,36 +217,6 @@ #define NFSPROC_PATHCONF 20 #define NFSPROC_COMMIT 21 -/* - * These cover all the procedures for V2 and 3. The higher numbers are - * used to reference other V4 ops. - * NFS_V3NPROCS is one greater than the last V3 op and NFS_NPROCS is - * one greater than the last number. - */ -#define NFS_V3NPROCS 22 - -#define NFSPROC_LOOKUPP 22 -#define NFSPROC_SETCLIENTID 23 -#define NFSPROC_SETCLIENTIDCFRM 24 -#define NFSPROC_LOCK 25 -#define NFSPROC_LOCKU 26 -#define NFSPROC_OPEN 27 -#define NFSPROC_CLOSE 28 -#define NFSPROC_OPENCONFIRM 29 -#define NFSPROC_LOCKT 30 -#define NFSPROC_OPENDOWNGRADE 31 -#define NFSPROC_RENEW 32 -#define NFSPROC_PUTROOTFH 33 -#define NFSPROC_RELEASELCKOWN 34 -#define NFSPROC_DELEGRETURN 35 -#define NFSPROC_RETDELEGREMOVE 36 -#define NFSPROC_RETDELEGRENAME1 37 -#define NFSPROC_RETDELEGRENAME2 38 -#define NFSPROC_GETACL 39 -#define NFSPROC_SETACL 40 - -#define NFS_NPROCS 41 - /* * NFSPROC_NOOP is a fake op# that can't be the same as any V2/3/4 Procedure * or Operation#. Since the NFS V4 Op #s go higher, use NFSV4OP_NOPS, which @@ -276,78 +246,12 @@ #define NFSV2PROC_STATFS 17 /* - * V4 Procedure and suboperation numbers + * V4 Procedure numbers */ #define NFSV4PROC_COMPOUND 1 #define NFSV4PROC_CBNULL 0 #define NFSV4PROC_CBCOMPOUND 1 -#define NFSV4OP_ACCESS 3 -#define NFSV4OP_CLOSE 4 -#define NFSV4OP_COMMIT 5 -#define NFSV4OP_CREATE 6 -#define NFSV4OP_DELEGPURGE 7 -#define NFSV4OP_DELEGRETURN 8 -#define NFSV4OP_GETATTR 9 -#define NFSV4OP_GETFH 10 -#define NFSV4OP_LINK 11 -#define NFSV4OP_LOCK 12 -#define NFSV4OP_LOCKT 13 -#define NFSV4OP_LOCKU 14 -#define NFSV4OP_LOOKUP 15 -#define NFSV4OP_LOOKUPP 16 -#define NFSV4OP_NVERIFY 17 -#define NFSV4OP_OPEN 18 -#define NFSV4OP_OPENATTR 19 -#define NFSV4OP_OPENCONFIRM 20 -#define NFSV4OP_OPENDOWNGRADE 21 -#define NFSV4OP_PUTFH 22 -#define NFSV4OP_PUTPUBFH 23 -#define NFSV4OP_PUTROOTFH 24 -#define NFSV4OP_READ 25 -#define NFSV4OP_READDIR 26 -#define NFSV4OP_READLINK 27 -#define NFSV4OP_REMOVE 28 -#define NFSV4OP_RENAME 29 -#define NFSV4OP_RENEW 30 -#define NFSV4OP_RESTOREFH 31 -#define NFSV4OP_SAVEFH 32 -#define NFSV4OP_SECINFO 33 -#define NFSV4OP_SETATTR 34 -#define NFSV4OP_SETCLIENTID 35 -#define NFSV4OP_SETCLIENTIDCFRM 36 -#define NFSV4OP_VERIFY 37 -#define NFSV4OP_WRITE 38 -#define NFSV4OP_RELEASELCKOWN 39 - -/* - * and the Callback OPs - */ -#define NFSV4OP_CBGETATTR 3 -#define NFSV4OP_CBRECALL 4 - -/* - * NFSV4OP_NOPS is one greater than the largest V4 Op#. (Used for sizing - * arrays, etc.) - */ -#define NFSV4OP_NOPS 40 -#define NFSV4OP_CBNOPS 5 - -/* - * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV4OP_NOPS. - */ -#define NFSV4OP_SYMLINK (NFSV4OP_NOPS) -#define NFSV4OP_MKDIR (NFSV4OP_NOPS + 1) -#define NFSV4OP_RMDIR (NFSV4OP_NOPS + 2) -#define NFSV4OP_READDIRPLUS (NFSV4OP_NOPS + 3) -#define NFSV4OP_MKNOD (NFSV4OP_NOPS + 4) -#define NFSV4OP_FSSTAT (NFSV4OP_NOPS + 5) -#define NFSV4OP_FSINFO (NFSV4OP_NOPS + 6) -#define NFSV4OP_PATHCONF (NFSV4OP_NOPS + 7) -#define NFSV4OP_V3CREATE (NFSV4OP_NOPS + 8) - -#define NFSV4OP_FAKENOPS 9 - /* * Constants used by the Version 3 and 4 protocols for various RPCs */ From 216fa4c607702164198de3d584c8e82699f3deb4 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Fri, 15 May 2009 19:41:10 +0000 Subject: [PATCH 204/544] Reduce diff against my local version: replace malloc+memset() cases to calloc(). --- usr.bin/truss/amd64-fbsd.c | 3 +-- usr.bin/truss/amd64-fbsd32.c | 3 +-- usr.bin/truss/amd64-linux32.c | 3 +-- usr.bin/truss/i386-fbsd.c | 3 +-- usr.bin/truss/i386-linux.c | 3 +-- usr.bin/truss/ia64-fbsd.c | 3 +-- usr.bin/truss/main.c | 7 +++---- usr.bin/truss/mips-fbsd.c | 3 +-- usr.bin/truss/powerpc-fbsd.c | 3 +-- usr.bin/truss/sparc64-fbsd.c | 3 +-- 10 files changed, 12 insertions(+), 22 deletions(-) diff --git a/usr.bin/truss/amd64-fbsd.c b/usr.bin/truss/amd64-fbsd.c index d43f92912587..f7c949ac697c 100644 --- a/usr.bin/truss/amd64-fbsd.c +++ b/usr.bin/truss/amd64-fbsd.c @@ -191,8 +191,7 @@ amd64_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/amd64-fbsd32.c b/usr.bin/truss/amd64-fbsd32.c index 4e6458a08920..9b0eb28e7fa8 100644 --- a/usr.bin/truss/amd64-fbsd32.c +++ b/usr.bin/truss/amd64-fbsd32.c @@ -194,8 +194,7 @@ amd64_fbsd32_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/amd64-linux32.c b/usr.bin/truss/amd64-linux32.c index 7f7390aa7688..7d88c8d56890 100644 --- a/usr.bin/truss/amd64-linux32.c +++ b/usr.bin/truss/amd64-linux32.c @@ -164,8 +164,7 @@ amd64_linux32_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/i386-fbsd.c b/usr.bin/truss/i386-fbsd.c index a65c7dbaa6ec..6f774b2a4c7b 100644 --- a/usr.bin/truss/i386-fbsd.c +++ b/usr.bin/truss/i386-fbsd.c @@ -184,8 +184,7 @@ i386_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/i386-linux.c b/usr.bin/truss/i386-linux.c index de17628c0797..2bd6e7b64bde 100644 --- a/usr.bin/truss/i386-linux.c +++ b/usr.bin/truss/i386-linux.c @@ -164,8 +164,7 @@ i386_linux_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/ia64-fbsd.c b/usr.bin/truss/ia64-fbsd.c index cd8c69eb234a..8c8221826f5e 100644 --- a/usr.bin/truss/ia64-fbsd.c +++ b/usr.bin/truss/ia64-fbsd.c @@ -166,8 +166,7 @@ ia64_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/main.c b/usr.bin/truss/main.c index 4333f2df3076..d0dd073e632f 100644 --- a/usr.bin/truss/main.c +++ b/usr.bin/truss/main.c @@ -179,11 +179,10 @@ main(int ac, char **av) initial_open = 1; /* Initialize the trussinfo struct */ - trussinfo = (struct trussinfo *)malloc(sizeof(struct trussinfo)); + trussinfo = (struct trussinfo *)calloc(1, sizeof(struct trussinfo)); if (trussinfo == NULL) - errx(1, "malloc() failed"); - bzero(trussinfo, sizeof(struct trussinfo)); - + errx(1, "calloc() failed"); + trussinfo->outfile = stderr; trussinfo->strsize = 32; trussinfo->pr_why = S_NONE; diff --git a/usr.bin/truss/mips-fbsd.c b/usr.bin/truss/mips-fbsd.c index bfefdd75bc16..342883cc66d7 100644 --- a/usr.bin/truss/mips-fbsd.c +++ b/usr.bin/truss/mips-fbsd.c @@ -211,8 +211,7 @@ mips_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/powerpc-fbsd.c b/usr.bin/truss/powerpc-fbsd.c index 2316740b32f1..43f7c9eece98 100644 --- a/usr.bin/truss/powerpc-fbsd.c +++ b/usr.bin/truss/powerpc-fbsd.c @@ -193,8 +193,7 @@ powerpc_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* diff --git a/usr.bin/truss/sparc64-fbsd.c b/usr.bin/truss/sparc64-fbsd.c index 31e304af977d..787774319430 100644 --- a/usr.bin/truss/sparc64-fbsd.c +++ b/usr.bin/truss/sparc64-fbsd.c @@ -209,8 +209,7 @@ sparc64_syscall_entry(struct trussinfo *trussinfo, int nargs) { fsc.nargs = nargs; } - fsc.s_args = malloc((1+fsc.nargs) * sizeof(char*)); - memset(fsc.s_args, 0, fsc.nargs * sizeof(char*)); + fsc.s_args = calloc(1, (1+fsc.nargs) * sizeof(char*)); fsc.sc = sc; /* From f633d09533bd1b9edb32da7bc673d68709669ae3 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Fri, 15 May 2009 21:06:28 +0000 Subject: [PATCH 205/544] Add a missing break in a switch statement. Found with: Coverity Prevent(tm) CID: 4302 MFC after: 2 weeks --- sys/dev/ep/if_ep.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/dev/ep/if_ep.c b/sys/dev/ep/if_ep.c index c56639d8940b..f5fd475f85ac 100644 --- a/sys/dev/ep/if_ep.c +++ b/sys/dev/ep/if_ep.c @@ -915,6 +915,7 @@ ep_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) } else { ifmr->ifm_active = IFM_ETHER | IFM_NONE; } + break; default: ifmr->ifm_active = sc->ifmedia.ifm_media; break; From 433e2f476300b0df5ad4afbc78b322be0ce3813b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 15 May 2009 21:34:58 +0000 Subject: [PATCH 206/544] Remove do-nothing code that was required to dirty the old buffer on Alpha. Coverity ID: 838 Approved by: jhb, alc --- sys/kern/kern_sysctl.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/sys/kern/kern_sysctl.c b/sys/kern/kern_sysctl.c index 0a8a096f0a49..d65041a01c3c 100644 --- a/sys/kern/kern_sysctl.c +++ b/sys/kern/kern_sysctl.c @@ -1373,8 +1373,7 @@ int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len) { int ret; - size_t i, wiredlen; - char *cp, dummy; + size_t wiredlen; wiredlen = (len > 0 && len < req->oldlen) ? len : req->oldlen; ret = 0; @@ -1387,16 +1386,6 @@ sysctl_wire_old_buffer(struct sysctl_req *req, size_t len) return (ret); wiredlen = 0; } - /* - * Touch all the wired pages to avoid PTE modified - * bit emulation traps on Alpha while holding locks - * in the sysctl handler. - */ - for (i = (wiredlen + PAGE_SIZE - 1) / PAGE_SIZE, - cp = req->oldptr; i > 0; i--, cp += PAGE_SIZE) { - copyin(cp, &dummy, 1); - copyout(&dummy, cp, 1); - } } req->lock = REQ_WIRED; req->validlen = wiredlen; From 15e8331f0e4acf4ad9f101dfad62e71101c881d5 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sat, 16 May 2009 03:12:55 +0000 Subject: [PATCH 207/544] Fixed the Null callback RPCs so that they work with the new krpc. This required two changes: setting the program and version numbers before connect and fixing the handling of the Null Rpc case in newnfs_request(). Approved by: kib (mentor) --- sys/fs/nfs/nfs_commonkrpc.c | 19 ++++++++++--------- sys/fs/nfsserver/nfs_nfsdstate.c | 8 ++++++++ 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 429eed29aee9..6e27e4d68384 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -456,7 +456,9 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, if (nrp->nr_client == NULL) newnfs_connect(nmp, nrp, cred, td, 0); - if (usegssname) + if (nd->nd_procnum == NFSPROC_NULL) + auth = authnone_create(); + else if (usegssname) auth = nfs_getauth(nrp, secflavour, nmp->nm_krbname, srv_principal, NULL, cred); else @@ -475,7 +477,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, procnum = nd->nd_procnum; if ((nd->nd_flag & ND_NFSV4) && - nd->nd_procnum != NFSV4PROC_CBNULL && + nd->nd_procnum != NFSPROC_NULL && nd->nd_procnum != NFSV4PROC_CBCOMPOUND) procnum = NFSV4PROC_COMPOUND; @@ -672,14 +674,13 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, rep != NULL && (rep->r_flags & R_DONTRECOVER)) nd->nd_repstat = NFSERR_STALEDONTRECOVER; } - - m_freem(nd->nd_mreq); - AUTH_DESTROY(auth); - if (rep != NULL) - FREE((caddr_t)rep, M_NFSDREQ); - return (0); } - error = EPROTONOSUPPORT; + + m_freem(nd->nd_mreq); + AUTH_DESTROY(auth); + if (rep != NULL) + FREE((caddr_t)rep, M_NFSDREQ); + return (0); nfsmout: mbuf_freem(nd->nd_mrep); mbuf_freem(nd->nd_mreq); diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index e312cb187164..f33c59a000ef 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3560,6 +3560,14 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, panic("docallb"); } clp->lc_cbref++; + + /* + * Fill the callback program# and version into the request + * structure for newnfs_connect() to use. + */ + clp->lc_req.nr_prog = clp->lc_program; + clp->lc_req.nr_vers = NFSV4_CBVERS; + /* * First, fill in some of the fields of nd and cr. */ From e27fb776f3466ceda634ab5ab8c3d2ee4ba7df0c Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sat, 16 May 2009 10:42:00 +0000 Subject: [PATCH 208/544] Add a manpage for the bwi(4) driver. --- share/man/man4/Makefile | 2 + share/man/man4/bwi.4 | 134 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 share/man/man4/bwi.4 diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile index 911b7a6f8e17..26cd5e1b82e6 100644 --- a/share/man/man4/Makefile +++ b/share/man/man4/Makefile @@ -51,6 +51,7 @@ MAN= aac.4 \ blackhole.4 \ bpf.4 \ bt.4 \ + bwi.4 \ cardbus.4 \ carp.4 \ ccd.4 \ @@ -465,6 +466,7 @@ MLINKS+=bce.4 if_bce.4 MLINKS+=bfe.4 if_bfe.4 MLINKS+=bge.4 if_bge.4 MLINKS+=bktr.4 brooktree.4 +MLINKS+=bwi.4 if_bwi.4 MLINKS+=crypto.4 cryptodev.4 MLINKS+=cue.4 if_cue.4 MLINKS+=dc.4 if_dc.4 diff --git a/share/man/man4/bwi.4 b/share/man/man4/bwi.4 new file mode 100644 index 000000000000..de36bfb06ce9 --- /dev/null +++ b/share/man/man4/bwi.4 @@ -0,0 +1,134 @@ +.\" Copyright (c) 2009 Christian Brueffer +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 16, 2009 +.Dt BWI 4 +.Os +.Sh NAME +.Nm bwi +.Nd Broadcom BCM43xx IEEE 802.11b/g wireless network driver +.Sh SYNOPSIS +To compile this driver into the kernel, +place the following lines in your +kernel configuration file: +.Bd -ragged -offset indent +.Cd "device bwi" +.Cd "device wlan" +.Cd "device wlan_amrr" +.Cd "device firmware" +.Ed +.Pp +Alternatively, to load the driver as a +module at boot time, place the following line in +.Xr loader.conf 5 : +.Bd -literal -offset indent +if_bwi_load="YES" +.Ed +.Sh DESCRIPTION +The +.Nm +driver provides support for Broadcom BCM43xx based +PCI/CardBus network adapters. +.Pp +It supports +.Cm station +and +.Cm monitor +mode operation. +Only one virtual interface may be configured at any time. +For more information on configuring this device, see +.Xr ifconfig 8 . +.Pp +This driver requires firmware to be loaded before it will work. +The +.Pa ports/net/bwi-firmware-kmod +port needs to be installed before +.Xr ifconfig 8 +will work. +.Sh HARDWARE +The +.Nm +driver supports Broadcom BCM43xx based wireless devices, including: +.Pp +.Bl -column -compact "Apple Airport Extreme" "BCM4306" "Mini PCI" "a/b/g" -offset 6n +.It Em "Card Chip Bus Standard" +.It "Apple Airport Extreme BCM4306 PCI b/g" +.It "Apple Airport Extreme BCM4318 PCI b/g" +.It "ASUS WL-138g BCM4318 PCI b/g" +.It "Buffalo WLI-CB-G54S BCM4318 CardBus b/g" +.It "Buffalo WLI-PCI-G54S BCM4306 PCI b/g" +.It "Compaq R4035 onboard BCM4306 PCI b/g" +.It "Dell Wireless 1470 BCM4318 Mini PCI b/g" +.It "Dell Truemobile 1400 BCM4309 Mini PCI b/g" +.It "HP nx6125 BCM4319 PCI b/g" +.It "Linksys WPC54G Ver 3 BCM4318 CardBus b/g" +.It "Linksys WPC54GS Ver 2 BCM4318 CardBus b/g" +.It "TRENDnet TEW-401PCplus BCM4306 CardBus b/g" +.It "US Robotics 5411 BCM4318 CardBus b/g" +.El +.Sh EXAMPLES +Join an existing BSS network (i.e., connect to an access point): +.Pp +.Bd -literal -offset indent +ifconfig wlan create wlandev bwi0 inet 192.168.0.20 \e + netmask 0xffffff00 +.Ed +.Pp +Join a specific BSS network with network name +.Dq Li my_net : +.Pp +.Dl "ifconfig wlan create wlandev bwi0 ssid my_net up" +.Pp +Join a specific BSS network with 64-bit WEP encryption: +.Bd -literal -offset indent +ifconfig wlan create wlandev bwi0 ssid my_net \e + wepmode on wepkey 0x1234567890 weptxkey 1 up +.Ed +.Sh SEE ALSO +.Xr arp 4 , +.Xr cardbus 4 , +.Xr intro 4 , +.Xr pci 4 , +.Xr wlan 4 , +.Xr wlan_amrr 4 , +.Xr ifconfig 8 , +.Xr wpa_supplicant 8 +.Sh HISTORY +The +.Nm +driver first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An -nosplit +The +.Nm +driver was written for DragonFly BSD by +.An Sepherosa Ziehau +and subsequently ported to +.Fx . +.Sh BUGS +Some card based on the BCM4306 and BCM4309 chips do not work properly +on channel 1, 2 and 3. From e1899ef6c8636efe8e3e5fc11e52d7ddba2cddce Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sat, 16 May 2009 10:48:20 +0000 Subject: [PATCH 209/544] Add support for booting from raidz1 and raidz2 pools. --- sys/boot/i386/zfsboot/zfsboot.c | 36 +- sys/boot/zfs/zfsimpl.c | 209 ++++++--- sys/cddl/boot/zfs/README | 2 +- sys/cddl/boot/zfs/zfsimpl.h | 11 +- sys/cddl/boot/zfs/zfssubr.c | 732 ++++++++++++++++++++++++++++++++ 5 files changed, 908 insertions(+), 82 deletions(-) diff --git a/sys/boot/i386/zfsboot/zfsboot.c b/sys/boot/i386/zfsboot/zfsboot.c index 43434ac78d90..ca035683dd74 100644 --- a/sys/boot/i386/zfsboot/zfsboot.c +++ b/sys/boot/i386/zfsboot/zfsboot.c @@ -413,6 +413,20 @@ int13probe(int drive) return(0); } +/* + * We call this when we find a ZFS vdev - ZFS consumes the dsk + * structure so we must make a new one. + */ +static struct dsk * +copy_dsk(struct dsk *dsk) +{ + struct dsk *newdsk; + + newdsk = malloc(sizeof(struct dsk)); + *newdsk = *dsk; + return (newdsk); +} + static void probe_drive(struct dsk *dsk, spa_t **spap) { @@ -426,9 +440,6 @@ probe_drive(struct dsk *dsk, spa_t **spap) char *sec; unsigned i; - if (!int13probe(dsk->drive)) - return; - /* * If we find a vdev on the whole disk, stop here. Otherwise dig * out the MBR and probe each slice in turn for a vdev. @@ -473,7 +484,7 @@ probe_drive(struct dsk *dsk, spa_t **spap) if (vdev_probe(vdev_read, dsk, spap) == 0) { /* * We record the first pool we find (we will try - * to boot from that one. + * to boot from that one). */ spap = 0; @@ -481,10 +492,7 @@ probe_drive(struct dsk *dsk, spa_t **spap) * This slice had a vdev. We need a new dsk * structure now since the vdev now owns this one. */ - struct dsk *newdsk; - newdsk = malloc(sizeof(struct dsk)); - *newdsk = *dsk; - dsk = newdsk; + dsk = copy_dsk(dsk); } break; } @@ -514,10 +522,7 @@ probe_drive(struct dsk *dsk, spa_t **spap) * This slice had a vdev. We need a new dsk structure now * since the vdev now owns this one. */ - struct dsk *newdsk; - newdsk = malloc(sizeof(struct dsk)); - *newdsk = *dsk; - dsk = newdsk; + dsk = copy_dsk(dsk); } } } @@ -569,10 +574,13 @@ main(void) * will find any other available pools and it may fill in missing * vdevs for the boot pool. */ - for (i = 0; i < 4; i++) { + for (i = 0; i < 128; i++) { if ((i | DRV_HARD) == *(uint8_t *)PTOV(ARGS)) continue; + if (!int13probe(i | DRV_HARD)) + break; + dsk = malloc(sizeof(struct dsk)); dsk->drive = i | DRV_HARD; dsk->type = dsk->drive & TYPE_AD; @@ -944,7 +952,7 @@ static int drvread(struct dsk *dsk, void *buf, unsigned lba, unsigned nblk) { #ifdef GPT - static unsigned c = 0x2d5c7c2f; + static unsigned c = 0x2d5c7c2f; if (!OPT_CHECK(RBX_QUIET)) printf("%c\b", c = c << 8 | c >> 24); diff --git a/sys/boot/zfs/zfsimpl.c b/sys/boot/zfs/zfsimpl.c index e6695cfaf796..ff567a462ef3 100644 --- a/sys/boot/zfs/zfsimpl.c +++ b/sys/boot/zfs/zfsimpl.c @@ -45,16 +45,13 @@ static vdev_list_t zfs_vdevs; static spa_list_t zfs_pools; static uint64_t zfs_crc64_table[256]; -static char *zfs_decomp_buf; static const dnode_phys_t *dnode_cache_obj = 0; static uint64_t dnode_cache_bn; static char *dnode_cache_buf; static char *zap_scratch; +static char *zfs_temp_buf, *zfs_temp_end, *zfs_temp_ptr; -/* - * Forward declarations. - */ -static int zio_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset); +#define TEMP_SIZE (1*SPA_MAXBLOCKSIZE) static void zfs_init(void) @@ -62,13 +59,37 @@ zfs_init(void) STAILQ_INIT(&zfs_vdevs); STAILQ_INIT(&zfs_pools); - zfs_decomp_buf = malloc(128*1024); - dnode_cache_buf = malloc(128*1024); - zap_scratch = malloc(128*1024); + zfs_temp_buf = malloc(TEMP_SIZE); + zfs_temp_end = zfs_temp_buf + TEMP_SIZE; + zfs_temp_ptr = zfs_temp_buf; + dnode_cache_buf = malloc(SPA_MAXBLOCKSIZE); + zap_scratch = malloc(SPA_MAXBLOCKSIZE); zfs_init_crc(); } +static char * +zfs_alloc_temp(size_t sz) +{ + char *p; + + if (zfs_temp_ptr + sz > zfs_temp_end) { + printf("ZFS: out of temporary buffer space\n"); + for (;;) ; + } + p = zfs_temp_ptr; + zfs_temp_ptr += sz; + + return (p); +} + +static void +zfs_reset_temp(void) +{ + + zfs_temp_ptr = zfs_temp_buf; +} + static int xdr_int(const unsigned char **xdr, int *ip) { @@ -299,7 +320,41 @@ nvlist_print(const unsigned char *nvlist, unsigned int indent) #endif static int -vdev_mirror_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size) +vdev_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf, + off_t offset, size_t size) +{ + size_t psize; + int rc; + + if (bp) { + psize = BP_GET_PSIZE(bp); + } else { + psize = size; + } + + /*printf("ZFS: reading %d bytes at 0x%llx to %p\n", psize, offset, buf);*/ + rc = vdev->v_phys_read(vdev, vdev->v_read_priv, offset, buf, psize); + if (rc) + return (rc); + if (bp && zio_checksum_error(bp, buf)) + return (EIO); + + return (0); +} + +static int +vdev_disk_read(vdev_t *vdev, const blkptr_t *bp, void *buf, + off_t offset, size_t bytes) +{ + + return (vdev_read_phys(vdev, bp, buf, + offset + VDEV_LABEL_START_SIZE, bytes)); +} + + +static int +vdev_mirror_read(vdev_t *vdev, const blkptr_t *bp, void *buf, + off_t offset, size_t bytes) { vdev_t *kid; int rc; @@ -308,7 +363,7 @@ vdev_mirror_read(vdev_t *vdev, void *priv, off_t offset, void *buf, size_t size) STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) { if (kid->v_state != VDEV_STATE_HEALTHY) continue; - rc = kid->v_read(kid, kid->v_read_priv, offset, buf, size); + rc = kid->v_read(kid, bp, buf, offset, bytes); if (!rc) return (0); } @@ -329,7 +384,7 @@ vdev_find(uint64_t guid) } static vdev_t * -vdev_create(uint64_t guid, vdev_read_t *read, void *read_priv) +vdev_create(uint64_t guid, vdev_read_t *read) { vdev_t *vdev; @@ -339,7 +394,8 @@ vdev_create(uint64_t guid, vdev_read_t *read, void *read_priv) vdev->v_guid = guid; vdev->v_state = VDEV_STATE_OFFLINE; vdev->v_read = read; - vdev->v_read_priv = read_priv; + vdev->v_phys_read = 0; + vdev->v_read_priv = 0; STAILQ_INSERT_TAIL(&zfs_vdevs, vdev, v_alllink); return (vdev); @@ -349,7 +405,7 @@ static int vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp) { int rc; - uint64_t guid, id; + uint64_t guid, id, ashift, nparity; const char *type; const char *path; vdev_t *vdev, *kid; @@ -378,17 +434,30 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp) } if (strcmp(type, VDEV_TYPE_MIRROR) - && strcmp(type, VDEV_TYPE_DISK)) { - printf("ZFS: can only boot from disk or mirror vdevs\n"); + && strcmp(type, VDEV_TYPE_DISK) + && strcmp(type, VDEV_TYPE_RAIDZ)) { + printf("ZFS: can only boot from disk, mirror or raidz vdevs\n"); return (EIO); } if (!strcmp(type, VDEV_TYPE_MIRROR)) - vdev = vdev_create(guid, vdev_mirror_read, 0); + vdev = vdev_create(guid, vdev_mirror_read); + else if (!strcmp(type, VDEV_TYPE_RAIDZ)) + vdev = vdev_create(guid, vdev_raidz_read); else - vdev = vdev_create(guid, 0, 0); - + vdev = vdev_create(guid, vdev_disk_read); + vdev->v_id = id; + if (nvlist_find(nvlist, ZPOOL_CONFIG_ASHIFT, + DATA_TYPE_UINT64, 0, &ashift) == 0) + vdev->v_ashift = ashift; + else + vdev->v_ashift = 0; + if (nvlist_find(nvlist, ZPOOL_CONFIG_NPARITY, + DATA_TYPE_UINT64, 0, &nparity) == 0) + vdev->v_nparity = nparity; + else + vdev->v_nparity = 0; if (nvlist_find(nvlist, ZPOOL_CONFIG_PATH, DATA_TYPE_STRING, 0, &path) == 0) { if (strlen(path) > 5 @@ -400,15 +469,22 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp) path += 5; vdev->v_name = strdup(path); } else { - vdev->v_name = strdup(type); + if (!strcmp(type, "raidz")) { + if (vdev->v_nparity == 1) + vdev->v_name = "raidz1"; + else + vdev->v_name = "raidz2"; + } else { + vdev->v_name = strdup(type); + } } - vdev->v_id = id; rc = nvlist_find(nvlist, ZPOOL_CONFIG_CHILDREN, DATA_TYPE_NVLIST_ARRAY, &nkids, &kids); /* * Its ok if we don't have any kids. */ if (rc == 0) { + vdev->v_nchildren = nkids; for (i = 0; i < nkids; i++) { rc = vdev_init_from_nvlist(kids, &kid); if (rc) @@ -416,6 +492,8 @@ vdev_init_from_nvlist(const unsigned char *nvlist, vdev_t **vdevp) STAILQ_INSERT_TAIL(&vdev->v_children, kid, v_childlink); kids = nvlist_next(kids); } + } else { + vdev->v_nchildren = 0; } if (vdevp) @@ -431,11 +509,10 @@ vdev_set_state(vdev_t *vdev) int bad_kids; /* - * We assume that if we have kids, we are a mirror. A mirror - * is healthy if all its kids are healthy. Its degraded (but - * working) if at least one kid is healty. + * A mirror or raidz is healthy if all its kids are healthy. A + * mirror is degraded if any of its kids is healthy; a raidz + * is degraded if at most nparity kids are offline. */ - if (STAILQ_FIRST(&vdev->v_children)) { good_kids = 0; bad_kids = 0; @@ -445,13 +522,22 @@ vdev_set_state(vdev_t *vdev) else bad_kids++; } - if (good_kids) { - if (!bad_kids && good_kids) - vdev->v_state = VDEV_STATE_HEALTHY; - else - vdev->v_state = VDEV_STATE_DEGRADED; + if (bad_kids == 0) { + vdev->v_state = VDEV_STATE_HEALTHY; } else { - vdev->v_state = VDEV_STATE_OFFLINE; + if (vdev->v_read == vdev_mirror_read) { + if (good_kids) { + vdev->v_state = VDEV_STATE_DEGRADED; + } else { + vdev->v_state = VDEV_STATE_OFFLINE; + } + } else if (vdev->v_read == vdev_raidz_read) { + if (bad_kids > vdev->v_nparity) { + vdev->v_state = VDEV_STATE_OFFLINE; + } else { + vdev->v_state = VDEV_STATE_DEGRADED; + } + } } } } @@ -609,7 +695,7 @@ spa_all_status(void) } static int -vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) +vdev_probe(vdev_phys_read_t *read, void *read_priv, spa_t **spap) { vdev_t vtmp; vdev_phys_t *vdev_label = (vdev_phys_t *) zap_scratch; @@ -632,7 +718,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) * uberblock is most current. */ memset(&vtmp, 0, sizeof(vtmp)); - vtmp.v_read = read; + vtmp.v_phys_read = read; vtmp.v_read_priv = read_priv; off = offsetof(vdev_label_t, vl_vdev_phys); BP_ZERO(&bp); @@ -641,7 +727,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL); BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF); ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0); - if (zio_read_phys(&vtmp, &bp, vdev_label, off)) + if (vdev_read_phys(&vtmp, &bp, vdev_label, off, 0)) return (EIO); if (vdev_label->vp_nvlist[0] != NV_ENCODE_XDR) { @@ -668,6 +754,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) return (EIO); } +#ifndef TEST if (val != POOL_STATE_ACTIVE) { /* * Don't print a message here. If we happen to reboot @@ -677,6 +764,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) /*printf("ZFS: pool is not active\n");*/ return (EIO); } +#endif if (nvlist_find(nvlist, ZPOOL_CONFIG_POOL_TXG, @@ -687,7 +775,11 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) || nvlist_find(nvlist, ZPOOL_CONFIG_POOL_NAME, DATA_TYPE_STRING, 0, &pool_name)) { - printf("ZFS: can't find pool details\n"); + /* + * Cache and spare devices end up here - just ignore + * them. + */ + /*printf("ZFS: can't find pool details\n");*/ return (EIO); } @@ -742,7 +834,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) */ vdev = vdev_find(guid); if (vdev) { - vdev->v_read = read; + vdev->v_phys_read = read; vdev->v_read_priv = read_priv; vdev->v_state = VDEV_STATE_HEALTHY; } else { @@ -772,7 +864,7 @@ vdev_probe(vdev_read_t *read, void *read_priv, spa_t **spap) BP_SET_CHECKSUM(&bp, ZIO_CHECKSUM_LABEL); BP_SET_COMPRESS(&bp, ZIO_COMPRESS_OFF); ZIO_SET_CHECKSUM(&bp.blk_cksum, off, 0, 0, 0); - if (zio_read_phys(vdev, &bp, upbuf, off)) + if (vdev_read_phys(vdev, &bp, upbuf, off, 0)) continue; up = (const struct uberblock *) upbuf; @@ -805,39 +897,20 @@ ilog2(int n) } static int -zio_read_phys(vdev_t *vdev, const blkptr_t *bp, void *buf, off_t offset) +zio_read(spa_t *spa, const blkptr_t *bp, void *buf) { int cpfunc = BP_GET_COMPRESS(bp); size_t lsize = BP_GET_LSIZE(bp); size_t psize = BP_GET_PSIZE(bp); - int rc; - - /*printf("ZFS: reading %d bytes at 0x%llx to %p\n", psize, offset, buf);*/ - if (cpfunc != ZIO_COMPRESS_OFF) { - rc = vdev->v_read(vdev, vdev->v_read_priv, offset, zfs_decomp_buf, psize); - if (rc) - return (rc); - if (zio_checksum_error(bp, zfs_decomp_buf)) - return (EIO); - if (zio_decompress_data(cpfunc, zfs_decomp_buf, psize, - buf, lsize)) - return (EIO); - } else { - rc = vdev->v_read(vdev, vdev->v_read_priv, offset, buf, psize); - if (rc) - return (rc); - - if (zio_checksum_error(bp, buf)) - return (EIO); - } - return (0); -} - -static int -zio_read(spa_t *spa, const blkptr_t *bp, void *buf) -{ + void *pbuf; int i; + zfs_reset_temp(); + if (cpfunc != ZIO_COMPRESS_OFF) + pbuf = zfs_alloc_temp(psize); + else + pbuf = buf; + for (i = 0; i < SPA_DVAS_PER_BP; i++) { const dva_t *dva = &bp->blk_dva[i]; vdev_t *vdev; @@ -848,15 +921,21 @@ zio_read(spa_t *spa, const blkptr_t *bp, void *buf) continue; vdevid = DVA_GET_VDEV(dva); - offset = DVA_GET_OFFSET(dva) + VDEV_LABEL_START_SIZE; + offset = DVA_GET_OFFSET(dva); STAILQ_FOREACH(vdev, &spa->spa_vdevs, v_childlink) if (vdev->v_id == vdevid) break; if (!vdev || !vdev->v_read) continue; - if (zio_read_phys(vdev, bp, buf, offset)) + if (vdev->v_read(vdev, bp, pbuf, offset, psize)) continue; + if (cpfunc != ZIO_COMPRESS_OFF) { + if (zio_decompress_data(cpfunc, pbuf, psize, + buf, lsize)) + return (EIO); + } + return (0); } printf("ZFS: i/o error - all block copies unavailable\n"); diff --git a/sys/cddl/boot/zfs/README b/sys/cddl/boot/zfs/README index 4b6218165ad4..d36e02e1c1b1 100644 --- a/sys/cddl/boot/zfs/README +++ b/sys/cddl/boot/zfs/README @@ -6,7 +6,7 @@ are used by the ZFS bootstrap: fletcher.c checksum support sha256.c checksum support lzjb.c compression support - zfssubr.c mostly checksum and compression support + zfssubr.c checksum, compression and raidz support zfsimpl.h mostly describing the physical layout The files fletcher.c, lzjb.c and sha256.c are largely identical to the diff --git a/sys/cddl/boot/zfs/zfsimpl.h b/sys/cddl/boot/zfs/zfsimpl.h index 7796d8e97ed7..a0b7b72c9293 100644 --- a/sys/cddl/boot/zfs/zfsimpl.h +++ b/sys/cddl/boot/zfs/zfsimpl.h @@ -1137,7 +1137,10 @@ typedef struct znode_phys { * In-core vdev representation. */ struct vdev; -typedef int vdev_read_t(struct vdev *vdev, void *priv, off_t offset, void *buf, size_t bytes); +typedef int vdev_phys_read_t(struct vdev *vdev, void *priv, + off_t offset, void *buf, size_t bytes); +typedef int vdev_read_t(struct vdev *vdev, const blkptr_t *bp, + void *buf, off_t offset, size_t bytes); typedef STAILQ_HEAD(vdev_list, vdev) vdev_list_t; @@ -1148,8 +1151,12 @@ typedef struct vdev { char *v_name; /* vdev name */ uint64_t v_guid; /* vdev guid */ int v_id; /* index in parent */ + int v_ashift; /* offset to block shift */ + int v_nparity; /* # parity for raidz */ + int v_nchildren; /* # children */ vdev_state_t v_state; /* current state */ - vdev_read_t *v_read; /* function to read from this vdev */ + vdev_phys_read_t *v_phys_read; /* read from raw leaf vdev */ + vdev_read_t *v_read; /* read from vdev */ void *v_read_priv; /* private data for read function */ } vdev_t; diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c index 40bb8638612c..fb4444f242eb 100644 --- a/sys/cddl/boot/zfs/zfssubr.c +++ b/sys/cddl/boot/zfs/zfssubr.c @@ -191,3 +191,735 @@ zap_hash(uint64_t salt, const char *name) return (crc); } + +static char *zfs_alloc_temp(size_t sz); + +typedef struct raidz_col { + uint64_t rc_devidx; /* child device index for I/O */ + uint64_t rc_offset; /* device offset */ + uint64_t rc_size; /* I/O size */ + void *rc_data; /* I/O data */ + int rc_error; /* I/O error for this device */ + uint8_t rc_tried; /* Did we attempt this I/O column? */ + uint8_t rc_skipped; /* Did we skip this I/O column? */ +} raidz_col_t; + +#define VDEV_RAIDZ_P 0 +#define VDEV_RAIDZ_Q 1 + +static void +vdev_raidz_reconstruct_p(raidz_col_t *cols, int nparity, int acols, int x) +{ + uint64_t *dst, *src, xcount, ccount, count, i; + int c; + + xcount = cols[x].rc_size / sizeof (src[0]); + //ASSERT(xcount <= cols[VDEV_RAIDZ_P].rc_size / sizeof (src[0])); + //ASSERT(xcount > 0); + + src = cols[VDEV_RAIDZ_P].rc_data; + dst = cols[x].rc_data; + for (i = 0; i < xcount; i++, dst++, src++) { + *dst = *src; + } + + for (c = nparity; c < acols; c++) { + src = cols[c].rc_data; + dst = cols[x].rc_data; + + if (c == x) + continue; + + ccount = cols[c].rc_size / sizeof (src[0]); + count = MIN(ccount, xcount); + + for (i = 0; i < count; i++, dst++, src++) { + *dst ^= *src; + } + } +} + +/* + * These two tables represent powers and logs of 2 in the Galois field defined + * above. These values were computed by repeatedly multiplying by 2 as above. + */ +static const uint8_t vdev_raidz_pow2[256] = { + 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, + 0x1d, 0x3a, 0x74, 0xe8, 0xcd, 0x87, 0x13, 0x26, + 0x4c, 0x98, 0x2d, 0x5a, 0xb4, 0x75, 0xea, 0xc9, + 0x8f, 0x03, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, + 0x9d, 0x27, 0x4e, 0x9c, 0x25, 0x4a, 0x94, 0x35, + 0x6a, 0xd4, 0xb5, 0x77, 0xee, 0xc1, 0x9f, 0x23, + 0x46, 0x8c, 0x05, 0x0a, 0x14, 0x28, 0x50, 0xa0, + 0x5d, 0xba, 0x69, 0xd2, 0xb9, 0x6f, 0xde, 0xa1, + 0x5f, 0xbe, 0x61, 0xc2, 0x99, 0x2f, 0x5e, 0xbc, + 0x65, 0xca, 0x89, 0x0f, 0x1e, 0x3c, 0x78, 0xf0, + 0xfd, 0xe7, 0xd3, 0xbb, 0x6b, 0xd6, 0xb1, 0x7f, + 0xfe, 0xe1, 0xdf, 0xa3, 0x5b, 0xb6, 0x71, 0xe2, + 0xd9, 0xaf, 0x43, 0x86, 0x11, 0x22, 0x44, 0x88, + 0x0d, 0x1a, 0x34, 0x68, 0xd0, 0xbd, 0x67, 0xce, + 0x81, 0x1f, 0x3e, 0x7c, 0xf8, 0xed, 0xc7, 0x93, + 0x3b, 0x76, 0xec, 0xc5, 0x97, 0x33, 0x66, 0xcc, + 0x85, 0x17, 0x2e, 0x5c, 0xb8, 0x6d, 0xda, 0xa9, + 0x4f, 0x9e, 0x21, 0x42, 0x84, 0x15, 0x2a, 0x54, + 0xa8, 0x4d, 0x9a, 0x29, 0x52, 0xa4, 0x55, 0xaa, + 0x49, 0x92, 0x39, 0x72, 0xe4, 0xd5, 0xb7, 0x73, + 0xe6, 0xd1, 0xbf, 0x63, 0xc6, 0x91, 0x3f, 0x7e, + 0xfc, 0xe5, 0xd7, 0xb3, 0x7b, 0xf6, 0xf1, 0xff, + 0xe3, 0xdb, 0xab, 0x4b, 0x96, 0x31, 0x62, 0xc4, + 0x95, 0x37, 0x6e, 0xdc, 0xa5, 0x57, 0xae, 0x41, + 0x82, 0x19, 0x32, 0x64, 0xc8, 0x8d, 0x07, 0x0e, + 0x1c, 0x38, 0x70, 0xe0, 0xdd, 0xa7, 0x53, 0xa6, + 0x51, 0xa2, 0x59, 0xb2, 0x79, 0xf2, 0xf9, 0xef, + 0xc3, 0x9b, 0x2b, 0x56, 0xac, 0x45, 0x8a, 0x09, + 0x12, 0x24, 0x48, 0x90, 0x3d, 0x7a, 0xf4, 0xf5, + 0xf7, 0xf3, 0xfb, 0xeb, 0xcb, 0x8b, 0x0b, 0x16, + 0x2c, 0x58, 0xb0, 0x7d, 0xfa, 0xe9, 0xcf, 0x83, + 0x1b, 0x36, 0x6c, 0xd8, 0xad, 0x47, 0x8e, 0x01 +}; +static const uint8_t vdev_raidz_log2[256] = { + 0x00, 0x00, 0x01, 0x19, 0x02, 0x32, 0x1a, 0xc6, + 0x03, 0xdf, 0x33, 0xee, 0x1b, 0x68, 0xc7, 0x4b, + 0x04, 0x64, 0xe0, 0x0e, 0x34, 0x8d, 0xef, 0x81, + 0x1c, 0xc1, 0x69, 0xf8, 0xc8, 0x08, 0x4c, 0x71, + 0x05, 0x8a, 0x65, 0x2f, 0xe1, 0x24, 0x0f, 0x21, + 0x35, 0x93, 0x8e, 0xda, 0xf0, 0x12, 0x82, 0x45, + 0x1d, 0xb5, 0xc2, 0x7d, 0x6a, 0x27, 0xf9, 0xb9, + 0xc9, 0x9a, 0x09, 0x78, 0x4d, 0xe4, 0x72, 0xa6, + 0x06, 0xbf, 0x8b, 0x62, 0x66, 0xdd, 0x30, 0xfd, + 0xe2, 0x98, 0x25, 0xb3, 0x10, 0x91, 0x22, 0x88, + 0x36, 0xd0, 0x94, 0xce, 0x8f, 0x96, 0xdb, 0xbd, + 0xf1, 0xd2, 0x13, 0x5c, 0x83, 0x38, 0x46, 0x40, + 0x1e, 0x42, 0xb6, 0xa3, 0xc3, 0x48, 0x7e, 0x6e, + 0x6b, 0x3a, 0x28, 0x54, 0xfa, 0x85, 0xba, 0x3d, + 0xca, 0x5e, 0x9b, 0x9f, 0x0a, 0x15, 0x79, 0x2b, + 0x4e, 0xd4, 0xe5, 0xac, 0x73, 0xf3, 0xa7, 0x57, + 0x07, 0x70, 0xc0, 0xf7, 0x8c, 0x80, 0x63, 0x0d, + 0x67, 0x4a, 0xde, 0xed, 0x31, 0xc5, 0xfe, 0x18, + 0xe3, 0xa5, 0x99, 0x77, 0x26, 0xb8, 0xb4, 0x7c, + 0x11, 0x44, 0x92, 0xd9, 0x23, 0x20, 0x89, 0x2e, + 0x37, 0x3f, 0xd1, 0x5b, 0x95, 0xbc, 0xcf, 0xcd, + 0x90, 0x87, 0x97, 0xb2, 0xdc, 0xfc, 0xbe, 0x61, + 0xf2, 0x56, 0xd3, 0xab, 0x14, 0x2a, 0x5d, 0x9e, + 0x84, 0x3c, 0x39, 0x53, 0x47, 0x6d, 0x41, 0xa2, + 0x1f, 0x2d, 0x43, 0xd8, 0xb7, 0x7b, 0xa4, 0x76, + 0xc4, 0x17, 0x49, 0xec, 0x7f, 0x0c, 0x6f, 0xf6, + 0x6c, 0xa1, 0x3b, 0x52, 0x29, 0x9d, 0x55, 0xaa, + 0xfb, 0x60, 0x86, 0xb1, 0xbb, 0xcc, 0x3e, 0x5a, + 0xcb, 0x59, 0x5f, 0xb0, 0x9c, 0xa9, 0xa0, 0x51, + 0x0b, 0xf5, 0x16, 0xeb, 0x7a, 0x75, 0x2c, 0xd7, + 0x4f, 0xae, 0xd5, 0xe9, 0xe6, 0xe7, 0xad, 0xe8, + 0x74, 0xd6, 0xf4, 0xea, 0xa8, 0x50, 0x58, 0xaf, +}; + +/* + * Multiply a given number by 2 raised to the given power. + */ +static uint8_t +vdev_raidz_exp2(uint8_t a, int exp) +{ + if (a == 0) + return (0); + + //ASSERT(exp >= 0); + //ASSERT(vdev_raidz_log2[a] > 0 || a == 1); + + exp += vdev_raidz_log2[a]; + if (exp > 255) + exp -= 255; + + return (vdev_raidz_pow2[exp]); +} + +static void +vdev_raidz_generate_parity_pq(raidz_col_t *cols, int nparity, int acols) +{ + uint64_t *q, *p, *src, pcount, ccount, mask, i; + int c; + + pcount = cols[VDEV_RAIDZ_P].rc_size / sizeof (src[0]); + //ASSERT(cols[VDEV_RAIDZ_P].rc_size == cols[VDEV_RAIDZ_Q].rc_size); + + for (c = nparity; c < acols; c++) { + src = cols[c].rc_data; + p = cols[VDEV_RAIDZ_P].rc_data; + q = cols[VDEV_RAIDZ_Q].rc_data; + ccount = cols[c].rc_size / sizeof (src[0]); + + if (c == nparity) { + //ASSERT(ccount == pcount || ccount == 0); + for (i = 0; i < ccount; i++, p++, q++, src++) { + *q = *src; + *p = *src; + } + for (; i < pcount; i++, p++, q++, src++) { + *q = 0; + *p = 0; + } + } else { + //ASSERT(ccount <= pcount); + + /* + * Rather than multiplying each byte + * individually (as described above), we are + * able to handle 8 at once by generating a + * mask based on the high bit in each byte and + * using that to conditionally XOR in 0x1d. + */ + for (i = 0; i < ccount; i++, p++, q++, src++) { + mask = *q & 0x8080808080808080ULL; + mask = (mask << 1) - (mask >> 7); + *q = ((*q << 1) & 0xfefefefefefefefeULL) ^ + (mask & 0x1d1d1d1d1d1d1d1dULL); + *q ^= *src; + *p ^= *src; + } + + /* + * Treat short columns as though they are full of 0s. + */ + for (; i < pcount; i++, q++) { + mask = *q & 0x8080808080808080ULL; + mask = (mask << 1) - (mask >> 7); + *q = ((*q << 1) & 0xfefefefefefefefeULL) ^ + (mask & 0x1d1d1d1d1d1d1d1dULL); + } + } + } +} + +static void +vdev_raidz_reconstruct_q(raidz_col_t *cols, int nparity, int acols, int x) +{ + uint64_t *dst, *src, xcount, ccount, count, mask, i; + uint8_t *b; + int c, j, exp; + + xcount = cols[x].rc_size / sizeof (src[0]); + //ASSERT(xcount <= cols[VDEV_RAIDZ_Q].rc_size / sizeof (src[0])); + + for (c = nparity; c < acols; c++) { + src = cols[c].rc_data; + dst = cols[x].rc_data; + + if (c == x) + ccount = 0; + else + ccount = cols[c].rc_size / sizeof (src[0]); + + count = MIN(ccount, xcount); + + if (c == nparity) { + for (i = 0; i < count; i++, dst++, src++) { + *dst = *src; + } + for (; i < xcount; i++, dst++) { + *dst = 0; + } + + } else { + /* + * For an explanation of this, see the comment in + * vdev_raidz_generate_parity_pq() above. + */ + for (i = 0; i < count; i++, dst++, src++) { + mask = *dst & 0x8080808080808080ULL; + mask = (mask << 1) - (mask >> 7); + *dst = ((*dst << 1) & 0xfefefefefefefefeULL) ^ + (mask & 0x1d1d1d1d1d1d1d1dULL); + *dst ^= *src; + } + + for (; i < xcount; i++, dst++) { + mask = *dst & 0x8080808080808080ULL; + mask = (mask << 1) - (mask >> 7); + *dst = ((*dst << 1) & 0xfefefefefefefefeULL) ^ + (mask & 0x1d1d1d1d1d1d1d1dULL); + } + } + } + + src = cols[VDEV_RAIDZ_Q].rc_data; + dst = cols[x].rc_data; + exp = 255 - (acols - 1 - x); + + for (i = 0; i < xcount; i++, dst++, src++) { + *dst ^= *src; + for (j = 0, b = (uint8_t *)dst; j < 8; j++, b++) { + *b = vdev_raidz_exp2(*b, exp); + } + } +} + + +static void +vdev_raidz_reconstruct_pq(raidz_col_t *cols, int nparity, int acols, + int x, int y) +{ + uint8_t *p, *q, *pxy, *qxy, *xd, *yd, tmp, a, b, aexp, bexp; + void *pdata, *qdata; + uint64_t xsize, ysize, i; + + //ASSERT(x < y); + //ASSERT(x >= nparity); + //ASSERT(y < acols); + + //ASSERT(cols[x].rc_size >= cols[y].rc_size); + + /* + * Move the parity data aside -- we're going to compute parity as + * though columns x and y were full of zeros -- Pxy and Qxy. We want to + * reuse the parity generation mechanism without trashing the actual + * parity so we make those columns appear to be full of zeros by + * setting their lengths to zero. + */ + pdata = cols[VDEV_RAIDZ_P].rc_data; + qdata = cols[VDEV_RAIDZ_Q].rc_data; + xsize = cols[x].rc_size; + ysize = cols[y].rc_size; + + cols[VDEV_RAIDZ_P].rc_data = + zfs_alloc_temp(cols[VDEV_RAIDZ_P].rc_size); + cols[VDEV_RAIDZ_Q].rc_data = + zfs_alloc_temp(cols[VDEV_RAIDZ_Q].rc_size); + cols[x].rc_size = 0; + cols[y].rc_size = 0; + + vdev_raidz_generate_parity_pq(cols, nparity, acols); + + cols[x].rc_size = xsize; + cols[y].rc_size = ysize; + + p = pdata; + q = qdata; + pxy = cols[VDEV_RAIDZ_P].rc_data; + qxy = cols[VDEV_RAIDZ_Q].rc_data; + xd = cols[x].rc_data; + yd = cols[y].rc_data; + + /* + * We now have: + * Pxy = P + D_x + D_y + * Qxy = Q + 2^(ndevs - 1 - x) * D_x + 2^(ndevs - 1 - y) * D_y + * + * We can then solve for D_x: + * D_x = A * (P + Pxy) + B * (Q + Qxy) + * where + * A = 2^(x - y) * (2^(x - y) + 1)^-1 + * B = 2^(ndevs - 1 - x) * (2^(x - y) + 1)^-1 + * + * With D_x in hand, we can easily solve for D_y: + * D_y = P + Pxy + D_x + */ + + a = vdev_raidz_pow2[255 + x - y]; + b = vdev_raidz_pow2[255 - (acols - 1 - x)]; + tmp = 255 - vdev_raidz_log2[a ^ 1]; + + aexp = vdev_raidz_log2[vdev_raidz_exp2(a, tmp)]; + bexp = vdev_raidz_log2[vdev_raidz_exp2(b, tmp)]; + + for (i = 0; i < xsize; i++, p++, q++, pxy++, qxy++, xd++, yd++) { + *xd = vdev_raidz_exp2(*p ^ *pxy, aexp) ^ + vdev_raidz_exp2(*q ^ *qxy, bexp); + + if (i < ysize) + *yd = *p ^ *pxy ^ *xd; + } + + /* + * Restore the saved parity data. + */ + cols[VDEV_RAIDZ_P].rc_data = pdata; + cols[VDEV_RAIDZ_Q].rc_data = qdata; +} + +static int +vdev_raidz_read(vdev_t *vdev, const blkptr_t *bp, void *buf, + off_t offset, size_t bytes) +{ + size_t psize = BP_GET_PSIZE(bp); + vdev_t *kid; + int unit_shift = vdev->v_ashift; + int dcols = vdev->v_nchildren; + int nparity = vdev->v_nparity; + int missingdata, missingparity; + int parity_errors, data_errors, unexpected_errors, total_errors; + int parity_untried; + uint64_t b = offset >> unit_shift; + uint64_t s = psize >> unit_shift; + uint64_t f = b % dcols; + uint64_t o = (b / dcols) << unit_shift; + int q, r, c, c1, bc, col, acols, coff, devidx, asize, n; + static raidz_col_t cols[16]; + raidz_col_t *rc, *rc1; + + q = s / (dcols - nparity); + r = s - q * (dcols - nparity); + bc = (r == 0 ? 0 : r + nparity); + + acols = (q == 0 ? bc : dcols); + asize = 0; + + for (c = 0; c < acols; c++) { + col = f + c; + coff = o; + if (col >= dcols) { + col -= dcols; + coff += 1ULL << unit_shift; + } + cols[c].rc_devidx = col; + cols[c].rc_offset = coff; + cols[c].rc_size = (q + (c < bc)) << unit_shift; + cols[c].rc_data = NULL; + cols[c].rc_error = 0; + cols[c].rc_tried = 0; + cols[c].rc_skipped = 0; + asize += cols[c].rc_size; + } + + asize = roundup(asize, (nparity + 1) << unit_shift); + + for (c = 0; c < nparity; c++) { + cols[c].rc_data = zfs_alloc_temp(cols[c].rc_size); + } + + cols[c].rc_data = buf; + + for (c = c + 1; c < acols; c++) + cols[c].rc_data = (char *)cols[c - 1].rc_data + + cols[c - 1].rc_size; + + /* + * If all data stored spans all columns, there's a danger that + * parity will always be on the same device and, since parity + * isn't read during normal operation, that that device's I/O + * bandwidth won't be used effectively. We therefore switch + * the parity every 1MB. + * + * ... at least that was, ostensibly, the theory. As a + * practical matter unless we juggle the parity between all + * devices evenly, we won't see any benefit. Further, + * occasional writes that aren't a multiple of the LCM of the + * number of children and the minimum stripe width are + * sufficient to avoid pessimal behavior. Unfortunately, this + * decision created an implicit on-disk format requirement + * that we need to support for all eternity, but only for + * single-parity RAID-Z. + */ + //ASSERT(acols >= 2); + //ASSERT(cols[0].rc_size == cols[1].rc_size); + + if (nparity == 1 && (offset & (1ULL << 20))) { + devidx = cols[0].rc_devidx; + o = cols[0].rc_offset; + cols[0].rc_devidx = cols[1].rc_devidx; + cols[0].rc_offset = cols[1].rc_offset; + cols[1].rc_devidx = devidx; + cols[1].rc_offset = o; + } + + /* + * Iterate over the columns in reverse order so that we hit + * the parity last -- any errors along the way will force us + * to read the parity data. + */ + missingdata = 0; + missingparity = 0; + for (c = acols - 1; c >= 0; c--) { + rc = &cols[c]; + devidx = rc->rc_devidx; + STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) + if (kid->v_id == devidx) + break; + if (kid == NULL || kid->v_state != VDEV_STATE_HEALTHY) { + if (c >= nparity) + missingdata++; + else + missingparity++; + rc->rc_error = ENXIO; + rc->rc_tried = 1; /* don't even try */ + rc->rc_skipped = 1; + continue; + } +#if 0 + /* + * Too hard for the bootcode + */ + if (vdev_dtl_contains(&cvd->vdev_dtl_map, bp->blk_birth, 1)) { + if (c >= nparity) + rm->rm_missingdata++; + else + rm->rm_missingparity++; + rc->rc_error = ESTALE; + rc->rc_skipped = 1; + continue; + } +#endif + if (c >= nparity || missingdata > 0) { + if (rc->rc_data) + rc->rc_error = kid->v_read(kid, NULL, + rc->rc_data, rc->rc_offset, rc->rc_size); + else + rc->rc_error = ENXIO; + rc->rc_tried = 1; + rc->rc_skipped = 0; + } + } + +reconstruct: + parity_errors = 0; + data_errors = 0; + unexpected_errors = 0; + total_errors = 0; + parity_untried = 0; + for (c = 0; c < acols; c++) { + rc = &cols[c]; + + if (rc->rc_error) { + if (c < nparity) + parity_errors++; + else + data_errors++; + + if (!rc->rc_skipped) + unexpected_errors++; + + total_errors++; + } else if (c < nparity && !rc->rc_tried) { + parity_untried++; + } + } + + /* + * There are three potential phases for a read: + * 1. produce valid data from the columns read + * 2. read all disks and try again + * 3. perform combinatorial reconstruction + * + * Each phase is progressively both more expensive and less + * likely to occur. If we encounter more errors than we can + * repair or all phases fail, we have no choice but to return + * an error. + */ + + /* + * If the number of errors we saw was correctable -- less than + * or equal to the number of parity disks read -- attempt to + * produce data that has a valid checksum. Naturally, this + * case applies in the absence of any errors. + */ + if (total_errors <= nparity - parity_untried) { + switch (data_errors) { + case 0: + if (zio_checksum_error(bp, buf) == 0) + return (0); + break; + + case 1: + /* + * We either attempt to read all the parity columns or + * none of them. If we didn't try to read parity, we + * wouldn't be here in the correctable case. There must + * also have been fewer parity errors than parity + * columns or, again, we wouldn't be in this code path. + */ + //ASSERT(parity_untried == 0); + //ASSERT(parity_errors < nparity); + + /* + * Find the column that reported the error. + */ + for (c = nparity; c < acols; c++) { + rc = &cols[c]; + if (rc->rc_error != 0) + break; + } + //ASSERT(c != acols); + //ASSERT(!rc->rc_skipped || rc->rc_error == ENXIO || rc->rc_error == ESTALE); + + if (cols[VDEV_RAIDZ_P].rc_error == 0) { + vdev_raidz_reconstruct_p(cols, nparity, + acols, c); + } else { + //ASSERT(nparity > 1); + vdev_raidz_reconstruct_q(cols, nparity, + acols, c); + } + + if (zio_checksum_error(bp, buf) == 0) + return (0); + break; + + case 2: + /* + * Two data column errors require double parity. + */ + //ASSERT(nparity == 2); + + /* + * Find the two columns that reported errors. + */ + for (c = nparity; c < acols; c++) { + rc = &cols[c]; + if (rc->rc_error != 0) + break; + } + //ASSERT(c != acols); + //ASSERT(!rc->rc_skipped || rc->rc_error == ENXIO || rc->rc_error == ESTALE); + + for (c1 = c++; c < acols; c++) { + rc = &cols[c]; + if (rc->rc_error != 0) + break; + } + //ASSERT(c != acols); + //ASSERT(!rc->rc_skipped || rc->rc_error == ENXIO || rc->rc_error == ESTALE); + + vdev_raidz_reconstruct_pq(cols, nparity, acols, + c1, c); + + if (zio_checksum_error(bp, buf) == 0) + return (0); + break; + + default: + break; + //ASSERT(nparity <= 2); + //ASSERT(0); + } + } + + /* + * This isn't a typical situation -- either we got a read + * error or a child silently returned bad data. Read every + * block so we can try again with as much data and parity as + * we can track down. If we've already been through once + * before, all children will be marked as tried so we'll + * proceed to combinatorial reconstruction. + */ + n = 0; + for (c = 0; c < acols; c++) { + rc = &cols[c]; + if (rc->rc_tried) + continue; + + devidx = rc->rc_devidx; + STAILQ_FOREACH(kid, &vdev->v_children, v_childlink) + if (kid->v_id == devidx) + break; + if (kid == NULL || kid->v_state != VDEV_STATE_HEALTHY) { + rc->rc_error = ENXIO; + rc->rc_tried = 1; /* don't even try */ + rc->rc_skipped = 1; + continue; + } + if (rc->rc_data) + rc->rc_error = kid->v_read(kid, NULL, + rc->rc_data, rc->rc_offset, rc->rc_size); + else + rc->rc_error = ENXIO; + if (rc->rc_error == 0) + n++; + rc->rc_tried = 1; + rc->rc_skipped = 0; + } + + /* + * If we managed to read anything more, retry the + * reconstruction. + */ + if (n) + goto reconstruct; + + /* + * At this point we've attempted to reconstruct the data given the + * errors we detected, and we've attempted to read all columns. There + * must, therefore, be one or more additional problems -- silent errors + * resulting in invalid data rather than explicit I/O errors resulting + * in absent data. Before we attempt combinatorial reconstruction make + * sure we have a chance of coming up with the right answer. + */ + if (total_errors >= nparity) { + return (EIO); + } + + asize = 0; + for (c = 0; c < acols; c++) { + rc = &cols[c]; + if (rc->rc_size > asize) + asize = rc->rc_size; + } + if (cols[VDEV_RAIDZ_P].rc_error == 0) { + /* + * Attempt to reconstruct the data from parity P. + */ + void *orig; + orig = zfs_alloc_temp(asize); + for (c = nparity; c < acols; c++) { + rc = &cols[c]; + + memcpy(orig, rc->rc_data, rc->rc_size); + vdev_raidz_reconstruct_p(cols, nparity, acols, c); + + if (zio_checksum_error(bp, buf) == 0) + return (0); + + memcpy(rc->rc_data, orig, rc->rc_size); + } + } + + if (nparity > 1 && cols[VDEV_RAIDZ_Q].rc_error == 0) { + /* + * Attempt to reconstruct the data from parity Q. + */ + void *orig; + orig = zfs_alloc_temp(asize); + for (c = nparity; c < acols; c++) { + rc = &cols[c]; + + memcpy(orig, rc->rc_data, rc->rc_size); + vdev_raidz_reconstruct_q(cols, nparity, acols, c); + + if (zio_checksum_error(bp, buf) == 0) + return (0); + + memcpy(rc->rc_data, orig, rc->rc_size); + } + } + + if (nparity > 1 && + cols[VDEV_RAIDZ_P].rc_error == 0 && + cols[VDEV_RAIDZ_Q].rc_error == 0) { + /* + * Attempt to reconstruct the data from both P and Q. + */ + void *orig, *orig1; + orig = zfs_alloc_temp(asize); + orig1 = zfs_alloc_temp(asize); + for (c = nparity; c < acols - 1; c++) { + rc = &cols[c]; + + memcpy(orig, rc->rc_data, rc->rc_size); + + for (c1 = c + 1; c1 < acols; c1++) { + rc1 = &cols[c1]; + + memcpy(orig1, rc1->rc_data, rc1->rc_size); + + vdev_raidz_reconstruct_pq(cols, nparity, + acols, c, c1); + + if (zio_checksum_error(bp, buf) == 0) + return (0); + + memcpy(rc1->rc_data, orig1, rc1->rc_size); + } + + memcpy(rc->rc_data, orig, rc->rc_size); + } + } + + return (EIO); +} + From 41aa1f3545420b69b455d4e327886bb75cfe7de6 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sat, 16 May 2009 12:11:06 +0000 Subject: [PATCH 210/544] Make the HARDWARE section ready for the automatic hardware notes generation, fix the date format. --- share/man/man4/urtw.4 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/share/man/man4/urtw.4 b/share/man/man4/urtw.4 index a62fa94390c5..80550a78a950 100644 --- a/share/man/man4/urtw.4 +++ b/share/man/man4/urtw.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd November 15 2008 $ +.Dd November 15, 2008 .Dt URTW 4 .Os .Sh NAME @@ -64,13 +64,15 @@ Only one virtual interface may be configured at any time. For more information on configuring this device, see .Xr ifconfig 8 . .Sh HARDWARE -The following adapters should work: +The +.Nm +driver supports Realtek RTL8187L based wireless network devices, including: .Pp -.Bl -column "Card " "Radio " "Bus" -compact -offset 6n +.Bl -column "Shuttle XPC Accessory PN20" "RTL8225" "USB" -compact -offset 6n .It Em "Card Radio Bus" -.It Li "Netgear WG111v2" Ta RTL8225 Ta USB -.It Li "Safehome WLG-1500SMA5" Ta RTL8225 Ta USB -.It Li "Shuttle XPC Accessory PN20" Ta RTL8225 Ta USB +.It "Netgear WG111v2 RTL8225 USB" +.It "Safehome WLG-1500SMA5 RTL8225 USB" +.It "Shuttle XPC Accessory PN20 RTL8225 USB" .El .Sh EXAMPLES Join an existing BSS network (i.e., connect to an access point): From 7d04813b132d5623b7435c9ff3bbeeaa095454ba Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sat, 16 May 2009 12:12:31 +0000 Subject: [PATCH 211/544] Add bwi(4) and urtw(4). --- release/doc/en_US.ISO8859-1/hardware/article.sgml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/release/doc/en_US.ISO8859-1/hardware/article.sgml b/release/doc/en_US.ISO8859-1/hardware/article.sgml index f7182029d768..3521600f1672 100644 --- a/release/doc/en_US.ISO8859-1/hardware/article.sgml +++ b/release/doc/en_US.ISO8859-1/hardware/article.sgml @@ -898,6 +898,8 @@ &hwlist.ath; + &hwlist.bwi; + [&arch.i386;, &arch.amd64;] Intel PRO/Wireless 2100 MiniPCI network adapter (&man.ipw.4; driver) @@ -922,6 +924,8 @@ &hwlist.ural; + &hwlist.urtw; + [&arch.amd64;, &arch.i386;, &arch.pc98;] Lucent Technologies WaveLAN/IEEE 802.11b wireless network adapters and workalikes using the Lucent Hermes, Intersil PRISM-II, From 36744d51a64166bef17df1555239cf0b45120a17 Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Sat, 16 May 2009 15:12:56 +0000 Subject: [PATCH 212/544] o Add missed semicolon in action script. PR: conf/134579 Submitted by: Lucius Windschuh MFC after: 1 week --- etc/devd.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/devd.conf b/etc/devd.conf index f4f04ad55881..696ac7c5f1aa 100644 --- a/etc/devd.conf +++ b/etc/devd.conf @@ -132,7 +132,7 @@ attach 100 { match "vendor" "0x1645"; match "product" "0x8001"; match "release" "0x0101"; - action "if ! kldstat -n usio > /dev/null 2>&1 ; then kldload usio; fi /usr/sbin/ezdownload -v -f /usr/share/usb/firmware/1645.8001.0101 /dev/$device-name"; + action "if ! kldstat -n usio > /dev/null 2>&1 ; then kldload usio; fi; /usr/sbin/ezdownload -v -f /usr/share/usb/firmware/1645.8001.0101 /dev/$device-name"; }; # This entry starts the ColdSync tool in daemon mode. Make sure you have an up From ae28ded2c8322f9363327cf2338070d08b0893b8 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Sat, 16 May 2009 15:21:08 +0000 Subject: [PATCH 213/544] - Fix spelling. --- sys/mips/mips/pm_machdep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/mips/mips/pm_machdep.c b/sys/mips/mips/pm_machdep.c index e9e6ea294a7a..9fb1feca3fb6 100644 --- a/sys/mips/mips/pm_machdep.c +++ b/sys/mips/mips/pm_machdep.c @@ -130,7 +130,7 @@ sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) sfp = (struct sigframe *)((vm_offset_t)(regs->sp - sizeof(struct sigframe)) & ~(sizeof(__int64_t) - 1)); - /* Translate the signal is appropriate */ + /* Translate the signal if appropriate */ if (p->p_sysent->sv_sigtbl) { if (sig <= p->p_sysent->sv_sigsize) sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)]; From d4dd69c46cf0a3513b5ae06bd7f3e579574985d3 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sat, 16 May 2009 18:42:18 +0000 Subject: [PATCH 214/544] Emulate SO_PEERCRED socket option. Temporarily use 0 for pid member as the FreeBSD does not cache remote UNIX domain socket peer pid. PR: kern/102956 Reviewed by: rwatson Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_socket.c | 21 ++++++++++++++++++++- sys/compat/linux/linux_socket.h | 6 ++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index bb2090c77725..da7d82905d66 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1354,7 +1354,9 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) } */ bsd_args; l_timeval linux_tv; struct timeval tv; - socklen_t tv_len; + socklen_t tv_len, xulen; + struct xucred xu; + struct l_ucred lxu; int error, name; bsd_args.s = args->s; @@ -1377,6 +1379,23 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) sizeof(linux_tv))); /* NOTREACHED */ break; + case LOCAL_PEERCRED: + if (args->optlen != sizeof(lxu)) + return (EINVAL); + xulen = sizeof(xu); + error = kern_getsockopt(td, args->s, bsd_args.level, + name, &xu, UIO_SYSSPACE, &xulen); + if (error) + return (error); + /* + * XXX Use 0 for pid as the FreeBSD does not cache peer pid. + */ + lxu.pid = 0; + lxu.uid = xu.cr_uid; + lxu.gid = xu.cr_gid; + return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu))); + /* NOTREACHED */ + break; default: break; } diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index 9257a7db593c..311b1524f21e 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -90,4 +90,10 @@ #define LINUX_AF_APPLETALK 5 #define LINUX_AF_INET6 10 +struct l_ucred { + uint32_t pid; + uint32_t uid; + uint32_t gid; +}; + #endif /* _LINUX_SOCKET_H_ */ From 6994ea543f06af0c76234dae538e8d9759735e12 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sat, 16 May 2009 18:44:56 +0000 Subject: [PATCH 215/544] Use the protocol family constants for the domain argument validation. Return immediately when the socket() failed. Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_socket.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index da7d82905d66..ee7bf184ad05 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -602,10 +602,12 @@ linux_socket(struct thread *td, struct linux_socket_args *args) return (EAFNOSUPPORT); retval_socket = socket(td, &bsd_args); + if (retval_socket) + return (retval_socket); + if (bsd_args.type == SOCK_RAW && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) - && bsd_args.domain == AF_INET - && retval_socket >= 0) { + && bsd_args.domain == PF_INET) { /* It's a raw IP socket: set the IP_HDRINCL option. */ int hdrincl; @@ -620,7 +622,7 @@ linux_socket(struct thread *td, struct linux_socket_args *args) * default and some apps depend on this. So, set V6ONLY to 0 * for Linux apps if the sysctl value is set to 1. */ - if (bsd_args.domain == PF_INET6 && retval_socket >= 0 + if (bsd_args.domain == PF_INET6 #ifndef KLD_MODULE /* * XXX: Avoid undefined symbol error with an IPv4 only From eeb63e515f60b0e1bdff8fc25130b8f3e9489582 Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sat, 16 May 2009 18:46:51 +0000 Subject: [PATCH 216/544] Return EINVAL in case when the incorrect or unsupported type argument is specified. Do not map type argument value as its Linux values are identical to FreeBSD values. Approved by: kib (mentor) --- sys/compat/linux/linux_socket.c | 2 ++ sys/compat/linux/linux_socket.h | 10 ++++++++++ 2 files changed, 12 insertions(+) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index ee7bf184ad05..e99ef84f414e 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -597,6 +597,8 @@ linux_socket(struct thread *td, struct linux_socket_args *args) bsd_args.protocol = args->protocol; bsd_args.type = args->type; + if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX) + return (EINVAL); bsd_args.domain = linux_to_bsd_domain(args->domain); if (bsd_args.domain == -1) return (EAFNOSUPPORT); diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index 311b1524f21e..0730761cfc2b 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -90,6 +90,16 @@ #define LINUX_AF_APPLETALK 5 #define LINUX_AF_INET6 10 +/* Supported socket types */ + +#define LINUX_SOCK_STREAM 1 +#define LINUX_SOCK_DGRAM 2 +#define LINUX_SOCK_RAW 3 +#define LINUX_SOCK_RDM 4 +#define LINUX_SOCK_SEQPACKET 5 + +#define LINUX_SOCK_MAX LINUX_SOCK_SEQPACKET + struct l_ucred { uint32_t pid; uint32_t uid; From 3933bde22e2b21e4be54f033529b164b72aca3ea Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Sat, 16 May 2009 18:48:41 +0000 Subject: [PATCH 217/544] Somewhere between 2.6.23 and 2.6.27, Linux added SOCK_CLOEXEC and SOCK_NONBLOCK flags, that allow to save fcntl() calls. Implement a variation of the socket() syscall which takes a flags in addition to the type argument. Approved by: kib (mentor) MFC after: 1 month --- sys/amd64/linux32/linux.h | 1 + sys/compat/linux/linux_socket.c | 25 +++++++++++++++++++++++-- sys/compat/linux/linux_socket.h | 7 +++++++ sys/i386/linux/linux.h | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 59970fdd3ce9..781acbbe9462 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -571,6 +571,7 @@ int linux_ioctl_unregister_handler(struct linux_ioctl_handler *h); #define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ #define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ #define LINUX_O_NOATIME 01000000 +#define LINUX_O_CLOEXEC 02000000 #define LINUX_F_DUPFD 0 #define LINUX_F_GETFD 1 diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index e99ef84f414e..86cbcd64a65a 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -593,10 +593,13 @@ linux_socket(struct thread *td, struct linux_socket_args *args) int type; int protocol; } */ bsd_args; - int retval_socket; + int retval_socket, socket_flags; bsd_args.protocol = args->protocol; - bsd_args.type = args->type; + socket_flags = args->type & ~LINUX_SOCK_TYPE_MASK; + if (socket_flags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK)) + return (EINVAL); + bsd_args.type = args->type & LINUX_SOCK_TYPE_MASK; if (bsd_args.type < 0 || bsd_args.type > LINUX_SOCK_MAX) return (EINVAL); bsd_args.domain = linux_to_bsd_domain(args->domain); @@ -607,6 +610,23 @@ linux_socket(struct thread *td, struct linux_socket_args *args) if (retval_socket) return (retval_socket); + if (socket_flags & LINUX_SOCK_NONBLOCK) { + retval_socket = kern_fcntl(td, td->td_retval[0], + F_SETFL, O_NONBLOCK); + if (retval_socket) { + (void)kern_close(td, td->td_retval[0]); + goto out; + } + } + if (socket_flags & LINUX_SOCK_CLOEXEC) { + retval_socket = kern_fcntl(td, td->td_retval[0], + F_SETFD, FD_CLOEXEC); + if (retval_socket) { + (void)kern_close(td, td->td_retval[0]); + goto out; + } + } + if (bsd_args.type == SOCK_RAW && (bsd_args.protocol == IPPROTO_RAW || bsd_args.protocol == 0) && bsd_args.domain == PF_INET) { @@ -642,6 +662,7 @@ linux_socket(struct thread *td, struct linux_socket_args *args) } #endif +out: return (retval_socket); } diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index 0730761cfc2b..67903c5e600e 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -100,6 +100,13 @@ #define LINUX_SOCK_MAX LINUX_SOCK_SEQPACKET +#define LINUX_SOCK_TYPE_MASK 0xf + +/* Flags for socket, socketpair, accept4 */ + +#define LINUX_SOCK_CLOEXEC LINUX_O_CLOEXEC +#define LINUX_SOCK_NONBLOCK LINUX_O_NONBLOCK + struct l_ucred { uint32_t pid; uint32_t uid; diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 132e431a6009..b7a883071b22 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -547,6 +547,7 @@ int linux_ioctl_unregister_handler(struct linux_ioctl_handler *h); #define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ #define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ #define LINUX_O_NOATIME 01000000 +#define LINUX_O_CLOEXEC 02000000 #define LINUX_F_DUPFD 0 #define LINUX_F_GETFD 1 From 32237d8492dbc0b2b232062f16fe47c5b1745f58 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 19:17:15 +0000 Subject: [PATCH 218/544] apply band-aid to x86_64 systems with more physical memory than kmem by allocating from the direct map --- .../opensolaris/uts/common/fs/zfs/arc.c | 22 +++-- .../opensolaris/uts/common/fs/zfs/zio.c | 93 ++++++++++++++++++- sys/vm/vm_contig.c | 7 +- 3 files changed, 109 insertions(+), 13 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index a3e25803933f..d1433dafedb7 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -172,6 +172,7 @@ uint64_t zfs_arc_max; uint64_t zfs_arc_min; uint64_t zfs_arc_meta_limit = 0; int zfs_mdcomp_disable = 0; +int arc_large_memory_enabled = 0; TUNABLE_QUAD("vfs.zfs.arc_max", &zfs_arc_max); TUNABLE_QUAD("vfs.zfs.arc_min", &zfs_arc_min); @@ -3429,17 +3430,13 @@ arc_init(void) arc_min_prefetch_lifespan = 1 * hz; /* Start out with 1/8 of all memory */ +#if defined(_KERNEL) && (__amd64__) + arc_c = physmem*PAGE_SIZE / 8; + if (physmem*PAGE_SIZE > kmem_size()) + arc_large_memory_enabled = 1; +#else arc_c = kmem_size() / 8; -#if 0 -#ifdef _KERNEL - /* - * On architectures where the physical memory can be larger - * than the addressable space (intel in 32-bit mode), we may - * need to limit the cache to 1/8 of VM size. - */ - arc_c = MIN(arc_c, vmem_size(heap_arena, VMEM_ALLOC | VMEM_FREE) / 8); -#endif -#endif +#endif /* set min cache to 1/32 of all memory, or 16MB, whichever is more */ arc_c_min = MAX(arc_c / 4, 64<<18); /* set max to 1/2 of all memory, or all but 1GB, whichever is more */ @@ -3453,8 +3450,13 @@ arc_init(void) * Allow the tunables to override our calculations if they are * reasonable (ie. over 16MB) */ +#if defined(_KERNEL) && defined(__amd64__) + if (zfs_arc_max >= 64<<18) + arc_c_max = zfs_arc_max; +#else if (zfs_arc_max >= 64<<18 && zfs_arc_max < kmem_size()) arc_c_max = zfs_arc_max; +#endif if (zfs_arc_min >= 64<<18 && zfs_arc_min <= arc_c_max) arc_c_min = zfs_arc_min; #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 4650d42b7c2f..6ac642edf33e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -33,6 +33,9 @@ #include #include +#if defined(_KERNEL) && defined(__amd64__) +#include +#endif /* * ========================================================================== * I/O priority table @@ -85,6 +88,8 @@ extern vmem_t *zio_alloc_arena; #define IO_IS_ALLOCATING(zio) \ ((zio)->io_orig_pipeline & (1U << ZIO_STAGE_DVA_ALLOCATE)) +extern int arc_large_memory_enabled; + void zio_init(void) { @@ -205,6 +210,80 @@ zio_buf_alloc(size_t size) #endif } +#if defined(_KERNEL) && defined(__amd64__) +extern int vm_contig_launder(int queue); + +static void * +zio_large_malloc(size_t size) +{ + void *ret; + vm_page_t pages; + unsigned long npgs; + int actl, actmax, inactl, inactmax, tries; + int flags = M_WAITOK; + vm_paddr_t low = (1UL<<29); /* leave lower 512MB untouched */ + vm_paddr_t high = ~(vm_paddr_t)0; + unsigned long alignment = 1; + unsigned long boundary = 0; + + npgs = round_page(size) >> PAGE_SHIFT; + tries = 0; +retry: + pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary); + if (pages == NULL) { + if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { + vm_page_lock_queues(); + inactl = 0; + inactmax = tries < 1 ? 0 : cnt.v_inactive_count; + actl = 0; + actmax = tries < 2 ? 0 : cnt.v_active_count; +again: + if (inactl < inactmax && + vm_contig_launder(PQ_INACTIVE)) { + inactl++; + goto again; + } + if (actl < actmax && + vm_contig_launder(PQ_ACTIVE)) { + actl++; + goto again; + } + vm_page_unlock_queues(); + tries++; + goto retry; + } + + ret = NULL; + } else { + int i; + + vm_page_lock_queues(); + for (i = 0; i < npgs; i++) + vm_page_wire(&pages[i]); + vm_page_unlock_queues(); + + return (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pages)); + } + return (ret); +} + +static void +zio_large_free(void *buf, size_t size) +{ + int npgs = round_page(size) >> PAGE_SHIFT; + int i; + vm_page_t m; + + m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)buf)); + vm_page_lock_queues(); + for (i = 0; i < npgs; i++, m++) { + vm_page_unwire(m, 0); + vm_page_free(m); + } + vm_page_unlock_queues(); +} +#endif + /* * Use zio_data_buf_alloc to allocate data. The data will not appear in a * crashdump if the kernel panics. This exists so that we will limit the amount @@ -221,7 +300,12 @@ zio_data_buf_alloc(size_t size) return (kmem_cache_alloc(zio_data_buf_cache[c], KM_PUSHPAGE)); #else - return (kmem_alloc(size, KM_SLEEP)); +#if defined(_KERNEL) && defined(__amd64__) + if (arc_large_memory_enabled && (size > PAGE_SIZE)) + return (zio_large_malloc(size)); + else +#endif + return (kmem_alloc(size, KM_SLEEP)); #endif } @@ -249,7 +333,12 @@ zio_data_buf_free(void *buf, size_t size) kmem_cache_free(zio_data_buf_cache[c], buf); #else - kmem_free(buf, size); +#if defined (_KERNEL) && defined(__amd64__) + if (arc_large_memory_enabled && (size > PAGE_SIZE)) + zio_large_free(buf, size); + else +#endif + kmem_free(buf, size); #endif } diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 8fec101d2e03..9a5220d72b3f 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -87,6 +87,11 @@ __FBSDID("$FreeBSD$"); #include #include +/* + * Only available as a band-aid to ZFS + */ +int vm_contig_launder(int queue); + static int vm_contig_launder_page(vm_page_t m, vm_page_t *next) { @@ -146,7 +151,7 @@ vm_contig_launder_page(vm_page_t m, vm_page_t *next) return (0); } -static int +int vm_contig_launder(int queue) { vm_page_t m, next; From 71bc1ce36ed658c10ee8c673d76b30daf0b29b83 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 20:09:07 +0000 Subject: [PATCH 219/544] only use direct map if system has more than 2GB --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index d1433dafedb7..871135583ffb 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -3432,7 +3432,7 @@ arc_init(void) /* Start out with 1/8 of all memory */ #if defined(_KERNEL) && (__amd64__) arc_c = physmem*PAGE_SIZE / 8; - if (physmem*PAGE_SIZE > kmem_size()) + if (physmem*PAGE_SIZE > kmem_size() && (physmem > (1UL<<31))) arc_large_memory_enabled = 1; #else arc_c = kmem_size() / 8; From 1adf50eea8d2b0e5de03d8b5fae9c92ab77a2a00 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 16 May 2009 20:26:01 +0000 Subject: [PATCH 220/544] Trim trailing whitespace from the end of a line --- etc/rc.d/named | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/etc/rc.d/named b/etc/rc.d/named index e40a464b3d99..e90fd13de8dd 100755 --- a/etc/rc.d/named +++ b/etc/rc.d/named @@ -79,7 +79,7 @@ chroot_autoupdate() fi fi - # Copy and/or update key files to the chroot /etc + # Copy and/or update key files to the chroot /etc # for file in localtime protocols services; do if [ -r /etc/$file ]; then From be08aa8b590b7b4d423d44c118ab7ea4a0201e95 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 20:33:13 +0000 Subject: [PATCH 221/544] - allow forced unmounts - don't assume snapshot was auto-mounted --- .../contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c index 835aa532327a..831bd2df415e 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c @@ -967,8 +967,7 @@ zfs_umount(vfs_t *vfsp, int fflag) if (fflag & MS_FORCE) { /* TODO: Force unmount is not well implemented yet, so deny it. */ - ZFS_LOG(0, "Force unmount is not supported, removing FORCE flag."); - fflag &= ~MS_FORCE; + ZFS_LOG(0, "Force unmount is experimental - report any problems."); } ret = secpolicy_fs_unmount(cr, vfsp); @@ -1070,8 +1069,9 @@ zfs_umount(vfs_t *vfsp, int fflag) if (zfsvfs->z_issnap) { vnode_t *svp = vfsp->mnt_vnodecovered; - ASSERT(svp->v_count == 2); - VN_RELE(svp); + ASSERT(svp->v_count == 2 || svp->v_count == 1); + if (svp->v_count == 2) + VN_RELE(svp); } zfs_freevfs(vfsp); From 94d77159ae203e774af3df615a590093f1ce10ce Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 16 May 2009 20:55:28 +0000 Subject: [PATCH 222/544] 1. New feature; option to have the script loop until a specified hostname (localhost by default) can be successfully looked up. Off by default. 2. New feature: option to create a forwarder configuration file based on the contents of /etc/resolv.conf. This allows you to utilize a local resolver for better performance, less network traffic, custom zones, etc. while still relying on the benefits of your local network resolver. Off by default. 3. Add named-checkconf into the startup routine. This will prevent named from trying to start in a situation where it would not be possible to do so. --- etc/defaults/rc.conf | 5 ++ etc/namedb/named.conf | 20 +++++--- etc/rc.d/named | 98 +++++++++++++++++++++++++++++++++++++++- share/man/man5/rc.conf.5 | 26 +++++++++++ 4 files changed, 142 insertions(+), 7 deletions(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index f1c37999727d..71b88a1b9362 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -247,6 +247,7 @@ inetd_flags="-wW -C 60" # Optional flags to inetd # named_enable="NO" # Run named, the DNS server (or NO). named_program="/usr/sbin/named" # Path to named, if you want a different one. +named_conf="/etc/namedb/named.conf" # Path to the configuration file #named_flags="-c /etc/namedb/named.conf" # Uncomment for named not in /usr/sbin named_pidfile="/var/run/named/pid" # Must set this in named.conf as well named_uid="bind" # User to run named as @@ -254,6 +255,10 @@ named_chrootdir="/var/named" # Chroot directory (or "" not to auto-chroot it) named_chroot_autoupdate="YES" # Automatically install/update chrooted # components of named. See /etc/rc.d/named. named_symlink_enable="YES" # Symlink the chrooted pid file +named_wait="NO" # Wait for working name service before exiting +named_wait_host="localhost" # Hostname to check if named_wait is enabled +named_auto_forward="NO" # Set up forwarders from /etc/resolv.conf +named_auto_forward_only="NO" # Do "forward only" instead of "forward first" # # kerberos. Do not run the admin daemons on slave servers diff --git a/etc/namedb/named.conf b/etc/namedb/named.conf index dd2d115db0be..c9b09cba7ce6 100644 --- a/etc/namedb/named.conf +++ b/etc/namedb/named.conf @@ -31,12 +31,6 @@ options { disable-empty-zone "0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA"; disable-empty-zone "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.IP6.ARPA"; -// In addition to the "forwarders" clause, you can force your name -// server to never initiate queries of its own, but always ask its -// forwarders only, by enabling the following line: -// -// forward only; - // If you've got a DNS server around at your upstream provider, enter // its IP address here, and enable the line below. This will make you // benefit from its cache, thus reduce overall DNS traffic in the Internet. @@ -45,6 +39,20 @@ options { 127.0.0.1; }; */ + +// If the 'forwarders' clause is not empty the default is to 'forward first' +// which will fall back to sending a query from your local server if the name +// servers in 'forwarders' do not have the answer. Alternatively you can +// force your name server to never initiate queries of its own by enabling the +// following line: +// forward only; + +// If you wish to have forwarding configured automatically based on +// the entries in /etc/resolv.conf, uncomment the following line and +// set named_auto_forward=yes in /etc/rc.conf. You can also enable +// named_auto_forward_only (the effect of which is described above). +// include "/etc/namedb/auto_forward.conf"; + /* Modern versions of BIND use a random UDP port for each outgoing query by default in order to dramatically reduce the possibility diff --git a/etc/rc.d/named b/etc/rc.d/named index e90fd13de8dd..65a13a54eb91 100755 --- a/etc/rc.d/named +++ b/etc/rc.d/named @@ -16,7 +16,7 @@ command="/usr/sbin/named" extra_commands="reload" start_precmd="named_precmd" -start_postcmd="make_symlinks" +start_postcmd="named_poststart" reload_cmd="named_reload" stop_cmd="named_stop" stop_postcmd="named_poststop" @@ -97,6 +97,17 @@ make_symlinks() ln -fs "${named_chrootdir}${pidfile}" ${pidfile} } +named_poststart () { + make_symlinks + + if checkyesno named_wait; then + until ${command%/sbin/named}/bin/host $named_wait_host >/dev/null 2>&1; do + echo " Waiting for nameserver to resolve $named_wait_host" + sleep 1 + done + fi +} + named_reload() { ${command%/named}/rndc reload @@ -135,8 +146,19 @@ named_poststop() fi } +create_file () { + if [ -e "$1" ]; then + unlink $1 + fi + > $1 + chown root:wheel $1 + chmod 644 $1 +} + named_precmd() { + local line nsip firstns + # Is the user using a sandbox? # if [ -n "$named_chrootdir" ]; then @@ -161,6 +183,80 @@ named_precmd() else $confgen_command fi + + # Create a forwarder configuration based on /etc/resolv.conf + if checkyesno named_auto_forward; then + if [ ! -s /etc/resolv.conf ]; then + warn "named_auto_forward enabled, but no /etc/resolv.conf" + + # Empty the file in case it is included in named.conf + [ -s "${named_chrootdir}/etc/namedb/auto_forward.conf" ] && + create_file ${named_chrootdir}/etc/namedb/auto_forward.conf + + ${command%/named}/named-checkconf $named_conf || + err 3 'named-checkconf for $named_conf failed' + return + fi + + create_file /var/run/naf-resolv.conf + create_file /var/run/auto_forward.conf + + echo ' forwarders {' > /var/run/auto_forward.conf + + while read line; do + case "$line" in + 'nameserver '*|'nameserver '*) + nsip=${line##nameserver[ ]} + + if [ -z "$firstns" ]; then + if [ ! "$nsip" = '127.0.0.1' ]; then + echo 'nameserver 127.0.0.1' + echo " ${nsip};" >> /var/run/auto_forward.conf + fi + + firstns=1 + else + [ "$nsip" = '127.0.0.1' ] && continue + echo " ${nsip};" >> /var/run/auto_forward.conf + fi + ;; + esac + + echo $line + done < /etc/resolv.conf > /var/run/naf-resolv.conf + + echo ' };' >> /var/run/auto_forward.conf + echo '' >> /var/run/auto_forward.conf + if checkyesno named_auto_forward_only; then + echo " forward only;" >> /var/run/auto_forward.conf + else + echo " forward first;" >> /var/run/auto_forward.conf + fi + + if cmp -s /etc/resolv.conf /var/run/naf-resolv.conf; then + unlink /var/run/naf-resolv.conf + else + [ -e /etc/resolv.conf ] && unlink /etc/resolv.conf + mv /var/run/naf-resolv.conf /etc/resolv.conf + fi + + if cmp -s ${named_chrootdir}/etc/namedb/auto_forward.conf \ + /var/run/auto_forward.conf; then + unlink /var/run/auto_forward.conf + else + [ -e "${named_chrootdir}/etc/namedb/auto_forward.conf" ] && + unlink ${named_chrootdir}/etc/namedb/auto_forward.conf + mv /var/run/auto_forward.conf \ + ${named_chrootdir}/etc/namedb/auto_forward.conf + fi + else + # Empty the file in case it is included in named.conf + [ -s "${named_chrootdir}/etc/namedb/auto_forward.conf" ] && + create_file ${named_chrootdir}/etc/namedb/auto_forward.conf + fi + + ${command%/named}/named-checkconf $named_conf || + err 3 'named-checkconf for $named_conf failed' } load_rc_config $name diff --git a/share/man/man5/rc.conf.5 b/share/man/man5/rc.conf.5 index 83460713a230..3075a4e70838 100644 --- a/share/man/man5/rc.conf.5 +++ b/share/man/man5/rc.conf.5 @@ -1631,6 +1631,12 @@ Path to .Xr named 8 (default .Pa /usr/sbin/named ) . +.It Va named_conf +.Pq Vt str +Path to +.Xr named 8 +configuration file, (default +.Pa /etc/namedb/named.conf ) . .It Va named_flags .Pq Vt str If @@ -1678,6 +1684,26 @@ daemon's PID file into the .Xr chroot 8 environment. +.It Va named_wait +.Pq Vt bool +Set to have +.Pa /etc/rc.d/named +loop until working name service is established. +.It Va named_wait_host +.Pq Vt str +Name of host to lookup for the named_wait option. +(Default localhost) +.It Va named_auto_forward +.Pq Vt bool +Set to enable automatic creation of a forwarder +configuration file derived from +.Pa /etc/resolv.conf . +.It Va named_auto_forward_only +.Pq Vt bool +Set to change the default forwarder configuration from +.Dq forward first +to +.Dq forward only . .It Va kerberos5_server_enable .Pq Vt bool Set to From b6d82b1ae9f943fab991ee8079a7364c10ef118b Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 20:57:08 +0000 Subject: [PATCH 223/544] Increase default kernel map to 512GB I briefly discussed this with alc. It could lead to problems for greater than 64GB. However, that seems unlikely in practice. --- sys/amd64/include/vmparam.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 38370de60c2c..3fec7480b795 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -155,7 +155,7 @@ * 0xffff804020101000 - 0xfffffeffffffffff unused * 0xffffff0000000000 - 0xffffff7fffffffff 512GB direct map mappings * 0xffffff8000000000 - 0xfffffffe3fffffff unused (505GB) - * 0xfffffffe40000000 - 0xffffffffffffffff 7GB kernel map + * 0xfffffffe40000000 - 0xffffffffffffffff 512GB kernel map * * Within the kernel map: * @@ -163,7 +163,7 @@ */ #define VM_MAX_KERNEL_ADDRESS KVADDR(KPML4I, NPDPEPG-1, NPDEPG-1, NPTEPG-1) -#define VM_MIN_KERNEL_ADDRESS KVADDR(KPML4I, NPDPEPG-7, 0, 0) +#define VM_MIN_KERNEL_ADDRESS KVADDR(KPML4I, NPDPEPG-512, 0, 0) #define DMAP_MIN_ADDRESS KVADDR(DMPML4I, 0, 0, 0) #define DMAP_MAX_ADDRESS KVADDR(DMPML4I+1, 0, 0, 0) From 7d7a10d26191136848a7ad88776af558ded1ef0e Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 16 May 2009 21:32:09 +0000 Subject: [PATCH 224/544] Add -L to the mtree invocation to chase symbolic links that are present in "Service jails." Submitted by: Jeremie Le Hen --- usr.sbin/mergemaster/mergemaster.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh index e44499617ab6..9b8c656e6d19 100755 --- a/usr.sbin/mergemaster/mergemaster.sh +++ b/usr.sbin/mergemaster/mergemaster.sh @@ -461,7 +461,7 @@ MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk" # CHANGED= if [ -n "${AUTO_UPGRADE}" -a -f "${DESTDIR}${MTREEFILE}" ]; then - for file in `mtree -eq -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \ + for file in `mtree -eqL -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \ 2>/dev/null | awk '($2 == "changed") {print $1}'`; do if [ -f "${DESTDIR}/$file" ]; then CHANGED="${CHANGED} ${DESTDIR}/$file" From cd65fa6f16ea80c15a4155c76aa8b587cdad1dda Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sat, 16 May 2009 21:38:55 +0000 Subject: [PATCH 225/544] Sync up to rev. 1.25 from OpenBSD: 1.19: nop 1.20: nop 1.21: nop 1.22: typo fixed 1.23: license clauses 3 and 4 nuked 1.24: nop 1.25: Sun Crypto Accelerator 1000 has a 5821 chip on it Obtained from: OpenBSD MFC after: 3 days --- share/man/man4/ubsec.4 | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/share/man/man4/ubsec.4 b/share/man/man4/ubsec.4 index fdd02c0ee61a..4675da074026 100644 --- a/share/man/man4/ubsec.4 +++ b/share/man/man4/ubsec.4 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ubsec.4,v 1.18 2002/09/26 07:55:41 miod Exp $ +.\" $OpenBSD: ubsec.4,v 1.25 2003/08/12 19:42:46 jason Exp $ .\" .\" Copyright (c) 2000 Jason L. Wright (jason@thought.net) .\" All rights reserved. @@ -11,11 +11,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by Jason L. Wright -.\" 4. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED @@ -31,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 1, 2006 +.Dd May 16, 2009 .Dt UBSEC 4 .Os .Sh NAME @@ -84,7 +79,7 @@ driver supports cards containing any of the following chips: .It Bluesteel 5501 The original chipset, no longer made. This extremely rare unit -was not very fast, lacked a RNG, and had a number of other bugs. +was not very fast, lacked an RNG, and had a number of other bugs. .It Bluesteel 5601 A faster and fixed version of the original, with a random number unit and large number engine added. @@ -98,6 +93,7 @@ Faster version of Bluesteel 5601. 64 bit version of the chip, and significantly more advanced. .It Broadcom BCM5821 Faster version of the BCM5820. +This is the chip found on the Sun Crypto Accelerator 1000. .It Broadcom BCM5822 Faster version of the BCM5820. .It Broadcom BCM5823 From e1279022293d41e68b05e7d9a79c8a2eff7b780d Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 22:00:13 +0000 Subject: [PATCH 226/544] update vm map comment pointed out by Larry Rosenman --- sys/amd64/include/vmparam.h | 1 - 1 file changed, 1 deletion(-) diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 3fec7480b795..0fae57ce6a02 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -154,7 +154,6 @@ * 0xffff800000000000 - 0xffff804020100fff recursive page table (512GB slot) * 0xffff804020101000 - 0xfffffeffffffffff unused * 0xffffff0000000000 - 0xffffff7fffffffff 512GB direct map mappings - * 0xffffff8000000000 - 0xfffffffe3fffffff unused (505GB) * 0xfffffffe40000000 - 0xffffffffffffffff 512GB kernel map * * Within the kernel map: From b522d2c99b43e0c9a2dfc6456afdf571db104f28 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 22:08:00 +0000 Subject: [PATCH 227/544] correct range in comment pointed out by alc --- sys/amd64/include/vmparam.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/amd64/include/vmparam.h b/sys/amd64/include/vmparam.h index 0fae57ce6a02..0b5004c68189 100644 --- a/sys/amd64/include/vmparam.h +++ b/sys/amd64/include/vmparam.h @@ -154,7 +154,7 @@ * 0xffff800000000000 - 0xffff804020100fff recursive page table (512GB slot) * 0xffff804020101000 - 0xfffffeffffffffff unused * 0xffffff0000000000 - 0xffffff7fffffffff 512GB direct map mappings - * 0xfffffffe40000000 - 0xffffffffffffffff 512GB kernel map + * 0xffffff8000000000 - 0xffffffffffffffff 512GB kernel map * * Within the kernel map: * From e43c3a8bd913d07a66c00a713946f81add803641 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sat, 16 May 2009 22:18:58 +0000 Subject: [PATCH 228/544] Drop clause 3 of the license as per rev. 1.35 from OpenBSD. Obtained from: OpenBSD MFC after: 3 days --- share/man/man4/hifn.4 | 2 -- 1 file changed, 2 deletions(-) diff --git a/share/man/man4/hifn.4 b/share/man/man4/hifn.4 index ec7a56438bb4..9aeccfaf5f3d 100644 --- a/share/man/man4/hifn.4 +++ b/share/man/man4/hifn.4 @@ -11,8 +11,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR .\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED From 1b855ebe6c3388220b9f14e223541ed4e7689ad0 Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Sat, 16 May 2009 22:22:31 +0000 Subject: [PATCH 229/544] Enhance the safety of the -U option: 1. In several places make sure that the mtree database is not empty using the -s argument to test instead of -f. (I thought I'd already changed this, but obviously not.) 2. When deriving the list of changed files use a colon-delimited list. 3. If the list of changed files is empty, unset the variable, and test for a non-empty CHANGED in diff_loop() before entering that routine. Enhance the speed of the -U option by using an internal case statement instead of echoing the variable to an external grep for every file. Fix indentation on one line. --- usr.sbin/mergemaster/mergemaster.sh | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/usr.sbin/mergemaster/mergemaster.sh b/usr.sbin/mergemaster/mergemaster.sh index 9b8c656e6d19..f8b92c0488e8 100755 --- a/usr.sbin/mergemaster/mergemaster.sh +++ b/usr.sbin/mergemaster/mergemaster.sh @@ -115,8 +115,10 @@ diff_loop () { while [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" -o \ "${HANDLE_COMPFILE}" = "NOT V" ]; do if [ -f "${DESTDIR}${COMPFILE#.}" -a -f "${COMPFILE}" ]; then - if [ -n "${AUTO_UPGRADE}" ]; then - if echo "${CHANGED}" | grep -qsv ${DESTDIR}${COMPFILE#.}; then + if [ -n "${AUTO_UPGRADE}" -a -n "${CHANGED}" ]; then + case "${CHANGED}" in + *:${DESTDIR}${COMPFILE#.}:*) ;; # File has been modified + *) echo '' echo " *** ${COMPFILE} has not been user modified." echo '' @@ -128,10 +130,11 @@ diff_loop () { AUTO_UPGRADED_FILES="${AUTO_UPGRADED_FILES} ${DESTDIR}${COMPFILE#.} " else - echo " *** Problem upgrading ${COMPFILE}, it will remain to merge by hand" + echo " *** Problem upgrading ${COMPFILE}, it will remain to merge by hand" fi return - fi + ;; + esac fi if [ "${HANDLE_COMPFILE}" = "v" -o "${HANDLE_COMPFILE}" = "V" ]; then echo '' @@ -348,7 +351,7 @@ fi case "${AUTO_UPGRADE}" in '') ;; # If the option is not set no need to run the test or warn the user *) - if [ ! -f "${DESTDIR}${MTREEFILE}" ]; then + if [ ! -s "${DESTDIR}${MTREEFILE}" ]; then echo '' echo "*** Unable to find mtree database. Skipping auto-upgrade." echo '' @@ -459,14 +462,15 @@ MM_MAKE="make ${ARCHSTRING} -m ${SOURCEDIR}/share/mk" # Check DESTDIR against the mergemaster mtree database to see what # files the user changed from the reference files. # -CHANGED= -if [ -n "${AUTO_UPGRADE}" -a -f "${DESTDIR}${MTREEFILE}" ]; then +if [ -n "${AUTO_UPGRADE}" -a -s "${DESTDIR}${MTREEFILE}" ]; then + CHANGED=: for file in `mtree -eqL -f ${DESTDIR}${MTREEFILE} -p ${DESTDIR}/ \ 2>/dev/null | awk '($2 == "changed") {print $1}'`; do if [ -f "${DESTDIR}/$file" ]; then - CHANGED="${CHANGED} ${DESTDIR}/$file" + CHANGED="${CHANGED}${DESTDIR}/${file}:" fi done + [ "$CHANGED" = ':' ] && unset CHANGED fi # Check the width of the user's terminal @@ -1055,7 +1059,7 @@ done # This is for the for way up there at the beginning of the comparison echo '' echo "*** Comparison complete" -if [ -f "${MTREENEW}" ]; then +if [ -s "${MTREENEW}" ]; then echo "*** Saving mtree database for future upgrades" test -e "${DESTDIR}${MTREEFILE}" && unlink ${DESTDIR}${MTREEFILE} mv ${MTREENEW} ${DESTDIR}${MTREEFILE} From 72d1bbba521cb0281cbf3494fc470464d0342569 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sat, 16 May 2009 22:31:38 +0000 Subject: [PATCH 230/544] Changed sys/fs/nfs_clbio.c in the same way Alan Cox changed sys/nfsclient/nfs_bio.c for r192134, so that the sources stay in sync. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clbio.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index 0eb30f990d48..ae06a88383a9 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -313,9 +313,9 @@ ncl_getpages(struct vop_getpages_args *ap) * Read operation filled a partial page. */ m->valid = 0; - vm_page_set_validclean(m, 0, size - toff); - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ + vm_page_set_valid(m, 0, size - toff); + KASSERT((m->dirty & vm_page_bits(0, size - toff)) == 0, + ("nfs_getpages: page %p is dirty", m)); } else { /* * Read operation was short. If no error occured From 2e9c90d55b96af727f0b113c7634e3da264c3990 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 16 May 2009 23:56:45 +0000 Subject: [PATCH 231/544] enable adaptive spinning on zfs locks --- sys/cddl/compat/opensolaris/sys/mutex.h | 4 ++-- sys/cddl/compat/opensolaris/sys/rwlock.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/cddl/compat/opensolaris/sys/mutex.h b/sys/cddl/compat/opensolaris/sys/mutex.h index 8756cd0534f4..56c41a4f5e9d 100644 --- a/sys/cddl/compat/opensolaris/sys/mutex.h +++ b/sys/cddl/compat/opensolaris/sys/mutex.h @@ -47,9 +47,9 @@ typedef enum { typedef struct sx kmutex_t; #ifndef DEBUG -#define MUTEX_FLAGS (SX_DUPOK | SX_NOWITNESS) +#define MUTEX_FLAGS (SX_DUPOK | SX_NOWITNESS | SX_ADAPTIVESPIN) #else -#define MUTEX_FLAGS (SX_DUPOK) +#define MUTEX_FLAGS (SX_DUPOK | SX_ADAPTIVESPIN) #endif #define mutex_init(lock, desc, type, arg) do { \ diff --git a/sys/cddl/compat/opensolaris/sys/rwlock.h b/sys/cddl/compat/opensolaris/sys/rwlock.h index a3e55153bbcf..0d4ac2e1e2a9 100644 --- a/sys/cddl/compat/opensolaris/sys/rwlock.h +++ b/sys/cddl/compat/opensolaris/sys/rwlock.h @@ -49,9 +49,9 @@ typedef enum { typedef struct sx krwlock_t; #ifndef DEBUG -#define RW_FLAGS (SX_DUPOK | SX_NOWITNESS) +#define RW_FLAGS (SX_DUPOK | SX_NOWITNESS | SX_ADAPTIVESPIN) #else -#define RW_FLAGS (SX_DUPOK) +#define RW_FLAGS (SX_DUPOK | SX_ADAPTIVESPIN) #endif #define RW_READ_HELD(x) (rw_read_held((x))) From ea41c775176d4eef212c7669e728f121fb512d9c Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sun, 17 May 2009 01:31:28 +0000 Subject: [PATCH 232/544] SAVESTART implies SAVENAME --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 458d5bcb88af..d0ddaaa9e6ac 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -4253,8 +4253,8 @@ zfs_freebsd_rename(ap) vnode_t *tvp = ap->a_tvp; int error; - ASSERT(ap->a_fcnp->cn_flags & SAVENAME); - ASSERT(ap->a_tcnp->cn_flags & SAVENAME); + ASSERT(ap->a_fcnp->cn_flags & (SAVENAME|SAVESTART)); + ASSERT(ap->a_tcnp->cn_flags & (SAVENAME|SAVESTART)); error = zfs_rename(fdvp, ap->a_fcnp->cn_nameptr, tdvp, ap->a_tcnp->cn_nameptr, ap->a_fcnp->cn_cred, NULL, 0); From 044fce530f89a819827d351de364d208a30e9645 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Sun, 17 May 2009 04:00:43 +0000 Subject: [PATCH 233/544] Add a -d option to ps to display descendant info with the output. This is similar to linux's -H (or -f) switch. MFC after: 3 weeks --- bin/ps/print.c | 33 +++++++++---- bin/ps/ps.1 | 13 ++++- bin/ps/ps.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++-- bin/ps/ps.h | 4 ++ 4 files changed, 167 insertions(+), 15 deletions(-) diff --git a/bin/ps/print.c b/bin/ps/print.c index 3ae37fc1607c..1bfce04489e8 100644 --- a/bin/ps/print.c +++ b/bin/ps/print.c @@ -130,9 +130,11 @@ command(KINFO *k, VARENT *ve) if (cflag) { /* If it is the last field, then don't pad */ if (STAILQ_NEXT(ve, next_ve) == NULL) { + if (k->ki_d.prefix) + (void)printf("%s", k->ki_d.prefix); (void)printf("%s", k->ki_p->ki_comm); if (showthreads && k->ki_p->ki_numthreads > 1) - printf("/%s", k->ki_p->ki_ocomm); + (void)printf("/%s", k->ki_p->ki_ocomm); } else (void)printf("%-*s", v->width, k->ki_p->ki_comm); return; @@ -140,16 +142,22 @@ command(KINFO *k, VARENT *ve) if ((vis_args = malloc(strlen(k->ki_args) * 4 + 1)) == NULL) errx(1, "malloc failed"); strvis(vis_args, k->ki_args, VIS_TAB | VIS_NL | VIS_NOSLASH); - if (k->ki_env) { - if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) == NULL) - errx(1, "malloc failed"); - strvis(vis_env, k->ki_env, VIS_TAB | VIS_NL | VIS_NOSLASH); - } else - vis_env = NULL; if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field */ + + if (k->ki_env) { + if ((vis_env = malloc(strlen(k->ki_env) * 4 + 1)) + == NULL) + errx(1, "malloc failed"); + strvis(vis_env, k->ki_env, + VIS_TAB | VIS_NL | VIS_NOSLASH); + } else + vis_env = NULL; + if (termwidth == UNLIMITED) { + if (k->ki_d.prefix) + (void)printf("%s", k->ki_d.prefix); if (vis_env) (void)printf("%s ", vis_env); (void)printf("%s", vis_args); @@ -157,6 +165,9 @@ command(KINFO *k, VARENT *ve) left = termwidth - (totwidth - v->width); if (left < 1) /* already wrapped, just use std width */ left = v->width; + if ((cp = k->ki_d.prefix) != NULL) + while (--left >= 0 && *cp) + (void)putchar(*cp++); if ((cp = vis_env) != NULL) { while (--left >= 0 && *cp) (void)putchar(*cp++); @@ -166,12 +177,12 @@ command(KINFO *k, VARENT *ve) for (cp = vis_args; --left >= 0 && *cp != '\0';) (void)putchar(*cp++); } + if (vis_env != NULL) + free(vis_env); } else - /* XXX env? */ + /* ki_d.prefix & ki_env aren't shown for interim fields */ (void)printf("%-*.*s", v->width, v->width, vis_args); free(vis_args); - if (vis_env != NULL) - free(vis_env); } void @@ -182,6 +193,8 @@ ucomm(KINFO *k, VARENT *ve) v = ve->var; if (STAILQ_NEXT(ve, next_ve) == NULL) { /* last field, don't pad */ + if (k->ki_d.prefix) + (void)printf("%s", k->ki_d.prefix); (void)printf("%s", k->ki_p->ki_comm); if (showthreads && k->ki_p->ki_numthreads > 1) printf("/%s", k->ki_p->ki_ocomm); diff --git a/bin/ps/ps.1 b/bin/ps/ps.1 index 01e654ed8a77..ebd70d056275 100644 --- a/bin/ps/ps.1 +++ b/bin/ps/ps.1 @@ -29,7 +29,7 @@ .\" @(#)ps.1 8.3 (Berkeley) 4/18/94 .\" $FreeBSD$ .\" -.Dd August 21, 2006 +.Dd May 16, 2009 .Dt PS 1 .Os .Sh NAME @@ -37,7 +37,7 @@ .Nd process status .Sh SYNOPSIS .Nm -.Op Fl aCcefHhjlmrSTuvwXxZ +.Op Fl aCcdefHhjlmrSTuvwXxZ .Op Fl O Ar fmt | Fl o Ar fmt .Op Fl G Ar gid Ns Op , Ns Ar gid Ns Ar ... .Op Fl M Ar core @@ -122,6 +122,15 @@ CPU calculation that ignores .Dq resident time (this normally has no effect). +.It Fl d +Arrange processes into descendancy order and prefix each command with +indentation text showing sibling and parent/child relationships. +If either of the +.Fl m +and +.Fl r +options are also used, they control how sibling processes are sorted +relative to eachother. .It Fl e Display the environment as well. .It Fl f diff --git a/bin/ps/ps.c b/bin/ps/ps.c index a3a1986ff87b..99c16d758b99 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -138,6 +138,7 @@ static int addelem_pid(struct listinfo *, const char *); static int addelem_tty(struct listinfo *, const char *); static int addelem_uid(struct listinfo *, const char *); static void add_list(struct listinfo *, const char *); +static void descendant_sort(KINFO *, int); static void dynsizevars(KINFO *); static void *expand_list(struct listinfo *); static const char * @@ -163,7 +164,7 @@ static char vfmt[] = "pid,state,time,sl,re,pagein,vsz,rss,lim,tsiz," "%cpu,%mem,command"; static char Zfmt[] = "label"; -#define PS_ARGS "AaCce" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ" +#define PS_ARGS "AaCcde" OPT_LAZY_f "G:gHhjLlM:mN:O:o:p:rSTt:U:uvwXxZ" int main(int argc, char *argv[]) @@ -177,7 +178,7 @@ main(int argc, char *argv[]) const char *nlistf, *memf; char *cols; int all, ch, elem, flag, _fmt, i, lineno; - int nentries, nkept, nselectors; + int descendancy, nentries, nkept, nselectors; int prtheader, wflag, what, xkeep, xkeep_implied; char errbuf[_POSIX2_LINE_MAX]; @@ -201,7 +202,7 @@ main(int argc, char *argv[]) if (argc > 1) argv[1] = kludge_oldps_options(PS_ARGS, argv[1], argv[2]); - all = _fmt = nselectors = optfatal = 0; + all = descendancy = _fmt = nselectors = optfatal = 0; prtheader = showthreads = wflag = xkeep_implied = 0; xkeep = -1; /* Neither -x nor -X. */ init_list(&gidlist, addelem_gid, sizeof(gid_t), "group"); @@ -233,6 +234,9 @@ main(int argc, char *argv[]) case 'c': cflag = 1; break; + case 'd': + descendancy = 1; + break; case 'e': /* XXX set ufmt */ needenv = 1; break; @@ -575,6 +579,8 @@ main(int argc, char *argv[]) keepit: next_KINFO = &kinfo[nkept]; next_KINFO->ki_p = kp; + next_KINFO->ki_d.level = 0; + next_KINFO->ki_d.prefix = NULL; next_KINFO->ki_pcpu = getpcpu(next_KINFO); if (sortby == SORTMEM) next_KINFO->ki_memsize = kp->ki_tsize + @@ -599,6 +605,13 @@ main(int argc, char *argv[]) * sort proc list */ qsort(kinfo, nkept, sizeof(KINFO), pscomp); + + /* + * We want things in descendant order + */ + if (descendancy) + descendant_sort(kinfo, nkept); + /* * For each process, call each variable output function. */ @@ -622,6 +635,9 @@ main(int argc, char *argv[]) free_list(&sesslist); free_list(&ttylist); free_list(&uidlist); + for (i = 0; i < nkept; i++) + free(kinfo[i].ki_d.prefix); + free(kinfo); exit(eval); } @@ -890,6 +906,116 @@ add_list(struct listinfo *inf, const char *argp) } } +static void +descendant_sort(KINFO *ki, int items) +{ + int dst, lvl, maxlvl, n, ndst, nsrc, siblings, src; + unsigned char *path; + KINFO kn; + + /* + * First, sort the entries by descendancy, tracking the descendancy + * depth in the ki_d.level field. + */ + src = 0; + maxlvl = 0; + while (src < items) { + if (ki[src].ki_d.level) { + src++; + continue; + } + for (nsrc = 1; src + nsrc < items; nsrc++) + if (!ki[src + nsrc].ki_d.level) + break; + + for (dst = 0; dst < items; dst++) { + if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_pid) + continue; + if (ki[dst].ki_p->ki_pid == ki[src].ki_p->ki_ppid) + break; + } + + if (dst == items) { + src += nsrc; + continue; + } + + for (ndst = 1; dst + ndst < items; ndst++) + if (ki[dst + ndst].ki_d.level <= ki[dst].ki_d.level) + break; + + for (n = src; n < src + nsrc; n++) { + ki[n].ki_d.level += ki[dst].ki_d.level + 1; + if (maxlvl < ki[n].ki_d.level) + maxlvl = ki[n].ki_d.level; + } + + while (nsrc) { + if (src < dst) { + kn = ki[src]; + memmove(ki + src, ki + src + 1, + (dst - src + ndst - 1) * sizeof *ki); + ki[dst + ndst - 1] = kn; + nsrc--; + dst--; + ndst++; + } else if (src != dst + ndst) { + kn = ki[src]; + memmove(ki + dst + ndst + 1, ki + dst + ndst, + (src - dst - ndst) * sizeof *ki); + ki[dst + ndst] = kn; + ndst++; + nsrc--; + src++; + } else { + ndst += nsrc; + src += nsrc; + nsrc = 0; + } + } + } + + /* + * Now populate ki_d.prefix (instead of ki_d.level) with the command + * prefix used to show descendancies. + */ + path = malloc((maxlvl + 7) / 8); + memset(path, '\0', (maxlvl + 7) / 8); + for (src = 0; src < items; src++) { + if ((lvl = ki[src].ki_d.level) == 0) { + ki[src].ki_d.prefix = NULL; + continue; + } + if ((ki[src].ki_d.prefix = malloc(lvl * 2 + 1)) == NULL) + errx(1, "malloc failed"); + for (n = 0; n < lvl - 2; n++) { + ki[src].ki_d.prefix[n * 2] = + path[n / 8] & 1 << (n % 8) ? '|' : ' '; + ki[src].ki_d.prefix[n * 2 + 1] = ' '; + + } + if (n == lvl - 2) { + /* Have I any more siblings? */ + for (siblings = 0, dst = src + 1; dst < items; dst++) { + if (ki[dst].ki_d.level > lvl) + continue; + if (ki[dst].ki_d.level == lvl) + siblings = 1; + break; + } + if (siblings) + path[n / 8] |= 1 << (n % 8); + else + path[n / 8] &= ~(1 << (n % 8)); + ki[src].ki_d.prefix[n * 2] = siblings ? '|' : '`'; + ki[src].ki_d.prefix[n * 2 + 1] = '-'; + n++; + } + strcpy(ki[src].ki_d.prefix + n * 2, "- "); + } + free(path); +} + static void * expand_list(struct listinfo *inf) { diff --git a/bin/ps/ps.h b/bin/ps/ps.h index 03adc0a35c18..ddaebed53127 100644 --- a/bin/ps/ps.h +++ b/bin/ps/ps.h @@ -42,6 +42,10 @@ typedef struct kinfo { int ki_valid; /* 1 => uarea stuff valid */ double ki_pcpu; /* calculated in main() */ segsz_t ki_memsize; /* calculated in main() */ + union { + int level; /* used in decendant_sort() */ + char *prefix; /* calculated in decendant_sort() */ + } ki_d; } KINFO; /* Variables. */ From 0fe5460dbd6d5214403e461460c52d3348a96781 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sun, 17 May 2009 04:04:25 +0000 Subject: [PATCH 234/544] set createtxg prop name PR: bin/130105 --- sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c index 27a6f2e3dd00..fef05abf3ce2 100644 --- a/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c +++ b/sys/cddl/contrib/opensolaris/common/zfs/zfs_prop.c @@ -297,7 +297,7 @@ zfs_prop_init(void) /* hidden properties */ register_hidden(ZFS_PROP_CREATETXG, "createtxg", PROP_TYPE_NUMBER, - PROP_READONLY, ZFS_TYPE_DATASET, NULL); + PROP_READONLY, ZFS_TYPE_DATASET, "CREATETXG"); register_hidden(ZFS_PROP_NUMCLONES, "numclones", PROP_TYPE_NUMBER, PROP_READONLY, ZFS_TYPE_SNAPSHOT, NULL); register_hidden(ZFS_PROP_NAME, "name", PROP_TYPE_STRING, From 0a091aebdec028802362e203e4f37a7e3a8756ca Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Sun, 17 May 2009 04:34:14 +0000 Subject: [PATCH 235/544] When finding processes, ignore ourself and our ancestors. It is almost always surprising when you kill a 'sh -c ...' ancestor or when you kill yourself when using -f. Add a -a switch for backwards compatibility. MFC after: 3 weeks --- bin/pkill/pkill.1 | 15 ++++++++++++--- bin/pkill/pkill.c | 30 ++++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/bin/pkill/pkill.1 b/bin/pkill/pkill.1 index 725f27eff849..1db38f042fde 100644 --- a/bin/pkill/pkill.1 +++ b/bin/pkill/pkill.1 @@ -36,7 +36,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd November 23, 2006 +.Dd May 16, 2009 .Dt PKILL 1 .Os .Sh NAME @@ -44,7 +44,7 @@ .Nd find or signal processes by name .Sh SYNOPSIS .Nm pgrep -.Op Fl LSfilnovx +.Op Fl LSafilnovx .Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core @@ -60,7 +60,7 @@ .Ar pattern ... .Nm pkill .Op Fl Ar signal -.Op Fl ILfinovx +.Op Fl ILafinovx .Op Fl F Ar pidfile .Op Fl G Ar gid .Op Fl M Ar core @@ -128,6 +128,15 @@ The default is a newline. This option can only be used with the .Nm pgrep command. +.It Fl a +Include process ancestors in the match list. +By default, the current +.Nm pgrep +or +.Nm pkill +process and all of its ancestors are excluded (unless +.Fl v +is used). .It Fl f Match against full argument lists. The default is to match against process names. diff --git a/bin/pkill/pkill.c b/bin/pkill/pkill.c index da8fbcdf749d..b4b96b880f46 100644 --- a/bin/pkill/pkill.c +++ b/bin/pkill/pkill.c @@ -133,7 +133,7 @@ main(int argc, char **argv) { char buf[_POSIX2_LINE_MAX], *mstr, **pargv, *p, *q, *pidfile; const char *execf, *coref; - int debug_opt; + int ancestors, debug_opt; int i, ch, bestidx, rv, criteria, pidfromfile, pidfilelock; size_t jsz; int (*action)(const struct kinfo_proc *); @@ -142,6 +142,7 @@ main(int argc, char **argv) struct timeval best_tval; regex_t reg; regmatch_t regmatch; + pid_t pid; setlocale(LC_ALL, ""); @@ -174,13 +175,14 @@ main(int argc, char **argv) } } + ancestors = 0; criteria = 0; debug_opt = 0; pidfile = NULL; pidfilelock = 0; execf = coref = _PATH_DEVNULL; - while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:d:fg:ij:lnos:t:u:vx")) != -1) + while ((ch = getopt(argc, argv, "DF:G:ILM:N:P:SU:ad:fg:ij:lnos:t:u:vx")) != -1) switch (ch) { case 'D': debug_opt++; @@ -220,6 +222,9 @@ main(int argc, char **argv) makelist(&ruidlist, LT_USER, optarg); criteria = 1; break; + case 'a': + ancestors++; + break; case 'd': if (!pgrep) usage(); @@ -468,6 +473,27 @@ main(int argc, char **argv) selected[i] = 1; } + if (!ancestors) { + pid = mypid; + while (pid) { + for (i = 0, kp = plist; i < nproc; i++, kp++) { + if (PSKIP(kp)) + continue; + if (kp->ki_pid == pid) { + selected[i] = 0; + pid = kp->ki_ppid; + break; + } + } + if (i == nproc) { + if (pid == mypid) + pid = getppid(); + else + break; /* Maybe we're in a jail ? */ + } + } + } + if (newest || oldest) { best_tval.tv_sec = 0; best_tval.tv_usec = 0; From a9eb07938f8b0e970f8ecc5427d0ab294656b119 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sun, 17 May 2009 05:54:25 +0000 Subject: [PATCH 236/544] add zfs oid to bsnmpd PR: bin/129360 Submitted by: Ulrich Spoerlein --- usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c index a35743b949f0..91505d594225 100644 --- a/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c +++ b/usr.sbin/bsnmpd/modules/snmp_hostres/hostres_fs_tbl.c @@ -131,6 +131,7 @@ static const struct { const struct asn_oid *oid; /* the OID to return */ } fs_type_map[] = { { "ufs", &OIDX_hrFSBerkeleyFFS_c }, + { "zfs", &OIDX_hrFSOther_c }, { "cd9660", &OIDX_hrFSiso9660_c }, { "nfs", &OIDX_hrFSNFS_c }, { "ext2fs", &OIDX_hrFSLinuxExt2_c }, From f2eb372e028f73ce016ecd2f7bc510653fb77996 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 17 May 2009 06:45:30 +0000 Subject: [PATCH 237/544] Merge r191964: Eliminate a case of unnecessary page queues locking. --- sys/fs/nfsclient/nfs_clbio.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clbio.c b/sys/fs/nfsclient/nfs_clbio.c index ae06a88383a9..37f824cb3752 100644 --- a/sys/fs/nfsclient/nfs_clbio.c +++ b/sys/fs/nfsclient/nfs_clbio.c @@ -232,10 +232,8 @@ ncl_getpages(struct vop_getpages_args *ap) vm_page_t m = pages[ap->a_reqpage]; VM_OBJECT_LOCK(object); - vm_page_lock_queues(); if (m->valid != 0) { - /* handled by vm_fault now */ - /* vm_page_zero_invalid(m, TRUE); */ + vm_page_lock_queues(); for (i = 0; i < npages; ++i) { if (i != ap->a_reqpage) vm_page_free(pages[i]); @@ -244,7 +242,6 @@ ncl_getpages(struct vop_getpages_args *ap) VM_OBJECT_UNLOCK(object); return(0); } - vm_page_unlock_queues(); VM_OBJECT_UNLOCK(object); } From d4d65a21bca42c1b3579c17b4b07e64e07fbfe5a Mon Sep 17 00:00:00 2001 From: Daniel Gerzo Date: Sun, 17 May 2009 08:25:02 +0000 Subject: [PATCH 238/544] - do not create and mount new file systems on top of the old ones on every invocation of this script once we already have one (in case tmpmfs="YES"). Reviewed by: dougb --- etc/rc.d/tmp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/etc/rc.d/tmp b/etc/rc.d/tmp index 9750b6e2d06b..abf53ac4de1d 100755 --- a/etc/rc.d/tmp +++ b/etc/rc.d/tmp @@ -43,8 +43,10 @@ load_rc_config $name # case "${tmpmfs}" in [Yy][Ee][Ss]) - mount_md ${tmpsize} /tmp "${tmpmfs_flags}" - chmod 01777 /tmp + if ! /bin/df /tmp | grep -q "^/dev/md[0-9]"; then + mount_md ${tmpsize} /tmp "${tmpmfs_flags}" + chmod 01777 /tmp + fi ;; [Nn][Oo]) ;; From 395ad99417ebfdd8d4afa67fdc6e39ac08ce161d Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 17 May 2009 10:58:50 +0000 Subject: [PATCH 239/544] Improve the accf_dns_load description. --- sys/boot/forth/loader.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/boot/forth/loader.conf b/sys/boot/forth/loader.conf index 59a50180f298..ecedf46b0632 100644 --- a/sys/boot/forth/loader.conf +++ b/sys/boot/forth/loader.conf @@ -397,7 +397,7 @@ bktr_load="NO" # Brooktree Bt848/Bt878 TV/Video Capture Card ispfw_load="NO" # Qlogic ISP Firmware agp_load="NO" # agp module accf_data_load="NO" # Wait for data accept filter -accf_dns_load="NO" # Wait for data accept filter +accf_dns_load="NO" # Wait for full DNS request accept filter accf_http_load="NO" # Wait for full HTTP request accept filter random_load="NO" # Random device speaker_load="NO" # AT speaker module From 964bb4d3d4589f2b9174707626dd3de4da905c2d Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 17 May 2009 12:21:11 +0000 Subject: [PATCH 240/544] Fix the example. --- share/man/man4/md.4 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/share/man/man4/md.4 b/share/man/man4/md.4 index ab0f569fd1c3..fea4a34b52c9 100644 --- a/share/man/man4/md.4 +++ b/share/man/man4/md.4 @@ -66,11 +66,12 @@ For more information, please see To create a kernel with a ramdisk or MD file system, your kernel config needs the following options: .Bd -literal -offset indent -options MD_ROOT #MD is a potential root device +options MD_ROOT # MD is a potential root device options MD_ROOT_SIZE=8192 # 8MB ram disk makeoptions MFS_IMAGE=/h/foo/ARM-MD -options ROOTDEVNAME=\"ufs:md0\" +options ROOTDEVNAME=\\"ufs:md0\\" .Ed +.Pp The image in .Pa /h/foo/ARM-MD will be loaded as the initial image each boot. From dd970f41f746043123b283651b574eb70c8bce14 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 17 May 2009 12:30:25 +0000 Subject: [PATCH 241/544] Several cleanups to tty_info(), better known as Ctrl-T. - Only pick up PROC_LOCK once, which means we can drop the PGRP_LOCK right after picking up PROC_LOCK for the first time. - Print the process real time, making it consistent with tools like time(1). - Use `p' and `td' to reference the process/thread we are going to print. Only use pick-variables inside the loops. We already did this for the threads, but not the processes. --- sys/kern/tty_info.c | 50 ++++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/sys/kern/tty_info.c b/sys/kern/tty_info.c index fc3a5cf75da4..8894fe7808c5 100644 --- a/sys/kern/tty_info.c +++ b/sys/kern/tty_info.c @@ -213,9 +213,9 @@ proc_compare(struct proc *p1, struct proc *p2) void tty_info(struct tty *tp) { - struct timeval utime, stime; - struct proc *p, *pick; - struct thread *td, *picktd; + struct timeval rtime, utime, stime; + struct proc *p, *ppick; + struct thread *td, *tdpick; const char *stateprefix, *state; long rss; int load, pctcpu; @@ -254,17 +254,17 @@ tty_info(struct tty *tp) * whole list. However, we're guaranteed not to reference an exited * thread or proc since we hold the tty locked. */ - pick = NULL; - LIST_FOREACH(p, &tp->t_pgrp->pg_members, p_pglist) - if (proc_compare(pick, p)) - pick = p; + p = NULL; + LIST_FOREACH(ppick, &tp->t_pgrp->pg_members, p_pglist) + if (proc_compare(p, ppick)) + p = ppick; - PROC_LOCK(pick); - picktd = NULL; - FOREACH_THREAD_IN_PROC(pick, td) - if (thread_compare(picktd, td)) - picktd = td; - td = picktd; + PROC_LOCK(p); + PGRP_UNLOCK(tp->t_pgrp); + td = NULL; + FOREACH_THREAD_IN_PROC(p, tdpick) + if (thread_compare(td, tdpick)) + td = tdpick; stateprefix = ""; thread_lock(td); if (TD_IS_RUNNING(td)) @@ -284,28 +284,28 @@ tty_info(struct tty *tp) state = "suspended"; else if (TD_AWAITING_INTR(td)) state = "intrwait"; - else if (pick->p_state == PRS_ZOMBIE) + else if (p->p_state == PRS_ZOMBIE) state = "zombie"; else state = "unknown"; pctcpu = (sched_pctcpu(td) * 10000 + FSCALE / 2) >> FSHIFT; thread_unlock(td); - if (pick->p_state == PRS_NEW || pick->p_state == PRS_ZOMBIE) + if (p->p_state == PRS_NEW || p->p_state == PRS_ZOMBIE) rss = 0; else - rss = pgtok(vmspace_resident_count(pick->p_vmspace)); - PROC_UNLOCK(pick); - PROC_LOCK(pick); - PGRP_UNLOCK(tp->t_pgrp); - rufetchcalc(pick, &ru, &utime, &stime); - pid = pick->p_pid; - strlcpy(comm, pick->p_comm, sizeof comm); - PROC_UNLOCK(pick); + rss = pgtok(vmspace_resident_count(p->p_vmspace)); + microuptime(&rtime); + timevalsub(&rtime, &p->p_stats->p_start); + rufetchcalc(p, &ru, &utime, &stime); + pid = p->p_pid; + strlcpy(comm, p->p_comm, sizeof comm); + PROC_UNLOCK(p); - /* Print command, pid, state, utime, stime, %cpu, and rss. */ + /* Print command, pid, state, rtime, utime, stime, %cpu, and rss. */ ttyprintf(tp, - " cmd: %s %d [%s%s] %ld.%02ldu %ld.%02lds %d%% %ldk\n", + " cmd: %s %d [%s%s] %ld.%02ldr %ld.%02ldu %ld.%02lds %d%% %ldk\n", comm, pid, stateprefix, state, + (long)rtime.tv_sec, rtime.tv_usec / 10000, (long)utime.tv_sec, utime.tv_usec / 10000, (long)stime.tv_sec, stime.tv_usec / 10000, pctcpu / 100, rss); From 379affd5cb4fd639bddd1a2171f1a69805b4feb1 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 17 May 2009 16:17:48 +0000 Subject: [PATCH 242/544] Print an extra newline when not at the first column already. This makes siginfo output look a lot better when pressing it the first time when in sh(1), for example: $ load: 0.00 cmd: sh 1945 [ttyin] 3.94r 0.00u 0.00s 0% 1960k load: 0.00 cmd: sh 1945 [ttyin] 4.19r 0.00u 0.00s 0% 1960k will now become: $ load: 0.00 cmd: sh 1945 [ttyin] 3.94r 0.00u 0.00s 0% 1960k load: 0.00 cmd: sh 1945 [ttyin] 4.19r 0.00u 0.00s 0% 1960k --- sys/kern/tty_info.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/kern/tty_info.c b/sys/kern/tty_info.c index 8894fe7808c5..d2b059ca41b0 100644 --- a/sys/kern/tty_info.c +++ b/sys/kern/tty_info.c @@ -230,7 +230,8 @@ tty_info(struct tty *tp) /* Print load average. */ load = (averunnable.ldavg[0] * 100 + FSCALE / 2) >> FSHIFT; - ttyprintf(tp, "load: %d.%02d ", load / 100, load % 100); + ttyprintf(tp, "%sload: %d.%02d ", tp->t_column == 0 ? "" : "\n", + load / 100, load % 100); if (tp->t_session == NULL) { ttyprintf(tp, "not a controlling terminal\n"); From 57d1e46484a28c8d609d1403b8e10702dca4b20d Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 17 May 2009 17:54:01 +0000 Subject: [PATCH 243/544] Added a SYSCTL to sys/fs/nfsserver/nfs_nfsdport.c so that the value of nfsrv_dolocallocks can be changed via sysctl. I also added some non-empty descriptor strings and reformatted some overly long lines. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdport.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 3a031250dda5..98a1822c5cdc 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -43,7 +43,6 @@ __FBSDID("$FreeBSD$"); #include #include -extern int nfsrv_dolocallocks; extern u_int32_t newnfs_true, newnfs_false, newnfs_xdrneg1; extern int nfsv4root_set; extern int nfsrv_useacl; @@ -58,17 +57,26 @@ struct mtx nfs_v4root_mutex; struct nfsrvfh nfs_rootfh, nfs_pubfh; int nfs_pubfhset = 0, nfs_rootfhset = 0; -static int nfssvc_srvcall(struct thread *, struct nfssvc_args *, struct ucred *); +static int nfssvc_srvcall(struct thread *, struct nfssvc_args *, + struct ucred *); static int enable_crossmntpt = 1; static int nfs_commit_blks; static int nfs_commit_miss; extern int nfsrv_issuedelegs; +extern int nfsrv_dolocallocks; + SYSCTL_DECL(_vfs_newnfs); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, mirrormnt, CTLFLAG_RW, &enable_crossmntpt, 0, ""); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, 0, ""); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, ""); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, issue_delegations, CTLFLAG_RW, &nfsrv_issuedelegs, 0, ""); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, mirrormnt, CTLFLAG_RW, &enable_crossmntpt, + 0, "Enable nfsd to cross mount points"); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_blks, CTLFLAG_RW, &nfs_commit_blks, + 0, ""); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, + 0, ""); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, issue_delegations, CTLFLAG_RW, + &nfsrv_issuedelegs, 0, "Enable nfsd to issue delegations"); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, enable_locallocks, CTLFLAG_RW, + &nfsrv_dolocallocks, 0, "Enable nfsd to acquire local locks on files"); #define NUM_HEURISTIC 1017 #define NHUSE_INIT 64 From 2c1b26b9764b569afc5dde975428f24becdc0c6e Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 17 May 2009 19:33:48 +0000 Subject: [PATCH 244/544] Fix the acquisition of local locks via VOP_ADVLOCK() by the experimental nfsv4 server. It was setting the a_id argument to a fixed value, but that wasn't sufficient for FreeBSD8. Instead, set l_pid and l_sysid to 0 plus set the F_REMOTE flag to indicate that these fields are used to check for same lock owner. Since, for NFSv4, a lockowner is a ClientID plus an up to 1024byte name, it can't be put in l_sysid easily. I also renamed the p variable to td, since it's a thread ptr. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdport.c | 39 +++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 11 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 98a1822c5cdc..d45b52dbab68 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -2749,14 +2749,13 @@ nfsvno_getvp(fhandle_t *fhp) return (vp); } -static int id_for_advlock; /* * Check to see it a byte range lock held by a process running * locally on the server conflicts with the new lock. */ int nfsvno_localconflict(struct vnode *vp, int ftype, u_int64_t first, - u_int64_t end, struct nfslockconflict *cfp, struct thread *p) + u_int64_t end, struct nfslockconflict *cfp, struct thread *td) { int error; struct flock fl; @@ -2771,11 +2770,20 @@ nfsvno_localconflict(struct vnode *vp, int ftype, u_int64_t first, else fl.l_len = (off_t)(end - first); /* - * FreeBSD8 doesn't like 0, so I'll use the address of id_for_advlock. + * For FreeBSD8, the l_pid and l_sysid must be set to the same + * values for all calls, so that all locks will be held by the + * nfsd server. (The nfsd server handles conflicts between the + * various clients.) + * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 + * bytes, so it can't be put in l_sysid. */ - NFSVOPUNLOCK(vp, 0, p); - error = VOP_ADVLOCK(vp, &id_for_advlock, F_GETLK, &fl, F_POSIX); - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); + fl.l_pid = (pid_t)0; + fl.l_sysid = 0; + + NFSVOPUNLOCK(vp, 0, td); + error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_GETLK, &fl, + (F_POSIX | F_REMOTE)); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); if (error) return (error); if (fl.l_type == F_UNLCK) @@ -2804,7 +2812,7 @@ nfsvno_localconflict(struct vnode *vp, int ftype, u_int64_t first, */ int nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, - u_int64_t end, struct thread *p) + u_int64_t end, struct thread *td) { int error; struct flock fl; @@ -2822,11 +2830,20 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, fl.l_len = (off_t)tlen; } /* - * FreeBSD8 doesn't like 0, so I'll use the address of id_for_advlock. + * For FreeBSD8, the l_pid and l_sysid must be set to the same + * values for all calls, so that all locks will be held by the + * nfsd server. (The nfsd server handles conflicts between the + * various clients.) + * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 + * bytes, so it can't be put in l_sysid. */ - NFSVOPUNLOCK(vp, 0, p); - error = VOP_ADVLOCK(vp, &id_for_advlock, F_SETLK, &fl, F_POSIX); - NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, p); + fl.l_pid = (pid_t)0; + fl.l_sysid = 0; + + NFSVOPUNLOCK(vp, 0, td); + error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl, + (F_POSIX | F_REMOTE)); + NFSVOPLOCK(vp, LK_EXCLUSIVE | LK_RETRY, td); return (error); } From f61336e4cb85e6a5bcacc9306431eeb16e1828db Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 17 May 2009 19:46:50 +0000 Subject: [PATCH 245/544] fix 11a channel use; mark OFDM operation correctly Submitted by: Lucius Windschuh --- sys/dev/usb/wlan/if_uath.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 8e6577030f55..b5665585f806 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -1492,9 +1492,9 @@ uath_set_chan(struct uath_softc *sc, struct ieee80211_channel *c) if (IEEE80211_IS_CHAN_5GHZ(c)) reset.flags |= htobe32(UATH_CHAN_5GHZ); /* NB: 11g =>'s 11b so don't specify both OFDM and CCK */ - if (IEEE80211_IS_CHAN_G(c)) + if (IEEE80211_IS_CHAN_OFDM(c)) reset.flags |= htobe32(UATH_CHAN_OFDM); - else if (IEEE80211_IS_CHAN_B(c)) + else if (IEEE80211_IS_CHAN_CCK(c)) reset.flags |= htobe32(UATH_CHAN_CCK); /* turbo can be used in either 2GHz or 5GHz */ if (c->ic_flags & IEEE80211_CHAN_TURBO) From afb8a6b50015962e1f807307111b35c49a763809 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sun, 17 May 2009 19:51:08 +0000 Subject: [PATCH 246/544] add TRENDnet TEW-504UB/EU Submitted by: Lucius Windschuh --- sys/dev/usb/usbdevs | 1 + sys/dev/usb/wlan/if_uath.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index 0e567476bd63..a626a1df1d65 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -2425,6 +2425,7 @@ product UMEDIA TEW429UBC1 0x300d TEW-429UB C1 product UMEDIA ALL0298V2 0x3204 ALL0298 v2 product UMEDIA AR5523_2 0x3205 AR5523 product UMEDIA AR5523_2_NF 0x3206 AR5523 (no firmware) +product UMEDIA AR5523_3 0x3207 AR5523 /* Universal Access products */ product UNIACCESS PANACHE 0x0101 Panache Surf USB ISDN Adapter diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index b5665585f806..98c494355bc6 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -192,6 +192,7 @@ static const struct usb2_device_id uath_devs[] = { UATH_DEV(NETGEAR3, WPN111), UATH_DEV(UMEDIA, TEW444UBEU), UATH_DEV(UMEDIA, AR5523_2), + UATH_DEV(UMEDIA, AR5523_3), UATH_DEV(WISTRONNEWEB, AR5523_1), UATH_DEV(WISTRONNEWEB, AR5523_2), UATH_DEV(ZCOM, AR5523) From 6e5982caf709ddf16c36a32e34fc36c49194f561 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 17 May 2009 20:26:00 +0000 Subject: [PATCH 247/544] Introduce vfs_bio_set_valid() and use it from ffs_realloccg(). This eliminates the misuse of vfs_bio_clrbuf() by ffs_realloccg(). In collaboration with: tegge --- sys/kern/vfs_bio.c | 38 ++++++++++++++++++++++++++++++++++++++ sys/sys/buf.h | 1 + sys/ufs/ffs/ffs_alloc.c | 14 ++++++-------- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 2979f61f24ce..e5a947b55c76 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3624,6 +3624,44 @@ vfs_clean_pages(struct buf *bp) VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); } +/* + * vfs_bio_set_valid: + * + * Set the range within the buffer to valid. The range is + * relative to the beginning of the buffer, b_offset. Note that + * b_offset itself may be offset from the beginning of the first + * page. + */ +void +vfs_bio_set_valid(struct buf *bp, int base, int size) +{ + int i, n; + vm_page_t m; + + if (!(bp->b_flags & B_VMIO)) + return; + + /* + * Fixup base to be relative to beginning of first page. + * Set initial n to be the maximum number of bytes in the + * first page that can be validated. + */ + base += (bp->b_offset & PAGE_MASK); + n = PAGE_SIZE - (base & PAGE_MASK); + + VM_OBJECT_LOCK(bp->b_bufobj->bo_object); + for (i = base / PAGE_SIZE; size > 0 && i < bp->b_npages; ++i) { + m = bp->b_pages[i]; + if (n > size) + n = size; + vm_page_set_valid(m, base & PAGE_MASK, n); + base += n; + size -= n; + n = PAGE_SIZE; + } + VM_OBJECT_UNLOCK(bp->b_bufobj->bo_object); +} + /* * vfs_bio_set_validclean: * diff --git a/sys/sys/buf.h b/sys/sys/buf.h index 7ca6ffa386f9..fb0d80474fad 100644 --- a/sys/sys/buf.h +++ b/sys/sys/buf.h @@ -498,6 +498,7 @@ int cluster_read(struct vnode *, u_quad_t, daddr_t, long, struct ucred *, long, int, struct buf **); int cluster_wbuild(struct vnode *, long, daddr_t, int); void cluster_write(struct vnode *, struct buf *, u_quad_t, int); +void vfs_bio_set_valid(struct buf *, int base, int size); void vfs_bio_set_validclean(struct buf *, int base, int size); void vfs_bio_clrbuf(struct buf *); void vfs_busy_pages(struct buf *, int clear_modify); diff --git a/sys/ufs/ffs/ffs_alloc.c b/sys/ufs/ffs/ffs_alloc.c index 4748f682101c..b4f001e6c677 100644 --- a/sys/ufs/ffs/ffs_alloc.c +++ b/sys/ufs/ffs/ffs_alloc.c @@ -326,10 +326,9 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp) ip->i_flag |= IN_CHANGE | IN_UPDATE; allocbuf(bp, nsize); bp->b_flags |= B_DONE; - if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO) - bzero((char *)bp->b_data + osize, nsize - osize); - else - vfs_bio_clrbuf(bp); + bzero(bp->b_data + osize, nsize - osize); + if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO) + vfs_bio_set_valid(bp, osize, nsize - osize); *bpp = bp; return (0); } @@ -404,10 +403,9 @@ ffs_realloccg(ip, lbprev, bprev, bpref, osize, nsize, flags, cred, bpp) ip->i_flag |= IN_CHANGE | IN_UPDATE; allocbuf(bp, nsize); bp->b_flags |= B_DONE; - if ((bp->b_flags & (B_MALLOC | B_VMIO)) != B_VMIO) - bzero((char *)bp->b_data + osize, nsize - osize); - else - vfs_bio_clrbuf(bp); + bzero(bp->b_data + osize, nsize - osize); + if ((bp->b_flags & (B_MALLOC | B_VMIO)) == B_VMIO) + vfs_bio_set_valid(bp, osize, nsize - osize); *bpp = bp; return (0); } From 47916d0c37424265cb1a5bf7b74d6aea603037a2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 17 May 2009 20:40:41 +0000 Subject: [PATCH 248/544] Eliminate a pointless call to pmap_clear_reference() from vm_pageout_scan(). If the page belongs to an object with a reference count of zero, then it can't have any managed mappings on which to clear a reference bit. --- sys/vm/vm_pageout.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/vm/vm_pageout.c b/sys/vm/vm_pageout.c index 6da486e11f6c..a76aaa540e56 100644 --- a/sys/vm/vm_pageout.c +++ b/sys/vm/vm_pageout.c @@ -786,7 +786,8 @@ vm_pageout_scan(int pass) */ if (object->ref_count == 0) { vm_page_flag_clear(m, PG_REFERENCED); - pmap_clear_reference(m); + KASSERT(!pmap_page_is_mapped(m), + ("vm_pageout_scan: page %p is mapped", m)); /* * Otherwise, if the page has been referenced while in the From 1600c117d8bea84cc352dba026491d672019b480 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 17 May 2009 20:53:10 +0000 Subject: [PATCH 249/544] Unbreak options VIMAGE builds, in a followup to r192011 which did not introduce INIT_VNET_NET() initializers necessary for accessing V_loif. Submitted by: zec Reviewed by: julian --- sys/netinet/in.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 5bc78273aeb5..eaa8c7e87480 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -814,6 +814,7 @@ static int in_ifinit(struct ifnet *ifp, struct in_ifaddr *ia, struct sockaddr_in *sin, int scrub) { + INIT_VNET_NET(ifp->if_vnet); INIT_VNET_INET(ifp->if_vnet); register u_long i = ntohl(sin->sin_addr.s_addr); struct sockaddr_in oldaddr; @@ -1007,6 +1008,7 @@ extern void arp_ifscrub(struct ifnet *ifp, uint32_t addr); static int in_scrubprefix(struct in_ifaddr *target) { + INIT_VNET_NET(curvnet); INIT_VNET_INET(curvnet); struct in_ifaddr *ia; struct in_addr prefix, mask, p; From c2a809c5e89399b46496b191348d658f714511e7 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 17 May 2009 20:55:33 +0000 Subject: [PATCH 250/544] Put the structs under #ifndef VIMAGE_GLOBALS as some constants are not defined for VIMAGE_GLOBALS and thus broke the build for that option. Reported by: csjp --- sys/sys/vimage.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index ca7209415e5f..0c76fdb8b3d5 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -160,7 +160,6 @@ void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); sizeof(vnet_ ## mod ## _0._ ## name) } #endif #define VNET_SYMMAP_END { NULL, 0 } -#endif /* !VIMAGE_GLOBALS */ struct vimage { LIST_ENTRY(vimage) vi_le; /* all vimage list */ @@ -191,7 +190,6 @@ struct vprocg { char _domainname[MAXHOSTNAMELEN]; }; -#ifndef VIMAGE_GLOBALS #ifdef VIMAGE LIST_HEAD(vimage_list_head, vimage); extern struct vimage_list_head vimage_head; From 9750be38ca09bf0861f5ebd2475d6f10afef33c9 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sun, 17 May 2009 20:59:09 +0000 Subject: [PATCH 251/544] Add a missing INIT_VNET_NET() to get VIMAGE closer to full LINT again. --- sys/contrib/altq/altq/altq_subr.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/contrib/altq/altq/altq_subr.c b/sys/contrib/altq/altq/altq_subr.c index b2715ad40209..6febbabf511d 100644 --- a/sys/contrib/altq/altq/altq_subr.c +++ b/sys/contrib/altq/altq/altq_subr.c @@ -454,6 +454,7 @@ static void tbr_timeout(arg) void *arg; { + INIT_VNET_NET(curvnet); struct ifnet *ifp; int active, s; From 72fba9d714038e2331f144fd98e0d84f2d0f3583 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Sun, 17 May 2009 21:28:37 +0000 Subject: [PATCH 252/544] Document sbuf_new_auto(). While here, add a missing `-' in phk's name. MFC after: 3 days --- share/man/man9/sbuf.9 | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/share/man/man9/sbuf.9 b/share/man/man9/sbuf.9 index 1a752dbc45fd..58efce039fdd 100644 --- a/share/man/man9/sbuf.9 +++ b/share/man/man9/sbuf.9 @@ -1,5 +1,5 @@ .\"- -.\" Copyright (c) 2000 Poul Henning Kamp and Dag-Erling Coïdan Smørgrav +.\" Copyright (c) 2000 Poul-Henning Kamp and Dag-Erling Coïdan Smørgrav .\" All rights reserved. .\" .\" Redistribution and use in source and binary forms, with or without @@ -25,12 +25,13 @@ .\" .\" $FreeBSD$ .\" -.Dd July 9, 2004 +.Dd May 17, 2009 .Dt SBUF 9 .Os .Sh NAME .Nm sbuf , .Nm sbuf_new , +.Nm sbuf_new_auto , .Nm sbuf_clear , .Nm sbuf_setpos , .Nm sbuf_bcat , @@ -55,6 +56,8 @@ .In sys/sbuf.h .Ft struct sbuf * .Fn sbuf_new "struct sbuf *s" "char *buf" "int length" "int flags" +.Ft struct sbuf * +.Fn sbuf_new_auto .Ft void .Fn sbuf_clear "struct sbuf *s" .Ft int @@ -148,6 +151,19 @@ The result of accessing that array directly while it is in use by the sbuf is undefined. .Pp The +.Fn sbuf_new_auto +function is a shortcut for creating a completely dynamic +.Nm . +It is the equivalent of calling +.Fn sbuf_new +with values +.Dv NULL , +.Dv NULL , +.Dv 0 , +and +.Dv SBUF_AUTOEXTEND . +.Pp +The .Fn sbuf_delete function clears the .Fa sbuf From 1be5269359b8791d1189233a9c3e3d87ab0e0406 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sun, 17 May 2009 23:25:53 +0000 Subject: [PATCH 253/544] Several changes to vfs_bio_clrbuf(): Provide a more descriptive comment. Eliminate dead code. The page cannot possibly have PG_ZERO set. Eliminate unnecessary blank lines. Reviewed by: tegge --- sys/kern/vfs_bio.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index e5a947b55c76..16df88959ee5 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -3706,24 +3706,25 @@ vfs_bio_set_validclean(struct buf *bp, int base, int size) /* * vfs_bio_clrbuf: * - * clear a buffer. This routine essentially fakes an I/O, so we need - * to clear BIO_ERROR and B_INVAL. + * If the specified buffer is a non-VMIO buffer, clear the entire + * buffer. If the specified buffer is a VMIO buffer, clear and + * validate only the previously invalid portions of the buffer. + * This routine essentially fakes an I/O, so we need to clear + * BIO_ERROR and B_INVAL. * * Note that while we only theoretically need to clear through b_bcount, * we go ahead and clear through b_bufsize. */ - void vfs_bio_clrbuf(struct buf *bp) { - int i, j, mask = 0; + int i, j, mask; caddr_t sa, ea; if ((bp->b_flags & (B_VMIO | B_MALLOC)) != B_VMIO) { clrbuf(bp); return; } - bp->b_flags &= ~B_INVAL; bp->b_ioflags &= ~BIO_ERROR; VM_OBJECT_LOCK(bp->b_bufobj->bo_object); @@ -3735,8 +3736,7 @@ vfs_bio_clrbuf(struct buf *bp) VM_OBJECT_LOCK_ASSERT(bp->b_pages[0]->object, MA_OWNED); if ((bp->b_pages[0]->valid & mask) == mask) goto unlock; - if (((bp->b_pages[0]->flags & PG_ZERO) == 0) && - ((bp->b_pages[0]->valid & mask) == 0)) { + if ((bp->b_pages[0]->valid & mask) == 0) { bzero(bp->b_data, bp->b_bufsize); bp->b_pages[0]->valid |= mask; goto unlock; @@ -3755,13 +3755,11 @@ vfs_bio_clrbuf(struct buf *bp) VM_OBJECT_LOCK_ASSERT(bp->b_pages[i]->object, MA_OWNED); if ((bp->b_pages[i]->valid & mask) == mask) continue; - if ((bp->b_pages[i]->valid & mask) == 0) { - if ((bp->b_pages[i]->flags & PG_ZERO) == 0) - bzero(sa, ea - sa); - } else { + if ((bp->b_pages[i]->valid & mask) == 0) + bzero(sa, ea - sa); + else { for (; sa < ea; sa += DEV_BSIZE, j++) { - if (((bp->b_pages[i]->flags & PG_ZERO) == 0) && - (bp->b_pages[i]->valid & (1 << j)) == 0) + if ((bp->b_pages[i]->valid & (1 << j)) == 0) bzero(sa, DEV_BSIZE); } } From e9d57f2fd16a94d3c1d35f032aaa6893322dde02 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 18 May 2009 01:00:11 +0000 Subject: [PATCH 254/544] Turns out that my BCM4318 has a PCI ID of 0x4319, which lead me to believe it was a BCM4319. However, it is the a/b/g variation of the BCM4318. The chip itself is labelled BCM4318EKFBG, and the board is BCM94318MKABG. Paradox's patch includes the type of 802.11 wireless for each card, but changes all the names (I don't think the latter is quite right). Import that part of the patch, but keep the current set of BCM names (with a minor tweak for the 4306 ones). I'll need to verify them via some other means. Obtained from: http://paradox.lissyara.su/bwi.diff (partially) --- sys/dev/bwi/if_bwi_pci.c | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/sys/dev/bwi/if_bwi_pci.c b/sys/dev/bwi/if_bwi_pci.c index 91b8229ae671..10a9e06c948b 100644 --- a/sys/dev/bwi/if_bwi_pci.c +++ b/sys/dev/bwi/if_bwi_pci.c @@ -80,16 +80,18 @@ static const struct bwi_dev { uint16_t did; const char *desc; } bwi_devices[] = { - { PCI_VENDOR_BROADCOM, 0x4301,"Broadcom BCM4301 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4307,"Broadcom BCM4307 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4311,"Broadcom BCM4311 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4312,"Broadcom BCM4312 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4320,"Broadcom BCM4306v1 802.11 Wireless Lan"}, - { PCI_VENDOR_BROADCOM, 0x4321,"Broadcom BCM4306v2 802.11 Wireless Lan"}, - { PCI_VENDOR_BROADCOM, 0x4325,"Broadcom BCM4306v3 802.11 Wireless Lan"}, - { PCI_VENDOR_BROADCOM, 0x4324,"Broadcom BCM4309 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4318,"Broadcom BCM4318 802.11 Wireless Lan" }, - { PCI_VENDOR_BROADCOM, 0x4319,"Broadcom BCM4319 802.11 Wireless Lan" } + { PCI_VENDOR_BROADCOM, 0x4301,"Broadcom BCM4301 802.11b Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4307,"Broadcom BCM4307 802.11b Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4311,"Broadcom BCM4311 802.11b/g Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4312,"Broadcom BCM4312 802.11a/b/g Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4313,"Broadcom BCM4312 802.11a Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4320,"Broadcom BCM4306 802.11b/g Wireless Lan"}, + { PCI_VENDOR_BROADCOM, 0x4321,"Broadcom BCM4306 802.11a Wireless Lan"}, + { PCI_VENDOR_BROADCOM, 0x4325,"Broadcom BCM4306 802.11b/g Wireless Lan"}, + { PCI_VENDOR_BROADCOM, 0x4324,"Broadcom BCM4309 802.11a/b/g Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4318,"Broadcom BCM4318 802.11b/g Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x4319,"Broadcom BCM4318 802.11a/b/g Wireless Lan" }, + { PCI_VENDOR_BROADCOM, 0x431a,"Broadcom BCM4318 802.11a Wireless Lan" } }; static int From ce9237f1b2b10c07dd85195269a91e3499680e21 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 18 May 2009 01:05:09 +0000 Subject: [PATCH 255/544] tbr_timeout() is a timer driven function[1]. While the previous commit made LINT happy this does the proper looping over all vnets as we are only called `globally' and not once per vnet instance. Reported by: zec [1] Missed by: bz [1] in r192264 Reviewed by: zec --- sys/contrib/altq/altq/altq_subr.c | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/sys/contrib/altq/altq/altq_subr.c b/sys/contrib/altq/altq/altq_subr.c index 6febbabf511d..17557c130719 100644 --- a/sys/contrib/altq/altq/altq_subr.c +++ b/sys/contrib/altq/altq/altq_subr.c @@ -454,7 +454,9 @@ static void tbr_timeout(arg) void *arg; { - INIT_VNET_NET(curvnet); +#if defined(__FreeBSD__) + VNET_ITERATOR_DECL(vnet_iter); +#endif struct ifnet *ifp; int active, s; @@ -466,16 +468,25 @@ tbr_timeout(arg) #endif #if defined(__FreeBSD__) && (__FreeBSD_version >= 500000) IFNET_RLOCK(); + VNET_LIST_RLOCK(); + VNET_FOREACH(vnet_iter) { + CURVNET_SET(vnet_iter); + INIT_VNET_NET(vnet_iter); #endif - for (ifp = TAILQ_FIRST(&V_ifnet); ifp; ifp = TAILQ_NEXT(ifp, if_list)) { - /* read from if_snd unlocked */ - if (!TBR_IS_ENABLED(&ifp->if_snd)) - continue; - active++; - if (!IFQ_IS_EMPTY(&ifp->if_snd) && ifp->if_start != NULL) - (*ifp->if_start)(ifp); - } + for (ifp = TAILQ_FIRST(&V_ifnet); ifp; + ifp = TAILQ_NEXT(ifp, if_list)) { + /* read from if_snd unlocked */ + if (!TBR_IS_ENABLED(&ifp->if_snd)) + continue; + active++; + if (!IFQ_IS_EMPTY(&ifp->if_snd) && + ifp->if_start != NULL) + (*ifp->if_start)(ifp); + } #if defined(__FreeBSD__) && (__FreeBSD_version >= 500000) + CURVNET_RESTORE(); + } + VNET_LIST_RUNLOCK(); IFNET_RUNLOCK(); #endif splx(s); From e9902ec0a67dac9c99c7a05435277bce5410772d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 18 May 2009 01:07:38 +0000 Subject: [PATCH 256/544] Correct types of PHY, per http://bcm-specs.sipsolutions.net/PHYVersioning # Note: The driver doesn't support either these PHY types, so this is # effectively a nop. Submitted by: "ddk" Obtained from: http://paradox.lissyara.su/bwi.diff --- sys/dev/bwi/if_bwireg.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/bwi/if_bwireg.h b/sys/dev/bwi/if_bwireg.h index 840067aaab0c..f376911186af 100644 --- a/sys/dev/bwi/if_bwireg.h +++ b/sys/dev/bwi/if_bwireg.h @@ -275,7 +275,8 @@ #define BWI_PHYINFO_TYPE_11A 0 #define BWI_PHYINFO_TYPE_11B 1 #define BWI_PHYINFO_TYPE_11G 2 -#define BWI_PHYINFO_TYPE_11N 5 +#define BWI_PHYINFO_TYPE_11N 4 +#define BWI_PHYINFO_TYPE_11LP 5 #define BWI_PHYINFO_VER_MASK __BITS(15, 12) #define BWI_RF_ANTDIV 0x3e2 /* Antenna Diversity?? */ From 8ba7efdad8f0ead5895fa504f2601bc3848ca645 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 18 May 2009 01:45:52 +0000 Subject: [PATCH 257/544] Remove redundant whitespace --- bin/ps/ps.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/bin/ps/ps.c b/bin/ps/ps.c index 99c16d758b99..21f6a7e849b3 100644 --- a/bin/ps/ps.c +++ b/bin/ps/ps.c @@ -764,7 +764,7 @@ addelem_tty(struct listinfo *inf, const char *elem) strlcat(pathbuf2, elem, sizeof(pathbuf2)); if (stat(pathbuf2, &sb) == 0 && S_ISCHR(sb.st_mode)) { /* No need to repeat stat() && S_ISCHR() checks */ - ttypath = NULL; + ttypath = NULL; break; } /* Check to see if /dev/pts/${elem} exists */ @@ -772,7 +772,7 @@ addelem_tty(struct listinfo *inf, const char *elem) strlcat(pathbuf3, elem, sizeof(pathbuf3)); if (stat(pathbuf3, &sb) == 0 && S_ISCHR(sb.st_mode)) { /* No need to repeat stat() && S_ISCHR() checks */ - ttypath = NULL; + ttypath = NULL; break; } break; @@ -992,7 +992,6 @@ descendant_sort(KINFO *ki, int items) ki[src].ki_d.prefix[n * 2] = path[n / 8] & 1 << (n % 8) ? '|' : ' '; ki[src].ki_d.prefix[n * 2 + 1] = ' '; - } if (n == lvl - 2) { /* Have I any more siblings? */ From ab7b2d927c9d9d183c2cf0021752d4a0d8b6ae82 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 18 May 2009 01:51:52 +0000 Subject: [PATCH 258/544] DMA synchronization fixes: - In bce_rx_intr(), use BUS_DMASYNC_POSTREAD instead of BUS_DMASYNC_POSTWRITE, as we want to "read" from the rx page chain pages. - Document why we need to do PREWRITE after we have updated the rx page chain pages. - In bce_intr(), use BUS_DMASYNC_POSTREAD and BUS_DMASYNC_PREREAD when before and after CPU "reading" the status block. - Adjust some nearby style mismatches/etc. Pointed out by: yongari Approved by: davidch (no objection) but bugs are mine :) --- sys/dev/bce/if_bce.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/sys/dev/bce/if_bce.c b/sys/dev/bce/if_bce.c index bd267f73af4e..43aec4b3b190 100644 --- a/sys/dev/bce/if_bce.c +++ b/sys/dev/bce/if_bce.c @@ -4884,7 +4884,7 @@ bce_get_rx_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, KASSERT(nsegs == 1, ("%s(): Too many segments returned (%d)!", __FUNCTION__, nsegs)); - /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */ + /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */ /* Setup the rx_bd for the segment. */ rxbd = &sc->rx_bd_chain[RX_PAGE(*chain_prod)][RX_IDX(*chain_prod)]; @@ -4993,7 +4993,7 @@ bce_get_pg_buf(struct bce_softc *sc, struct mbuf *m, u16 *prod, goto bce_get_pg_buf_exit; } - /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREWRITE) here? */ + /* ToDo: Do we need bus_dmamap_sync(,,BUS_DMASYNC_PREREAD) here? */ /* * The page chain uses the same rx_bd data structure @@ -5270,13 +5270,11 @@ bce_init_rx_chain(struct bce_softc *sc) rxbd->rx_bd_haddr_lo = htole32(BCE_ADDR_LO(sc->rx_bd_chain_paddr[j])); } -/* Fill up the RX chain. */ + /* Fill up the RX chain. */ bce_fill_rx_chain(sc); for (i = 0; i < RX_PAGES; i++) { - bus_dmamap_sync( - sc->rx_bd_chain_tag, - sc->rx_bd_chain_map[i], + bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i], BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } @@ -5447,9 +5445,7 @@ bce_init_pg_chain(struct bce_softc *sc) bce_fill_pg_chain(sc); for (i = 0; i < PG_PAGES; i++) { - bus_dmamap_sync( - sc->pg_bd_chain_tag, - sc->pg_bd_chain_map[i], + bus_dmamap_sync(sc->pg_bd_chain_tag, sc->pg_bd_chain_map[i], BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } @@ -5732,13 +5728,13 @@ bce_rx_intr(struct bce_softc *sc) /* Prepare the RX chain pages to be accessed by the host CPU. */ for (int i = 0; i < RX_PAGES; i++) bus_dmamap_sync(sc->rx_bd_chain_tag, - sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTWRITE); + sc->rx_bd_chain_map[i], BUS_DMASYNC_POSTREAD); #ifdef ZERO_COPY_SOCKETS /* Prepare the page chain pages to be accessed by the host CPU. */ for (int i = 0; i < PG_PAGES; i++) bus_dmamap_sync(sc->pg_bd_chain_tag, - sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTWRITE); + sc->pg_bd_chain_map[i], BUS_DMASYNC_POSTREAD); #endif /* Get the hardware's view of the RX consumer index. */ @@ -5765,9 +5761,8 @@ bce_rx_intr(struct bce_softc *sc) sw_rx_cons_idx = RX_CHAIN_IDX(sw_rx_cons); /* Unmap the mbuf from DMA space. */ - bus_dmamap_sync(sc->rx_mbuf_tag, - sc->rx_mbuf_map[sw_rx_cons_idx], - BUS_DMASYNC_POSTREAD); + bus_dmamap_sync(sc->rx_mbuf_tag, sc->rx_mbuf_map[sw_rx_cons_idx], + BUS_DMASYNC_POSTREAD); bus_dmamap_unload(sc->rx_mbuf_tag, sc->rx_mbuf_map[sw_rx_cons_idx]); @@ -6011,6 +6006,7 @@ bce_rx_intr(struct bce_softc *sc) sc->rx_cons = sw_rx_cons; bce_fill_rx_chain(sc); + /* Prepare the page chain pages to be accessed by the NIC. */ for (int i = 0; i < RX_PAGES; i++) bus_dmamap_sync(sc->rx_bd_chain_tag, sc->rx_bd_chain_map[i], BUS_DMASYNC_PREWRITE); @@ -7023,8 +7019,9 @@ bce_intr(void *xsc) DBRUN(sc->interrupts_generated++); + /* Synchnorize before we read from interface's status block */ bus_dmamap_sync(sc->status_tag, sc->status_map, - BUS_DMASYNC_POSTWRITE); + BUS_DMASYNC_POSTREAD); /* * If the hardware status block index @@ -7112,7 +7109,7 @@ bce_intr(void *xsc) } bus_dmamap_sync(sc->status_tag, sc->status_map, - BUS_DMASYNC_PREWRITE); + BUS_DMASYNC_PREREAD); /* Re-enable interrupts. */ bce_enable_intr(sc, 0); From 511e8a53439540af2e6e8b0e9860e2e1c8496d96 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Mon, 18 May 2009 02:25:45 +0000 Subject: [PATCH 259/544] This patch resolves the following issues: -- A routing socket message is not generated when an IPv6 address is either inserted or deleted from an interface. The missing routing message problem was discovered by Randall Stewart and Michael Tuxen during SCTP testing. -- Previously when an IPv6 address is configured on an interface, if the prefix length is /128, then a host route is instaleld in the kernel for this address. But this host route is not deleted when that IPv6 address is removed from the interface. -- Routes to the link-local all-nodes multicast address and the interface-local all-nodes multicast address are not removed when the last IPv6 address is removed from an interface. Reviewed by: bz, gnn --- sys/netinet6/in6.c | 197 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 196 insertions(+), 1 deletion(-) diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index df57bf6f25bc..a2321ff94c1a 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1151,6 +1151,28 @@ in6_purgeaddr(struct ifaddr *ifa) struct ifnet *ifp = ifa->ifa_ifp; struct in6_ifaddr *ia = (struct in6_ifaddr *) ifa; struct in6_multi_mship *imm; + struct sockaddr_in6 mltaddr, mltmask; + struct rtentry rt0; + struct sockaddr_dl gateway; + struct sockaddr_in6 mask, addr; + int plen, error; + struct rtentry *rt; + struct ifaddr *ifa0, *nifa; + + /* + * find another IPv6 address as the gateway for the + * link-local and node-local all-nodes multicast + * address routes + */ + TAILQ_FOREACH_SAFE(ifa0, &ifp->if_addrhead, ifa_link, nifa) { + if ((ifa0->ifa_addr->sa_family != AF_INET6) || + memcmp(&satosin6(ifa0->ifa_addr)->sin6_addr, + &ia->ia_addr.sin6_addr, + sizeof(struct in6_addr)) == 0) + continue; + else + break; + } /* stop DAD processing */ nd6_dad_stop(ifa); @@ -1159,7 +1181,25 @@ in6_purgeaddr(struct ifaddr *ifa) lla_lookup(LLTABLE6(ifp), (LLE_DELETE | LLE_IFADDR), (struct sockaddr *)&ia->ia_addr); IF_AFDATA_UNLOCK(ifp); - + + /* + * initialize for rtmsg generation + */ + bzero(&gateway, sizeof(gateway)); + gateway.sdl_len = sizeof(gateway); + gateway.sdl_family = AF_LINK; + gateway.sdl_nlen = 0; + gateway.sdl_alen = ifp->if_addrlen; + /* */ + bzero(&rt0, sizeof(rt0)); + rt0.rt_gateway = (struct sockaddr *)&gateway; + memcpy(&mask, &ia->ia_prefixmask, sizeof(ia->ia_prefixmask)); + memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr)); + rt_mask(&rt0) = (struct sockaddr *)&mask; + rt_key(&rt0) = (struct sockaddr *)&addr; + rt0.rt_flags = RTF_HOST | RTF_STATIC; + rt_newaddrmsg(RTM_DELETE, ifa, 0, &rt0); + /* * leave from multicast groups we have joined for the interface */ @@ -1168,6 +1208,139 @@ in6_purgeaddr(struct ifaddr *ifa) in6_leavegroup(imm); } + /* + * remove the link-local all-nodes address + */ + bzero(&mltmask, sizeof(mltmask)); + mltmask.sin6_len = sizeof(struct sockaddr_in6); + mltmask.sin6_family = AF_INET6; + mltmask.sin6_addr = in6mask32; + + bzero(&mltaddr, sizeof(mltaddr)); + mltaddr.sin6_len = sizeof(struct sockaddr_in6); + mltaddr.sin6_family = AF_INET6; + mltaddr.sin6_addr = in6addr_linklocal_allnodes; + + if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != + 0) + goto cleanup; + + rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL); + if (rt != NULL && rt->rt_gateway != NULL && + (memcmp(&satosin6(rt->rt_gateway)->sin6_addr, + &ia->ia_addr.sin6_addr, + sizeof(ia->ia_addr.sin6_addr)) == 0)) { + /* + * if no more IPv6 address exists on this interface + * then remove the multicast address route + */ + if (ifa0 == NULL) { + memcpy(&mltaddr.sin6_addr, &satosin6(rt_key(rt))->sin6_addr, + sizeof(mltaddr.sin6_addr)); + RTFREE_LOCKED(rt); + error = rtrequest(RTM_DELETE, (struct sockaddr *)&mltaddr, + (struct sockaddr *)&ia->ia_addr, + (struct sockaddr *)&mltmask, RTF_UP, + (struct rtentry **)0); + if (error) + log(LOG_INFO, "in6_purgeaddr: link-local all-nodes" + "multicast address deletion error\n"); + } else { + /* + * replace the gateway of the route + */ + struct sockaddr_in6 sa; + + bzero(&sa, sizeof(sa)); + sa.sin6_len = sizeof(struct sockaddr_in6); + sa.sin6_family = AF_INET6; + memcpy(&sa.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr, + sizeof(sa.sin6_addr)); + in6_setscope(&sa.sin6_addr, ifa0->ifa_ifp, NULL); + memcpy(rt->rt_gateway, &sa, sizeof(sa)); + RTFREE_LOCKED(rt); + } + } else { + if (rt != NULL) + RTFREE_LOCKED(rt); + } + + /* + * remove the node-local all-nodes address + */ + mltaddr.sin6_addr = in6addr_nodelocal_allnodes; + if ((error = in6_setscope(&mltaddr.sin6_addr, ifp, NULL)) != + 0) + goto cleanup; + + rt = rtalloc1((struct sockaddr *)&mltaddr, 0, 0UL); + if (rt != NULL && rt->rt_gateway != NULL && + (memcmp(&satosin6(rt->rt_gateway)->sin6_addr, + &ia->ia_addr.sin6_addr, + sizeof(ia->ia_addr.sin6_addr)) == 0)) { + /* + * if no more IPv6 address exists on this interface + * then remove the multicast address route + */ + if (ifa0 == NULL) { + memcpy(&mltaddr.sin6_addr, &satosin6(rt_key(rt))->sin6_addr, + sizeof(mltaddr.sin6_addr)); + + RTFREE_LOCKED(rt); + error = rtrequest(RTM_DELETE, (struct sockaddr *)&mltaddr, + (struct sockaddr *)&ia->ia_addr, + (struct sockaddr *)&mltmask, RTF_UP, + (struct rtentry **)0); + + if (error) + log(LOG_INFO, "in6_purgeaddr: node-local all-nodes" + "multicast address deletion error\n"); + } else { + /* + * replace the gateway of the route + */ + struct sockaddr_in6 sa; + + bzero(&sa, sizeof(sa)); + sa.sin6_len = sizeof(struct sockaddr_in6); + sa.sin6_family = AF_INET6; + memcpy(&sa.sin6_addr, &satosin6(ifa0->ifa_addr)->sin6_addr, + sizeof(sa.sin6_addr)); + in6_setscope(&sa.sin6_addr, ifa0->ifa_ifp, NULL); + memcpy(rt->rt_gateway, &sa, sizeof(sa)); + RTFREE_LOCKED(rt); + } + } else { + if (rt != NULL) + RTFREE_LOCKED(rt); + } + +cleanup: + + plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */ + if ((ia->ia_flags & IFA_ROUTE) && plen == 128) { + int error; + struct sockaddr *dstaddr; + + /* + * use the interface address if configuring an + * interface address with a /128 prefix len + */ + if (ia->ia_dstaddr.sin6_family == AF_INET6) + dstaddr = (struct sockaddr *)&ia->ia_dstaddr; + else + dstaddr = (struct sockaddr *)&ia->ia_addr; + + error = rtrequest(RTM_DELETE, + (struct sockaddr *)dstaddr, + (struct sockaddr *)&ia->ia_addr, + (struct sockaddr *)&ia->ia_prefixmask, + ia->ia_flags | RTF_HOST, NULL); + if (error != 0) + return; + ia->ia_flags &= ~IFA_ROUTE; + } + in6_unlink_ifa(ia, ifp); } @@ -1571,6 +1744,9 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, /* Add ownaddr as loopback rtentry, if necessary (ex. on p2p link). */ if (newhost) { struct llentry *ln; + struct rtentry rt; + struct sockaddr_dl gateway; + struct sockaddr_in6 mask, addr; IF_AFDATA_LOCK(ifp); ia->ia_ifa.ifa_rtrequest = NULL; @@ -1584,8 +1760,27 @@ in6_ifinit(struct ifnet *ifp, struct in6_ifaddr *ia, if (ln != NULL) { ln->la_expire = 0; /* for IPv6 this means permanent */ ln->ln_state = ND6_LLINFO_REACHABLE; + /* + * initialize for rtmsg generation + */ + bzero(&gateway, sizeof(gateway)); + gateway.sdl_len = sizeof(gateway); + gateway.sdl_family = AF_LINK; + gateway.sdl_nlen = 0; + gateway.sdl_alen = 6; + memcpy(gateway.sdl_data, &ln->ll_addr.mac_aligned, sizeof(ln->ll_addr)); + /* */ LLE_WUNLOCK(ln); } + + bzero(&rt, sizeof(rt)); + rt.rt_gateway = (struct sockaddr *)&gateway; + memcpy(&mask, &ia->ia_prefixmask, sizeof(ia->ia_prefixmask)); + memcpy(&addr, &ia->ia_addr, sizeof(ia->ia_addr)); + rt_mask(&rt) = (struct sockaddr *)&mask; + rt_key(&rt) = (struct sockaddr *)&addr; + rt.rt_flags = RTF_UP | RTF_HOST | RTF_STATIC; + rt_newaddrmsg(RTM_ADD, &ia->ia_ifa, 0, &rt); } return (error); From 3a72bf04c4bf5ac46ccfd8868087947205bf2dbe Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Mon, 18 May 2009 04:07:46 +0000 Subject: [PATCH 260/544] Implement MSG_CMSG_CLOEXEC flag for linux_recvmsg(). Approved by: kib (mentor) MFC after: 1 month --- sys/compat/linux/linux_socket.c | 33 ++++++++++++++++++++++++--------- sys/compat/linux/linux_socket.h | 1 + 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 86cbcd64a65a..114a6d5e7de9 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1148,7 +1148,7 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) struct mbuf **controlp; caddr_t outbuf; void *data; - int error; + int error, i, fd, fds, *fdp; error = copyin(PTRIN(args->msg), &linux_msg, sizeof(linux_msg)); if (error) @@ -1217,15 +1217,30 @@ linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args) data = CMSG_DATA(cm); datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data; - if (outlen + LINUX_CMSG_LEN(datalen) > - linux_msg.msg_controllen) { - if (outlen == 0) { - error = EMSGSIZE; - goto bad; - } else { - linux_msg.msg_flags |= LINUX_MSG_CTRUNC; - goto out; + switch (linux_cmsg->cmsg_type) + { + case LINUX_SCM_RIGHTS: + if (outlen + LINUX_CMSG_LEN(datalen) > + linux_msg.msg_controllen) { + if (outlen == 0) { + error = EMSGSIZE; + goto bad; + } else { + linux_msg.msg_flags |= + LINUX_MSG_CTRUNC; + goto out; + } } + if (args->flags & LINUX_MSG_CMSG_CLOEXEC) { + fds = datalen / sizeof(int); + fdp = data; + for (i = 0; i < fds; i++) { + fd = *fdp++; + (void)kern_fcntl(td, fd, + F_SETFD, FD_CLOEXEC); + } + } + break; } linux_cmsg->cmsg_len = LINUX_CMSG_LEN(datalen); diff --git a/sys/compat/linux/linux_socket.h b/sys/compat/linux/linux_socket.h index 67903c5e600e..c716f02779ba 100644 --- a/sys/compat/linux/linux_socket.h +++ b/sys/compat/linux/linux_socket.h @@ -48,6 +48,7 @@ #define LINUX_MSG_RST 0x1000 #define LINUX_MSG_ERRQUEUE 0x2000 #define LINUX_MSG_NOSIGNAL 0x4000 +#define LINUX_MSG_CMSG_CLOEXEC 0x40000000 /* Socket-level control message types */ From aa6aea071581dd6dea81dfa6f40d9f949e7e1668 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 18 May 2009 04:50:31 +0000 Subject: [PATCH 261/544] Disable some un-needed console debugging. --- sys/dev/xen/console/console.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/xen/console/console.c b/sys/dev/xen/console/console.c index 5c16b1f5ff29..9b376b52fbfb 100644 --- a/sys/dev/xen/console/console.c +++ b/sys/dev/xen/console/console.c @@ -152,7 +152,7 @@ xccncheckc(struct consdev *dev) CN_LOCK(cn_mtx); if ((rp - rc)) { - if (kdb_active) printf("%s:%d\n", __func__, __LINE__); + /* if (kdb_active) printf("%s:%d\n", __func__, __LINE__); */ /* we need to return only one char */ ret = (int)rbuf[RBUF_MASK(rc)]; rc++; From 3a5391225be58e307424649a031e33d6ce30b563 Mon Sep 17 00:00:00 2001 From: Adrian Chadd Date: Mon, 18 May 2009 04:56:37 +0000 Subject: [PATCH 262/544] The merge in r189699 reverted part of the work done in a previous commit (r188036.) Re-revert that change so the Xen networking functions again. --- sys/dev/xen/netfront/netfront.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sys/dev/xen/netfront/netfront.c b/sys/dev/xen/netfront/netfront.c index a70c47cffd82..f6b6641bdad1 100644 --- a/sys/dev/xen/netfront/netfront.c +++ b/sys/dev/xen/netfront/netfront.c @@ -1297,11 +1297,12 @@ xennet_get_responses(struct netfront_info *np, gnttab_release_grant_reference(&np->gref_rx_head, ref); next: - if (m != NULL) { - m->m_len = rx->status; - m->m_data += rx->offset; - m0->m_pkthdr.len += rx->status; - } + if (m == NULL) + break; + + m->m_len = rx->status; + m->m_data += rx->offset; + m0->m_pkthdr.len += rx->status; if (!(rx->flags & NETRXF_more_data)) break; From 284c81cbcb4237c4e0c621b18c1500d88a1eaee4 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:02:54 +0000 Subject: [PATCH 263/544] Use ANSI C declarations for all functions. --- sys/dev/nge/if_nge.c | 133 ++++++++++++------------------------------- 1 file changed, 37 insertions(+), 96 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 55ee4ee3594c..3ee4723784b5 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -244,8 +244,7 @@ DRIVER_MODULE(miibus, nge, miibus_driver, miibus_devclass, 0, 0); CSR_WRITE_4(sc, NGE_MEAR, CSR_READ_4(sc, NGE_MEAR) & ~(x)) static void -nge_delay(sc) - struct nge_softc *sc; +nge_delay(struct nge_softc *sc) { int idx; @@ -256,8 +255,7 @@ nge_delay(sc) } static void -nge_eeprom_idle(sc) - struct nge_softc *sc; +nge_eeprom_idle(struct nge_softc *sc) { register int i; @@ -286,9 +284,7 @@ nge_eeprom_idle(sc) * Send a read command and address to the EEPROM, check for ACK. */ static void -nge_eeprom_putbyte(sc, addr) - struct nge_softc *sc; - int addr; +nge_eeprom_putbyte(struct nge_softc *sc, int addr) { register int d, i; @@ -317,10 +313,7 @@ nge_eeprom_putbyte(sc, addr) * Read a word of data stored in the EEPROM at address 'addr.' */ static void -nge_eeprom_getword(sc, addr, dest) - struct nge_softc *sc; - int addr; - u_int16_t *dest; +nge_eeprom_getword(struct nge_softc *sc, int addr, u_int16_t *dest) { register int i; u_int16_t word = 0; @@ -365,12 +358,7 @@ nge_eeprom_getword(sc, addr, dest) * Read a sequence of words from the EEPROM. */ static void -nge_read_eeprom(sc, dest, off, cnt, swap) - struct nge_softc *sc; - caddr_t dest; - int off; - int cnt; - int swap; +nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) { int i; u_int16_t word = 0, *ptr; @@ -391,8 +379,7 @@ nge_read_eeprom(sc, dest, off, cnt, swap) * Sync the PHYs by setting data bit and strobing the clock 32 times. */ static void -nge_mii_sync(sc) - struct nge_softc *sc; +nge_mii_sync(struct nge_softc *sc) { register int i; @@ -412,10 +399,7 @@ nge_mii_sync(sc) * Clock a series of bits through the MII. */ static void -nge_mii_send(sc, bits, cnt) - struct nge_softc *sc; - u_int32_t bits; - int cnt; +nge_mii_send(struct nge_softc *sc, u_int32_t bits, int cnt) { int i; @@ -438,10 +422,7 @@ nge_mii_send(sc, bits, cnt) * Read an PHY register through the MII. */ static int -nge_mii_readreg(sc, frame) - struct nge_softc *sc; - struct nge_mii_frame *frame; - +nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) { int i, ack; @@ -527,10 +508,7 @@ nge_mii_readreg(sc, frame) * Write to a PHY register through the MII. */ static int -nge_mii_writereg(sc, frame) - struct nge_softc *sc; - struct nge_mii_frame *frame; - +nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame) { /* @@ -570,9 +548,7 @@ nge_mii_writereg(sc, frame) } static int -nge_miibus_readreg(dev, phy, reg) - device_t dev; - int phy, reg; +nge_miibus_readreg(device_t dev, int phy, int reg) { struct nge_softc *sc; struct nge_mii_frame frame; @@ -589,9 +565,7 @@ nge_miibus_readreg(dev, phy, reg) } static int -nge_miibus_writereg(dev, phy, reg, data) - device_t dev; - int phy, reg, data; +nge_miibus_writereg(device_t dev, int phy, int reg, int data) { struct nge_softc *sc; struct nge_mii_frame frame; @@ -609,8 +583,7 @@ nge_miibus_writereg(dev, phy, reg, data) } static void -nge_miibus_statchg(dev) - device_t dev; +nge_miibus_statchg(device_t dev) { int status; struct nge_softc *sc; @@ -666,8 +639,7 @@ nge_miibus_statchg(dev) } static void -nge_setmulti(sc) - struct nge_softc *sc; +nge_setmulti(struct nge_softc *sc) { struct ifnet *ifp; struct ifmultiaddr *ifma; @@ -728,8 +700,7 @@ nge_setmulti(sc) } static void -nge_reset(sc) - struct nge_softc *sc; +nge_reset(struct nge_softc *sc) { register int i; @@ -761,8 +732,7 @@ nge_reset(sc) * IDs against our list and return a device name if we find a match. */ static int -nge_probe(dev) - device_t dev; +nge_probe(device_t dev) { struct nge_type *t; @@ -785,8 +755,7 @@ nge_probe(dev) * setup and ethernet/BPF attach. */ static int -nge_attach(dev) - device_t dev; +nge_attach(device_t dev) { u_char eaddr[ETHER_ADDR_LEN]; struct nge_softc *sc; @@ -938,8 +907,7 @@ nge_attach(dev) } static int -nge_detach(dev) - device_t dev; +nge_detach(device_t dev) { struct nge_softc *sc; struct ifnet *ifp; @@ -978,8 +946,7 @@ nge_detach(dev) * Initialize the transmit descriptors. */ static int -nge_list_tx_init(sc) - struct nge_softc *sc; +nge_list_tx_init(struct nge_softc *sc) { struct nge_list_data *ld; struct nge_ring_data *cd; @@ -1017,8 +984,7 @@ nge_list_tx_init(sc) * points back to the first. */ static int -nge_list_rx_init(sc) - struct nge_softc *sc; +nge_list_rx_init(struct nge_softc *sc) { struct nge_list_data *ld; struct nge_ring_data *cd; @@ -1053,10 +1019,7 @@ nge_list_rx_init(sc) * Initialize an RX descriptor and attach an MBUF cluster. */ static int -nge_newbuf(sc, c, m) - struct nge_softc *sc; - struct nge_desc *c; - struct mbuf *m; +nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) { if (m == NULL) { @@ -1080,8 +1043,7 @@ nge_newbuf(sc, c, m) #ifdef NGE_FIXUP_RX static __inline void -nge_fixup_rx(m) - struct mbuf *m; +nge_fixup_rx(struct mbuf *m) { int i; uint16_t *src, *dst; @@ -1103,8 +1065,7 @@ nge_fixup_rx(m) * the higher level protocols. */ static void -nge_rxeof(sc) - struct nge_softc *sc; +nge_rxeof(struct nge_softc *sc) { struct mbuf *m; struct ifnet *ifp; @@ -1247,8 +1208,7 @@ nge_rxeof(sc) */ static void -nge_txeof(sc) - struct nge_softc *sc; +nge_txeof(struct nge_softc *sc) { struct nge_desc *cur_tx; struct ifnet *ifp; @@ -1305,8 +1265,7 @@ nge_txeof(sc) } static void -nge_tick(xsc) - void *xsc; +nge_tick(void *xsc) { struct nge_softc *sc; struct mii_data *mii; @@ -1400,8 +1359,7 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) #endif /* DEVICE_POLLING */ static void -nge_intr(arg) - void *arg; +nge_intr(void *arg) { struct nge_softc *sc; struct ifnet *ifp; @@ -1498,10 +1456,7 @@ nge_intr(arg) * pointers to the fragment pointers. */ static int -nge_encap(sc, m_head, txidx) - struct nge_softc *sc; - struct mbuf *m_head; - u_int32_t *txidx; +nge_encap(struct nge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) { struct nge_desc *f = NULL; struct mbuf *m; @@ -1569,8 +1524,7 @@ nge_encap(sc, m_head, txidx) */ static void -nge_start(ifp) - struct ifnet *ifp; +nge_start(struct ifnet *ifp) { struct nge_softc *sc; @@ -1581,8 +1535,7 @@ nge_start(ifp) } static void -nge_start_locked(ifp) - struct ifnet *ifp; +nge_start_locked(struct ifnet *ifp) { struct nge_softc *sc; struct mbuf *m_head = NULL; @@ -1630,8 +1583,7 @@ nge_start_locked(ifp) } static void -nge_init(xsc) - void *xsc; +nge_init(void *xsc) { struct nge_softc *sc = xsc; @@ -1641,8 +1593,7 @@ nge_init(xsc) } static void -nge_init_locked(sc) - struct nge_softc *sc; +nge_init_locked(struct nge_softc *sc) { struct ifnet *ifp = sc->nge_ifp; struct mii_data *mii; @@ -1832,8 +1783,7 @@ nge_init_locked(sc) * Set media options. */ static int -nge_ifmedia_upd(ifp) - struct ifnet *ifp; +nge_ifmedia_upd(struct ifnet *ifp) { struct nge_softc *sc; @@ -1845,8 +1795,7 @@ nge_ifmedia_upd(ifp) } static void -nge_ifmedia_upd_locked(ifp) - struct ifnet *ifp; +nge_ifmedia_upd_locked(struct ifnet *ifp) { struct nge_softc *sc; struct mii_data *mii; @@ -1900,9 +1849,7 @@ nge_ifmedia_upd_locked(ifp) * Report current media status. */ static void -nge_ifmedia_sts(ifp, ifmr) - struct ifnet *ifp; - struct ifmediareq *ifmr; +nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { struct nge_softc *sc; struct mii_data *mii; @@ -1954,10 +1901,7 @@ nge_ifmedia_sts(ifp, ifmr) } static int -nge_ioctl(ifp, command, data) - struct ifnet *ifp; - u_long command; - caddr_t data; +nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { struct nge_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; @@ -2069,8 +2013,7 @@ nge_ioctl(ifp, command, data) } static void -nge_watchdog(ifp) - struct ifnet *ifp; +nge_watchdog(struct ifnet *ifp) { struct nge_softc *sc; @@ -2098,8 +2041,7 @@ nge_watchdog(ifp) * RX and TX lists. */ static void -nge_stop(sc) - struct nge_softc *sc; +nge_stop(struct nge_softc *sc) { register int i; struct ifnet *ifp; @@ -2162,8 +2104,7 @@ nge_stop(sc) * get confused by errant DMAs when rebooting. */ static int -nge_shutdown(dev) - device_t dev; +nge_shutdown(device_t dev) { struct nge_softc *sc; From 2cf2d79999396aaf712fc2d9a1785d71e6363ac0 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:05:50 +0000 Subject: [PATCH 264/544] Remove register keyword. --- sys/dev/nge/if_nge.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 3ee4723784b5..8c853efec0c0 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -257,7 +257,7 @@ nge_delay(struct nge_softc *sc) static void nge_eeprom_idle(struct nge_softc *sc) { - register int i; + int i; SIO_SET(NGE_MEAR_EE_CSEL); nge_delay(sc); @@ -286,7 +286,7 @@ nge_eeprom_idle(struct nge_softc *sc) static void nge_eeprom_putbyte(struct nge_softc *sc, int addr) { - register int d, i; + int d, i; d = addr | NGE_EECMD_READ; @@ -315,7 +315,7 @@ nge_eeprom_putbyte(struct nge_softc *sc, int addr) static void nge_eeprom_getword(struct nge_softc *sc, int addr, u_int16_t *dest) { - register int i; + int i; u_int16_t word = 0; /* Force EEPROM to idle state. */ @@ -381,7 +381,7 @@ nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) static void nge_mii_sync(struct nge_softc *sc) { - register int i; + int i; SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA); @@ -702,7 +702,7 @@ nge_setmulti(struct nge_softc *sc) static void nge_reset(struct nge_softc *sc) { - register int i; + int i; NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RESET); @@ -2043,7 +2043,7 @@ nge_watchdog(struct ifnet *ifp) static void nge_stop(struct nge_softc *sc) { - register int i; + int i; struct ifnet *ifp; struct mii_data *mii; From a13d3502937686249b51134068040bf0cf455e8f Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:09:10 +0000 Subject: [PATCH 265/544] Remove trailling whitespaces. --- sys/dev/nge/if_nge.c | 70 ++++++++++++++++++++--------------------- sys/dev/nge/if_ngereg.h | 4 +-- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 8c853efec0c0..0fd7bbb8af94 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -433,7 +433,7 @@ nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) frame->mii_opcode = NGE_MII_READOP; frame->mii_turnaround = 0; frame->mii_data = 0; - + CSR_WRITE_4(sc, NGE_MEAR, 0); /* @@ -518,7 +518,7 @@ nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame) frame->mii_stdelim = NGE_MII_STARTDELIM; frame->mii_opcode = NGE_MII_WRITEOP; frame->mii_turnaround = NGE_MII_TURNAROUND; - + /* * Turn on data output. */ @@ -585,7 +585,7 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data) static void nge_miibus_statchg(device_t dev) { - int status; + int status; struct nge_softc *sc; struct mii_data *mii; @@ -604,7 +604,7 @@ nge_miibus_statchg(device_t dev) NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); } - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) + } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) != IFM_FDX) { NGE_CLRBIT(sc, NGE_TX_CFG, (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); @@ -846,10 +846,10 @@ nge_attach(device_t dev) if (CSR_READ_4(sc, NGE_CFG) & NGE_CFG_TBI_EN) { sc->nge_tbi = 1; device_printf(dev, "Using TBI\n"); - + sc->nge_miibus = dev; - ifmedia_init(&sc->nge_ifmedia, 0, nge_ifmedia_upd, + ifmedia_init(&sc->nge_ifmedia, 0, nge_ifmedia_upd, nge_ifmedia_sts); #define ADD(m, c) ifmedia_add(&sc->nge_ifmedia, (m), (c), NULL) ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, 0), 0); @@ -858,16 +858,16 @@ nge_attach(device_t dev) ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0), 0); #undef ADD device_printf(dev, " 1000baseSX, 1000baseSX-FDX, auto\n"); - - ifmedia_set(&sc->nge_ifmedia, + + ifmedia_set(&sc->nge_ifmedia, IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0)); - + CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) - | NGE_GPIO_GP4_OUT - | NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB + | NGE_GPIO_GP4_OUT + | NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB | NGE_GPIO_GP3_OUTENB | NGE_GPIO_GP3_IN | NGE_GPIO_GP4_IN); - + } else { device_printf(dev, "MII without any PHY!\n"); error = ENXIO; @@ -1044,20 +1044,20 @@ nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) #ifdef NGE_FIXUP_RX static __inline void nge_fixup_rx(struct mbuf *m) -{ +{ int i; uint16_t *src, *dst; - + src = mtod(m, uint16_t *); dst = src - 1; - + for (i = 0; i < (m->m_len / sizeof(uint16_t) + 1); i++) *dst++ = *src++; - + m->m_data -= ETHER_ALIGN; - + return; -} +} #endif /* @@ -1277,10 +1277,10 @@ nge_tick(void *xsc) if (sc->nge_tbi) { if (!sc->nge_link) { - if (CSR_READ_4(sc, NGE_TBI_BMSR) + if (CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { if (bootverbose) - device_printf(sc->nge_dev, + device_printf(sc->nge_dev, "gigabit link up\n"); nge_miibus_statchg(sc->nge_miibus); sc->nge_link++; @@ -1296,9 +1296,9 @@ nge_tick(void *xsc) if (mii->mii_media_status & IFM_ACTIVE && IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { sc->nge_link++; - if (IFM_SUBTYPE(mii->mii_media_active) + if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T && bootverbose) - device_printf(sc->nge_dev, + device_printf(sc->nge_dev, "gigabit link up\n"); if (ifp->if_snd.ifq_head != NULL) nge_start_locked(ifp); @@ -1422,7 +1422,7 @@ nge_intr(void *arg) } #if 0 - /* + /* * XXX: nge_tick() is not ready to be called this way * it screws up the aneg timeout because mii_tick() is * only to be called once per second. @@ -1711,7 +1711,7 @@ nge_init_locked(struct nge_softc *sc) /* Set full/half duplex mode. */ if (sc->nge_tbi) { - if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) + if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) == IFM_FDX) { NGE_SETBIT(sc, NGE_TX_CFG, (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); @@ -1804,16 +1804,16 @@ nge_ifmedia_upd_locked(struct ifnet *ifp) NGE_LOCK_ASSERT(sc); if (sc->nge_tbi) { - if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) + if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) == IFM_AUTO) { - CSR_WRITE_4(sc, NGE_TBI_ANAR, + CSR_WRITE_4(sc, NGE_TBI_ANAR, CSR_READ_4(sc, NGE_TBI_ANAR) | NGE_TBIANAR_HDX | NGE_TBIANAR_FDX | NGE_TBIANAR_PS1 | NGE_TBIANAR_PS2); CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG | NGE_TBIBMCR_RESTART_ANEG); CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG); - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media + } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) == IFM_FDX) { NGE_SETBIT(sc, NGE_TX_CFG, (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); @@ -1829,7 +1829,7 @@ nge_ifmedia_upd_locked(struct ifnet *ifp) CSR_WRITE_4(sc, NGE_TBI_ANAR, 0); CSR_WRITE_4(sc, NGE_TBI_BMCR, 0); } - + CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) & ~NGE_GPIO_GP3_OUT); } else { @@ -1863,7 +1863,7 @@ nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) if (CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { ifmr->ifm_status |= IFM_ACTIVE; - } + } if (CSR_READ_4(sc, NGE_TBI_BMCR) & NGE_TBIBMCR_LOOPBACK) ifmr->ifm_active |= IFM_LOOP; if (!CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { @@ -1871,7 +1871,7 @@ nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_status = 0; NGE_UNLOCK(sc); return; - } + } ifmr->ifm_active |= IFM_1000_SX; if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) == IFM_AUTO) { @@ -1883,12 +1883,12 @@ nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) & NGE_TBIANAR_HDX) { ifmr->ifm_active |= IFM_HDX; } - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) + } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) == IFM_FDX) ifmr->ifm_active |= IFM_FDX; else ifmr->ifm_active |= IFM_HDX; - + } else { mii = device_get_softc(sc->nge_miibus); mii_pollstat(mii); @@ -1969,11 +1969,11 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCGIFMEDIA: case SIOCSIFMEDIA: if (sc->nge_tbi) { - error = ifmedia_ioctl(ifp, ifr, &sc->nge_ifmedia, + error = ifmedia_ioctl(ifp, ifr, &sc->nge_ifmedia, command); } else { mii = device_get_softc(sc->nge_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); } break; @@ -1990,7 +1990,7 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_capenable |= IFCAP_POLLING; NGE_UNLOCK(sc); return (error); - + } if (!(ifr->ifr_reqcap & IFCAP_POLLING) && ifp->if_capenable & IFCAP_POLLING) { diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h index 8927bee9fb7c..aa79953d644a 100644 --- a/sys/dev/nge/if_ngereg.h +++ b/sys/dev/nge/if_ngereg.h @@ -422,7 +422,7 @@ /* TBI BMCR */ #define NGE_TBIBMCR_RESTART_ANEG 0x00000200 #define NGE_TBIBMCR_ENABLE_ANEG 0x00001000 -#define NGE_TBIBMCR_LOOPBACK 0x00004000 +#define NGE_TBIBMCR_LOOPBACK 0x00004000 /* TBI BMSR */ #define NGE_TBIBMSR_ANEG_DONE 0x00000004 @@ -467,7 +467,7 @@ * After this, we include some additional structure members for * use by the driver. Note that for this structure will be a different * size on the alpha, but that's okay as long as it's a multiple of 4 - * bytes in size. + * bytes in size. * */ struct nge_desc_64 { From 2da9a170c0e7aa4223ee4f803c9c06b313cdb437 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:13:56 +0000 Subject: [PATCH 266/544] Remove return statement at the end of functions that return void. --- sys/dev/nge/if_nge.c | 35 ----------------------------------- 1 file changed, 35 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 0fd7bbb8af94..ea3bc8ea3022 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -250,8 +250,6 @@ nge_delay(struct nge_softc *sc) for (idx = (300 / 33) + 1; idx > 0; idx--) CSR_READ_4(sc, NGE_CSR); - - return; } static void @@ -276,8 +274,6 @@ nge_eeprom_idle(struct nge_softc *sc) SIO_CLR(NGE_MEAR_EE_CSEL); nge_delay(sc); CSR_WRITE_4(sc, NGE_MEAR, 0x00000000); - - return; } /* @@ -305,8 +301,6 @@ nge_eeprom_putbyte(struct nge_softc *sc, int addr) SIO_CLR(NGE_MEAR_EE_CLK); nge_delay(sc); } - - return; } /* @@ -350,8 +344,6 @@ nge_eeprom_getword(struct nge_softc *sc, int addr, u_int16_t *dest) nge_eeprom_idle(sc); *dest = word; - - return; } /* @@ -371,8 +363,6 @@ nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) else *ptr = word; } - - return; } /* @@ -391,8 +381,6 @@ nge_mii_sync(struct nge_softc *sc) SIO_CLR(NGE_MEAR_MII_CLK); DELAY(1); } - - return; } /* @@ -635,7 +623,6 @@ nge_miibus_statchg(device_t dev) NGE_CLRBIT(sc, NGE_CFG, NGE_CFG_MODE_1000); } } - return; } static void @@ -695,8 +682,6 @@ nge_setmulti(struct nge_softc *sc) IF_ADDR_UNLOCK(ifp); CSR_WRITE_4(sc, NGE_RXFILT_CTL, filtsave); - - return; } static void @@ -723,8 +708,6 @@ nge_reset(struct nge_softc *sc) */ CSR_WRITE_4(sc, NGE_CLKRUN, NGE_CLKRUN_PMESTS); CSR_WRITE_4(sc, NGE_CLKRUN, 0); - - return; } /* @@ -1198,8 +1181,6 @@ nge_rxeof(struct nge_softc *sc) } sc->nge_cdata.nge_rx_prod = i; - - return; } /* @@ -1260,8 +1241,6 @@ nge_txeof(struct nge_softc *sc) if (idx == sc->nge_cdata.nge_tx_prod) ifp->if_timer = 0; - - return; } static void @@ -1306,8 +1285,6 @@ nge_tick(void *xsc) } } callout_reset(&sc->nge_stat_ch, hz, nge_tick, sc); - - return; } #ifdef DEVICE_POLLING @@ -1447,8 +1424,6 @@ nge_intr(void *arg) & ~NGE_GPIO_GP3_OUT); NGE_UNLOCK(sc); - - return; } /* @@ -1578,8 +1553,6 @@ nge_start_locked(struct ifnet *ifp) * Set a timeout in case the chip goes out to lunch. */ ifp->if_timer = 5; - - return; } static void @@ -1775,8 +1748,6 @@ nge_init_locked(struct nge_softc *sc) ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - - return; } /* @@ -1896,8 +1867,6 @@ nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) ifmr->ifm_status = mii->mii_media_status; } NGE_UNLOCK(sc); - - return; } static int @@ -2032,8 +2001,6 @@ nge_watchdog(struct ifnet *ifp) nge_start_locked(ifp); NGE_UNLOCK(sc); - - return; } /* @@ -2095,8 +2062,6 @@ nge_stop(struct nge_softc *sc) sizeof(sc->nge_ldata->nge_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - return; } /* From 25d7155f3d5f939338231c3f2443829e33f670aa Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:19:17 +0000 Subject: [PATCH 267/544] style(9) - space after keyword. --- sys/dev/nge/if_nge.c | 50 ++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index ea3bc8ea3022..26f3309bd3d3 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -459,7 +459,7 @@ nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) * need to clock through 16 cycles to keep the PHY(s) in sync. */ if (ack) { - for(i = 0; i < 16; i++) { + for (i = 0; i < 16; i++) { SIO_CLR(NGE_MEAR_MII_CLK); DELAY(1); SIO_SET(NGE_MEAR_MII_CLK); @@ -488,8 +488,8 @@ nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) DELAY(1); if (ack) - return(1); - return(0); + return (1); + return (0); } /* @@ -532,7 +532,7 @@ nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame) */ SIO_CLR(NGE_MEAR_MII_DIR); - return(0); + return (0); } static int @@ -549,7 +549,7 @@ nge_miibus_readreg(device_t dev, int phy, int reg) frame.mii_regaddr = reg; nge_mii_readreg(sc, &frame); - return(frame.mii_data); + return (frame.mii_data); } static int @@ -567,7 +567,7 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data) frame.mii_data = data; nge_mii_writereg(sc, &frame); - return(0); + return (0); } static void @@ -721,16 +721,16 @@ nge_probe(device_t dev) t = nge_devs; - while(t->nge_name != NULL) { + while (t->nge_name != NULL) { if ((pci_get_vendor(dev) == t->nge_vid) && (pci_get_device(dev) == t->nge_did)) { device_set_desc(dev, t->nge_name); - return(BUS_PROBE_DEFAULT); + return (BUS_PROBE_DEFAULT); } t++; } - return(ENXIO); + return (ENXIO); } /* @@ -886,7 +886,7 @@ nge_attach(device_t dev) if (sc->nge_res) bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); NGE_LOCK_DESTROY(sc); - return(error); + return (error); } static int @@ -922,7 +922,7 @@ nge_detach(device_t dev) NGE_LOCK_DESTROY(sc); - return(0); + return (0); } /* @@ -957,7 +957,7 @@ nge_list_tx_init(struct nge_softc *sc) cd->nge_tx_prod = cd->nge_tx_cons = cd->nge_tx_cnt = 0; - return(0); + return (0); } @@ -978,7 +978,7 @@ nge_list_rx_init(struct nge_softc *sc) for (i = 0; i < NGE_RX_LIST_CNT; i++) { if (nge_newbuf(sc, &ld->nge_rx_list[i], NULL) == ENOBUFS) - return(ENOBUFS); + return (ENOBUFS); if (i == (NGE_RX_LIST_CNT - 1)) { ld->nge_rx_list[i].nge_nextdesc = &ld->nge_rx_list[0]; @@ -995,7 +995,7 @@ nge_list_rx_init(struct nge_softc *sc) cd->nge_rx_prod = 0; sc->nge_head = sc->nge_tail = NULL; - return(0); + return (0); } /* @@ -1021,7 +1021,7 @@ nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) c->nge_ctl = m->m_len; c->nge_extsts = 0; - return(0); + return (0); } #ifdef NGE_FIXUP_RX @@ -1060,7 +1060,7 @@ nge_rxeof(struct nge_softc *sc) ifp = sc->nge_ifp; i = sc->nge_cdata.nge_rx_prod; - while(NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) { + while (NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) { u_int32_t extsts; #ifdef DEVICE_POLLING @@ -1364,7 +1364,7 @@ nge_intr(void *arg) CSR_WRITE_4(sc, NGE_IER, 0); /* Data LED on for TBI mode */ - if(sc->nge_tbi) + if (sc->nge_tbi) CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) | NGE_GPIO_GP3_OUT); @@ -1419,7 +1419,7 @@ nge_intr(void *arg) /* Data LED off for TBI mode */ - if(sc->nge_tbi) + if (sc->nge_tbi) CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) & ~NGE_GPIO_GP3_OUT); @@ -1449,7 +1449,7 @@ nge_encap(struct nge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) if (m->m_len != 0) { if ((NGE_TX_LIST_CNT - (sc->nge_cdata.nge_tx_cnt + cnt)) < 2) - return(ENOBUFS); + return (ENOBUFS); f = &sc->nge_ldata->nge_tx_list[frag]; f->nge_ctl = NGE_CMDSTS_MORE | m->m_len; f->nge_ptr = vtophys(mtod(m, vm_offset_t)); @@ -1462,7 +1462,7 @@ nge_encap(struct nge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) } if (m != NULL) - return(ENOBUFS); + return (ENOBUFS); sc->nge_ldata->nge_tx_list[*txidx].nge_extsts = 0; if (m_head->m_pkthdr.csum_flags) { @@ -1488,7 +1488,7 @@ nge_encap(struct nge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) sc->nge_cdata.nge_tx_cnt += cnt; *txidx = frag; - return(0); + return (0); } /* @@ -1526,7 +1526,7 @@ nge_start_locked(struct ifnet *ifp) if (ifp->if_drv_flags & IFF_DRV_OACTIVE) return; - while(sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) { + while (sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) { IF_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; @@ -1877,7 +1877,7 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct mii_data *mii; int error = 0; - switch(command) { + switch (command) { case SIOCSIFMTU: if (ifr->ifr_mtu > NGE_JUMBO_MTU) error = EINVAL; @@ -1952,7 +1952,7 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) !(ifp->if_capenable & IFCAP_POLLING)) { error = ether_poll_register(nge_poll, ifp); if (error) - return(error); + return (error); NGE_LOCK(sc); /* Disable interrupts */ CSR_WRITE_4(sc, NGE_IER, 0); @@ -1978,7 +1978,7 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) break; } - return(error); + return (error); } static void From 3929ff51cf702b01a1a6a11f698e73e75d5b8b41 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 06:32:38 +0000 Subject: [PATCH 268/544] s/u_int8_t/uint8_t/g s/u_int16_t/uint16_t/g s/u_int32_t/uint32_t/g --- sys/dev/nge/if_nge.c | 40 +++++++++++++++---------------- sys/dev/nge/if_ngereg.h | 52 ++++++++++++++++++++--------------------- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 26f3309bd3d3..5974d9090002 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -151,7 +151,7 @@ static int nge_attach(device_t); static int nge_detach(device_t); static int nge_newbuf(struct nge_softc *, struct nge_desc *, struct mbuf *); -static int nge_encap(struct nge_softc *, struct mbuf *, u_int32_t *); +static int nge_encap(struct nge_softc *, struct mbuf *, uint32_t *); #ifdef NGE_FIXUP_RX static __inline void nge_fixup_rx (struct mbuf *); #endif @@ -174,11 +174,11 @@ static void nge_ifmedia_sts(struct ifnet *, struct ifmediareq *); static void nge_delay(struct nge_softc *); static void nge_eeprom_idle(struct nge_softc *); static void nge_eeprom_putbyte(struct nge_softc *, int); -static void nge_eeprom_getword(struct nge_softc *, int, u_int16_t *); +static void nge_eeprom_getword(struct nge_softc *, int, uint16_t *); static void nge_read_eeprom(struct nge_softc *, caddr_t, int, int, int); static void nge_mii_sync(struct nge_softc *); -static void nge_mii_send(struct nge_softc *, u_int32_t, int); +static void nge_mii_send(struct nge_softc *, uint32_t, int); static int nge_mii_readreg(struct nge_softc *, struct nge_mii_frame *); static int nge_mii_writereg(struct nge_softc *, struct nge_mii_frame *); @@ -307,10 +307,10 @@ nge_eeprom_putbyte(struct nge_softc *sc, int addr) * Read a word of data stored in the EEPROM at address 'addr.' */ static void -nge_eeprom_getword(struct nge_softc *sc, int addr, u_int16_t *dest) +nge_eeprom_getword(struct nge_softc *sc, int addr, uint16_t *dest) { int i; - u_int16_t word = 0; + uint16_t word = 0; /* Force EEPROM to idle state. */ nge_eeprom_idle(sc); @@ -353,11 +353,11 @@ static void nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) { int i; - u_int16_t word = 0, *ptr; + uint16_t word = 0, *ptr; for (i = 0; i < cnt; i++) { nge_eeprom_getword(sc, off + i, &word); - ptr = (u_int16_t *)(dest + (i * 2)); + ptr = (uint16_t *)(dest + (i * 2)); if (swap) *ptr = ntohs(word); else @@ -387,7 +387,7 @@ nge_mii_sync(struct nge_softc *sc) * Clock a series of bits through the MII. */ static void -nge_mii_send(struct nge_softc *sc, u_int32_t bits, int cnt) +nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt) { int i; @@ -630,7 +630,7 @@ nge_setmulti(struct nge_softc *sc) { struct ifnet *ifp; struct ifmultiaddr *ifma; - u_int32_t h = 0, i, filtsave; + uint32_t h = 0, i, filtsave; int bit, index; NGE_LOCK_ASSERT(sc); @@ -1014,7 +1014,7 @@ nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) m->m_len = m->m_pkthdr.len = MCLBYTES; - m_adj(m, sizeof(u_int64_t)); + m_adj(m, sizeof(uint64_t)); c->nge_mbuf = m; c->nge_ptr = vtophys(mtod(m, caddr_t)); @@ -1054,14 +1054,14 @@ nge_rxeof(struct nge_softc *sc) struct ifnet *ifp; struct nge_desc *cur_rx; int i, total_len = 0; - u_int32_t rxstat; + uint32_t rxstat; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; i = sc->nge_cdata.nge_rx_prod; while (NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) { - u_int32_t extsts; + uint32_t extsts; #ifdef DEVICE_POLLING if (ifp->if_capenable & IFCAP_POLLING) { @@ -1193,7 +1193,7 @@ nge_txeof(struct nge_softc *sc) { struct nge_desc *cur_tx; struct ifnet *ifp; - u_int32_t idx; + uint32_t idx; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; @@ -1315,7 +1315,7 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) nge_start_locked(ifp); if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) { - u_int32_t status; + uint32_t status; /* Reading the ISR register clears all interrupts. */ status = CSR_READ_4(sc, NGE_ISR); @@ -1340,7 +1340,7 @@ nge_intr(void *arg) { struct nge_softc *sc; struct ifnet *ifp; - u_int32_t status; + uint32_t status; sc = arg; ifp = sc->nge_ifp; @@ -1431,7 +1431,7 @@ nge_intr(void *arg) * pointers to the fragment pointers. */ static int -nge_encap(struct nge_softc *sc, struct mbuf *m_head, u_int32_t *txidx) +nge_encap(struct nge_softc *sc, struct mbuf *m_head, uint32_t *txidx) { struct nge_desc *f = NULL; struct mbuf *m; @@ -1514,7 +1514,7 @@ nge_start_locked(struct ifnet *ifp) { struct nge_softc *sc; struct mbuf *m_head = NULL; - u_int32_t idx; + uint32_t idx; sc = ifp->if_softc; @@ -1590,13 +1590,13 @@ nge_init_locked(struct nge_softc *sc) /* Set MAC address */ CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR0); CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((u_int16_t *)IF_LLADDR(sc->nge_ifp))[0]); + ((uint16_t *)IF_LLADDR(sc->nge_ifp))[0]); CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR1); CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((u_int16_t *)IF_LLADDR(sc->nge_ifp))[1]); + ((uint16_t *)IF_LLADDR(sc->nge_ifp))[1]); CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR2); CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((u_int16_t *)IF_LLADDR(sc->nge_ifp))[2]); + ((uint16_t *)IF_LLADDR(sc->nge_ifp))[2]); /* Init circular RX list. */ if (nge_list_rx_init(sc) == ENOBUFS) { diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h index aa79953d644a..0f494a13ceff 100644 --- a/sys/dev/nge/if_ngereg.h +++ b/sys/dev/nge/if_ngereg.h @@ -472,43 +472,43 @@ */ struct nge_desc_64 { /* Hardware descriptor section */ - volatile u_int32_t nge_next_lo; - volatile u_int32_t nge_next_hi; - volatile u_int32_t nge_ptr_lo; - volatile u_int32_t nge_ptr_hi; - volatile u_int32_t nge_cmdsts; + volatile uint32_t nge_next_lo; + volatile uint32_t nge_next_hi; + volatile uint32_t nge_ptr_lo; + volatile uint32_t nge_ptr_hi; + volatile uint32_t nge_cmdsts; #define nge_rxstat nge_cmdsts #define nge_txstat nge_cmdsts #define nge_ctl nge_cmdsts - volatile u_int32_t nge_extsts; + volatile uint32_t nge_extsts; /* Driver software section */ union { struct mbuf *nge_mbuf; - u_int64_t nge_dummy; + uint64_t nge_dummy; } nge_mb_u; union { struct nge_desc_32 *nge_nextdesc; - u_int64_t nge_dummy; + uint64_t nge_dummy; } nge_nd_u; }; struct nge_desc_32 { /* Hardware descriptor section */ - volatile u_int32_t nge_next; - volatile u_int32_t nge_ptr; - volatile u_int32_t nge_cmdsts; + volatile uint32_t nge_next; + volatile uint32_t nge_ptr; + volatile uint32_t nge_cmdsts; #define nge_rxstat nge_cmdsts #define nge_txstat nge_cmdsts #define nge_ctl nge_cmdsts - volatile u_int32_t nge_extsts; + volatile uint32_t nge_extsts; /* Driver software section */ union { struct mbuf *nge_mbuf; - u_int64_t nge_dummy; + uint64_t nge_dummy; } nge_mb_u; union { struct nge_desc_32 *nge_nextdesc; - u_int64_t nge_dummy; + uint64_t nge_dummy; } nge_nd_u; }; @@ -611,18 +611,18 @@ struct nge_list_data { #define NGE_DEVICEID 0x0022 struct nge_type { - u_int16_t nge_vid; - u_int16_t nge_did; + uint16_t nge_vid; + uint16_t nge_did; char *nge_name; }; struct nge_mii_frame { - u_int8_t mii_stdelim; - u_int8_t mii_opcode; - u_int8_t mii_phyaddr; - u_int8_t mii_regaddr; - u_int8_t mii_turnaround; - u_int16_t mii_data; + uint8_t mii_stdelim; + uint8_t mii_opcode; + uint8_t mii_phyaddr; + uint8_t mii_regaddr; + uint8_t mii_turnaround; + uint16_t mii_data; }; /* @@ -657,16 +657,16 @@ struct nge_softc { void *nge_intrhand; device_t nge_miibus; int nge_if_flags; - u_int8_t nge_type; - u_int8_t nge_link; - u_int8_t nge_width; + uint8_t nge_type; + uint8_t nge_link; + uint8_t nge_width; #define NGE_WIDTH_32BITS 0 #define NGE_WIDTH_64BITS 1 struct nge_list_data *nge_ldata; struct nge_ring_data nge_cdata; struct callout nge_stat_ch; struct mtx nge_mtx; - u_int8_t nge_tbi; + uint8_t nge_tbi; struct ifmedia nge_ifmedia; #ifdef DEVICE_POLLING int rxcycles; From 6f94c0fd1712c4d4e52ac461213b4e51cc8b8cfd Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 07:04:03 +0000 Subject: [PATCH 269/544] style(9) --- sys/dev/nge/if_nge.c | 152 +++++++++++++++++++++---------------------- 1 file changed, 76 insertions(+), 76 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 5974d9090002..51c1d1d8e7ed 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -246,7 +246,7 @@ DRIVER_MODULE(miibus, nge, miibus_driver, miibus_devclass, 0, 0); static void nge_delay(struct nge_softc *sc) { - int idx; + int idx; for (idx = (300 / 33) + 1; idx > 0; idx--) CSR_READ_4(sc, NGE_CSR); @@ -255,7 +255,7 @@ nge_delay(struct nge_softc *sc) static void nge_eeprom_idle(struct nge_softc *sc) { - int i; + int i; SIO_SET(NGE_MEAR_EE_CSEL); nge_delay(sc); @@ -282,7 +282,7 @@ nge_eeprom_idle(struct nge_softc *sc) static void nge_eeprom_putbyte(struct nge_softc *sc, int addr) { - int d, i; + int d, i; d = addr | NGE_EECMD_READ; @@ -309,8 +309,8 @@ nge_eeprom_putbyte(struct nge_softc *sc, int addr) static void nge_eeprom_getword(struct nge_softc *sc, int addr, uint16_t *dest) { - int i; - uint16_t word = 0; + int i; + uint16_t word = 0; /* Force EEPROM to idle state. */ nge_eeprom_idle(sc); @@ -352,8 +352,8 @@ nge_eeprom_getword(struct nge_softc *sc, int addr, uint16_t *dest) static void nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) { - int i; - uint16_t word = 0, *ptr; + int i; + uint16_t word = 0, *ptr; for (i = 0; i < cnt; i++) { nge_eeprom_getword(sc, off + i, &word); @@ -371,7 +371,7 @@ nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) static void nge_mii_sync(struct nge_softc *sc) { - int i; + int i; SIO_SET(NGE_MEAR_MII_DIR|NGE_MEAR_MII_DATA); @@ -389,7 +389,7 @@ nge_mii_sync(struct nge_softc *sc) static void nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt) { - int i; + int i; SIO_CLR(NGE_MEAR_MII_CLK); @@ -412,7 +412,7 @@ nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt) static int nge_mii_readreg(struct nge_softc *sc, struct nge_mii_frame *frame) { - int i, ack; + int i, ack; /* * Set up frame for RX. @@ -538,8 +538,8 @@ nge_mii_writereg(struct nge_softc *sc, struct nge_mii_frame *frame) static int nge_miibus_readreg(device_t dev, int phy, int reg) { - struct nge_softc *sc; - struct nge_mii_frame frame; + struct nge_softc *sc; + struct nge_mii_frame frame; sc = device_get_softc(dev); @@ -555,8 +555,8 @@ nge_miibus_readreg(device_t dev, int phy, int reg) static int nge_miibus_writereg(device_t dev, int phy, int reg, int data) { - struct nge_softc *sc; - struct nge_mii_frame frame; + struct nge_softc *sc; + struct nge_mii_frame frame; sc = device_get_softc(dev); @@ -573,9 +573,9 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data) static void nge_miibus_statchg(device_t dev) { - int status; - struct nge_softc *sc; - struct mii_data *mii; + int status; + struct nge_softc *sc; + struct mii_data *mii; sc = device_get_softc(dev); if (sc->nge_tbi) { @@ -628,10 +628,10 @@ nge_miibus_statchg(device_t dev) static void nge_setmulti(struct nge_softc *sc) { - struct ifnet *ifp; - struct ifmultiaddr *ifma; - uint32_t h = 0, i, filtsave; - int bit, index; + struct ifnet *ifp; + struct ifmultiaddr *ifma; + uint32_t h = 0, i, filtsave; + int bit, index; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; @@ -687,7 +687,7 @@ nge_setmulti(struct nge_softc *sc) static void nge_reset(struct nge_softc *sc) { - int i; + int i; NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RESET); @@ -717,7 +717,7 @@ nge_reset(struct nge_softc *sc) static int nge_probe(device_t dev) { - struct nge_type *t; + struct nge_type *t; t = nge_devs; @@ -740,10 +740,10 @@ nge_probe(device_t dev) static int nge_attach(device_t dev) { - u_char eaddr[ETHER_ADDR_LEN]; - struct nge_softc *sc; - struct ifnet *ifp = NULL; - int error = 0, rid; + u_char eaddr[ETHER_ADDR_LEN]; + struct nge_softc *sc; + struct ifnet *ifp = NULL; + int error = 0, rid; sc = device_get_softc(dev); sc->nge_dev = dev; @@ -892,8 +892,8 @@ nge_attach(device_t dev) static int nge_detach(device_t dev) { - struct nge_softc *sc; - struct ifnet *ifp; + struct nge_softc *sc; + struct ifnet *ifp; sc = device_get_softc(dev); ifp = sc->nge_ifp; @@ -931,9 +931,9 @@ nge_detach(device_t dev) static int nge_list_tx_init(struct nge_softc *sc) { - struct nge_list_data *ld; - struct nge_ring_data *cd; - int i; + struct nge_list_data *ld; + struct nge_ring_data *cd; + int i; cd = &sc->nge_cdata; ld = sc->nge_ldata; @@ -969,9 +969,9 @@ nge_list_tx_init(struct nge_softc *sc) static int nge_list_rx_init(struct nge_softc *sc) { - struct nge_list_data *ld; - struct nge_ring_data *cd; - int i; + struct nge_list_data *ld; + struct nge_ring_data *cd; + int i; ld = sc->nge_ldata; cd = &sc->nge_cdata; @@ -1028,8 +1028,8 @@ nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) static __inline void nge_fixup_rx(struct mbuf *m) { - int i; - uint16_t *src, *dst; + int i; + uint16_t *src, *dst; src = mtod(m, uint16_t *); dst = src - 1; @@ -1050,11 +1050,11 @@ nge_fixup_rx(struct mbuf *m) static void nge_rxeof(struct nge_softc *sc) { - struct mbuf *m; - struct ifnet *ifp; - struct nge_desc *cur_rx; - int i, total_len = 0; - uint32_t rxstat; + struct mbuf *m; + struct ifnet *ifp; + struct nge_desc *cur_rx; + int i, total_len = 0; + uint32_t rxstat; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; @@ -1191,9 +1191,9 @@ nge_rxeof(struct nge_softc *sc) static void nge_txeof(struct nge_softc *sc) { - struct nge_desc *cur_tx; - struct ifnet *ifp; - uint32_t idx; + struct nge_desc *cur_tx; + struct ifnet *ifp; + uint32_t idx; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; @@ -1246,9 +1246,9 @@ nge_txeof(struct nge_softc *sc) static void nge_tick(void *xsc) { - struct nge_softc *sc; - struct mii_data *mii; - struct ifnet *ifp; + struct nge_softc *sc; + struct mii_data *mii; + struct ifnet *ifp; sc = xsc; NGE_LOCK_ASSERT(sc); @@ -1293,7 +1293,7 @@ static poll_handler_t nge_poll; static void nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { - struct nge_softc *sc = ifp->if_softc; + struct nge_softc *sc = ifp->if_softc; NGE_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { @@ -1338,9 +1338,9 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) static void nge_intr(void *arg) { - struct nge_softc *sc; - struct ifnet *ifp; - uint32_t status; + struct nge_softc *sc; + struct ifnet *ifp; + uint32_t status; sc = arg; ifp = sc->nge_ifp; @@ -1433,9 +1433,9 @@ nge_intr(void *arg) static int nge_encap(struct nge_softc *sc, struct mbuf *m_head, uint32_t *txidx) { - struct nge_desc *f = NULL; - struct mbuf *m; - int frag, cur, cnt = 0; + struct nge_desc *f = NULL; + struct mbuf *m; + int frag, cur, cnt = 0; /* * Start packing the mbufs in this chain into @@ -1501,7 +1501,7 @@ nge_encap(struct nge_softc *sc, struct mbuf *m_head, uint32_t *txidx) static void nge_start(struct ifnet *ifp) { - struct nge_softc *sc; + struct nge_softc *sc; sc = ifp->if_softc; NGE_LOCK(sc); @@ -1512,9 +1512,9 @@ nge_start(struct ifnet *ifp) static void nge_start_locked(struct ifnet *ifp) { - struct nge_softc *sc; - struct mbuf *m_head = NULL; - uint32_t idx; + struct nge_softc *sc; + struct mbuf *m_head = NULL; + uint32_t idx; sc = ifp->if_softc; @@ -1558,7 +1558,7 @@ nge_start_locked(struct ifnet *ifp) static void nge_init(void *xsc) { - struct nge_softc *sc = xsc; + struct nge_softc *sc = xsc; NGE_LOCK(sc); nge_init_locked(sc); @@ -1568,8 +1568,8 @@ nge_init(void *xsc) static void nge_init_locked(struct nge_softc *sc) { - struct ifnet *ifp = sc->nge_ifp; - struct mii_data *mii; + struct ifnet *ifp = sc->nge_ifp; + struct mii_data *mii; NGE_LOCK_ASSERT(sc); @@ -1756,7 +1756,7 @@ nge_init_locked(struct nge_softc *sc) static int nge_ifmedia_upd(struct ifnet *ifp) { - struct nge_softc *sc; + struct nge_softc *sc; sc = ifp->if_softc; NGE_LOCK(sc); @@ -1768,8 +1768,8 @@ nge_ifmedia_upd(struct ifnet *ifp) static void nge_ifmedia_upd_locked(struct ifnet *ifp) { - struct nge_softc *sc; - struct mii_data *mii; + struct nge_softc *sc; + struct mii_data *mii; sc = ifp->if_softc; NGE_LOCK_ASSERT(sc); @@ -1822,8 +1822,8 @@ nge_ifmedia_upd_locked(struct ifnet *ifp) static void nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) { - struct nge_softc *sc; - struct mii_data *mii; + struct nge_softc *sc; + struct mii_data *mii; sc = ifp->if_softc; @@ -1872,10 +1872,10 @@ nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) static int nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) { - struct nge_softc *sc = ifp->if_softc; - struct ifreq *ifr = (struct ifreq *) data; - struct mii_data *mii; - int error = 0; + struct nge_softc *sc = ifp->if_softc; + struct ifreq *ifr = (struct ifreq *) data; + struct mii_data *mii; + int error = 0; switch (command) { case SIOCSIFMTU: @@ -1984,7 +1984,7 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) static void nge_watchdog(struct ifnet *ifp) { - struct nge_softc *sc; + struct nge_softc *sc; sc = ifp->if_softc; @@ -2010,9 +2010,9 @@ nge_watchdog(struct ifnet *ifp) static void nge_stop(struct nge_softc *sc) { - int i; - struct ifnet *ifp; - struct mii_data *mii; + int i; + struct ifnet *ifp; + struct mii_data *mii; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; @@ -2071,7 +2071,7 @@ nge_stop(struct nge_softc *sc) static int nge_shutdown(device_t dev) { - struct nge_softc *sc; + struct nge_softc *sc; sc = device_get_softc(dev); From 056e0442f6ffcfc77dfe27b178647ee1e9d99b73 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 07:10:48 +0000 Subject: [PATCH 270/544] Consistently use tab characters instead of spaces. --- sys/dev/nge/if_nge.c | 14 +++++++------- sys/dev/nge/if_ngereg.h | 36 ++++++++++++++++++------------------ 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 51c1d1d8e7ed..988305d6cf04 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -394,11 +394,11 @@ nge_mii_send(struct nge_softc *sc, uint32_t bits, int cnt) SIO_CLR(NGE_MEAR_MII_CLK); for (i = (0x1 << (cnt - 1)); i; i >>= 1) { - if (bits & i) { + if (bits & i) { SIO_SET(NGE_MEAR_MII_DATA); - } else { + } else { SIO_CLR(NGE_MEAR_MII_DATA); - } + } DELAY(1); SIO_CLR(NGE_MEAR_MII_CLK); DELAY(1); @@ -1028,8 +1028,8 @@ nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) static __inline void nge_fixup_rx(struct mbuf *m) { - int i; - uint16_t *src, *dst; + int i; + uint16_t *src, *dst; src = mtod(m, uint16_t *); dst = src - 1; @@ -1050,8 +1050,8 @@ nge_fixup_rx(struct mbuf *m) static void nge_rxeof(struct nge_softc *sc) { - struct mbuf *m; - struct ifnet *ifp; + struct mbuf *m; + struct ifnet *ifp; struct nge_desc *cur_rx; int i, total_len = 0; uint32_t rxstat; diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h index 0f494a13ceff..4533b7fceb23 100644 --- a/sys/dev/nge/if_ngereg.h +++ b/sys/dev/nge/if_ngereg.h @@ -481,15 +481,15 @@ struct nge_desc_64 { #define nge_txstat nge_cmdsts #define nge_ctl nge_cmdsts volatile uint32_t nge_extsts; - /* Driver software section */ - union { - struct mbuf *nge_mbuf; - uint64_t nge_dummy; - } nge_mb_u; - union { - struct nge_desc_32 *nge_nextdesc; - uint64_t nge_dummy; - } nge_nd_u; + /* Driver software section */ + union { + struct mbuf *nge_mbuf; + uint64_t nge_dummy; + } nge_mb_u; + union { + struct nge_desc_32 *nge_nextdesc; + uint64_t nge_dummy; + } nge_nd_u; }; struct nge_desc_32 { @@ -501,15 +501,15 @@ struct nge_desc_32 { #define nge_txstat nge_cmdsts #define nge_ctl nge_cmdsts volatile uint32_t nge_extsts; - /* Driver software section */ - union { - struct mbuf *nge_mbuf; - uint64_t nge_dummy; - } nge_mb_u; - union { - struct nge_desc_32 *nge_nextdesc; - uint64_t nge_dummy; - } nge_nd_u; + /* Driver software section */ + union { + struct mbuf *nge_mbuf; + uint64_t nge_dummy; + } nge_mb_u; + union { + struct nge_desc_32 *nge_nextdesc; + uint64_t nge_dummy; + } nge_nd_u; }; #define nge_mbuf nge_mb_u.nge_mbuf From a315e86aad99b022cb2accec008bec66461a922d Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 18 May 2009 07:13:42 +0000 Subject: [PATCH 271/544] Remove extra parenthesis used in macros. These macros are not used in driver, though. --- sys/dev/nge/if_ngereg.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h index 4533b7fceb23..e4d5e527cf15 100644 --- a/sys/dev/nge/if_ngereg.h +++ b/sys/dev/nge/if_ngereg.h @@ -525,8 +525,8 @@ struct nge_desc_32 { #define NGE_CMDSTS_MORE 0x40000000 #define NGE_CMDSTS_OWN 0x80000000 -#define NGE_LASTDESC(x) (!((x)->nge_ctl & NGE_CMDSTS_MORE))) -#define NGE_MORE(x) ((x)->nge_ctl & NGE_CMDSTS_MORE)) +#define NGE_LASTDESC(x) (!((x)->nge_ctl & NGE_CMDSTS_MORE)) +#define NGE_MORE(x) ((x)->nge_ctl & NGE_CMDSTS_MORE) #define NGE_OWNDESC(x) ((x)->nge_ctl & NGE_CMDSTS_OWN) #define NGE_INC(x, y) (x) = (x + 1) % y #define NGE_RXBYTES(x) ((x)->nge_ctl & NGE_CMDSTS_BUFLEN) From a765f96051a19961a3d0f9d2d86b694954642648 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 18 May 2009 10:33:23 +0000 Subject: [PATCH 272/544] Garbage collect unused NETISR_{ATM,NETGRAPH,PPP} netisr constants. --- sys/net/netisr.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/net/netisr.h b/sys/net/netisr.h index 1bc7b0c204f8..79293027e544 100644 --- a/sys/net/netisr.h +++ b/sys/net/netisr.h @@ -53,11 +53,8 @@ #define NETISR_ATALK1 17 /* Appletalk phase 1 */ #define NETISR_ARP 18 /* same as AF_LINK */ #define NETISR_IPX 23 /* same as AF_IPX */ -#define NETISR_PPP 26 /* PPP soft interrupt */ #define NETISR_IPV6 27 #define NETISR_NATM 28 -#define NETISR_ATM 29 -#define NETISR_NETGRAPH 30 #define NETISR_POLLMORE 31 /* polling callback, must be last */ #ifndef LOCORE From 314a700e2e24c73cf7e729c671ff52b8b88f449e Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Mon, 18 May 2009 11:23:15 +0000 Subject: [PATCH 273/544] Remove license clauses 3 and 4 as per rev. 1.2 from NetBSD. Also, FreeBSD 8.0 will be the first release including this driver. (1) PR: 134093 (1) Submitted by: gavin --- share/man/man4/uchcom.4 | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/share/man/man4/uchcom.4 b/share/man/man4/uchcom.4 index 456833964364..2fad9887770c 100644 --- a/share/man/man4/uchcom.4 +++ b/share/man/man4/uchcom.4 @@ -1,4 +1,4 @@ -.\" $NetBSD: uchcom.4,v 1.1 2007/09/03 18:02:17 tshiozak Exp $ +.\" $NetBSD: uchcom.4,v 1.2 2008/04/30 13:10:54 martin Exp $ .\" .\" Copyright (c) 2007 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -14,13 +14,6 @@ .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the NetBSD -.\" Foundation, Inc. and its contributors. -.\" 4. Neither the name of The NetBSD Foundation nor the names of its -.\" contributors may be used to endorse or promote products derived -.\" from this software without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS .\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED @@ -36,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd May 15, 2009 +.Dd May 18, 2009 .Dt UCHCOM 4 .Os .Sh NAME @@ -88,7 +81,7 @@ driver first appeared in The first .Fx release to include it was -.Fx 7.0 . +.Fx 8.0 . .Sh BUGS Actually, this chip seems unable to drive other than 8 data bits and 1 stop bit line. From c383c2211bfbb63c31fa5a8dea1e63548b949129 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 18 May 2009 12:03:43 +0000 Subject: [PATCH 274/544] Mark the clock sysctls as MPSAFE. These sysctls don't need any form of locking. At least cp_times is used by powerd very often, which means I get 50% less calls to non-MPSAFE sysctls on my system. The other 50% is consumed by dev.cpu.0.freq, but this seems to need Giant for Newbus. --- sys/kern/kern_clock.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/kern/kern_clock.c b/sys/kern/kern_clock.c index b311d3053d82..e95bc19152cb 100644 --- a/sys/kern/kern_clock.c +++ b/sys/kern/kern_clock.c @@ -112,7 +112,7 @@ sysctl_kern_cp_time(SYSCTL_HANDLER_ARGS) return error; } -SYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD, +SYSCTL_PROC(_kern, OID_AUTO, cp_time, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE, 0,0, sysctl_kern_cp_time, "LU", "CPU time statistics"); static long empty[CPUSTATES]; @@ -156,7 +156,7 @@ sysctl_kern_cp_times(SYSCTL_HANDLER_ARGS) return error; } -SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD, +SYSCTL_PROC(_kern, OID_AUTO, cp_times, CTLTYPE_LONG|CTLFLAG_RD|CTLFLAG_MPSAFE, 0,0, sysctl_kern_cp_times, "LU", "per-CPU time statistics"); void @@ -559,7 +559,8 @@ sysctl_kern_clockrate(SYSCTL_HANDLER_ARGS) return (sysctl_handle_opaque(oidp, &clkinfo, sizeof clkinfo, req)); } -SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, CTLTYPE_STRUCT|CTLFLAG_RD, +SYSCTL_PROC(_kern, KERN_CLOCKRATE, clockrate, + CTLTYPE_STRUCT|CTLFLAG_RD|CTLFLAG_MPSAFE, 0, 0, sysctl_kern_clockrate, "S,clockinfo", "Rate and period of various kernel clocks"); From e84bcd849429ed2719d1edc500c38acf7df70699 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 18 May 2009 14:02:55 +0000 Subject: [PATCH 275/544] Binding interrupts to a CPU consists of two parts: setting up CPU affinity for the interrupt thread, and requesting that underlying hardware direct interrupts to the CPU. For software interrupt threads, implement a no-op interrupt event binder that returns success, so that the interrupt management code will just set the ithread's affinity and succeed. Reviewed by: jhb MFC after: 1 week --- sys/kern/kern_intr.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_intr.c b/sys/kern/kern_intr.c index f998645f5476..1893f48dc2a6 100644 --- a/sys/kern/kern_intr.c +++ b/sys/kern/kern_intr.c @@ -967,6 +967,18 @@ intr_event_schedule_thread(struct intr_event *ie, struct intr_thread *it) } #endif +/* + * Allow interrupt event binding for software interrupt handlers -- a no-op, + * since interrupts are generated in software rather than being directed by + * a PIC. + */ +static int +swi_assign_cpu(void *arg, u_char cpu) +{ + + return (0); +} + /* * Add a software interrupt handler to a specified event. If a given event * is not specified, then a new event is created. @@ -988,7 +1000,7 @@ swi_add(struct intr_event **eventp, const char *name, driver_intr_t handler, return (EINVAL); } else { error = intr_event_create(&ie, NULL, IE_SOFT, 0, - NULL, NULL, NULL, NULL, "swi%d:", pri); + NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri); if (error) return (error); if (eventp != NULL) From b16a8a5859040e617848aedc2517fd750ebc3393 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 18 May 2009 15:31:26 +0000 Subject: [PATCH 276/544] Fix a typo from the original driver. We need to write ctrl2 into RF register 0x52, not ctrl1. This appears to be a mistake in the bcm reverse engineering page, and has been corrected there. Tracing through the code, this is more in keeping with the "documented" register. Sephe thinks it looks interesting and may be worth fixing. :) Submitted by: ddkprog at yahoo com Reviewed by: Sepherosa Ziehau --- sys/dev/bwi/bwiphy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c index a0be96df9533..9a45c8437189 100644 --- a/sys/dev/bwi/bwiphy.c +++ b/sys/dev/bwi/bwiphy.c @@ -375,7 +375,7 @@ bwi_phy_init_11g(struct bwi_mac *mac) RF_WRITE(mac, 0x52, (tpctl->tp_ctrl1 << 4) | tpctl->tp_ctrl2); } else { - RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl1); + RF_FILT_SETBITS(mac, 0x52, 0xfff0, tpctl->tp_ctrl2); } if (phy->phy_rev >= 6) { From f4fcd5ddec6d6820c13aa155d284116e214433de Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Mon, 18 May 2009 15:46:34 +0000 Subject: [PATCH 277/544] Remove unnecessary comments. 11A read/write is the same: its just the classic indirect register dance. Submitted by: ddkprog at yahoo not com --- sys/dev/bwi/bwiphy.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/dev/bwi/bwiphy.c b/sys/dev/bwi/bwiphy.c index 9a45c8437189..c41c0f854872 100644 --- a/sys/dev/bwi/bwiphy.c +++ b/sys/dev/bwi/bwiphy.c @@ -135,7 +135,6 @@ bwi_phy_write(struct bwi_mac *mac, uint16_t ctrl, uint16_t data) { struct bwi_softc *sc = mac->mac_sc; - /* TODO: 11A */ CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); CSR_WRITE_2(sc, BWI_PHY_DATA, data); } @@ -145,7 +144,6 @@ bwi_phy_read(struct bwi_mac *mac, uint16_t ctrl) { struct bwi_softc *sc = mac->mac_sc; - /* TODO: 11A */ CSR_WRITE_2(sc, BWI_PHY_CTRL, ctrl); return CSR_READ_2(sc, BWI_PHY_DATA); } From 715238635df71408bdf4cac22a213c7598da2546 Mon Sep 17 00:00:00 2001 From: Maksim Yevmenkin Date: Mon, 18 May 2009 16:00:18 +0000 Subject: [PATCH 278/544] Teach btpand(8) to recognized Bluetooth device node names. Tested by: Daniel O'Connor MFC after: 3 days --- usr.sbin/bluetooth/btpand/btpand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.sbin/bluetooth/btpand/btpand.c b/usr.sbin/bluetooth/btpand/btpand.c index 99a3bc7eacd4..938744448bea 100644 --- a/usr.sbin/bluetooth/btpand/btpand.c +++ b/usr.sbin/bluetooth/btpand/btpand.c @@ -101,7 +101,7 @@ main(int argc, char *argv[]) break; case 'd': /* local address */ - if (!bt_aton(optarg, &local_bdaddr)) { + if (!bt_devaddr(optarg, &local_bdaddr)) { struct hostent *he; if ((he = bt_gethostbyname(optarg)) == NULL) From b743c31009e3b9ee8d367d1464e023c4be89049e Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 18 May 2009 17:18:40 +0000 Subject: [PATCH 279/544] add bpf_track eventhandler for monitoring bpf taps attached/detached Reviewed by: csjp --- sys/net/bpf.c | 4 ++++ sys/sys/eventhandler.h | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index d8ed7c2aa1a8..5bca0eb27787 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -534,6 +534,8 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp) bpf_bpfd_cnt++; BPFIF_UNLOCK(bp); + + EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, 1); } /* @@ -561,6 +563,8 @@ bpf_detachd(struct bpf_d *d) BPFD_UNLOCK(d); BPFIF_UNLOCK(bp); + EVENTHANDLER_INVOKE(bpf_track, ifp, 0); + /* * Check if this descriptor had requested promiscuous mode. * If so, turn it off. diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index 5013fe89bd46..de787afc627f 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -182,6 +182,11 @@ typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t); EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); +/* BPF attach/detach events */ +struct ifnet; +typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* 1 =>'s attach */); +EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); + /* * Process events * process_fork and exit handlers are called without Giant. From 0d6b4bcc58d2fdf8fe0a48abac67734f750cd74b Mon Sep 17 00:00:00 2001 From: Alexander Kabaev Date: Mon, 18 May 2009 17:20:24 +0000 Subject: [PATCH 280/544] Remove empty files and do nto try to build them. Apparently, they are problematic for CTF users. PR: 119298 Submitted by: Julian H. Stacey --- sys/gnu/fs/xfs/FreeBSD/xfsdmapistubs.c | 0 sys/gnu/fs/xfs/FreeBSD/xfsquotasstubs.c | 0 sys/gnu/fs/xfs/FreeBSD/xfsrtstubs.c | 0 sys/modules/xfs/Makefile | 3 --- 4 files changed, 3 deletions(-) delete mode 100644 sys/gnu/fs/xfs/FreeBSD/xfsdmapistubs.c delete mode 100644 sys/gnu/fs/xfs/FreeBSD/xfsquotasstubs.c delete mode 100644 sys/gnu/fs/xfs/FreeBSD/xfsrtstubs.c diff --git a/sys/gnu/fs/xfs/FreeBSD/xfsdmapistubs.c b/sys/gnu/fs/xfs/FreeBSD/xfsdmapistubs.c deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sys/gnu/fs/xfs/FreeBSD/xfsquotasstubs.c b/sys/gnu/fs/xfs/FreeBSD/xfsquotasstubs.c deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sys/gnu/fs/xfs/FreeBSD/xfsrtstubs.c b/sys/gnu/fs/xfs/FreeBSD/xfsrtstubs.c deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/sys/modules/xfs/Makefile b/sys/modules/xfs/Makefile index 5d7ce509771f..e713b05aa3d2 100644 --- a/sys/modules/xfs/Makefile +++ b/sys/modules/xfs/Makefile @@ -54,9 +54,6 @@ SRCS = vnode_if.h \ xfs_iget.c \ xfs_attr_leaf.c \ xfs_attr.c \ - xfsrtstubs.c \ - xfsquotasstubs.c \ - xfsdmapistubs.c \ xfs_dmops.c \ xfs_qmops.c \ xfs_mountops.c \ From 97ea741513b4a3722cdafb8db8167ca40573a001 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 18 May 2009 17:48:46 +0000 Subject: [PATCH 281/544] Add two missing INIT_VNET_INET6(curvnet) to make VIMAGE kernels happier. --- sys/netinet6/ip6_mroute.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/netinet6/ip6_mroute.c b/sys/netinet6/ip6_mroute.c index 5a76ef38db2d..79abf1f3cde4 100644 --- a/sys/netinet6/ip6_mroute.c +++ b/sys/netinet6/ip6_mroute.c @@ -363,6 +363,7 @@ pim6_init(void) int X_ip6_mrouter_set(struct socket *so, struct sockopt *sopt) { + INIT_VNET_INET6(curvnet); int error = 0; int optval; struct mif6ctl mifc; @@ -1715,6 +1716,7 @@ phyint_send(struct ip6_hdr *ip6, struct mif6 *mifp, struct mbuf *m) static int register_send(struct ip6_hdr *ip6, struct mif6 *mif, struct mbuf *m) { + INIT_VNET_INET6(curvnet); struct mbuf *mm; int i, len = m->m_pkthdr.len; static struct sockaddr_in6 sin6 = { sizeof(sin6), AF_INET6 }; @@ -2036,6 +2038,7 @@ pim6_input(struct mbuf **mp, int *offp, int proto) static int ip6_mroute_modevent(module_t mod, int type, void *unused) { + INIT_VNET_INET6(curvnet); switch (type) { case MOD_LOAD: From e13e5f8fa52267fd6ec2cb15e7b05c01b02832fa Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 18 May 2009 18:12:45 +0000 Subject: [PATCH 282/544] fix typo --- tools/tools/net80211/scripts/setup.tdma-slave | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/tools/net80211/scripts/setup.tdma-slave b/tools/tools/net80211/scripts/setup.tdma-slave index dc6c29ea8fd0..22607c2f842f 100644 --- a/tools/tools/net80211/scripts/setup.tdma-slave +++ b/tools/tools/net80211/scripts/setup.tdma-slave @@ -10,7 +10,7 @@ PATH=.:$PATH SSID='freebsd+tdma' WLAN=`ifconfig wlan create wlanmode tdma wlandev $WIRELESS` -ifconfig $WLAN ssid "$SSID" 0 +ifconfig $WLAN ssid "$SSID" wlandebug -i $WLAN state+scan+tdma BRIDGE=`ifconfig bridge create` From dbb95048da3ac080e2f3f83bcb730fe83661962b Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 18 May 2009 18:37:18 +0000 Subject: [PATCH 283/544] Add cpu_flush_dcache() for use after non-DMA based I/O so that a possible future I-cache coherency operation can succeed. On ARM for example the L1 cache can be (is) virtually mapped, which means that any I/O that uses temporary mappings will not see the I-cache made coherent. On ia64 a similar behaviour has been observed. By flushing the D-cache, execution of binaries backed by md(4) and/or NFS work reliably. For Book-E (powerpc), execution over NFS exhibits SIGILL once in a while as well, though cpu_flush_dcache() hasn't been implemented yet. Doing an explicit D-cache flush as part of the non-DMA based I/O read operation eliminates the need to do it as part of the I-cache coherency operation itself and as such avoids pessimizing the DMA-based I/O read operations for which D-cache are already flushed/invalidated. It also allows future optimizations whereby the bcopy() followed by the D-cache flush can be integrated in a single operation, which could be implemented using on-chips DMA engines, by-passing the D-cache altogether. --- sys/amd64/amd64/machdep.c | 10 ++++++++++ sys/arm/arm/machdep.c | 12 ++++++++++++ sys/dev/md/md.c | 9 ++++++--- sys/i386/i386/machdep.c | 10 ++++++++++ sys/ia64/ia64/machdep.c | 15 +++++++++++++++ sys/mips/mips/machdep.c | 10 ++++++++++ sys/nfs/nfs_common.c | 5 +++-- sys/pc98/pc98/machdep.c | 10 ++++++++++ sys/powerpc/aim/machdep.c | 10 ++++++++++ sys/powerpc/booke/machdep.c | 10 ++++++++++ sys/sparc64/sparc64/machdep.c | 10 ++++++++++ sys/sun4v/sun4v/machdep.c | 10 ++++++++++ sys/sys/systm.h | 1 + 13 files changed, 117 insertions(+), 5 deletions(-) diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index eb1e72247307..6993dea8e584 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -506,6 +506,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 0f574c1e46ae..597cdf541063 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -316,6 +316,18 @@ cpu_startup(void *dummy) SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL); +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + + cpu_dcache_wb_range((uintptr_t)ptr, len); + cpu_l2cache_wb_range((uintptr_t)ptr, len); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/dev/md/md.c b/sys/dev/md/md.c index 48d48fdeec0d..a03b0784a26e 100644 --- a/sys/dev/md/md.c +++ b/sys/dev/md/md.c @@ -436,10 +436,11 @@ mdstart_malloc(struct md_s *sc, struct bio *bp) if (osp == 0) bzero(dst, sc->sectorsize); else if (osp <= 255) - for (i = 0; i < sc->sectorsize; i++) - dst[i] = osp; - else + memset(dst, osp, sc->sectorsize); + else { bcopy((void *)osp, dst, sc->sectorsize); + cpu_flush_dcache(dst, sc->sectorsize); + } osp = 0; } else if (bp->bio_cmd == BIO_WRITE) { if (sc->flags & MD_COMPRESS) { @@ -491,6 +492,7 @@ mdstart_preload(struct md_s *sc, struct bio *bp) case BIO_READ: bcopy(sc->pl_ptr + bp->bio_offset, bp->bio_data, bp->bio_length); + cpu_flush_dcache(bp->bio_data, bp->bio_length); break; case BIO_WRITE: bcopy(bp->bio_data, sc->pl_ptr + bp->bio_offset, @@ -633,6 +635,7 @@ mdstart_swap(struct md_s *sc, struct bio *bp) break; } bcopy((void *)(sf_buf_kva(sf) + offs), p, len); + cpu_flush_dcache(p, len); } else if (bp->bio_cmd == BIO_WRITE) { if (len != PAGE_SIZE && m->valid != VM_PAGE_BITS_ALL) rv = vm_pager_get_pages(sc->object, &m, 1, 0); diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index a74db11cdc2c..e64bcd2b66c9 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -1113,6 +1113,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 3c6e61d9872b..8ffdcf23ff1f 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -311,6 +311,21 @@ cpu_boot(int howto) efi_reset_system(); } +void +cpu_flush_dcache(void *ptr, size_t len) +{ + vm_offset_t lim, va; + + va = (uintptr_t)ptr & ~31; + lim = (uintptr_t)ptr + len; + while (va < lim) { + ia64_fc(va); + va += 32; + } + + ia64_srlz_d(); +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/mips/mips/machdep.c b/sys/mips/mips/machdep.c index 9aa3044dc81c..6bd518018e7c 100644 --- a/sys/mips/mips/machdep.c +++ b/sys/mips/mips/machdep.c @@ -200,6 +200,16 @@ cpu_reset(void) platform_reset(); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/nfs/nfs_common.c b/sys/nfs/nfs_common.c index 4c0a2c994c9b..faa9302c31d1 100644 --- a/sys/nfs/nfs_common.c +++ b/sys/nfs/nfs_common.c @@ -127,9 +127,10 @@ nfsm_mbuftouio(struct mbuf **mrep, struct uio *uiop, int siz, caddr_t *dpos) (mbufcp, uiocp, xfer); else #endif - if (uiop->uio_segflg == UIO_SYSSPACE) + if (uiop->uio_segflg == UIO_SYSSPACE) { bcopy(mbufcp, uiocp, xfer); - else + cpu_flush_dcache(uiocp, xfer); + } else copyout(mbufcp, uiocp, xfer); left -= xfer; len -= xfer; diff --git a/sys/pc98/pc98/machdep.c b/sys/pc98/pc98/machdep.c index ba3d04796c62..0025a8aa52d5 100644 --- a/sys/pc98/pc98/machdep.c +++ b/sys/pc98/pc98/machdep.c @@ -1050,6 +1050,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* Not applicable */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 590741ce4cbe..662fd1445420 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -864,6 +864,16 @@ cpu_boot(int howto) { } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + void cpu_initclocks(void) { diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 3d3dcadc6749..6d37653fcbc4 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -556,6 +556,16 @@ fill_fpregs(struct thread *td, struct fpreg *fpregs) return (0); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index 4eb8d9c4cb04..164a8b391fea 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -742,6 +742,16 @@ cpu_shutdown(void *args) ofw_exit(args); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given CPU ID. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/sun4v/sun4v/machdep.c b/sys/sun4v/sun4v/machdep.c index b7c0869c36c5..79750408c01f 100644 --- a/sys/sun4v/sun4v/machdep.c +++ b/sys/sun4v/sun4v/machdep.c @@ -767,6 +767,16 @@ cpu_shutdown(void *args) hv_mach_exit(0); } +/* + * Flush the D-cache for non-DMA I/O so that the I-cache can + * be made coherent later. + */ +void +cpu_flush_dcache(void *ptr, size_t len) +{ + /* TBD */ +} + /* Get current clock frequency for the given cpu id. */ int cpu_est_clockrate(int cpu_id, uint64_t *rate) diff --git a/sys/sys/systm.h b/sys/sys/systm.h index 31fb750a206a..c20536a01a3c 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -147,6 +147,7 @@ void panic(const char *, ...) __dead2 __printflike(1, 2); #endif void cpu_boot(int); +void cpu_flush_dcache(void *, size_t); void cpu_rootconf(void); void critical_enter(void); void critical_exit(void); From f1c12cd66d5ffc2993bf8725acfde5727372d0f4 Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Mon, 18 May 2009 18:44:54 +0000 Subject: [PATCH 284/544] Rename ia64_invalidate_icache() to ia64_sync_icache(). We're not invalidating anything. --- sys/ia64/ia64/elf_machdep.c | 7 +++++-- sys/ia64/ia64/machdep.c | 8 ++++---- sys/ia64/ia64/pmap.c | 4 ++-- sys/ia64/include/md_var.h | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/sys/ia64/ia64/elf_machdep.c b/sys/ia64/ia64/elf_machdep.c index 3d3d21405bfb..a100671f379d 100644 --- a/sys/ia64/ia64/elf_machdep.c +++ b/sys/ia64/ia64/elf_machdep.c @@ -300,9 +300,12 @@ elf_cpu_load_file(linker_file_t lf) ++ph; } - /* Invalidate the I-cache, but not for the kernel itself. */ + /* + * Make the I-cache coherent, but don't worry obout the kernel + * itself because the loader needs to do that. + */ if (lf->id != 1) - ia64_invalidate_icache((uintptr_t)lf->address, lf->size); + ia64_sync_icache((uintptr_t)lf->address, lf->size); return (0); } diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 8ffdcf23ff1f..dda1a08c948e 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -122,7 +122,7 @@ struct fpswa_iface *fpswa_iface; u_int64_t ia64_pal_base; u_int64_t ia64_port_base; -static int ia64_inval_icache_needed; +static int ia64_sync_icache_needed; char machine[] = MACHINE; SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, ""); @@ -216,7 +216,7 @@ identifycpu(void) } break; case 0x20: - ia64_inval_icache_needed = 1; + ia64_sync_icache_needed = 1; family_name = "Itanium 2"; switch (model) { @@ -1537,11 +1537,11 @@ ia64_highfp_save(struct thread *td) } void -ia64_invalidate_icache(vm_offset_t va, vm_offset_t sz) +ia64_sync_icache(vm_offset_t va, vm_offset_t sz) { vm_offset_t lim; - if (!ia64_inval_icache_needed) + if (!ia64_sync_icache_needed) return; lim = va + sz; diff --git a/sys/ia64/ia64/pmap.c b/sys/ia64/ia64/pmap.c index 6b559a052bb1..355aa71fe790 100644 --- a/sys/ia64/ia64/pmap.c +++ b/sys/ia64/ia64/pmap.c @@ -1500,7 +1500,7 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) } if (prot & VM_PROT_EXECUTE) - ia64_invalidate_icache(sva, PAGE_SIZE); + ia64_sync_icache(sva, PAGE_SIZE); pmap_pte_prot(pmap, pte, prot); pmap_invalidate_page(pmap, sva); @@ -1635,7 +1635,7 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, /* Invalidate the I-cache when needed. */ if (icache_inval) - ia64_invalidate_icache(va, PAGE_SIZE); + ia64_sync_icache(va, PAGE_SIZE); if ((prot & VM_PROT_WRITE) != 0) vm_page_flag_set(m, PG_WRITEABLE); diff --git a/sys/ia64/include/md_var.h b/sys/ia64/include/md_var.h index 5fc86fa54bae..adc4725fcb40 100644 --- a/sys/ia64/include/md_var.h +++ b/sys/ia64/include/md_var.h @@ -88,8 +88,8 @@ uint64_t ia64_get_hcdp(void); int ia64_highfp_drop(struct thread *); int ia64_highfp_save(struct thread *); struct ia64_init_return ia64_init(void); -void ia64_invalidate_icache(vm_offset_t, vm_size_t); void ia64_probe_sapics(void); +void ia64_sync_icache(vm_offset_t, vm_size_t); void interrupt(struct trapframe *); void map_gateway_page(void); void map_pal_code(void); From 1fdf2b505810588905b1f5533a6ebb536eafa0af Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 18 May 2009 19:02:55 +0000 Subject: [PATCH 285/544] add block ack frame id --- sys/net80211/ieee80211.h | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/net80211/ieee80211.h b/sys/net80211/ieee80211.h index 8857dc369e59..d9b4c54409d0 100644 --- a/sys/net80211/ieee80211.h +++ b/sys/net80211/ieee80211.h @@ -133,6 +133,7 @@ struct ieee80211_qosframe_addr4 { #define IEEE80211_FC0_SUBTYPE_ACTION 0xd0 /* for TYPE_CTL */ #define IEEE80211_FC0_SUBTYPE_BAR 0x80 +#define IEEE80211_FC0_SUBTYPE_BA 0x90 #define IEEE80211_FC0_SUBTYPE_PS_POLL 0xa0 #define IEEE80211_FC0_SUBTYPE_RTS 0xb0 #define IEEE80211_FC0_SUBTYPE_CTS 0xc0 From 8aba835b8e29b19c56e50876157194b174907343 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 18 May 2009 19:33:59 +0000 Subject: [PATCH 286/544] Bump CACHE_LINE_SIZE to 128 for x86. Intel's manuals explicitly recommend using 128 byte alignment for locks. (See IA-32 SDM Vol 3A 7.11.6.7) --- sys/amd64/include/param.h | 2 +- sys/i386/include/param.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/amd64/include/param.h b/sys/amd64/include/param.h index 842e8bb04b19..6ccf7ada4e77 100644 --- a/sys/amd64/include/param.h +++ b/sys/amd64/include/param.h @@ -93,7 +93,7 @@ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an * architecture. It should be used with appropriate caution. */ -#define CACHE_LINE_SHIFT 6 +#define CACHE_LINE_SHIFT 7 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) /* Size of the level 1 page table units */ diff --git a/sys/i386/include/param.h b/sys/i386/include/param.h index 3c22c7c4ca23..a6108db09e49 100644 --- a/sys/i386/include/param.h +++ b/sys/i386/include/param.h @@ -78,7 +78,7 @@ * CACHE_LINE_SIZE is the compile-time maximum cache line size for an * architecture. It should be used with appropriate caution. */ -#define CACHE_LINE_SHIFT 6 +#define CACHE_LINE_SHIFT 7 #define CACHE_LINE_SIZE (1 << CACHE_LINE_SHIFT) #define PAGE_SHIFT 12 /* LOG2(PAGE_SIZE) */ From 47a598563d1d74a4c7e41c5062980f2666886947 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 18 May 2009 21:22:03 +0000 Subject: [PATCH 287/544] Change the experimental NFSv4 client so that it does not do the NFSv4 Close operations until ncl_inactive(). This is necessary so that the Open StateIDs are available for doing I/O on mmap'd files after VOP_CLOSE(). I also changed some indentation for the nfscl_getclose() function. Approved by: kib (mentor) --- sys/fs/nfs/nfs_var.h | 5 +- sys/fs/nfsclient/nfs_clnode.c | 7 +++ sys/fs/nfsclient/nfs_clrpcops.c | 11 ++-- sys/fs/nfsclient/nfs_clstate.c | 101 ++++++++++++++++++-------------- sys/fs/nfsclient/nfs_clvnops.c | 18 +++--- 5 files changed, 79 insertions(+), 63 deletions(-) diff --git a/sys/fs/nfs/nfs_var.h b/sys/fs/nfs/nfs_var.h index 27465e83dfff..08bcafc4526f 100644 --- a/sys/fs/nfs/nfs_var.h +++ b/sys/fs/nfs/nfs_var.h @@ -351,7 +351,7 @@ int nfsrpc_openrpc(struct nfsmount *, vnode_t, u_int8_t *, int, u_int8_t *, int, u_int32_t, struct ucred *, NFSPROC_T *, int, int); int nfsrpc_opendowngrade(vnode_t, u_int32_t, struct nfsclopen *, struct ucred *, NFSPROC_T *); -int nfsrpc_close(vnode_t, struct ucred *, NFSPROC_T *); +int nfsrpc_close(vnode_t, int, NFSPROC_T *); int nfsrpc_closerpc(struct nfsrv_descript *, struct nfsmount *, struct nfsclopen *, struct ucred *, NFSPROC_T *, int); int nfsrpc_openconfirm(vnode_t, u_int8_t *, int, struct nfsclopen *, @@ -457,8 +457,7 @@ void nfscl_initiate_recovery(struct nfsclclient *); int nfscl_hasexpired(struct nfsclclient *, u_int32_t, NFSPROC_T *); void nfscl_dumpstate(struct nfsmount *, int, int, int, int); void nfscl_dupopen(vnode_t, int); -int nfscl_getclose(vnode_t, struct ucred *, NFSPROC_T *, - struct nfsclclient **, struct nfsclopenhead *); +int nfscl_getclose(vnode_t, struct nfsclclient **, struct nfsclopenhead *); int nfscl_deleg(mount_t, struct nfsclclient *, u_int8_t *, int, struct ucred *, NFSPROC_T *, struct nfscldeleg **); void nfscl_lockinit(struct nfsv4lock *); diff --git a/sys/fs/nfsclient/nfs_clnode.c b/sys/fs/nfsclient/nfs_clnode.c index 188b72b76d5d..5148357dce11 100644 --- a/sys/fs/nfsclient/nfs_clnode.c +++ b/sys/fs/nfsclient/nfs_clnode.c @@ -190,6 +190,13 @@ ncl_inactive(struct vop_inactive_args *ap) np = VTONFS(ap->a_vp); if (prtactive && vrefcnt(ap->a_vp) != 0) vprint("ncl_inactive: pushing active", ap->a_vp); + + /* + * Since mmap()'d files to I/O after VOP_CLOSE(), the NFSv4 Close + * operations are delayed until now. + */ + (void) nfsrpc_close(ap->a_vp, 1, td); + if (ap->a_vp->v_type != VDIR) { sp = np->n_sillyrename; np->n_sillyrename = NULL; diff --git a/sys/fs/nfsclient/nfs_clrpcops.c b/sys/fs/nfsclient/nfs_clrpcops.c index 9287d703d025..b42415af5a72 100644 --- a/sys/fs/nfsclient/nfs_clrpcops.c +++ b/sys/fs/nfsclient/nfs_clrpcops.c @@ -550,7 +550,7 @@ nfsrpc_opendowngrade(vnode_t vp, u_int32_t mode, struct nfsclopen *op, * V4 Close operation. */ APPLESTATIC int -nfsrpc_close(vnode_t vp, struct ucred *cred, NFSPROC_T *p) +nfsrpc_close(vnode_t vp, int doclose, NFSPROC_T *p) { struct nfsclclient *clp; struct nfsclopenhead oh; @@ -558,11 +558,14 @@ nfsrpc_close(vnode_t vp, struct ucred *cred, NFSPROC_T *p) if (vnode_vtype(vp) != VREG) return (0); - error = nfscl_getclose(vp, cred, p, &clp, &oh); + if (doclose) + error = nfscl_getclose(vp, &clp, &oh); + else + error = nfscl_getclose(vp, &clp, NULL); if (error) return (error); - if (!LIST_EMPTY(&oh)) + if (doclose && !LIST_EMPTY(&oh)) nfsrpc_doclose(VFSTONFS(vnode_mount(vp)), &oh, p); nfscl_clientrelease(clp); return (0); @@ -997,7 +1000,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T *aclp, if (lckp != NULL) nfscl_lockderef(lckp); if (!openerr) - (void) nfsrpc_close(vp, cred, p); + (void) nfsrpc_close(vp, 0, p); if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID || error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY || error == NFSERR_OLDSTATEID) { diff --git a/sys/fs/nfsclient/nfs_clstate.c b/sys/fs/nfsclient/nfs_clstate.c index 501fab0f880f..e3cf76a2449d 100644 --- a/sys/fs/nfsclient/nfs_clstate.c +++ b/sys/fs/nfsclient/nfs_clstate.c @@ -663,6 +663,9 @@ nfscl_openrelease(struct nfsclopen *op, int error, int candelete) * client data structures to do the SetClientId/SetClientId_confirm, * but will release that lock and return the clientid with a refernce * count on it. + * If the p argument is NULL, it will not do the SetClientId/Confirm + * and the cred argument is not used, so it can be NULL too. + * It always clpp with a reference count on it, unless returning an error. */ APPLESTATIC int nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p, @@ -2748,8 +2751,8 @@ nfscl_dupopen(vnode_t vp, int dupopens) * on ohp. */ APPLESTATIC int -nfscl_getclose(vnode_t vp, struct ucred *cred, NFSPROC_T *p, - struct nfsclclient **clpp, struct nfsclopenhead *ohp) +nfscl_getclose(vnode_t vp, struct nfsclclient **clpp, + struct nfsclopenhead *ohp) { struct nfsclclient *clp; struct nfsclowner *owp, *nowp; @@ -2758,12 +2761,13 @@ nfscl_getclose(vnode_t vp, struct ucred *cred, NFSPROC_T *p, struct nfsfh *nfhp; int error, notdecr, candelete; - error = nfscl_getcl(vp, cred, p, &clp); + error = nfscl_getcl(vp, NULL, NULL, &clp); if (error) return (error); *clpp = clp; - LIST_INIT(ohp); + if (ohp != NULL) + LIST_INIT(ohp); nfhp = VTONFS(vp)->n_fhp; notdecr = 1; NFSLOCKCLSTATE(); @@ -2798,49 +2802,56 @@ nfscl_getclose(vnode_t vp, struct ucred *cred, NFSPROC_T *p, /* Now process the opens against the server. */ LIST_FOREACH(owp, &clp->nfsc_owner, nfsow_list) { - op = LIST_FIRST(&owp->nfsow_open); - while (op != NULL) { - nop = LIST_NEXT(op, nfso_list); - if (op->nfso_fhlen == nfhp->nfh_len && - !NFSBCMP(op->nfso_fh, nfhp->nfh_fh, nfhp->nfh_len)) { - /* Found an open, decrement cnt if possible */ - if (notdecr && op->nfso_opencnt > 0) { - notdecr = 0; - op->nfso_opencnt--; - } - /* - * There are more opens, so just return after - * putting any opens already found back in the - * state list. - */ - if (op->nfso_opencnt > 0) { - /* reuse op, since we're returning */ - op = LIST_FIRST(ohp); - while (op != NULL) { - nop = LIST_NEXT(op, nfso_list); - LIST_REMOVE(op, nfso_list); - LIST_INSERT_HEAD(&op->nfso_own->nfsow_open, - op, nfso_list); - op = nop; - } - NFSUNLOCKCLSTATE(); - LIST_INIT(ohp); - return (0); - } + op = LIST_FIRST(&owp->nfsow_open); + while (op != NULL) { + nop = LIST_NEXT(op, nfso_list); + if (op->nfso_fhlen == nfhp->nfh_len && + !NFSBCMP(op->nfso_fh, nfhp->nfh_fh, + nfhp->nfh_len)) { + /* Found an open, decrement cnt if possible */ + if (notdecr && op->nfso_opencnt > 0) { + notdecr = 0; + op->nfso_opencnt--; + } + /* + * There are more opens, so just return after + * putting any opens already found back in the + * state list. + */ + if (op->nfso_opencnt > 0) { + if (ohp != NULL) { + /* Reattach open until later */ + op = LIST_FIRST(ohp); + while (op != NULL) { + nop = LIST_NEXT(op, nfso_list); + LIST_REMOVE(op, nfso_list); + LIST_INSERT_HEAD( + &op->nfso_own->nfsow_open, + op, nfso_list); + op = nop; + } + LIST_INIT(ohp); + } + NFSUNLOCKCLSTATE(); + return (0); + } - /* - * Move this entry to the list of opens to be returned. - * (If we find other open(s) still in use, it will be - * put back in the state list in the code just above.) - */ - LIST_REMOVE(op, nfso_list); - LIST_INSERT_HEAD(ohp, op, nfso_list); + /* + * Move this entry to the list of opens to be + * returned. (If we find other open(s) still in + * use, it will be put back in the state list + * in the code just above.) + */ + if (ohp != NULL) { + LIST_REMOVE(op, nfso_list); + LIST_INSERT_HEAD(ohp, op, nfso_list); + } + } + op = nop; } - op = nop; - } } - if (dp != NULL) { + if (dp != NULL && ohp != NULL) { /* * If we are flushing all writes against the server for this * file upon close, we do not need to keep the local opens @@ -2869,8 +2880,8 @@ nfscl_getclose(vnode_t vp, struct ucred *cred, NFSPROC_T *p, } } NFSUNLOCKCLSTATE(); - if (notdecr) - printf("nfscl: never fnd open\n"); + if (notdecr && ohp == NULL) + printf("nfscl: never fnd open\n"); return (0); } diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 62808a4a4497..4b320ac881e3 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -517,8 +517,7 @@ nfs_open(struct vop_open_args *ap) error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error == EINTR || error == EIO) { if (NFS_ISV4(vp)) - (void) nfsrpc_close(vp, ap->a_cred, - ap->a_td); + (void) nfsrpc_close(vp, 0, ap->a_td); return (error); } np->n_attrstamp = 0; @@ -527,8 +526,7 @@ nfs_open(struct vop_open_args *ap) error = VOP_GETATTR(vp, &vattr, ap->a_cred); if (error) { if (NFS_ISV4(vp)) - (void) nfsrpc_close(vp, ap->a_cred, - ap->a_td); + (void) nfsrpc_close(vp, 0, ap->a_td); return (error); } mtx_lock(&np->n_mtx); @@ -549,8 +547,7 @@ nfs_open(struct vop_open_args *ap) error = VOP_GETATTR(vp, &vattr, ap->a_cred); if (error) { if (NFS_ISV4(vp)) - (void) nfsrpc_close(vp, ap->a_cred, - ap->a_td); + (void) nfsrpc_close(vp, 0, ap->a_td); return (error); } mtx_lock(&np->n_mtx); @@ -562,8 +559,8 @@ nfs_open(struct vop_open_args *ap) error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error == EINTR || error == EIO) { if (NFS_ISV4(vp)) - (void) nfsrpc_close(vp, - ap->a_cred, ap->a_td); + (void) nfsrpc_close(vp, 0, + ap->a_td); return (error); } mtx_lock(&np->n_mtx); @@ -583,8 +580,7 @@ nfs_open(struct vop_open_args *ap) error = ncl_vinvalbuf(vp, V_SAVE, ap->a_td, 1); if (error) { if (NFS_ISV4(vp)) - (void) nfsrpc_close(vp, ap->a_cred, - ap->a_td); + (void) nfsrpc_close(vp, 0, ap->a_td); return (error); } mtx_lock(&np->n_mtx); @@ -745,7 +741,7 @@ nfs_close(struct vop_close_args *ap) /* * and do the close. */ - ret = nfsrpc_close(vp, cred, ap->a_td); + ret = nfsrpc_close(vp, 0, ap->a_td); if (!error && ret) error = ret; if (error) From 10f5c8be92a09f7979aeb2740db43df3707d09d9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 18 May 2009 21:46:46 +0000 Subject: [PATCH 288/544] - Fix typo in description of 'net.inet.ip.fw.autoinc_step'. - Use 'vnet_ipfw' instead of 'vnet_inet' for 'net.inet.ip.fw.one_pass'. --- sys/netinet/ip_fw2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index af70451ddd9a..ab238c01759a 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -181,8 +181,8 @@ SYSCTL_V_PROC(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, enable, CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_SECURE3, fw_enable, 0, ipfw_chg_hook, "I", "Enable ipfw"); SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, autoinc_step, - CTLFLAG_RW, autoinc_step, 0, "Rule number autincrement step"); -SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip_fw, OID_AUTO, one_pass, + CTLFLAG_RW, autoinc_step, 0, "Rule number auto-increment step"); +SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, one_pass, CTLFLAG_RW | CTLFLAG_SECURE3, fw_one_pass, 0, "Only do a single pass through ipfw when using dummynet(4)"); SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, verbose, From d3da228f37fb8bb616f0ca27e6bc52cd049b5d73 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 18 May 2009 21:47:32 +0000 Subject: [PATCH 289/544] Add a read-only sysctl hw.pci.mcfg to mirror the tunable by the same name. MFC after: 1 week --- sys/amd64/pci/pci_cfgreg.c | 5 +++++ sys/i386/pci/pci_cfgreg.c | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sys/amd64/pci/pci_cfgreg.c b/sys/amd64/pci/pci_cfgreg.c index 61a2db55f1d8..be9e40488ee0 100644 --- a/sys/amd64/pci/pci_cfgreg.c +++ b/sys/amd64/pci/pci_cfgreg.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -56,6 +57,8 @@ static void pciereg_cfgwrite(int bus, unsigned slot, unsigned func, static int pcireg_cfgread(int bus, int slot, int func, int reg, int bytes); static void pcireg_cfgwrite(int bus, int slot, int func, int reg, int data, int bytes); +SYSCTL_DECL(_hw_pci); + static int cfgmech; static vm_offset_t pcie_base; static int pcie_minbus, pcie_maxbus; @@ -63,6 +66,8 @@ static uint32_t pcie_badslots; static struct mtx pcicfg_mtx; static int mcfg_enable = 1; TUNABLE_INT("hw.pci.mcfg", &mcfg_enable); +SYSCTL_INT(_hw_pci, OID_AUTO, mcfg, CTLFLAG_RDTUN, &mcfg_enable, 0, + "Enable support for PCI-e memory mapped config access"); /* * Initialise access to PCI configuration space diff --git a/sys/i386/pci/pci_cfgreg.c b/sys/i386/pci/pci_cfgreg.c index ecefa17f987a..20050e6f0144 100644 --- a/sys/i386/pci/pci_cfgreg.c +++ b/sys/i386/pci/pci_cfgreg.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -75,6 +76,8 @@ enum { CFGMECH_PCIE, }; +SYSCTL_DECL(_hw_pci); + static TAILQ_HEAD(pcie_cfg_list, pcie_cfg_elem) pcie_list[MAXCPU]; static uint64_t pcie_base; static int pcie_minbus, pcie_maxbus; @@ -84,6 +87,8 @@ static int devmax; static struct mtx pcicfg_mtx; static int mcfg_enable = 1; TUNABLE_INT("hw.pci.mcfg", &mcfg_enable); +SYSCTL_INT(_hw_pci, OID_AUTO, mcfg, CTLFLAG_RDTUN, &mcfg_enable, 0, + "Enable support for PCI-e memory mapped config access"); static uint32_t pci_docfgregread(int bus, int slot, int func, int reg, int bytes); From dfc77ef51f83bd9e6a0ad57582686aa03adf2a98 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Mon, 18 May 2009 21:50:06 +0000 Subject: [PATCH 290/544] - Add a tunable 'hw.mca.enabled' that can be used to enable/disable the machine check code. Disable it by default for now. - When computing the mask of bits that determines a non-restartable event during a machine check exception, or-in the overflow flag rather than replacing the other flags. PR: i386/134586 [2] Submitted by: Andi Kleen andi-fbsd firstfloor.org --- sys/amd64/amd64/mca.c | 25 ++++++++++++++----------- sys/i386/i386/mca.c | 25 ++++++++++++++----------- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c index f0cf57232aea..8669c2bd74b7 100644 --- a/sys/amd64/amd64/mca.c +++ b/sys/amd64/amd64/mca.c @@ -55,10 +55,15 @@ struct mca_internal { static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture"); -static struct sysctl_oid *mca_sysctl_tree; - static int mca_count; /* Number of records stored. */ +SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture"); + +static int mca_enabled = 0; +TUNABLE_INT("hw.mca.enabled", &mca_enabled); +SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0, + "Administrative toggle for machine check support"); + static STAILQ_HEAD(, mca_internal) mca_records; static struct callout mca_timer; static int mca_ticks = 3600; /* Check hourly by default. */ @@ -346,7 +351,7 @@ mca_scan(int mcip) /* When handling a MCE#, treat the OVER flag as non-restartable. */ if (mcip) - ucmask = MC_STATUS_OVER; + ucmask |= MC_STATUS_OVER; mcg_cap = rdmsr(MSR_MCG_CAP); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { rec = mca_record_entry(i); @@ -426,7 +431,7 @@ static void mca_startup(void *dummy) { - if (!(cpu_feature & CPUID_MCA)) + if (!mca_enabled || !(cpu_feature & CPUID_MCA)) return; callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, @@ -442,17 +447,15 @@ mca_setup(void) STAILQ_INIT(&mca_records); TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL); callout_init(&mca_timer, CALLOUT_MPSAFE); - mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw), - OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container"); - SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "count", CTLFLAG_RD, &mca_count, 0, "Record count"); - SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks, 0, sysctl_mca_ticks, "I", "Periodic interval in seconds to scan for machine checks"); - SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records"); - SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, sysctl_mca_scan, "I", "Force an immediate scan for machine checks"); } @@ -465,7 +468,7 @@ mca_init(void) int i; /* MCE is required. */ - if (!(cpu_feature & CPUID_MCE)) + if (!mca_enabled || !(cpu_feature & CPUID_MCE)) return; if (cpu_feature & CPUID_MCA) { diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c index 63317ee34025..5ad8c526d18a 100644 --- a/sys/i386/i386/mca.c +++ b/sys/i386/i386/mca.c @@ -55,10 +55,15 @@ struct mca_internal { static MALLOC_DEFINE(M_MCA, "MCA", "Machine Check Architecture"); -static struct sysctl_oid *mca_sysctl_tree; - static int mca_count; /* Number of records stored. */ +SYSCTL_NODE(_hw, OID_AUTO, mca, CTLFLAG_RD, NULL, "Machine Check Architecture"); + +static int mca_enabled = 0; +TUNABLE_INT("hw.mca.enabled", &mca_enabled); +SYSCTL_INT(_hw_mca, OID_AUTO, enabled, CTLFLAG_RDTUN, &mca_enabled, 0, + "Administrative toggle for machine check support"); + static STAILQ_HEAD(, mca_internal) mca_records; static struct callout mca_timer; static int mca_ticks = 3600; /* Check hourly by default. */ @@ -346,7 +351,7 @@ mca_scan(int mcip) /* When handling a MCE#, treat the OVER flag as non-restartable. */ if (mcip) - ucmask = MC_STATUS_OVER; + ucmask |= MC_STATUS_OVER; mcg_cap = rdmsr(MSR_MCG_CAP); for (i = 0; i < (mcg_cap & MCG_CAP_COUNT); i++) { rec = mca_record_entry(i); @@ -426,7 +431,7 @@ static void mca_startup(void *dummy) { - if (!(cpu_feature & CPUID_MCA)) + if (!mca_enabled || !(cpu_feature & CPUID_MCA)) return; callout_reset(&mca_timer, mca_ticks * hz, mca_periodic_scan, @@ -442,17 +447,15 @@ mca_setup(void) STAILQ_INIT(&mca_records); TASK_INIT(&mca_task, 0x8000, mca_scan_cpus, NULL); callout_init(&mca_timer, CALLOUT_MPSAFE); - mca_sysctl_tree = SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw), - OID_AUTO, "mca", CTLFLAG_RW, NULL, "MCA container"); - SYSCTL_ADD_INT(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_INT(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "count", CTLFLAG_RD, &mca_count, 0, "Record count"); - SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "interval", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, &mca_ticks, 0, sysctl_mca_ticks, "I", "Periodic interval in seconds to scan for machine checks"); - SYSCTL_ADD_NODE(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_NODE(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "records", CTLFLAG_RD, sysctl_mca_records, "Machine check records"); - SYSCTL_ADD_PROC(NULL, SYSCTL_CHILDREN(mca_sysctl_tree), OID_AUTO, + SYSCTL_ADD_PROC(NULL, SYSCTL_STATIC_CHILDREN(_hw_mca), OID_AUTO, "force_scan", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, 0, sysctl_mca_scan, "I", "Force an immediate scan for machine checks"); } @@ -465,7 +468,7 @@ mca_init(void) int i; /* MCE is required. */ - if (!(cpu_feature & CPUID_MCE)) + if (!mca_enabled || !(cpu_feature & CPUID_MCE)) return; if (cpu_feature & CPUID_MCA) { From b873e82fedb8026ff397a976c38d4182a21da706 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 18 May 2009 22:27:42 +0000 Subject: [PATCH 291/544] Virgin import of Christos Zoulas's FILE 5.03. Security: CVE-2009-1515 --- ChangeLog | 56 + Magdir/cafebabe | 9 + Magdir/compress | 9 + Magdir/database | 25 + Magdir/erlang | 6 +- Magdir/filesystems | 2 +- Magdir/fonts | 6 +- Magdir/fortran | 2 +- Magdir/kml | 32 + Magdir/linux | 2 +- Magdir/lisp | 18 +- Magdir/python | 2 + Magdir/troff | 4 + Magdir/windows | 6 + Makefile.am | 3 +- Makefile.in | 8 +- README | 7 +- acinclude.m4 | 11 + aclocal.m4 | 1562 ++++++++----- apprentice.c | 66 +- apptype.c | 4 +- cdf.c | 374 ++-- cdf.h | 41 +- cdf_time.c | 5 +- compress.c | 5 +- config.guess | 1504 ------------- config.h.in | 3 + config.sub | 1622 -------------- configure | 5177 ++++++++++++++++++++------------------------ configure.ac | 10 +- file.c | 4 +- file.h | 10 +- funcs.c | 11 +- getopt_long.c | 4 +- magic.c | 34 +- patchlevel.h | 13 +- readcdf.c | 91 +- softmagic.c | 24 +- strlcat.c | 58 + strlcpy.c | 54 + tests/Makefile.in | 5 +- 41 files changed, 4166 insertions(+), 6723 deletions(-) create mode 100644 Magdir/kml delete mode 100755 config.guess delete mode 100755 config.sub create mode 100644 strlcat.c create mode 100644 strlcpy.c diff --git a/ChangeLog b/ChangeLog index d2110415a1af..90a32fcecffb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,59 @@ +2009-05-06 10:25 Christos Zoulas + + * Avoid null dereference in cdf code (Drew Yao) + + * More cdf bounds checks and overflow checks + +2009-05-01 18:37 Christos Zoulas + + * Buffer overflow fixes from Drew Yao + +2009-04-30 17:10 Christos Zoulas + + * Fix more cdf lossage. All the documents I have + right now print the correct information. + +2009-03-27 18:43 Christos Zoulas + + * don't print \012- separators in the same magic entry + if it consists of multiple magic printing lines. + +2009-03-23 10:20 Christos Zoulas + + * Avoid file descriptor leak in compress code from + (Daniel Novotny) + +2009-03-18 16:50 Christos Zoulas + + * Allow escaping of relation characters, so that we can say \^[A-Z] + and the ^ is not eaten as a relation char. + + * Fix troff and fortran to their previous glory using + regex. This was broken since their removel from ascmagic. + +2009-03-10 16:50 Christos Zoulas + + * don't use strlen in strndup() (Toby Peterson) + +2009-03-10 7:45 Christos Zoulas + + * avoid c99 syntax. + +2009-02-23 15:45 Christos Zoulas + + * make the cdf code use the buffer first if available, + and then the fd code. + +2009-02-13 13:45 Christos Zoulas + + * look for struct option to determine if getopt.h is usable for IRIX. + + * sanitize cdf document strings + +2009-02-04 13:25 Christos Zoulas + + * fix OS/2 warnings. + 2008-12-12 15:50 Christos Zoulas * fix initial offset calculation for non 4K sector files diff --git a/Magdir/cafebabe b/Magdir/cafebabe index 2168d95139d8..e25c974dd55b 100644 --- a/Magdir/cafebabe +++ b/Magdir/cafebabe @@ -17,6 +17,15 @@ >4 belong >30 compiled Java class data, >>6 beshort x version %d. >>4 beshort x \b%d +# Which is which? +#>>4 belong 0x032d (Java 1.0) +#>>4 belong 0x032d (Java 1.1) +>>4 belong 0x002e (Java 1.2) +>>4 belong 0x002f (Java 1.3) +>>4 belong 0x0030 (Java 1.4) +>>4 belong 0x0031 (Java 1.5) +>>4 belong 0x0032 (Java 1.6) + 0 belong 0xcafebabe >4 belong 1 Mach-O fat file with 1 architecture diff --git a/Magdir/compress b/Magdir/compress index 5cbb1c87a911..5e18de0b8b71 100644 --- a/Magdir/compress +++ b/Magdir/compress @@ -195,6 +195,10 @@ # bug #364260) #0 string ]\000\000\200\000 LZMA compressed data +# http://tukaani.org/xz/xz-file-format.txt +0 ustring \xFD7zXZ\x00 xz compressed data +!:mime application/x-xz + # AFX compressed files (Wolfram Kleff) 2 string -afx- AFX compressed file data @@ -208,3 +212,8 @@ >4 byte x - version %d >5 byte x \b.%d >6 belong x (%d bytes) + +# Type: XZ +# URL: http://tukaani.org/xz/ +0 string \xfd\x37\x7a\x58\x5a\x00 XZ compressed data +!:mime application/x-xz diff --git a/Magdir/database b/Magdir/database index 2e6ad2fdd2c8..0134355f3816 100644 --- a/Magdir/database +++ b/Magdir/database @@ -242,3 +242,28 @@ # URL: http://www.grc.nasa.gov/WWW/cgns/adf/ # From: Nicolas Chauvat 0 string @(#)ADF\ Database CGNS Advanced Data Format + +# Tokyo Cabinet magic data +# http://tokyocabinet.sourceforge.net/index.html +0 string ToKyO\ CaBiNeT\n Tokyo Cabinet +>14 string x \b (%s) +>32 byte 0 \b, Hash +!:mime application/x-tokyocabinet-hash +>32 byte 1 \b, B+ tree +!:mime application/x-tokyocabinet-btree +>32 byte 2 \b, Fixed-length +!:mime application/x-tokyocabinet-fixed +>32 byte 3 \b, Table +!:mime application/x-tokyocabinet-table +>33 byte &1 \b, [open] +>33 byte &2 \b, [fatal] +>34 byte x \b, apow=%d +>35 byte x \b, fpow=%d +>36 byte &0x01 \b, [large] +>36 byte &0x02 \b, [deflate] +>36 byte &0x04 \b, [bzip] +>36 byte &0x08 \b, [tcbs] +>36 byte &0x10 \b, [excodec] +>40 lequad x \b, bnum=%lld +>48 lequad x \b, rnum=%lld +>56 lequad x \b, fsiz=%lld diff --git a/Magdir/erlang b/Magdir/erlang index 59f55ecb31b6..6b2c4dcc3c66 100644 --- a/Magdir/erlang +++ b/Magdir/erlang @@ -12,7 +12,7 @@ >8 string BEAM Erlang BEAM file # 4.2 version may have a copyright notice! -4 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2 -79 string Tue Jan 22 14:32:44 MET 1991 Erlang JAM file - version 4.2 +4 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2 +79 string Tue\ Jan\ 22\ 14:32:44\ MET\ 1991 Erlang JAM file - version 4.2 -4 string 1.0 Fri Feb 3 09:55:56 MET 1995 Erlang JAM file - version 4.3 +4 string 1.0\ Fri\ Feb\ 3\ 09:55:56\ MET\ 1995 Erlang JAM file - version 4.3 diff --git a/Magdir/filesystems b/Magdir/filesystems index b682df1d931e..93da429432aa 100644 --- a/Magdir/filesystems +++ b/Magdir/filesystems @@ -891,7 +891,7 @@ 0x410 leshort 0x2478 Minix filesystem, version 2, 30 char names # romfs filesystems - Juan Cespedes -0 string -rom1fs-\0 romfs filesystem, version 1 +0 string -rom1fs- romfs filesystem, version 1 >8 belong x %d bytes, >16 string x named %s. diff --git a/Magdir/fonts b/Magdir/fonts index a6f43e74b4bf..31ff8a2c8b1e 100644 --- a/Magdir/fonts +++ b/Magdir/fonts @@ -6,8 +6,8 @@ 0 short 017001 byte-swapped Berkeley vfont data # PostScript fonts (must precede "printer" entries), quinlan@yggdrasil.com -0 search/1 %!PS-AdobeFont-1. PostScript Type 1 font text ->20 search/1 >\0 (%s) +0 string %!PS-AdobeFont-1. PostScript Type 1 font text +>20 string >\0 (%s) 6 string %!PS-AdobeFont-1. PostScript Type 1 font program data # X11 font files in SNF (Server Natural Format) format @@ -55,6 +55,8 @@ 0 string \007\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font 0 string \012\001\001\000Copyright\ (c)\ 199 Adobe Multiple Master font +0 string ttcf TrueType font collection data + # Opentype font data from Avi Bercovich 0 string OTTO OpenType font data diff --git a/Magdir/fortran b/Magdir/fortran index 3e490333e180..f42c7c8a8d52 100644 --- a/Magdir/fortran +++ b/Magdir/fortran @@ -1,3 +1,3 @@ # FORTRAN source -0 string/c c\ FORTRAN program +0 regex/100 \^[Cc][\ \t] FORTRAN program !:mime text/x-fortran diff --git a/Magdir/kml b/Magdir/kml new file mode 100644 index 000000000000..5b59b9e55501 --- /dev/null +++ b/Magdir/kml @@ -0,0 +1,32 @@ +#------------------------------------------------------------------------------ +# Type: Google KML, formerly Keyhole Markup Language +# Future development of this format has been handed +# over to the Open Geospatial Consortium. +# http://www.opengeospatial.org/standards/kml/ +# From: Asbjoern Sloth Toennesen +0 string \20 search/400 \ xmlns= +>>&0 regex ['"]http://earth.google.com/kml Google KML document +!:mime application/vnd.google-earth.kml+xml +>>>&1 string 2.0' \b, version 2.0 +>>>&1 string 2.1' \b, version 2.1 +>>>&1 string 2.2' \b, version 2.2 + +#------------------------------------------------------------------------------ +# Type: OpenGIS KML, formerly Keyhole Markup Language +# This standard is maintained by the +# Open Geospatial Consortium. +# http://www.opengeospatial.org/standards/kml/ +# From: Asbjoern Sloth Toennesen +>>&0 regex ['"]http://www.opengis.net/kml OpenGIS KML document +!:mime application/vnd.google-earth.kml+xml +>>>&1 string 2.2 \b, version 2.2 + +#------------------------------------------------------------------------------ +# Type: Google KML Archive (ZIP based) +# http://code.google.com/apis/kml/documentation/kml_tut.html +# From: Asbjoern Sloth Toennesen +0 string PK\003\004 +>4 byte 0x14 +>>30 string doc.kml Compressed Google KML Document, including resources. +!:mime application/vnd.google-earth.kmz diff --git a/Magdir/linux b/Magdir/linux index aaedff42d86f..83d4305d0a1f 100644 --- a/Magdir/linux +++ b/Magdir/linux @@ -84,7 +84,7 @@ 514 string HdrS Linux kernel >510 leshort 0xAA55 x86 boot executable >>518 leshort >0x1ff ->>529 byte 0 zImage, +>>>529 byte 0 zImage, >>>529 byte 1 bzImage, >>>(526.s+0x200) string >\0 version %s, >>498 leshort 1 RO-rootFS, diff --git a/Magdir/lisp b/Magdir/lisp index 60b740a86a7a..c6f31dae4238 100644 --- a/Magdir/lisp +++ b/Magdir/lisp @@ -8,22 +8,22 @@ #0 string ;; # windows INF files often begin with semicolon and use CRLF as line end # lisp files are mainly created on unix system with LF as line end -#>2 search/2048 !\r Lisp/Scheme program text -#>2 search/2048 \r Windows INF file +#>2 search/4096 !\r Lisp/Scheme program text +#>2 search/4096 \r Windows INF file -0 search/256 (if\ Lisp/Scheme program text +0 search/4096 (if\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (setq\ Lisp/Scheme program text +0 search/4096 (setq\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (defvar\ Lisp/Scheme program text +0 search/4096 (defvar\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (defparam\ Lisp/Scheme program text +0 search/4096 (defparam\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (defun\ Lisp/Scheme program text +0 search/4096 (defun\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (autoload\ Lisp/Scheme program text +0 search/4096 (autoload\ Lisp/Scheme program text !:mime text/x-lisp -0 search/256 (custom-set-variables\ Lisp/Scheme program text +0 search/4096 (custom-set-variables\ Lisp/Scheme program text !:mime text/x-lisp # Emacs 18 - this is always correct, but not very magical. diff --git a/Magdir/python b/Magdir/python index 9fac2b9ae707..4803203dcfa8 100644 --- a/Magdir/python +++ b/Magdir/python @@ -14,6 +14,8 @@ 0 belong 0x3bf20d0a python 2.3 byte-compiled 0 belong 0x6df20d0a python 2.4 byte-compiled 0 belong 0xb3f20d0a python 2.5 byte-compiled +0 belong 0xd1f20d0a python 2.6 byte-compiled + 0 string/b #!\ /usr/bin/python python script text executable diff --git a/Magdir/troff b/Magdir/troff index 337ca6837714..73731a89b3fc 100644 --- a/Magdir/troff +++ b/Magdir/troff @@ -14,6 +14,10 @@ !:mime text/troff 0 search/1 ''' troff or preprocessor input text !:mime text/troff +0 regex/20 \^\\.[A-Za-z0-9][A-Za-z0-9][\ \t] troff or preprocessor input text +!:mime text/troff +0 regex/20 \^\\.[A-Za-z0-9][A-Za-z0-9]$ troff or preprocessor input text +!:mime text/troff # ditroff intermediate output text 0 search/1 x\ T ditroff output text diff --git a/Magdir/windows b/Magdir/windows index 5cde739f633d..8d7680732160 100644 --- a/Magdir/windows +++ b/Magdir/windows @@ -113,3 +113,9 @@ 0 string REGEDIT4\r\n\r\n Windows Registry text (Win95 or above) 0 string Windows\ Registry\ Editor\ >&0 string Version\ 5.00\r\n\r\n Windows Registry text (Win2K or above) + + +# From: Pal Tamas +# Autorun File +0 string/c [autorun]\r\n Microsoft Windows Autorun file. +!:mime application/x-setupscript. diff --git a/Makefile.am b/Makefile.am index 5849f40e2f00..fadbea8a703f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ # -# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $ +# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE) @@ -97,6 +97,7 @@ $(MAGIC_FRAGMENT_DIR)/java \ $(MAGIC_FRAGMENT_DIR)/jpeg \ $(MAGIC_FRAGMENT_DIR)/karma \ $(MAGIC_FRAGMENT_DIR)/kde \ +$(MAGIC_FRAGMENT_DIR)/kml \ $(MAGIC_FRAGMENT_DIR)/lecter \ $(MAGIC_FRAGMENT_DIR)/lex \ $(MAGIC_FRAGMENT_DIR)/lif \ diff --git a/Makefile.in b/Makefile.in index b6fabbef0a87..42cb2fd16f9d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -15,7 +15,6 @@ @SET_MAKE@ VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd @@ -54,6 +53,7 @@ am__installdirs = "$(DESTDIR)$(pkgdatadir)" pkgdataDATA_INSTALL = $(INSTALL_DATA) DATA = $(pkgdata_DATA) DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ @@ -73,6 +73,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -95,6 +96,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -104,6 +106,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ @@ -163,7 +166,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ # -# $File: Makefile.am,v 1.44 2009/01/28 02:11:20 christos Exp $ +# $File: Makefile.am,v 1.45 2009/03/05 22:40:59 christos Exp $ # MAGIC_FRAGMENT_BASE = Magdir MAGIC_FRAGMENT_DIR = $(top_srcdir)/magic/$(MAGIC_FRAGMENT_BASE) @@ -259,6 +262,7 @@ $(MAGIC_FRAGMENT_DIR)/java \ $(MAGIC_FRAGMENT_DIR)/jpeg \ $(MAGIC_FRAGMENT_DIR)/karma \ $(MAGIC_FRAGMENT_DIR)/kde \ +$(MAGIC_FRAGMENT_DIR)/kml \ $(MAGIC_FRAGMENT_DIR)/lecter \ $(MAGIC_FRAGMENT_DIR)/lex \ $(MAGIC_FRAGMENT_DIR)/lif \ diff --git a/README b/README index 25c3abca34a7..901989a0e296 100644 --- a/README +++ b/README @@ -1,15 +1,18 @@ ** README for file(1) Command ** -@(#) $File: README,v 1.41 2008/12/02 16:34:46 christos Exp $ +@(#) $File: README,v 1.42 2009/02/14 15:16:24 christos Exp $ E-mail: christos@astron.com Mailing List: file@mx.gw.com Phone: Do not even think of telephoning me about this program. Send cash first! -This is Release 4.x of Ian Darwin's (copyright but distributable) +This is Release 5.x of Ian Darwin's (copyright but distributable) file(1) command. This version is the standard "file" command for Linux, *BSD, and other systems. (See "patchlevel.h" for the exact release number). +The major changes for 5.x are CDF file parsing, indirect magic, and +overhaul in mime and ascii encoding handling. + The major feature of 4.x is the refactoring of the code into a library, and the re-write of the file command in terms of that library. The library itself, libmagic can be used by 3rd party programs that wish to identify diff --git a/acinclude.m4 b/acinclude.m4 index 31677b18215b..ff6a657d7d37 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -9,6 +9,7 @@ AC_CACHE_CHECK([for tm_zone in struct tm], ac_cv_struct_tm_zone, if test "$ac_cv_struct_tm_zone" = yes; then AC_DEFINE(HAVE_TM_ZONE,1,[HAVE_TM_ZONE]) fi + AC_CACHE_CHECK(for tzname, ac_cv_var_tzname, [AC_TRY_LINK( changequote(<<, >>)dnl @@ -29,6 +30,7 @@ AC_CACHE_CHECK([for tm_isdst in struct tm], ac_cv_struct_tm_isdst, if test "$ac_cv_struct_tm_isdst" = yes; then AC_DEFINE(HAVE_TM_ISDST,1,[HAVE_TM_ISDST]) fi + AC_CACHE_CHECK(for daylight, ac_cv_var_daylight, [AC_TRY_LINK( changequote(<<, >>)dnl @@ -42,3 +44,12 @@ changequote([, ])dnl AC_DEFINE(HAVE_DAYLIGHT,1,[HAVE_DAYLIGHT]) fi ]) + +AC_DEFUN([AC_STRUCT_OPTION_GETOPT_H], +[AC_CACHE_CHECK([for struct option in getopt], ac_cv_struct_option_getopt_h, +[AC_TRY_COMPILE([#include ], [struct option op; op.name;], + ac_cv_struct_option_getopt_h=yes, ac_cv_struct_option_getopt_h=no)]) +if test "$ac_cv_struct_option_getopt_h" = yes; then + AC_DEFINE(HAVE_STRUCT_OPTION,1,[HAVE_STRUCT_OPTION]) +fi +]) diff --git a/aclocal.m4 b/aclocal.m4 index 593d2e957b4b..2dd34f626e71 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -18,7 +18,7 @@ you should regenerate the build system entirely.], [63])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- -# serial 47 AC_PROG_LIBTOOL +# serial 52 AC_PROG_LIBTOOL # AC_PROVIDE_IFELSE(MACRO-NAME, IF-PROVIDED, IF-NOT-PROVIDED) @@ -106,7 +106,6 @@ AC_REQUIRE([AC_DEPLIBS_CHECK_METHOD])dnl AC_REQUIRE([AC_OBJEXT])dnl AC_REQUIRE([AC_EXEEXT])dnl dnl - AC_LIBTOOL_SYS_MAX_CMD_LEN AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE AC_LIBTOOL_OBJDIR @@ -148,7 +147,7 @@ rm="rm -f" default_ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, +# All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" @@ -168,6 +167,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" @@ -180,17 +180,17 @@ test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" @@ -207,6 +207,8 @@ file_magic*) ;; esac +_LT_REQUIRED_DARWIN_CHECKS + AC_PROVIDE_IFELSE([AC_LIBTOOL_DLOPEN], enable_dlopen=yes, enable_dlopen=no) AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], enable_win32_dll=yes, enable_win32_dll=no) @@ -238,6 +240,9 @@ AC_DEFUN([_LT_AC_SYS_COMPILER], # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC ])# _LT_AC_SYS_COMPILER @@ -264,9 +269,10 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # Check for compiler boilerplate output or warnings with # the simple compiler test code. AC_DEFUN([_LT_COMPILER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ])# _LT_COMPILER_BOILERPLATE @@ -277,13 +283,85 @@ $rm conftest* # Check for linker boilerplate output or warnings with # the simple link test code. AC_DEFUN([_LT_LINKER_BOILERPLATE], -[ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +[AC_REQUIRE([LT_AC_PROG_SED])dnl +ac_outfile=conftest.$ac_objext +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* ])# _LT_LINKER_BOILERPLATE +# _LT_REQUIRED_DARWIN_CHECKS +# -------------------------- +# Check for some things on darwin +AC_DEFUN([_LT_REQUIRED_DARWIN_CHECKS],[ + case $host_os in + rhapsody* | darwin*) + AC_CHECK_TOOL([DSYMUTIL], [dsymutil], [:]) + AC_CHECK_TOOL([NMEDIT], [nmedit], [:]) + + AC_CACHE_CHECK([for -single_module linker flag],[lt_cv_apple_cc_single_mod], + [lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + echo "int foo(void){return 1;}" > conftest.c + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib ${wl}-single_module conftest.c + if test -f libconftest.dylib; then + lt_cv_apple_cc_single_mod=yes + rm -rf libconftest.dylib* + fi + rm conftest.c + fi]) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], + [lt_cv_ld_exported_symbols_list], + [lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + AC_LINK_IFELSE([AC_LANG_PROGRAM([],[])], + [lt_cv_ld_exported_symbols_list=yes], + [lt_cv_ld_exported_symbols_list=no]) + LDFLAGS="$save_LDFLAGS" + ]) + case $host_os in + rhapsody* | darwin1.[[0123]]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[[012]]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}" + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil="~$DSYMUTIL \$lib || :" + else + _lt_dsymutil= + fi + ;; + esac +]) # _LT_AC_SYS_LIBPATH_AIX # ---------------------- @@ -294,12 +372,20 @@ $rm conftest* # If we don't find anything, use the default library path according # to the aix ld manual. AC_DEFUN([_LT_AC_SYS_LIBPATH_AIX], -[AC_LINK_IFELSE(AC_LANG_PROGRAM,[ -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_LINK_IFELSE(AC_LANG_PROGRAM,[ +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi],[]) +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi],[]) if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ])# _LT_AC_SYS_LIBPATH_AIX @@ -364,8 +450,8 @@ if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "[$]0"' 'sed 20q "[$]0"' 'sed 10q "[$]0"' 'sed 2q "[$]0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break @@ -530,13 +616,17 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case "`/usr/bin/file conftest.o`" in + case `/usr/bin/file conftest.o` in *32-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; @@ -553,6 +643,9 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ;; *64-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; @@ -585,6 +678,26 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) CFLAGS="$SAVE_CFLAGS" fi ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + AC_PROVIDE_IFELSE([AC_LIBTOOL_WIN32_DLL], [*-*-cygwin* | *-*-mingw* | *-*-pw32*) AC_CHECK_TOOL(DLLTOOL, dlltool, false) @@ -608,7 +721,7 @@ AC_DEFUN([AC_LIBTOOL_COMPILER_OPTION], AC_CACHE_CHECK([$1], [$2], [$2=no ifelse([$4], , [ac_outfile=conftest.$ac_objext], [ac_outfile=$4]) - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$3" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -616,7 +729,7 @@ AC_CACHE_CHECK([$1], [$2], # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) @@ -627,9 +740,9 @@ AC_CACHE_CHECK([$1], [$2], if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi fi @@ -649,19 +762,20 @@ fi # ------------------------------------------------------------ # Check whether the given compiler option works AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], -[AC_CACHE_CHECK([$1], [$2], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_CACHE_CHECK([$1], [$2], [$2=no save_LDFLAGS="$LDFLAGS" LDFLAGS="$LDFLAGS $3" - printf "$lt_simple_link_test_code" > conftest.$ac_ext + echo "$lt_simple_link_test_code" > conftest.$ac_ext if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized + # The linker can only warn and ignore the option if not recognized # So say no if there are warnings if test -s conftest.err; then # Append any errors to the config.log. cat conftest.err 1>&AS_MESSAGE_LOG_FD - $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 if diff conftest.exp conftest.er2 >/dev/null; then $2=yes fi @@ -669,7 +783,7 @@ AC_DEFUN([AC_LIBTOOL_LINKER_OPTION], $2=yes fi fi - $rm conftest* + $rm -r conftest* LDFLAGS="$save_LDFLAGS" ]) @@ -730,44 +844,64 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [dnl elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else - lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not # nice to cause kernel panics so lets avoid the loop below. # First set a reasonable default. lt_cv_sys_max_cmd_len=16384 - # + # if test -x /sbin/sysconfig; then case `/sbin/sysconfig -q proc exec_disable_arg_limit` in *1*) lt_cv_sys_max_cmd_len=-1 ;; esac fi ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL [$]0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi ;; esac ]) @@ -780,7 +914,7 @@ fi # _LT_AC_CHECK_DLFCN -# -------------------- +# ------------------ AC_DEFUN([_LT_AC_CHECK_DLFCN], [AC_CHECK_HEADERS(dlfcn.h)dnl ])# _LT_AC_CHECK_DLFCN @@ -788,7 +922,7 @@ AC_DEFUN([_LT_AC_CHECK_DLFCN], # _LT_AC_TRY_DLOPEN_SELF (ACTION-IF-TRUE, ACTION-IF-TRUE-W-USCORE, # ACTION-IF-FALSE, ACTION-IF-CROSS-COMPILING) -# ------------------------------------------------------------------ +# --------------------------------------------------------------------- AC_DEFUN([_LT_AC_TRY_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "$cross_compiling" = yes; then : @@ -854,17 +988,19 @@ int main () else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; /* dlclose (self); */ } + else + puts (dlerror ()); exit (status); }] EOF if AC_TRY_EVAL(ac_link) && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&AS_MESSAGE_LOG_FD 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) $1 ;; x$lt_dlneed_uscore) $2 ;; - x$lt_unknown|x*) $3 ;; + x$lt_dlunknown|x*) $3 ;; esac else : # compilation failed @@ -876,7 +1012,7 @@ rm -fr conftest* # AC_LIBTOOL_DLOPEN_SELF -# ------------------- +# ---------------------- AC_DEFUN([AC_LIBTOOL_DLOPEN_SELF], [AC_REQUIRE([_LT_AC_CHECK_DLFCN])dnl if test "x$enable_dlopen" != xyes; then @@ -918,7 +1054,7 @@ else AC_CHECK_FUNC([shl_load], [lt_cv_dlopen="shl_load"], [AC_CHECK_LIB([dld], [shl_load], - [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld"], + [lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld"], [AC_CHECK_FUNC([dlopen], [lt_cv_dlopen="dlopen"], [AC_CHECK_LIB([dl], [dlopen], @@ -926,7 +1062,7 @@ else [AC_CHECK_LIB([svld], [dlopen], [lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld"], [AC_CHECK_LIB([dld], [dld_link], - [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld"]) + [lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld"]) ]) ]) ]) @@ -947,7 +1083,7 @@ else test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" @@ -960,7 +1096,7 @@ else ]) if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" AC_CACHE_CHECK([whether a statically linked program can dlopen itself], lt_cv_dlopen_self_static, [dnl _LT_AC_TRY_DLOPEN_SELF( @@ -992,7 +1128,8 @@ fi # --------------------------------- # Check to see if options -c and -o are simultaneously supported by compiler AC_DEFUN([AC_LIBTOOL_PROG_CC_C_O], -[AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_REQUIRE([_LT_AC_SYS_COMPILER])dnl AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)], [_LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=no @@ -1000,7 +1137,7 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -1008,7 +1145,7 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [[^ ]]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` (eval echo "\"\$as_me:__oline__: $lt_compile\"" >&AS_MESSAGE_LOG_FD) @@ -1020,13 +1157,13 @@ AC_CACHE_CHECK([if $compiler supports -c -o file.$ac_objext], then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1)=yes fi fi - chmod u+w . + chmod u+w . 2>&AS_MESSAGE_LOG_FD $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -1140,6 +1277,7 @@ else darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" + old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) @@ -1157,7 +1295,8 @@ fi # ----------------------------- # PORTME Fill in your ld.so characteristics AC_DEFUN([AC_LIBTOOL_SYS_DYNAMIC_LINKER], -[AC_MSG_CHECKING([dynamic linker characteristics]) +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([dynamic linker characteristics]) library_names_spec= libname_spec='lib$name' soname_spec= @@ -1171,20 +1310,58 @@ shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" +m4_if($1,[],[ if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[[lt_foo]]++; } + if (lt_freq[[lt_foo]] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi +fi]) need_lib_prefix=unknown hardcode_into_libs=no @@ -1202,7 +1379,7 @@ aix3*) soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[[4-9]]*) version_type=linux need_lib_prefix=no need_version=no @@ -1286,7 +1463,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -1339,13 +1517,9 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + m4_if([$1], [],[ + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib"]) sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -1362,22 +1536,17 @@ freebsd1*) dynamic_linker=no ;; -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[[123]]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -1399,10 +1568,15 @@ freebsd* | dragonfly*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[[2-9]]* | freebsdelf3.[[2-9]]* | \ + freebsd4.[[0-5]] | freebsdelf4.[[0-5]] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -1422,7 +1596,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -1462,6 +1636,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix[[3-9]]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -1505,7 +1691,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -1521,7 +1707,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -1534,18 +1720,6 @@ linux*) dynamic_linker='GNU/Linux ld.so' ;; -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -1583,6 +1757,7 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in @@ -1626,11 +1801,8 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH +rdos*) + dynamic_linker=no ;; solaris*) @@ -1658,7 +1830,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -1691,6 +1863,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -1704,13 +1899,26 @@ uts4*) esac AC_MSG_RESULT([$dynamic_linker]) test "$dynamic_linker" = no && can_build_shared=no + +AC_CACHE_VAL([lt_cv_sys_lib_search_path_spec], +[lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec"]) +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +AC_CACHE_VAL([lt_cv_sys_lib_dlsearch_path_spec], +[lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec"]) +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi ])# AC_LIBTOOL_SYS_DYNAMIC_LINKER # _LT_AC_TAGCONFIG # ---------------- AC_DEFUN([_LT_AC_TAGCONFIG], -[AC_ARG_WITH([tags], +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_ARG_WITH([tags], [AC_HELP_STRING([--with-tags@<:@=TAGS@:>@], [include additional configurations @<:@automatic@:>@])], [tagnames="$withval"]) @@ -1728,6 +1936,9 @@ if test -f "$ltmain" && test -n "$tagnames"; then AC_MSG_WARN([using `LTCC=$LTCC', extracted from `$ofile']) fi fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. @@ -1818,7 +2029,7 @@ AC_DEFUN([AC_LIBTOOL_DLOPEN], # AC_LIBTOOL_WIN32_DLL # -------------------- -# declare package support for building win32 dll's +# declare package support for building win32 DLLs AC_DEFUN([AC_LIBTOOL_WIN32_DLL], [AC_BEFORE([$0], [AC_LIBTOOL_SETUP]) ])# AC_LIBTOOL_WIN32_DLL @@ -1856,7 +2067,7 @@ AC_ARG_ENABLE([shared], # AC_DISABLE_SHARED # ----------------- -#- set the default shared flag to --disable-shared +# set the default shared flag to --disable-shared AC_DEFUN([AC_DISABLE_SHARED], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl AC_ENABLE_SHARED(no) @@ -1968,7 +2179,7 @@ m4_ifndef([AC_PROG_EGREP], [AC_DEFUN([AC_PROG_EGREP], # AC_PATH_TOOL_PREFIX # ------------------- -# find a file program which can recognise shared library +# find a file program which can recognize shared library AC_DEFUN([AC_PATH_TOOL_PREFIX], [AC_REQUIRE([AC_PROG_EGREP])dnl AC_MSG_CHECKING([for $1]) @@ -1992,7 +2203,7 @@ dnl not every word. This closes a longstanding sh security hole. if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -2031,7 +2242,7 @@ fi # AC_PATH_MAGIC # ------------- -# find a file program which can recognise a shared library +# find a file program which can recognize a shared library AC_DEFUN([AC_PATH_MAGIC], [AC_PATH_TOOL_PREFIX(${ac_tool_prefix}file, /usr/bin$PATH_SEPARATOR$PATH) if test -z "$lt_cv_path_MAGIC_CMD"; then @@ -2102,7 +2313,7 @@ AC_CACHE_VAL(lt_cv_path_LD, if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &1 /dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | kfreebsd*-gnu | dragonfly*) +freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then case $host_cpu in i*86 ) @@ -2248,7 +2465,7 @@ gnu*) hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in + case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so @@ -2264,6 +2481,11 @@ hpux10.20* | hpux11*) esac ;; +interix[[3-9]]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so|\.a)$' + ;; + irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; @@ -2275,7 +2497,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -2309,7 +2531,7 @@ osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; -sco3.2v5*) +rdos*) lt_cv_deplibs_check_method=pass_all ;; @@ -2317,7 +2539,7 @@ solaris*) lt_cv_deplibs_check_method=pass_all ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib) M[[0-9]][[0-9]]* Version [[0-9]]' @@ -2338,10 +2560,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) siemens) lt_cv_deplibs_check_method=pass_all ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; esac ;; -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7* | sysv4*uw2*) +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac @@ -2361,36 +2586,43 @@ AC_DEFUN([AC_PROG_NM], # Let the user override the test. lt_cv_path_NM="$NM" else - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/${ac_tool_prefix}nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" break ;; *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac ;; esac - esac - fi + fi + done + IFS="$lt_save_ifs" done - IFS="$lt_save_ifs" test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi]) NM="$lt_cv_path_NM" @@ -2422,13 +2654,13 @@ esac # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl convenience library and # LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-convenience to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided, it is assumed to be `libltdl'. LIBLTDL will -# be prefixed with '${top_builddir}/' and LTDLINCL will be prefixed with -# '${top_srcdir}/' (note the single quotes!). If your package is not -# flat and you're not using automake, define top_builddir and -# top_srcdir appropriately in the Makefiles. +# --enable-ltdl-convenience to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# it is assumed to be `libltdl'. LIBLTDL will be prefixed with +# '${top_builddir}/' and LTDLINCL will be prefixed with '${top_srcdir}/' +# (note the single quotes!). If your package is not flat and you're not +# using automake, define top_builddir and top_srcdir appropriately in +# the Makefiles. AC_DEFUN([AC_LIBLTDL_CONVENIENCE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl case $enable_ltdl_convenience in @@ -2447,13 +2679,13 @@ AC_DEFUN([AC_LIBLTDL_CONVENIENCE], # ----------------------------------- # sets LIBLTDL to the link flags for the libltdl installable library and # LTDLINCL to the include flags for the libltdl header and adds -# --enable-ltdl-install to the configure arguments. Note that LIBLTDL -# and LTDLINCL are not AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If -# DIRECTORY is not provided and an installed libltdl is not found, it is -# assumed to be `libltdl'. LIBLTDL will be prefixed with '${top_builddir}/' -# and LTDLINCL will be prefixed with '${top_srcdir}/' (note the single -# quotes!). If your package is not flat and you're not using automake, -# define top_builddir and top_srcdir appropriately in the Makefiles. +# --enable-ltdl-install to the configure arguments. Note that +# AC_CONFIG_SUBDIRS is not called here. If DIRECTORY is not provided, +# and an installed libltdl is not found, it is assumed to be `libltdl'. +# LIBLTDL will be prefixed with '${top_builddir}/'# and LTDLINCL with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and top_srcdir +# appropriately in the Makefiles. # In the future, this macro may have to be called after AC_PROG_LIBTOOL. AC_DEFUN([AC_LIBLTDL_INSTALLABLE], [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl @@ -2496,7 +2728,7 @@ _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}CXX]) ])# _LT_AC_LANG_CXX # _LT_AC_PROG_CXXCPP -# --------------- +# ------------------ AC_DEFUN([_LT_AC_PROG_CXXCPP], [ AC_REQUIRE([AC_PROG_CXX]) @@ -2545,7 +2777,7 @@ _LT_AC_SHELL_INIT([tagnames=${tagnames+${tagnames},}GCJ]) # AC_LIBTOOL_RC -# -------------- +# ------------- # enable support for Windows resource files AC_DEFUN([AC_LIBTOOL_RC], [AC_REQUIRE([LT_AC_PROG_RC]) @@ -2571,10 +2803,10 @@ objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' +lt_simple_link_test_code='int main(){return(0);}' _LT_AC_SYS_COMPILER @@ -2582,37 +2814,6 @@ _LT_AC_SYS_COMPILER _LT_COMPILER_BOILERPLATE _LT_LINKER_BOILERPLATE -# -# Check for any special shared library compilation flags. -# -_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_cc_shlib, $1)='-belf' - ;; - esac -fi -if test -n "$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)"; then - AC_MSG_WARN([`$CC' requires `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to build shared libraries]) - if echo "$old_CC $old_CFLAGS " | grep "[[ ]]$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)[[ ]]" >/dev/null; then : - else - AC_MSG_WARN([add `$_LT_AC_TAGVAR(lt_prog_cc_shlib, $1)' to the CC or CFLAGS env variable and reconfigure]) - _LT_AC_TAGVAR(lt_cv_prog_cc_can_build_shared, $1)=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $_LT_AC_TAGVAR(lt_prog_compiler_static, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_static_works, $1), - $_LT_AC_TAGVAR(lt_prog_compiler_static, $1), - [], - [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) - - AC_LIBTOOL_PROG_COMPILER_NO_RTTI($1) AC_LIBTOOL_PROG_COMPILER_PIC($1) AC_LIBTOOL_PROG_CC_C_O($1) @@ -2621,9 +2822,9 @@ AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) +AC_LIBTOOL_DLOPEN_SELF -# Report which librarie types wil actually be built +# Report which library types will actually be built AC_MSG_CHECKING([if libtool supports shared libraries]) AC_MSG_RESULT([$can_build_shared]) @@ -2632,7 +2833,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -2641,7 +2842,7 @@ aix3*) fi ;; -aix4* | aix5*) +aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -2682,6 +2883,7 @@ _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)= _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= _LT_AC_TAGVAR(hardcode_minus_L, $1)=no +_LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(hardcode_automatic, $1)=no _LT_AC_TAGVAR(module_cmds, $1)= _LT_AC_TAGVAR(module_expsym_cmds, $1)= @@ -2697,19 +2899,20 @@ _LT_AC_TAGVAR(postdep_objects, $1)= _LT_AC_TAGVAR(predeps, $1)= _LT_AC_TAGVAR(postdeps, $1)= _LT_AC_TAGVAR(compiler_lib_search_path, $1)= +_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)= # Source file extension for C++ test sources. -ac_ext=cc +ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *[]) { return(0); }\n' +lt_simple_link_test_code='int main(int, char *[[]]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -2728,12 +2931,12 @@ lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else - unset lt_cv_prog_gnu_ld + $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else - unset lt_cv_path_LD + $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} @@ -2806,7 +3009,7 @@ case $host_os in # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - aix4* | aix5*) + aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -2819,7 +3022,7 @@ case $host_os in # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do case $ld_flag in *-brtl*) @@ -2828,6 +3031,7 @@ case $host_os in ;; esac done + ;; esac exp_sym_flag='-bexport' @@ -2854,7 +3058,7 @@ case $host_os in strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes + : else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported @@ -2865,6 +3069,7 @@ case $host_os in _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -2896,12 +3101,12 @@ case $host_os in _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX @@ -2910,16 +3115,26 @@ case $host_os in # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + chorus*) case $cc_basename in *) @@ -2929,7 +3144,6 @@ case $host_os in esac ;; - cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. @@ -2939,7 +3153,7 @@ case $host_os in _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -2948,65 +3162,37 @@ case $host_os in echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; darwin* | rhapsody*) - case "$host_os" in - rhapsody* | darwin1.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[[012]]) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_automatic, $1)=yes _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=unsupported _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='' _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no + _LT_AC_TAGVAR(allow_undefined_flag, $1)="$_lt_dar_allow_undefined" + if test "$GXX" = yes ; then output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -3040,7 +3226,7 @@ case $host_os in freebsd-elf*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_AC_TAGVAR(ld_shlibs, $1)=yes @@ -3085,34 +3271,21 @@ case $host_os in ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - ;; + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + case $host_cpu in + hppa*64*|ia64*) ;; *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; esac fi - case "$host_cpu" in - hppa*64*) + case $host_cpu in + hppa*64*|ia64*) _LT_AC_TAGVAR(hardcode_direct, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - ia64*) - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; *) _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes # Not in the search PATH, @@ -3127,9 +3300,12 @@ case $host_os in _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; aCC*) - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -3148,9 +3324,12 @@ case $host_os in *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -3164,6 +3343,20 @@ case $host_os in ;; esac ;; + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; irix5* | irix6*) case $cc_basename in CC*) @@ -3190,7 +3383,7 @@ case $host_os in _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath ${wl}$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -3242,14 +3435,14 @@ case $host_os in _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}--rpath ${wl}$libdir' _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}--export-dynamic' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ @@ -3270,6 +3463,29 @@ case $host_os in # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + _LT_AC_TAGVAR(old_archive_cmds, $1)='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; esac ;; lynxos*) @@ -3308,16 +3524,20 @@ case $host_os in _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no fi - output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in @@ -3446,19 +3666,6 @@ case $host_os in # FIXME: insert proper C++ library support _LT_AC_TAGVAR(ld_shlibs, $1)=no ;; - sco*) - _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - *) - # FIXME: insert proper C++ library support - _LT_AC_TAGVAR(ld_shlibs, $1)=no - ;; - esac - ;; sunos4*) case $cc_basename in CC*) @@ -3481,38 +3688,26 @@ case $host_os in case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ + _LT_AC_TAGVAR(archive_cmds_need_lc,$1)=yes _LT_AC_TAGVAR(no_undefined_flag, $1)=' -zdefs' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[[LR]]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is @@ -3554,12 +3749,69 @@ case $host_os in fi _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $wl$libdir' + case $host_os in + solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; + *) + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac fi ;; esac ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac ;; tandem*) case $cc_basename in @@ -3596,8 +3848,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) AC_LIBTOOL_CONFIG($1) @@ -3615,12 +3865,13 @@ lt_cv_prog_gnu_ld=$lt_save_with_gnu_ld ])# AC_LIBTOOL_LANG_CXX_CONFIG # AC_LIBTOOL_POSTDEP_PREDEP([TAGNAME]) -# ------------------------ +# ------------------------------------ # Figure out "hidden" library dependencies from verbose # compiler output when linking a shared library. # Parse the compiler output and extract the necessary # objects, libraries and library flags. -AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP],[ +AC_DEFUN([AC_LIBTOOL_POSTDEP_PREDEP], +[AC_REQUIRE([LT_AC_PROG_SED])dnl dnl we can't use the lt_simple_compile_test_code here, dnl because it contains code intended for an executable, dnl not a library. It's possible we should let each @@ -3669,7 +3920,7 @@ if AC_TRY_EVAL(ac_compile); then # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. - output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in @@ -3745,13 +3996,74 @@ fi $rm -f confest.$objext +_LT_AC_TAGVAR(compiler_lib_search_dirs, $1)= +if test -n "$_LT_AC_TAGVAR(compiler_lib_search_path, $1)"; then + _LT_AC_TAGVAR(compiler_lib_search_dirs, $1)=`echo " ${_LT_AC_TAGVAR(compiler_lib_search_path, $1)}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + +# PORTME: override above test on systems where it is broken +ifelse([$1],[CXX], +[case $host_os in +interix[[3-9]]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + _LT_AC_TAGVAR(predep_objects,$1)= + _LT_AC_TAGVAR(postdep_objects,$1)= + _LT_AC_TAGVAR(postdeps,$1)= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + _LT_AC_TAGVAR(postdeps,$1)='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac +]) case " $_LT_AC_TAGVAR(postdeps, $1) " in *" -lc "*) _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no ;; esac ])# AC_LIBTOOL_POSTDEP_PREDEP # AC_LIBTOOL_LANG_F77_CONFIG -# ------------------------ +# -------------------------- # Ensure that the configuration vars for the C compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. @@ -3787,10 +4099,17 @@ objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" +lt_simple_compile_test_code="\ + subroutine t + return + end +" # Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" +lt_simple_link_test_code="\ + program t + end +" # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -3814,7 +4133,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -3822,7 +4141,7 @@ aix3*) postinstall_cmds='$RANLIB $lib' fi ;; -aix4* | aix5*) +aix[[4-9]]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -3835,8 +4154,6 @@ AC_MSG_CHECKING([whether to build static libraries]) test "$enable_shared" = yes || enable_static=yes AC_MSG_RESULT([$enable_static]) -test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no - _LT_AC_TAGVAR(GCC, $1)="$G77" _LT_AC_TAGVAR(LD, $1)="$LD" @@ -3846,8 +4163,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP - AC_LIBTOOL_CONFIG($1) @@ -3873,10 +4188,10 @@ objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" +lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }\n' +lt_simple_link_test_code='public class conftest { public static void main(String[[]] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. _LT_AC_SYS_COMPILER @@ -3904,8 +4219,6 @@ AC_LIBTOOL_SYS_HARD_LINK_LOCKS($1) AC_LIBTOOL_PROG_LD_SHLIBS($1) AC_LIBTOOL_SYS_DYNAMIC_LINKER($1) AC_LIBTOOL_PROG_LD_HARDCODE_LIBPATH($1) -AC_LIBTOOL_SYS_LIB_STRIP -AC_LIBTOOL_DLOPEN_SELF($1) AC_LIBTOOL_CONFIG($1) @@ -3915,7 +4228,7 @@ CC="$lt_save_CC" # AC_LIBTOOL_LANG_RC_CONFIG -# -------------------------- +# ------------------------- # Ensure that the configuration vars for the Windows resource compiler are # suitably defined. Those variables are subsequently used by # AC_LIBTOOL_CONFIG to write the compiler configuration to `libtool'. @@ -3931,7 +4244,7 @@ objext=o _LT_AC_TAGVAR(objext, $1)=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" @@ -3978,7 +4291,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -4005,6 +4318,7 @@ if test -f "$ltmain"; then _LT_AC_TAGVAR(predeps, $1) \ _LT_AC_TAGVAR(postdeps, $1) \ _LT_AC_TAGVAR(compiler_lib_search_path, $1) \ + _LT_AC_TAGVAR(compiler_lib_search_dirs, $1) \ _LT_AC_TAGVAR(archive_cmds, $1) \ _LT_AC_TAGVAR(archive_expsym_cmds, $1) \ _LT_AC_TAGVAR(postinstall_cmds, $1) \ @@ -4020,6 +4334,7 @@ if test -f "$ltmain"; then _LT_AC_TAGVAR(module_cmds, $1) \ _LT_AC_TAGVAR(module_expsym_cmds, $1) \ _LT_AC_TAGVAR(lt_cv_prog_compiler_c_o, $1) \ + _LT_AC_TAGVAR(fix_srcfile_path, $1) \ _LT_AC_TAGVAR(exclude_expsyms, $1) \ _LT_AC_TAGVAR(include_expsyms, $1); do @@ -4066,7 +4381,7 @@ ifelse([$1], [], # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: @@ -4147,6 +4462,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_[]_LT_AC_TAGVAR(compiler, $1) @@ -4300,6 +4618,10 @@ predeps=$lt_[]_LT_AC_TAGVAR(predeps, $1) # shared library. postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1) +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_dirs, $1) + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) @@ -4388,7 +4710,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$_LT_AC_TAGVAR(fix_srcfile_path, $1)" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$_LT_AC_TAGVAR(always_export_symbols, $1) @@ -4471,6 +4793,7 @@ fi # --------------------------------- AC_DEFUN([AC_LIBTOOL_SYS_GLOBAL_SYMBOL_PIPE], [AC_REQUIRE([AC_CANONICAL_HOST]) +AC_REQUIRE([LT_AC_PROG_SED]) AC_REQUIRE([AC_PROG_NM]) AC_REQUIRE([AC_OBJEXT]) # Check for command to grab the raw symbol name followed by C symbol from nm. @@ -4507,7 +4830,7 @@ hpux*) # Its linker distinguishes data from code symbols lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([[^ ]]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([[^ ]]*\) \([[^ ]]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; -linux*) +linux* | k*bsd*-gnu) if test "$host_cpu" = ia64; then symcode='[[ABCDGIRSTW]]' lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" @@ -4520,9 +4843,18 @@ irix* | nonstopux*) osf*) symcode='[[BCDEGQRST]]' ;; -solaris* | sysv5*) +solaris*) symcode='[[BDRT]]' ;; +sco3.2v5*) + symcode='[[DT]]' + ;; +sysv4.2uw2*) + symcode='[[DT]]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[[ABDT]]' + ;; sysv4) symcode='[[DFNSTU]]' ;; @@ -4639,7 +4971,7 @@ EOF echo "$progname: failed program was:" >&AS_MESSAGE_LOG_FD cat conftest.$ac_ext >&5 fi - rm -f conftest* conftst* + rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then @@ -4688,13 +5020,16 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) # like `-m68040'. _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | os2* | pw32*) + mingw* | cygwin* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) # PIC is the default on this platform @@ -4705,6 +5040,10 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) # DJGPP does not support shared libraries at all _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; sysv4*MP*) if test -d /usr/nec; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)=-Kconform_pic @@ -4713,7 +5052,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) ;; *) @@ -4727,7 +5066,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) esac else case $host_os in - aix4* | aix5*) + aix[[4-9]]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor @@ -4767,22 +5106,22 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='+Z' fi ;; aCC*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='${wl}-a ${wl}archive' + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -4795,6 +5134,10 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) @@ -4806,7 +5149,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler @@ -4819,11 +5162,11 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler. _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; cxx*) # Compaq C++ @@ -4833,6 +5176,14 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Qoption ld ' + ;; + esac ;; esac ;; @@ -4874,15 +5225,6 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; psos*) ;; - sco*) - case $cc_basename in - CC*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' - ;; - *) - ;; - esac - ;; solaris*) case $cc_basename in CC*) @@ -4924,7 +5266,14 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) ;; esac ;; - unixware*) + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + esac ;; vxworks*) ;; @@ -4955,14 +5304,17 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; darwin* | rhapsody*) @@ -4971,6 +5323,11 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fno-common' ;; + interix[[3-9]]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -4987,7 +5344,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -5024,17 +5381,18 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) esac ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT' + m4_if([$1], [GCJ], [], + [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-DDLL_EXPORT']) ;; hpux9* | hpux10* | hpux11*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -5057,25 +5415,41 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; - pgcc* | pgf77* | pgf90*) + pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-fpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-static' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; ccc*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' # All Alpha code is PIC. _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='' + ;; + esac + ;; esac ;; @@ -5085,9 +5459,8 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; - sco3.2v5*) - _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-Kpic' - _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-dn' + rdos*) + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; solaris*) @@ -5107,7 +5480,7 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -5120,6 +5493,12 @@ AC_MSG_CHECKING([for $compiler option to produce PIC]) fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' + _LT_AC_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' + ;; + unicos*) _LT_AC_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no @@ -5143,7 +5522,7 @@ AC_MSG_RESULT([$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)]) # if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then AC_LIBTOOL_COMPILER_OPTION([if $compiler PIC flag $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) works], - _LT_AC_TAGVAR(lt_prog_compiler_pic_works, $1), + _LT_AC_TAGVAR(lt_cv_prog_compiler_pic_works, $1), [$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])], [], [case $_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) in "" | " "*) ;; @@ -5152,7 +5531,7 @@ if test -n "$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)"; then [_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= _LT_AC_TAGVAR(lt_prog_compiler_can_build_shared, $1)=no]) fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)= @@ -5161,6 +5540,16 @@ case "$host_os" in _LT_AC_TAGVAR(lt_prog_compiler_pic, $1)="$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1)ifelse([$1],[],[ -DPIC],[ifelse([$1],[CXX],[ -DPIC],[])])" ;; esac + +# +# Check to make sure the static flag actually works. +# +wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) eval lt_tmp_static_flag=\"$_LT_AC_TAGVAR(lt_prog_compiler_static, $1)\" +AC_LIBTOOL_LINKER_OPTION([if $compiler static flag $lt_tmp_static_flag works], + _LT_AC_TAGVAR(lt_cv_prog_compiler_static_works, $1), + $lt_tmp_static_flag, + [], + [_LT_AC_TAGVAR(lt_prog_compiler_static, $1)=]) ]) @@ -5168,11 +5557,12 @@ esac # ------------------------------------ # See if the linker supports building shared libraries. AC_DEFUN([AC_LIBTOOL_PROG_LD_SHLIBS], -[AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) +[AC_REQUIRE([LT_AC_PROG_SED])dnl +AC_MSG_CHECKING([whether the $compiler linker ($LD) supports shared libraries]) ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in - aix4* | aix5*) + aix[[4-9]]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then @@ -5185,12 +5575,13 @@ ifelse([$1],[CXX],[ _LT_AC_TAGVAR(export_symbols_cmds, $1)="$ltdll_cmds" ;; cygwin* | mingw*) - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([[^ ]]*\) [[^ ]]*/\1 DATA/;/^I /d;/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;/^.*[[ ]]__nm__/s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' ;; *) _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] ],[ runpath_var= _LT_AC_TAGVAR(allow_undefined_flag, $1)= @@ -5221,12 +5612,14 @@ ifelse([$1],[CXX],[ # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. - _LT_AC_TAGVAR(exclude_expsyms, $1)="_GLOBAL_OFFSET_TABLE_" + _LT_AC_TAGVAR(exclude_expsyms, $1)=['_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*'] # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. +dnl Note also adjust exclude_expsyms for C++ above. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. _LT_CC_BASENAME([$compiler]) @@ -5239,6 +5632,10 @@ ifelse([$1],[CXX],[ with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -5248,7 +5645,7 @@ ifelse([$1],[CXX],[ if test "$with_gnu_ld" = yes; then # If archive_cmds runs LD, not CC, wlarc should be empty wlarc='${wl}' - + # Set some defaults for GNU ld with shared library support. These # are reset later if shared libraries are not supported. Putting them # here allows them to be overridden if necessary. @@ -5269,10 +5666,10 @@ ifelse([$1],[CXX],[ *\ 2.11.*) ;; # other 2.11 versions *) supports_anon_versioning=yes ;; esac - + # See if GNU ld supports shared libraries. case $host_os in - aix3* | aix4* | aix5*) + aix[[3-9]]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -5320,10 +5717,10 @@ EOF _LT_AC_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_AC_TAGVAR(always_export_symbols, $1)=no _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes - _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]] /s/.* \([[^ ]]*\)/\1 DATA/'\'' | $SED -e '\''/^[[AITW]] /s/.* //'\'' | sort | uniq > $export_symbols' + _LT_AC_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/'\'' -e '\''/^[[AITW]][[ ]]/s/.*[[ ]]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... _LT_AC_TAGVAR(archive_expsym_cmds, $1)='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -5332,22 +5729,37 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; - linux*) + interix[[3-9]]*) + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; - pgf77* | pgf90* ) # Portland Group f77 and f90 compilers - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -5356,13 +5768,22 @@ EOF ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + _LT_AC_TAGVAR(archive_cmds, $1)='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else _LT_AC_TAGVAR(ld_shlibs, $1)=no @@ -5379,7 +5800,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then _LT_AC_TAGVAR(ld_shlibs, $1)=no cat <&2 @@ -5400,6 +5821,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.1[[0-5]].*) + _LT_AC_TAGVAR(ld_shlibs, $1)=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + _LT_AC_TAGVAR(ld_shlibs, $1)=no + fi + ;; + esac + ;; + sunos4*) _LT_AC_TAGVAR(archive_cmds, $1)='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -5433,14 +5881,14 @@ EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported fi ;; - aix4* | aix5*) + aix[[4-9]]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -5460,13 +5908,14 @@ EOF # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[[23]]|aix4.[[23]].*|aix5*) + case $host_os in aix4.[[23]]|aix4.[[23]].*|aix[[5-9]]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done + ;; esac exp_sym_flag='-bexport' @@ -5493,7 +5942,7 @@ EOF strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - _LT_AC_TAGVAR(hardcode_direct, $1)=yes + : else # We have old collect2 _LT_AC_TAGVAR(hardcode_direct, $1)=unsupported @@ -5504,6 +5953,7 @@ EOF _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' _LT_AC_TAGVAR(hardcode_libdir_separator, $1)= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -5516,11 +5966,11 @@ EOF # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -5534,12 +5984,12 @@ EOF # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-blibpath:$libdir:'"$aix_libpath" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-R $libdir:/usr/lib:/lib' _LT_AC_TAGVAR(allow_undefined_flag, $1)="-z nodefs" - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. _LT_AC_SYS_LIBPATH_AIX @@ -5548,13 +5998,11 @@ EOF # -berok will link without error, but may produce a broken library. _LT_AC_TAGVAR(no_undefined_flag, $1)=' ${wl}-bernotok' _LT_AC_TAGVAR(allow_undefined_flag, $1)=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - _LT_AC_TAGVAR(always_export_symbols, $1)=yes # Exported symbols can be pulled into shared objects from archives - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)=' ' + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='$convenience' _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=yes - # This is similar to how AIX traditionally builds it's shared libraries. - _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -5587,13 +6035,13 @@ EOF # The linker will automatically build a .lib file if we build a DLL. _LT_AC_TAGVAR(old_archive_From_new_cmds, $1)='true' # FIXME: Should let the user specify the lib program. - _LT_AC_TAGVAR(old_archive_cmds, $1)='lib /OUT:$oldlib$oldobjs$old_deplibs' + _LT_AC_TAGVAR(old_archive_cmds, $1)='lib -OUT:$oldlib$oldobjs$old_deplibs' _LT_AC_TAGVAR(fix_srcfile_path, $1)='`cygpath -w "$srcfile"`' _LT_AC_TAGVAR(enable_shared_with_static_runtimes, $1)=yes ;; darwin* | rhapsody*) - case "$host_os" in + case $host_os in rhapsody* | darwin1.[[012]]) _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-undefined ${wl}suppress' ;; @@ -5620,19 +6068,18 @@ EOF _LT_AC_TAGVAR(link_all_deplibs, $1)=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + _LT_AC_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + _LT_AC_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + _LT_AC_TAGVAR(archive_expsym_cmds, $1)="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + _LT_AC_TAGVAR(module_expsym_cmds, $1)="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' _LT_AC_TAGVAR(module_cmds, $1)='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' _LT_AC_TAGVAR(module_expsym_cmds, $1)='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -5672,7 +6119,7 @@ EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_AC_TAGVAR(hardcode_direct, $1)=yes @@ -5695,47 +6142,62 @@ EOF _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: + + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - ;; - ia64*) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' - _LT_AC_TAGVAR(hardcode_direct, $1)=no - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - _LT_AC_TAGVAR(hardcode_minus_L, $1)=yes + case $host_cpu in + hppa*64*|ia64*) + _LT_AC_TAGVAR(hardcode_libdir_flag_spec_ld, $1)='+b $libdir' + _LT_AC_TAGVAR(hardcode_direct, $1)=no + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; *) - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}+b ${wl}$libdir' - _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: _LT_AC_TAGVAR(hardcode_direct, $1)=yes _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' @@ -5779,24 +6241,28 @@ EOF ;; openbsd*) - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + if test -f /usr/libexec/ld.so; then + _LT_AC_TAGVAR(hardcode_direct, $1)=yes + _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-E' + else + case $host_os in + openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) + _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' + ;; + *) + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' + ;; + esac + fi else - case $host_os in - openbsd[[01]].* | openbsd2.[[0-7]] | openbsd2.[[0-7]].*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' - ;; - *) - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='${wl}-rpath,$libdir' - ;; - esac + _LT_AC_TAGVAR(ld_shlibs, $1)=no fi ;; @@ -5837,14 +6303,6 @@ EOF _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=: ;; - sco3.2v5*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' if test "$GCC" = yes; then @@ -5863,17 +6321,16 @@ EOF case $host_os in solaris2.[[0-5]] | solaris2.[[0-5]].*) ;; *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' ;; - *) - _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; + if test "$GCC" = yes; then + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + _LT_AC_TAGVAR(whole_archive_flag_spec, $1)='-z allextract$convenience -z defaultextract' + fi + ;; esac _LT_AC_TAGVAR(link_all_deplibs, $1)=yes ;; @@ -5930,36 +6387,45 @@ EOF fi ;; - sysv4.2uw2*) - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(hardcode_direct, $1)=yes - _LT_AC_TAGVAR(hardcode_minus_L, $1)=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[[01]].[[10]]* | unixware7* | sco3.2v5.0.[[024]]*) + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[[78]]* | unixware7*) - _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z ${wl}text' if test "$GCC" = yes; then - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no ;; - sysv5*) - _LT_AC_TAGVAR(no_undefined_flag, $1)=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - _LT_AC_TAGVAR(archive_cmds, $1)='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + _LT_AC_TAGVAR(no_undefined_flag, $1)='${wl}-z,text' + _LT_AC_TAGVAR(allow_undefined_flag, $1)='${wl}-z,nodefs' + _LT_AC_TAGVAR(archive_cmds_need_lc, $1)=no _LT_AC_TAGVAR(hardcode_shlibpath_var, $1)=no + _LT_AC_TAGVAR(hardcode_libdir_flag_spec, $1)='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + _LT_AC_TAGVAR(hardcode_libdir_separator, $1)=':' + _LT_AC_TAGVAR(link_all_deplibs, $1)=yes + _LT_AC_TAGVAR(export_dynamic_flag_spec, $1)='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + _LT_AC_TAGVAR(archive_cmds, $1)='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + _LT_AC_TAGVAR(archive_expsym_cmds, $1)='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -5977,11 +6443,6 @@ EOF AC_MSG_RESULT([$_LT_AC_TAGVAR(ld_shlibs, $1)]) test "$_LT_AC_TAGVAR(ld_shlibs, $1)" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -6001,7 +6462,7 @@ x|xyes) # to ld, don't add -lc before -lgcc. AC_MSG_CHECKING([whether -lc should be explicitly linked in]) $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext if AC_TRY_EVAL(ac_compile) 2>conftest.err; then soname=conftest @@ -6009,6 +6470,7 @@ x|xyes) libobjs=conftest.$ac_objext deplibs= wl=$_LT_AC_TAGVAR(lt_prog_compiler_wl, $1) + pic_flag=$_LT_AC_TAGVAR(lt_prog_compiler_pic, $1) compiler_flags=-v linker_flags=-v verstring= @@ -6103,6 +6565,30 @@ AC_DEFUN([LT_AC_PROG_RC], [AC_CHECK_TOOL(RC, windres, no) ]) + +# Cheap backport of AS_EXECUTABLE_P and required macros +# from Autoconf 2.59; we should not use $as_executable_p directly. + +# _AS_TEST_PREPARE +# ---------------- +m4_ifndef([_AS_TEST_PREPARE], +[m4_defun([_AS_TEST_PREPARE], +[if test -x / >/dev/null 2>&1; then + as_executable_p='test -x' +else + as_executable_p='test -f' +fi +])])# _AS_TEST_PREPARE + +# AS_EXECUTABLE_P +# --------------- +# Check whether a file is executable. +m4_ifndef([AS_EXECUTABLE_P], +[m4_defun([AS_EXECUTABLE_P], +[AS_REQUIRE([_AS_TEST_PREPARE])dnl +$as_executable_p $1[]dnl +])])# AS_EXECUTABLE_P + # NOTE: This macro has been submitted for inclusion into # # GNU Autoconf as AC_PROG_SED. When it is available in # # a released version of Autoconf we should remove this # @@ -6123,12 +6609,13 @@ do test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + if AS_EXECUTABLE_P(["$as_dir/$lt_ac_prog$ac_exec_ext"]); then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done +IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris @@ -6161,6 +6648,7 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do done ]) SED=$lt_cv_path_SED +AC_SUBST([SED]) AC_MSG_RESULT([$SED]) ]) diff --git a/apprentice.c b/apprentice.c index 39d30caf559b..bbadc0c25b47 100644 --- a/apprentice.c +++ b/apprentice.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apprentice.c,v 1.147 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: apprentice.c,v 1.151 2009/03/18 15:19:23 christos Exp $") #endif /* lint */ #include "magic.h" @@ -89,8 +89,8 @@ const size_t file_nnames = FILE_NAMES_SIZE; private int getvalue(struct magic_set *ms, struct magic *, const char **, int); private int hextoint(int); -private const char *getstr(struct magic_set *, const char *, char *, int, - int *, int); +private const char *getstr(struct magic_set *, struct magic *, const char *, + int); private int parse(struct magic_set *, struct magic_entry **, uint32_t *, const char *, size_t, int); private void eatsize(const char **); @@ -324,11 +324,15 @@ file_delmagic(struct magic *p, int type, size_t entries) if (p == NULL) return; switch (type) { -#ifdef QUICK case 2: +#ifdef QUICK p--; (void)munmap((void *)p, sizeof(*p) * (entries + 1)); break; +#else + (void)&entries; + abort(); + /*NOTREACHED*/ #endif case 1: p--; @@ -1712,8 +1716,7 @@ check_format(struct magic_set *ms, struct magic *m) * string is not one character long */ file_magwarn(ms, "Printf format `%c' is not valid for type " - "`%s' in description `%s'", - ptr && *ptr ? *ptr : '?', + "`%s' in description `%s'", *ptr ? *ptr : '?', file_names[m->type], m->desc); return -1; } @@ -1738,8 +1741,6 @@ check_format(struct magic_set *ms, struct magic *m) private int getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) { - int slen; - switch (m->type) { case FILE_BESTRING16: case FILE_LESTRING16: @@ -1747,16 +1748,13 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) case FILE_PSTRING: case FILE_REGEX: case FILE_SEARCH: - *p = getstr(ms, *p, m->value.s, sizeof(m->value.s), &slen, action); + *p = getstr(ms, m, *p, action == FILE_COMPILE); if (*p == NULL) { if (ms->flags & MAGIC_CHECK) file_magwarn(ms, "cannot get string from `%s'", m->value.s); return -1; } - m->vallen = slen; - if (m->type == FILE_PSTRING) - m->vallen++; return 0; case FILE_FLOAT: case FILE_BEFLOAT: @@ -1795,13 +1793,15 @@ getvalue(struct magic_set *ms, struct magic *m, const char **p, int action) /* * Convert a string containing C character escapes. Stop at an unescaped * space or tab. - * Copy the converted version to "p", returning its length in *slen. - * Return updated scan pointer as function result. + * Copy the converted version to "m->value.s", and the length in m->vallen. + * Return updated scan pointer as function result. Warn if set. */ private const char * -getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int action) +getstr(struct magic_set *ms, struct magic *m, const char *s, int warn) { const char *origs = s; + char *p = m->value.s; + size_t plen = sizeof(m->value.s); char *origp = p; char *pmax = p + plen - 1; int c; @@ -1818,25 +1818,33 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac switch(c = *s++) { case '\0': - if (action == FILE_COMPILE) + if (warn) file_magwarn(ms, "incomplete escape"); goto out; case '\t': - if (action == FILE_COMPILE) { + if (warn) { file_magwarn(ms, "escaped tab found, use \\t instead"); - action++; + warn = 0; /* already did */ } /*FALLTHROUGH*/ default: - if (action == FILE_COMPILE) { - if (isprint((unsigned char)c)) - file_magwarn(ms, - "no need to escape `%c'", c); - else - file_magwarn(ms, - "unknown escape sequence: \\%03o", c); + if (warn) { + if (isprint((unsigned char)c)) { + /* Allow escaping of + * ``relations'' */ + if (strchr("<>&^=!", c) + == NULL) { + file_magwarn(ms, "no " + "need to escape " + "`%c'", c); + } + } else { + file_magwarn(ms, + "unknown escape sequence: " + "\\%03o", c); + } } /*FALLTHROUGH*/ /* space, perhaps force people to use \040? */ @@ -1935,7 +1943,9 @@ getstr(struct magic_set *ms, const char *s, char *p, int plen, int *slen, int ac } out: *p = '\0'; - *slen = p - origp; + m->vallen = p - origp; + if (m->type == FILE_PSTRING) + m->vallen++; return s; } @@ -2084,7 +2094,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, file_oomem(ms, (size_t)st.st_size); goto error1; } - if (read(fd, mm, (size_t)st.st_size) != (size_t)st.st_size) { + if (read(fd, mm, (size_t)st.st_size) != (ssize_t)st.st_size) { file_badread(ms); goto error1; } @@ -2107,7 +2117,7 @@ apprentice_map(struct magic_set *ms, struct magic **magicp, uint32_t *nmagicp, else version = ptr[1]; if (version != VERSIONNO) { - file_error(ms, 0, "File %d.%d supports only %d version magic " + file_error(ms, 0, "File %d.%d supports only version %d magic " "files. `%s' is version %d", FILE_VERSION_MAJOR, patchlevel, VERSIONNO, dbname, version); goto error1; diff --git a/apptype.c b/apptype.c index 6f171ad1e0a4..31b8095e13ba 100644 --- a/apptype.c +++ b/apptype.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: apptype.c,v 1.10 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: apptype.c,v 1.11 2009/02/04 18:24:32 christos Exp $") #endif /* lint */ #include @@ -76,7 +76,7 @@ file_os2_apptype(struct magic_set *ms, const char *fn, const void *buf, } (void)fclose(fp); } - rc = DosQueryAppType(path, &type); + rc = DosQueryAppType((unsigned char *)path, &type); if (fn == NULL) { unlink(path); diff --git a/cdf.c b/cdf.c index 0c66d11bdb12..fd13bc00e993 100644 --- a/cdf.c +++ b/cdf.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: cdf.c,v 1.30 2009/05/06 14:29:47 christos Exp $") #endif #include @@ -56,7 +56,7 @@ FILE_RCSID("@(#)$File: cdf.c,v 1.17 2009/02/03 20:27:51 christos Exp $") #endif #ifdef CDF_DEBUG -#define DPRINTF(a) printf a +#define DPRINTF(a) printf a, fflush(stdout) #else #define DPRINTF(a) #endif @@ -227,34 +227,85 @@ cdf_unpack_dir(cdf_directory_t *d, char *buf) CDF_UNPACK(d->d_unused0); } -int -cdf_read_header(int fd, cdf_header_t *h) +static int +cdf_check_stream_offset(const cdf_stream_t *sst, const void *p, size_t tail) { - (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); - char buf[512]; - if (lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) + const char *b = (const char *)sst->sst_tab; + const char *e = ((const char *)p) + tail; + if (e >= b && (size_t)(e - b) < sst->sst_dirlen * sst->sst_len) + return 0; + DPRINTF((stderr, "offset begin %p end %p %zu >= %zu\n", b, e, + (size_t)(e - b), sst->sst_dirlen * sst->sst_len)); + errno = EFTYPE; + return -1; +} + +static ssize_t +cdf_read(const cdf_info_t *info, off_t off, void *buf, size_t len) +{ + size_t siz = (size_t)off + len; + + if ((off_t)(off + len) != (off_t)siz) { + errno = EINVAL; return -1; - if (read(fd, buf, sizeof(buf)) != sizeof(buf)) + } + + if (info->i_buf != NULL && info->i_len >= siz) { + (void)memcpy(buf, &info->i_buf[off], len); + return (ssize_t)len; + } + + if (info->i_fd == -1) + return -1; + + if (lseek(info->i_fd, off, SEEK_SET) == (off_t)-1) + return -1; + + if (read(info->i_fd, buf, len) != (ssize_t)len) + return -1; + + return (ssize_t)len; +} + +int +cdf_read_header(const cdf_info_t *info, cdf_header_t *h) +{ + char buf[512]; + + (void)memcpy(cdf_bo.s, "\01\02\03\04", 4); + if (cdf_read(info, (off_t)0, buf, sizeof(buf)) == -1) return -1; cdf_unpack_header(h, buf); cdf_swap_header(h); if (h->h_magic != CDF_MAGIC) { - DPRINTF(("Bad magic 0x%x != 0x$x\n", h->h_magic, CDF_MAGIC)); - errno = EFTYPE; - return -1; + DPRINTF(("Bad magic 0x%llx != 0x%llx\n", + (unsigned long long)h->h_magic, + (unsigned long long)CDF_MAGIC)); + goto out; + } + if (h->h_sec_size_p2 > 20) { + DPRINTF(("Bad sector size 0x%u\n", h->h_sec_size_p2)); + goto out; + } + if (h->h_short_sec_size_p2 > 20) { + DPRINTF(("Bad short sector size 0x%u\n", + h->h_short_sec_size_p2)); + goto out; } return 0; +out: + errno = EFTYPE; + return -1; } ssize_t -cdf_read_sector(int fd, void *buf, size_t offs, size_t len, +cdf_read_sector(const cdf_info_t *info, void *buf, size_t offs, size_t len, const cdf_header_t *h, cdf_secid_t id) { assert((size_t)CDF_SEC_SIZE(h) == len); - if (lseek(fd, (off_t)CDF_SEC_POS(h, id), SEEK_SET) == (off_t)-1) - return -1; - return read(fd, ((char *)buf) + offs, len); + return cdf_read(info, (off_t)CDF_SEC_POS(h, id), + ((char *)buf) + offs, len); } ssize_t @@ -271,24 +322,35 @@ cdf_read_short_sector(const cdf_stream_t *sst, void *buf, size_t offs, * Read the sector allocation table. */ int -cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat) +cdf_read_sat(const cdf_info_t *info, cdf_header_t *h, cdf_sat_t *sat) { size_t i, j, k; size_t ss = CDF_SEC_SIZE(h); - cdf_secid_t *msa, mid; + cdf_secid_t *msa, mid, sec; + size_t nsatpersec = (ss / sizeof(mid)) - 1; for (i = 0; i < __arraycount(h->h_master_sat); i++) if (h->h_master_sat[i] == CDF_SECID_FREE) break; - sat->sat_len = (h->h_num_sectors_in_master_sat + i); +#define CDF_SEC_LIMIT (UINT32_MAX / (4 * ss)) + if (h->h_num_sectors_in_master_sat > CDF_SEC_LIMIT / nsatpersec || + i > CDF_SEC_LIMIT) { + DPRINTF(("Number of sectors in master SAT too big %u %zu\n", + h->h_num_sectors_in_master_sat, i)); + errno = EFTYPE; + return -1; + } + + sat->sat_len = h->h_num_sectors_in_master_sat * nsatpersec + i; + DPRINTF(("sat_len = %zu ss = %zu\n", sat->sat_len, ss)); if ((sat->sat_tab = calloc(sat->sat_len, ss)) == NULL) return -1; for (i = 0; i < __arraycount(h->h_master_sat); i++) { if (h->h_master_sat[i] < 0) break; - if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h, + if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, h->h_master_sat[i]) != (ssize_t)ss) { DPRINTF(("Reading sector %d", h->h_master_sat[i])); goto out1; @@ -300,24 +362,38 @@ cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat) mid = h->h_secid_first_sector_in_master_sat; for (j = 0; j < h->h_num_sectors_in_master_sat; j++) { + if (mid < 0) + goto out; if (j >= CDF_LOOP_LIMIT) { DPRINTF(("Reading master sector loop limit")); errno = EFTYPE; goto out2; } - if (cdf_read_sector(fd, msa, 0, ss, h, mid) != (ssize_t)ss) { + if (cdf_read_sector(info, msa, 0, ss, h, mid) != (ssize_t)ss) { DPRINTF(("Reading master sector %d", mid)); goto out2; } - for (k = 0; k < (ss / sizeof(mid)) - 1; k++, i++) - if (cdf_read_sector(fd, sat->sat_tab, ss * i, ss, h, - CDF_TOLE4(msa[k])) != (ssize_t)ss) { + for (k = 0; k < nsatpersec; k++, i++) { + sec = CDF_TOLE4(msa[k]); + if (sec < 0) + goto out; + if (i >= sat->sat_len) { + DPRINTF(("Out of bounds reading MSA %u >= %u", + i, sat->sat_len)); + errno = EFTYPE; + goto out2; + } + if (cdf_read_sector(info, sat->sat_tab, ss * i, ss, h, + sec) != (ssize_t)ss) { DPRINTF(("Reading sector %d", CDF_TOLE4(msa[k]))); goto out2; } - mid = CDF_TOLE4(msa[(ss / sizeof(mid)) - 1]); + } + mid = CDF_TOLE4(msa[nsatpersec]); } +out: + sat->sat_len = i; free(msa); return 0; out2: @@ -328,11 +404,10 @@ cdf_read_sat(int fd, cdf_header_t *h, cdf_sat_t *sat) } size_t -cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat, - cdf_secid_t sid) +cdf_count_chain(const cdf_sat_t *sat, cdf_secid_t sid, size_t size) { - size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t); - cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * s); + size_t i, j; + cdf_secid_t maxsector = (cdf_secid_t)(sat->sat_len * size); DPRINTF(("Chain:")); for (j = i = 0; sid >= 0; i++, j++) { @@ -354,12 +429,12 @@ cdf_count_chain(const cdf_header_t *h, const cdf_sat_t *sat, } int -cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - cdf_secid_t sid, size_t len, cdf_stream_t *scn) +cdf_read_long_sector_chain(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, cdf_secid_t sid, size_t len, cdf_stream_t *scn) { size_t ss = CDF_SEC_SIZE(h), i, j; ssize_t nr; - scn->sst_len = cdf_count_chain(h, sat, sid); + scn->sst_len = cdf_count_chain(sat, sid, ss); scn->sst_dirlen = len; if (scn->sst_len == (size_t)-1) @@ -370,7 +445,18 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, return -1; for (j = i = 0; sid >= 0; i++, j++) { - if ((nr = cdf_read_sector(fd, scn->sst_tab, i * ss, ss, h, + if (j >= CDF_LOOP_LIMIT) { + DPRINTF(("Read long sector chain loop limit")); + errno = EFTYPE; + goto out; + } + if (i >= scn->sst_len) { + DPRINTF(("Out of bounds reading long sector chain " + "%u > %u\n", i, scn->sst_len)); + errno = EFTYPE; + goto out; + } + if ((nr = cdf_read_sector(info, scn->sst_tab, i * ss, ss, h, sid)) != (ssize_t)ss) { if (i == scn->sst_len - 1 && nr > 0) { /* Last sector might be truncated */ @@ -380,16 +466,11 @@ cdf_read_long_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, goto out; } sid = CDF_TOLE4(sat->sat_tab[sid]); - if (j >= CDF_LOOP_LIMIT) { - DPRINTF(("Read long sector chain loop limit")); - errno = EFTYPE; - goto out; - } } return 0; out: free(scn->sst_tab); - return (size_t)-1; + return -1; } int @@ -398,10 +479,10 @@ cdf_read_short_sector_chain(const cdf_header_t *h, cdf_secid_t sid, size_t len, cdf_stream_t *scn) { size_t ss = CDF_SHORT_SEC_SIZE(h), i, j; - scn->sst_len = cdf_count_chain(h, ssat, sid); + scn->sst_len = cdf_count_chain(ssat, sid, CDF_SEC_SIZE(h)); scn->sst_dirlen = len; - if (scn->sst_len == (size_t)-1) + if (sst->sst_tab == NULL || scn->sst_len == (size_t)-1) return -1; scn->sst_tab = calloc(scn->sst_len, ss); @@ -414,6 +495,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h, errno = EFTYPE; goto out; } + if (i >= scn->sst_len) { + DPRINTF(("Out of bounds reading short sector chain " + "%u > %u\n", i, scn->sst_len)); + errno = EFTYPE; + goto out; + } if (cdf_read_short_sector(sst, scn->sst_tab, i * ss, ss, h, sid) != (ssize_t)ss) { DPRINTF(("Reading short sector chain %d", sid)); @@ -424,12 +511,12 @@ cdf_read_short_sector_chain(const cdf_header_t *h, return 0; out: free(scn->sst_tab); - return (size_t)-1; + return -1; } int -cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - const cdf_sat_t *ssat, const cdf_stream_t *sst, +cdf_read_sector_chain(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, cdf_secid_t sid, size_t len, cdf_stream_t *scn) { @@ -437,19 +524,19 @@ cdf_read_sector_chain(int fd, const cdf_header_t *h, const cdf_sat_t *sat, return cdf_read_short_sector_chain(h, ssat, sst, sid, len, scn); else - return cdf_read_long_sector_chain(fd, h, sat, sid, len, scn); + return cdf_read_long_sector_chain(info, h, sat, sid, len, scn); } int -cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - cdf_dir_t *dir) +cdf_read_dir(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, cdf_dir_t *dir) { size_t i, j; size_t ss = CDF_SEC_SIZE(h), ns, nd; char *buf; cdf_secid_t sid = h->h_secid_first_directory; - ns = cdf_count_chain(h, sat, sid); + ns = cdf_count_chain(sat, sid, ss); if (ns == (size_t)-1) return -1; @@ -471,7 +558,7 @@ cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, errno = EFTYPE; goto out; } - if (cdf_read_sector(fd, buf, 0, ss, h, sid) != (ssize_t)ss) { + if (cdf_read_sector(info, buf, 0, ss, h, sid) != (ssize_t)ss) { DPRINTF(("Reading directory sector %d", sid)); goto out; } @@ -494,14 +581,14 @@ cdf_read_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, int -cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - cdf_sat_t *ssat) +cdf_read_ssat(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, cdf_sat_t *ssat) { size_t i, j; size_t ss = CDF_SEC_SIZE(h); cdf_secid_t sid = h->h_secid_first_sector_in_short_sat; - ssat->sat_len = cdf_count_chain(h, sat, sid); + ssat->sat_len = cdf_count_chain(sat, sid, CDF_SEC_SIZE(h)); if (ssat->sat_len == (size_t)-1) return -1; @@ -515,7 +602,13 @@ cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat, errno = EFTYPE; goto out; } - if (cdf_read_sector(fd, ssat->sat_tab, i * ss, ss, h, sid) != + if (i >= ssat->sat_len) { + DPRINTF(("Out of bounds reading short sector chain " + "%u > %u\n", i, ssat->sat_len)); + errno = EFTYPE; + goto out; + } + if (cdf_read_sector(info, ssat->sat_tab, i * ss, ss, h, sid) != (ssize_t)ss) { DPRINTF(("Reading short sat sector %d", sid)); goto out; @@ -529,8 +622,8 @@ cdf_read_ssat(int fd, const cdf_header_t *h, const cdf_sat_t *sat, } int -cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - const cdf_dir_t *dir, cdf_stream_t *scn) +cdf_read_short_stream(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, const cdf_dir_t *dir, cdf_stream_t *scn) { size_t i; const cdf_directory_t *d; @@ -539,22 +632,22 @@ cdf_read_short_stream(int fd, const cdf_header_t *h, const cdf_sat_t *sat, if (dir->dir_tab[i].d_type == CDF_DIR_TYPE_ROOT_STORAGE) break; - if (i == dir->dir_len) { - DPRINTF(("Cannot find root storage node\n")); - errno = EFTYPE; - return -1; - } + /* If the it is not there, just fake it; some docs don't have it */ + if (i == dir->dir_len) + goto out; d = &dir->dir_tab[i]; /* If the it is not there, just fake it; some docs don't have it */ - if (d->d_stream_first_sector < 0) { - scn->sst_tab = NULL; - scn->sst_len = 0; - return 0; - } + if (d->d_stream_first_sector < 0) + goto out; - return cdf_read_long_sector_chain(fd, h, sat, + return cdf_read_long_sector_chain(info, h, sat, d->d_stream_first_sector, d->d_size, scn); +out: + scn->sst_tab = NULL; + scn->sst_len = 0; + scn->sst_dirlen = 0; + return 0; } static int @@ -567,7 +660,7 @@ cdf_namecmp(const char *d, const uint16_t *s, size_t l) } int -cdf_read_summary_info(int fd, const cdf_header_t *h, +cdf_read_summary_info(const cdf_info_t *info, const cdf_header_t *h, const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, const cdf_dir_t *dir, cdf_stream_t *scn) { @@ -587,7 +680,7 @@ cdf_read_summary_info(int fd, const cdf_header_t *h, return -1; } d = &dir->dir_tab[i]; - return cdf_read_sector_chain(fd, h, sat, ssat, sst, + return cdf_read_sector_chain(info, h, sat, ssat, sst, d->d_stream_first_sector, d->d_size, scn); } @@ -607,12 +700,28 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, size_t i, o, nelements, j; cdf_property_info_t *inp; + if (offs > UINT32_MAX / 4) { + errno = EFTYPE; + goto out; + } shp = (const void *)((const char *)sst->sst_tab + offs); + if (cdf_check_stream_offset(sst, shp, sizeof(*shp)) == -1) + goto out; sh.sh_len = CDF_TOLE4(shp->sh_len); +#define CDF_SHLEN_LIMIT (UINT32_MAX / 8) + if (sh.sh_len > CDF_SHLEN_LIMIT) { + errno = EFTYPE; + goto out; + } sh.sh_properties = CDF_TOLE4(shp->sh_properties); - DPRINTF(("section len: %d properties %d\n", sh.sh_len, +#define CDF_PROP_LIMIT (UINT32_MAX / (4 * sizeof(*inp))) + if (sh.sh_properties > CDF_PROP_LIMIT) + goto out; + DPRINTF(("section len: %u properties %u\n", sh.sh_len, sh.sh_properties)); if (*maxcount) { + if (*maxcount > CDF_PROP_LIMIT) + goto out; *maxcount += sh.sh_properties; inp = realloc(*info, *maxcount * sizeof(*inp)); } else { @@ -626,6 +735,8 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, *count += sh.sh_properties; p = (const void *)((const char *)sst->sst_tab + offs + sizeof(sh)); e = (const void *)(((const char *)shp) + sh.sh_len); + if (cdf_check_stream_offset(sst, e, 0) == -1) + goto out; for (i = 0; i < sh.sh_properties; i++) { q = (const uint32_t *)((const char *)p + CDF_TOLE4(p[(i << 1) + 1])) - 2; @@ -683,6 +794,9 @@ cdf_read_property_info(const cdf_stream_t *sst, uint32_t offs, case CDF_LENGTH32_STRING: if (nelements > 1) { size_t nelem = inp - *info; + if (*maxcount > CDF_PROP_LIMIT + || nelements > CDF_PROP_LIMIT) + goto out; *maxcount += nelements; inp = realloc(*info, *maxcount * sizeof(*inp)); if (inp == NULL) @@ -735,6 +849,9 @@ cdf_unpack_summary_info(const cdf_stream_t *sst, cdf_summary_info_header_t *ssi, const cdf_section_declaration_t *sd = (const void *) ((const char *)sst->sst_tab + CDF_SECTION_DECLARATION_OFFSET); + if (cdf_check_stream_offset(sst, si, sizeof(*si)) == -1 || + cdf_check_stream_offset(sst, sd, sizeof(*sd)) == -1) + return -1; ssi->si_byte_order = CDF_TOLE2(si->si_byte_order); ssi->si_os_version = CDF_TOLE2(si->si_os_version); ssi->si_os = CDF_TOLE2(si->si_os); @@ -848,12 +965,14 @@ cdf_dump_header(const cdf_header_t *h) { size_t i; -#define DUMP(a, b) printf("%40.40s = " a "\n", # b, h->h_ ## b) +#define DUMP(a, b) (void)fprintf(stderr, "%40.40s = " a "\n", # b, h->h_ ## b) +#define DUMP2(a, b) (void)fprintf(stderr, "%40.40s = " a " (" a ")\n", # b, \ + h->h_ ## b, 1 << h->h_ ## b) DUMP("%d", revision); DUMP("%d", version); DUMP("0x%x", byte_order); - DUMP("%d", sec_size_p2); - DUMP("%d", short_sec_size_p2); + DUMP2("%d", sec_size_p2); + DUMP2("%d", short_sec_size_p2); DUMP("%d", num_sectors_in_sat); DUMP("%d", secid_first_directory); DUMP("%d", min_size_standard_stream); @@ -864,24 +983,26 @@ cdf_dump_header(const cdf_header_t *h) for (i = 0; i < __arraycount(h->h_master_sat); i++) { if (h->h_master_sat[i] == CDF_SECID_FREE) break; - printf("%35.35s[%.3zu] = %d\n", + (void)fprintf(stderr, "%35.35s[%.3zu] = %d\n", "master_sat", i, h->h_master_sat[i]); } } void -cdf_dump_sat(const char *prefix, const cdf_header_t *h, const cdf_sat_t *sat) +cdf_dump_sat(const char *prefix, const cdf_sat_t *sat, size_t size) { - size_t i, j, s = CDF_SEC_SIZE(h) / sizeof(cdf_secid_t); + size_t i, j, s = size / sizeof(cdf_secid_t); for (i = 0; i < sat->sat_len; i++) { - printf("%s[%zu]:\n", prefix, i); + (void)fprintf(stderr, "%s[%zu]:\n%.6d: ", prefix, i, i * s); for (j = 0; j < s; j++) { - printf("%5d, ", CDF_TOLE4(sat->sat_tab[s * i + j])); + (void)fprintf(stderr, "%5d, ", + CDF_TOLE4(sat->sat_tab[s * i + j])); if ((j + 1) % 10 == 0) - printf("\n"); + (void)fprintf(stderr, "\n%.6d: ", + i * s + j + 1); } - printf("\n"); + (void)fprintf(stderr, "\n"); } } @@ -891,17 +1012,17 @@ cdf_dump(void *v, size_t len) size_t i, j; unsigned char *p = v; char abuf[16]; - printf("%.4x: ", 0); + (void)fprintf(stderr, "%.4x: ", 0); for (i = 0, j = 0; i < len; i++, p++) { - printf("%.2x ", *p); + (void)fprintf(stderr, "%.2x ", *p); abuf[j++] = isprint(*p) ? *p : '.'; if (j == 16) { j = 0; abuf[15] = '\0'; - printf("%s\n%.4x: ", abuf, i + 1); + (void)fprintf(stderr, "%s\n%.4x: ", abuf, i + 1); } } - printf("\n"); + (void)fprintf(stderr, "\n"); } void @@ -913,8 +1034,8 @@ cdf_dump_stream(const cdf_header_t *h, const cdf_stream_t *sst) } void -cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, - const cdf_sat_t *ssat, const cdf_stream_t *sst, +cdf_dump_dir(const cdf_info_t *info, const cdf_header_t *h, + const cdf_sat_t *sat, const cdf_sat_t *ssat, const cdf_stream_t *sst, const cdf_dir_t *dir) { size_t i, j; @@ -930,29 +1051,30 @@ cdf_dump_dir(int fd, const cdf_header_t *h, const cdf_sat_t *sat, d = &dir->dir_tab[i]; for (j = 0; j < sizeof(name); j++) name[j] = (char)CDF_TOLE2(d->d_name[j]); - printf("Directory %zu: %s\n", i, name); + (void)fprintf(stderr, "Directory %zu: %s\n", i, name); if (d->d_type < __arraycount(types)) - printf("Type: %s\n", types[d->d_type]); + (void)fprintf(stderr, "Type: %s\n", types[d->d_type]); else - printf("Type: %d\n", d->d_type); - printf("Color: %s\n", d->d_color ? "black" : "red"); - printf("Left child: %d\n", d->d_left_child); - printf("Right child: %d\n", d->d_right_child); - printf("Flags: 0x%x\n", d->d_flags); + (void)fprintf(stderr, "Type: %d\n", d->d_type); + (void)fprintf(stderr, "Color: %s\n", + d->d_color ? "black" : "red"); + (void)fprintf(stderr, "Left child: %d\n", d->d_left_child); + (void)fprintf(stderr, "Right child: %d\n", d->d_right_child); + (void)fprintf(stderr, "Flags: 0x%x\n", d->d_flags); cdf_timestamp_to_timespec(&ts, d->d_created); - printf("Created %s", ctime(&ts.tv_sec)); + (void)fprintf(stderr, "Created %s", ctime(&ts.tv_sec)); cdf_timestamp_to_timespec(&ts, d->d_modified); - printf("Modified %s", ctime(&ts.tv_sec)); - printf("Stream %d\n", d->d_stream_first_sector); - printf("Size %d\n", d->d_size); + (void)fprintf(stderr, "Modified %s", ctime(&ts.tv_sec)); + (void)fprintf(stderr, "Stream %d\n", d->d_stream_first_sector); + (void)fprintf(stderr, "Size %d\n", d->d_size); switch (d->d_type) { case CDF_DIR_TYPE_USER_STORAGE: - printf("Storage: %d\n", d->d_storage); + (void)fprintf(stderr, "Storage: %d\n", d->d_storage); break; case CDF_DIR_TYPE_USER_STREAM: if (sst == NULL) break; - if (cdf_read_sector_chain(fd, h, sat, ssat, sst, + if (cdf_read_sector_chain(info, h, sat, ssat, sst, d->d_stream_first_sector, d->d_size, &scn) == -1) { warn("Can't read stream for %s at %d len %d", name, d->d_stream_first_sector, d->d_size); @@ -978,33 +1100,38 @@ cdf_dump_property_info(const cdf_property_info_t *info, size_t count) for (i = 0; i < count; i++) { cdf_print_property_name(buf, sizeof(buf), info[i].pi_id); - printf("%zu) %s: ", i, buf); + (void)fprintf(stderr, "%zu) %s: ", i, buf); switch (info[i].pi_type) { case CDF_SIGNED16: - printf("signed 16 [%hd]\n", info[i].pi_s16); + (void)fprintf(stderr, "signed 16 [%hd]\n", + info[i].pi_s16); break; case CDF_SIGNED32: - printf("signed 32 [%d]\n", info[i].pi_s32); + (void)fprintf(stderr, "signed 32 [%d]\n", + info[i].pi_s32); break; case CDF_UNSIGNED32: - printf("unsigned 32 [%u]\n", info[i].pi_u32); + (void)fprintf(stderr, "unsigned 32 [%u]\n", + info[i].pi_u32); break; case CDF_LENGTH32_STRING: - printf("string %u [%.*s]\n", info[i].pi_str.s_len, + (void)fprintf(stderr, "string %u [%.*s]\n", + info[i].pi_str.s_len, info[i].pi_str.s_len, info[i].pi_str.s_buf); break; case CDF_FILETIME: tp = info[i].pi_tp; if (tp < 1000000000000000LL) { cdf_print_elapsed_time(buf, sizeof(buf), tp); - printf("timestamp %s\n", buf); + (void)fprintf(stderr, "timestamp %s\n", buf); } else { cdf_timestamp_to_timespec(&ts, tp); - printf("timestamp %s", ctime(&ts.tv_sec)); + (void)fprintf(stderr, "timestamp %s", + ctime(&ts.tv_sec)); } break; case CDF_CLIPBOARD: - printf("CLIPBOARD %u\n", info[i].pi_u32); + (void)fprintf(stderr, "CLIPBOARD %u\n", info[i].pi_u32); break; default: DPRINTF(("Don't know how to deal with %x\n", @@ -1026,13 +1153,13 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst) (void)&h; if (cdf_unpack_summary_info(sst, &ssi, &info, &count) == -1) return; - printf("Endian: %x\n", ssi.si_byte_order); - printf("Os Version %d.%d\n", ssi.si_os_version & 0xff, + (void)fprintf(stderr, "Endian: %x\n", ssi.si_byte_order); + (void)fprintf(stderr, "Os Version %d.%d\n", ssi.si_os_version & 0xff, ssi.si_os_version >> 8); - printf("Os %d\n", ssi.si_os); + (void)fprintf(stderr, "Os %d\n", ssi.si_os); cdf_print_classid(buf, sizeof(buf), &ssi.si_class); - printf("Class %s\n", buf); - printf("Count %d\n", ssi.si_count); + (void)fprintf(stderr, "Class %s\n", buf); + (void)fprintf(stderr, "Count %d\n", ssi.si_count); cdf_dump_property_info(info, count); free(info); } @@ -1043,61 +1170,64 @@ cdf_dump_summary_info(const cdf_header_t *h, const cdf_stream_t *sst) int main(int argc, char *argv[]) { - int fd, i; + int i; cdf_header_t h; cdf_sat_t sat, ssat; cdf_stream_t sst, scn; cdf_dir_t dir; + cdf_info_t info; if (argc < 2) { (void)fprintf(stderr, "Usage: %s \n", getprogname()); return -1; } + info.i_buf = NULL; + info.i_len = 0; for (i = 1; i < argc; i++) { - if ((fd = open(argv[1], O_RDONLY)) == -1) + if ((info.i_fd = open(argv[1], O_RDONLY)) == -1) err(1, "Cannot open `%s'", argv[1]); - if (cdf_read_header(fd, &h) == -1) + if (cdf_read_header(&info, &h) == -1) err(1, "Cannot read header"); #ifdef CDF_DEBUG cdf_dump_header(&h); #endif - if (cdf_read_sat(fd, &h, &sat) == -1) + if (cdf_read_sat(&info, &h, &sat) == -1) err(1, "Cannot read sat"); #ifdef CDF_DEBUG - cdf_dump_sat("SAT", &h, &sat); + cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); #endif - if (cdf_read_ssat(fd, &h, &sat, &ssat) == -1) + if (cdf_read_ssat(&info, &h, &sat, &ssat) == -1) err(1, "Cannot read ssat"); #ifdef CDF_DEBUG - cdf_dump_sat("SSAT", &h, &ssat); + cdf_dump_sat("SSAT", &h, &ssat, CDF_SHORT_SEC_SIZE(&h)); #endif - if (cdf_read_dir(fd, &h, &sat, &dir) == -1) + if (cdf_read_dir(&info, &h, &sat, &dir) == -1) err(1, "Cannot read dir"); - if (cdf_read_short_stream(fd, &h, &sat, &dir, &sst) == -1) + if (cdf_read_short_stream(&info, &h, &sat, &dir, &sst) == -1) err(1, "Cannot read short stream"); #ifdef CDF_DEBUG cdf_dump_stream(&h, &sst); #endif #ifdef CDF_DEBUG - cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir); + cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); #endif - if (cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, + if (cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, &scn) == -1) err(1, "Cannot read summary info"); #ifdef CDF_DEBUG cdf_dump_summary_info(&h, &scn); #endif - (void)close(fd); + (void)close(info.i_fd); } return 0; diff --git a/cdf.h b/cdf.h index eace7ab714bb..6fa3fc693917 100644 --- a/cdf.h +++ b/cdf.h @@ -242,38 +242,45 @@ typedef struct { #define CDF_PROPERTY_SECURITY 0x00000013 #define CDF_PROPERTY_LOCALE_ID 0x80000000 +typedef struct { + int i_fd; + const unsigned char *i_buf; + size_t i_len; +} cdf_info_t; + struct timespec; int cdf_timestamp_to_timespec(struct timespec *, cdf_timestamp_t); int cdf_timespec_to_timestamp(cdf_timestamp_t *, const struct timespec *); -int cdf_read_header(int, cdf_header_t *); +int cdf_read_header(const cdf_info_t *, cdf_header_t *); void cdf_swap_header(cdf_header_t *); void cdf_unpack_header(cdf_header_t *, char *); void cdf_swap_dir(cdf_directory_t *); void cdf_unpack_dir(cdf_directory_t *, char *); void cdf_swap_class(cdf_classid_t *); -ssize_t cdf_read_sector(int, void *, size_t, size_t, const cdf_header_t *, - cdf_secid_t); +ssize_t cdf_read_sector(const cdf_info_t *, void *, size_t, size_t, + const cdf_header_t *, cdf_secid_t); ssize_t cdf_read_short_sector(const cdf_stream_t *, void *, size_t, size_t, const cdf_header_t *, cdf_secid_t); -int cdf_read_sat(int, cdf_header_t *, cdf_sat_t *); -size_t cdf_count_chain(const cdf_header_t *, const cdf_sat_t *, - cdf_secid_t); -int cdf_read_long_sector_chain(int, const cdf_header_t *, +int cdf_read_sat(const cdf_info_t *, cdf_header_t *, cdf_sat_t *); +size_t cdf_count_chain(const cdf_sat_t *, cdf_secid_t, size_t); +int cdf_read_long_sector_chain(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, cdf_secid_t, size_t, cdf_stream_t *); int cdf_read_short_sector_chain(const cdf_header_t *, const cdf_sat_t *, const cdf_stream_t *, cdf_secid_t, size_t, cdf_stream_t *); -int cdf_read_sector_chain(int, const cdf_header_t *, +int cdf_read_sector_chain(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, cdf_secid_t, size_t, cdf_stream_t *); -int cdf_read_dir(int, const cdf_header_t *, const cdf_sat_t *, cdf_dir_t *); -int cdf_read_ssat(int, const cdf_header_t *, const cdf_sat_t *, cdf_sat_t *); -int cdf_read_short_stream(int, const cdf_header_t *, const cdf_sat_t *, - const cdf_dir_t *, cdf_stream_t *); +int cdf_read_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, + cdf_dir_t *); +int cdf_read_ssat(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, + cdf_sat_t *); +int cdf_read_short_stream(const cdf_info_t *, const cdf_header_t *, + const cdf_sat_t *, const cdf_dir_t *, cdf_stream_t *); int cdf_read_property_info(const cdf_stream_t *, uint32_t, cdf_property_info_t **, size_t *, size_t *); -int cdf_read_summary_info(int, const cdf_header_t *, const cdf_sat_t *, - const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *, - cdf_stream_t *); +int cdf_read_summary_info(const cdf_info_t *, const cdf_header_t *, + const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, + const cdf_dir_t *, cdf_stream_t *); int cdf_unpack_summary_info(const cdf_stream_t *, cdf_summary_info_header_t *, cdf_property_info_t **, size_t *); int cdf_print_classid(char *, size_t, const cdf_classid_t *); @@ -285,10 +292,10 @@ uint64_t cdf_tole8(uint64_t); #ifdef CDF_DEBUG void cdf_dump_header(const cdf_header_t *); -void cdf_dump_sat(const char *, const cdf_header_t *, const cdf_sat_t *); +void cdf_dump_sat(const char *, const cdf_sat_t *, size_t); void cdf_dump(void *, size_t); void cdf_dump_stream(const cdf_header_t *, const cdf_stream_t *); -void cdf_dump_dir(int, const cdf_header_t *, const cdf_sat_t *, +void cdf_dump_dir(const cdf_info_t *, const cdf_header_t *, const cdf_sat_t *, const cdf_sat_t *, const cdf_stream_t *, const cdf_dir_t *); void cdf_dump_property_info(const cdf_property_info_t *, size_t); void cdf_dump_summary_info(const cdf_header_t *, const cdf_stream_t *); diff --git a/cdf_time.c b/cdf_time.c index e531b2dee716..932253bef402 100644 --- a/cdf_time.c +++ b/cdf_time.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: cdf_time.c,v 1.5 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $") #endif #include @@ -102,6 +102,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t) #ifdef HAVE_STRUCT_TM_TM_ZONE static char UTC[] = "UTC"; #endif + int rdays; /* Unit is 100's of nanoseconds */ ts->tv_nsec = (t % CDF_TIME_PREC) * 100; @@ -119,7 +120,7 @@ cdf_timestamp_to_timespec(struct timespec *ts, cdf_timestamp_t t) // XXX: Approx tm.tm_year = CDF_BASE_YEAR + (t / 365); - int rdays = cdf_getdays(tm.tm_year); + rdays = cdf_getdays(tm.tm_year); t -= rdays; tm.tm_mday = cdf_getday(tm.tm_year, t); tm.tm_mon = cdf_getmonth(tm.tm_year, t); diff --git a/compress.c b/compress.c index 0a30803c40d9..28dacd338cec 100644 --- a/compress.c +++ b/compress.c @@ -35,7 +35,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: compress.c,v 1.61 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: compress.c,v 1.63 2009/03/23 14:21:51 christos Exp $") #endif #include "magic.h" @@ -76,6 +76,7 @@ private const struct { /* ...only first file examined */ { "BZh", 3, { "bzip2", "-cd", NULL }, 1 }, /* bzip2-ed */ { "LZIP", 4, { "lzip", "-cdq", NULL }, 1 }, + { "\3757zXZ\0",6,{ "xz", "-cd", NULL }, 1 }, /* XZ Utils */ }; private size_t ncompr = sizeof(compr) / sizeof(compr[0]); @@ -486,6 +487,8 @@ uncompressbuf(struct magic_set *ms, int fd, size_t method, #else (void)wait(NULL); #endif + (void) close(fdin[0]); + return n; } } diff --git a/config.guess b/config.guess deleted file mode 100755 index 3d427f02150a..000000000000 --- a/config.guess +++ /dev/null @@ -1,1504 +0,0 @@ -#! /bin/sh -# -# $NetBSD: config.guess,v 1.9 2006/10/29 23:50:54 wiz Exp $ -# -# Attempt to guess a canonical system name. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. - -timestamp='2006-07-02' - -# This file is free software; you can redistribute it and/or modify it -# under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, but -# WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -# General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Originally written by Per Bothner . -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# This script attempts to guess a canonical system name similar to -# config.sub. If it succeeds, it prints the system name on stdout, and -# exits with 0. Otherwise, it exits with 1. -# -# The plan is that this can be called by configure scripts if you -# don't specify an explicit build system type. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] - -Output the configuration name of the system \`$me' is run on. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.guess ($timestamp) - -Originally written by Per Bothner. -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" >&2 - exit 1 ;; - * ) - break ;; - esac -done - -if test $# != 0; then - echo "$me: too many arguments$help" >&2 - exit 1 -fi - -trap 'exit 1' 1 2 15 - -# CC_FOR_BUILD -- compiler used by this script. Note that the use of a -# compiler to aid in system detection is discouraged as it requires -# temporary files to be created and, as you can see below, it is a -# headache to deal with in a portable fashion. - -# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still -# use `HOST_CC' if defined, but it is deprecated. - -# Portable tmp directory creation inspired by the Autoconf team. - -set_cc_for_build=' -trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ; -trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ; -: ${TMPDIR=/tmp} ; - { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } || - { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } || - { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } || - { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ; -dummy=$tmp/dummy ; -tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ; -case $CC_FOR_BUILD,$HOST_CC,$CC in - ,,) echo "int x;" > $dummy.c ; - for c in cc gcc c89 c99 ; do - if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then - CC_FOR_BUILD="$c"; break ; - fi ; - done ; - if test x"$CC_FOR_BUILD" = x ; then - CC_FOR_BUILD=no_compiler_found ; - fi - ;; - ,,*) CC_FOR_BUILD=$CC ;; - ,*,*) CC_FOR_BUILD=$HOST_CC ;; -esac ; set_cc_for_build= ;' - -# This is needed to find uname on a Pyramid OSx when run in the BSD universe. -# (ghazi@noc.rutgers.edu 1994-08-24) -if (test -f /.attbin/uname) >/dev/null 2>&1 ; then - PATH=$PATH:/.attbin ; export PATH -fi - -UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown -UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown -UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown -UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown - -# Note: order is significant - the case branches are not exclusive. - -case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in - *:NetBSD:*:*) - # NetBSD (nbsd) targets should (where applicable) match one or - # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, - # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently - # switched to ELF, *-*-netbsd* would select the old - # object file format. This provides both forward - # compatibility and a consistent mechanism for selecting the - # object file format. - # - # Note: NetBSD doesn't particularly care about the vendor - # portion of the name. We always set it to "unknown". - sysctl="sysctl -n hw.machine_arch" - UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \ - /usr/sbin/$sysctl 2>/dev/null || echo unknown)` - case "${UNAME_MACHINE_ARCH}" in - armeb) machine=armeb-unknown ;; - arm*) machine=arm-unknown ;; - sh3el) machine=shl-unknown ;; - sh3eb) machine=sh-unknown ;; - sh5el) machine=sh5le-unknown ;; - *) machine=${UNAME_MACHINE_ARCH}-unknown ;; - esac - # The Operating System including object format, if it has switched - # to ELF recently, or will in the future. - case "${UNAME_MACHINE_ARCH}" in - arm*|i386|m68k|ns32k|sh3*|sparc|vax) - eval $set_cc_for_build - if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ - | grep __ELF__ >/dev/null - then - # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). - # Return netbsd for either. FIX? - os=netbsd - else - os=netbsdelf - fi - ;; - *) - os=netbsd - ;; - esac - # The OS release - # Debian GNU/NetBSD machines have a different userland, and - # thus, need a distinct triplet. However, they do not need - # kernel version information, so it can be replaced with a - # suitable tag, in the style of linux-gnu. - case "${UNAME_VERSION}" in - Debian*) - release='-gnu' - ;; - *) - release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` - ;; - esac - # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: - # contains redundant information, the shorter form: - # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. - echo "${machine}-${os}${release}" - exit ;; - *:OpenBSD:*:*) - UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'` - echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE} - exit ;; - *:ekkoBSD:*:*) - echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE} - exit ;; - *:SolidBSD:*:*) - echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE} - exit ;; - macppc:MirBSD:*:*) - echo powerpc-unknown-mirbsd${UNAME_RELEASE} - exit ;; - *:MirBSD:*:*) - echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE} - exit ;; - alpha:OSF1:*:*) - case $UNAME_RELEASE in - *4.0) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` - ;; - *5.*) - UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'` - ;; - esac - # According to Compaq, /usr/sbin/psrinfo has been available on - # OSF/1 and Tru64 systems produced since 1995. I hope that - # covers most systems running today. This code pipes the CPU - # types through head -n 1, so we only detect the type of CPU 0. - ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1` - case "$ALPHA_CPU_TYPE" in - "EV4 (21064)") - UNAME_MACHINE="alpha" ;; - "EV4.5 (21064)") - UNAME_MACHINE="alpha" ;; - "LCA4 (21066/21068)") - UNAME_MACHINE="alpha" ;; - "EV5 (21164)") - UNAME_MACHINE="alphaev5" ;; - "EV5.6 (21164A)") - UNAME_MACHINE="alphaev56" ;; - "EV5.6 (21164PC)") - UNAME_MACHINE="alphapca56" ;; - "EV5.7 (21164PC)") - UNAME_MACHINE="alphapca57" ;; - "EV6 (21264)") - UNAME_MACHINE="alphaev6" ;; - "EV6.7 (21264A)") - UNAME_MACHINE="alphaev67" ;; - "EV6.8CB (21264C)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8AL (21264B)") - UNAME_MACHINE="alphaev68" ;; - "EV6.8CX (21264D)") - UNAME_MACHINE="alphaev68" ;; - "EV6.9A (21264/EV69A)") - UNAME_MACHINE="alphaev69" ;; - "EV7 (21364)") - UNAME_MACHINE="alphaev7" ;; - "EV7.9 (21364A)") - UNAME_MACHINE="alphaev79" ;; - esac - # A Pn.n version is a patched version. - # A Vn.n version is a released version. - # A Tn.n version is a released field test version. - # A Xn.n version is an unreleased experimental baselevel. - # 1.2 uses "1.2" for uname -r. - echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - exit ;; - Alpha\ *:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # Should we change UNAME_MACHINE based on the output of uname instead - # of the specific Alpha model? - echo alpha-pc-interix - exit ;; - 21064:Windows_NT:50:3) - echo alpha-dec-winnt3.5 - exit ;; - Amiga*:UNIX_System_V:4.0:*) - echo m68k-unknown-sysv4 - exit ;; - *:[Aa]miga[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-amigaos - exit ;; - *:[Mm]orph[Oo][Ss]:*:*) - echo ${UNAME_MACHINE}-unknown-morphos - exit ;; - *:OS/390:*:*) - echo i370-ibm-openedition - exit ;; - *:z/VM:*:*) - echo s390-ibm-zvmoe - exit ;; - *:OS400:*:*) - echo powerpc-ibm-os400 - exit ;; - arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) - echo arm-acorn-riscix${UNAME_RELEASE} - exit ;; - arm:riscos:*:*|arm:RISCOS:*:*) - echo arm-unknown-riscos - exit ;; - SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) - echo hppa1.1-hitachi-hiuxmpp - exit ;; - Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) - # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. - if test "`(/bin/universe) 2>/dev/null`" = att ; then - echo pyramid-pyramid-sysv3 - else - echo pyramid-pyramid-bsd - fi - exit ;; - NILE*:*:*:dcosx) - echo pyramid-pyramid-svr4 - exit ;; - DRS?6000:unix:4.0:6*) - echo sparc-icl-nx6 - exit ;; - DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*) - case `/usr/bin/uname -p` in - sparc) echo sparc-icl-nx7; exit ;; - esac ;; - sun4H:SunOS:5.*:*) - echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) - echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - i86pc:SunOS:5.*:*) - echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:6*:*) - # According to config.sub, this is the proper way to canonicalize - # SunOS6. Hard to guess exactly what SunOS6 will be like, but - # it's likely to be more like Solaris than SunOS4. - echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - sun4*:SunOS:*:*) - case "`/usr/bin/arch -k`" in - Series*|S4*) - UNAME_RELEASE=`uname -v` - ;; - esac - # Japanese Language versions have a version number like `4.1.3-JL'. - echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` - exit ;; - sun3*:SunOS:*:*) - echo m68k-sun-sunos${UNAME_RELEASE} - exit ;; - sun*:*:4.2BSD:*) - UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` - test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 - case "`/bin/arch`" in - sun3) - echo m68k-sun-sunos${UNAME_RELEASE} - ;; - sun4) - echo sparc-sun-sunos${UNAME_RELEASE} - ;; - esac - exit ;; - aushp:SunOS:*:*) - echo sparc-auspex-sunos${UNAME_RELEASE} - exit ;; - # The situation for MiNT is a little confusing. The machine name - # can be virtually everything (everything which is not - # "atarist" or "atariste" at least should have a processor - # > m68000). The system name ranges from "MiNT" over "FreeMiNT" - # to the lowercase version "mint" (or "freemint"). Finally - # the system name "TOS" denotes a system which is actually not - # MiNT. But MiNT is downward compatible to TOS, so this should - # be no problem. - atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) - echo m68k-atari-mint${UNAME_RELEASE} - exit ;; - milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) - echo m68k-milan-mint${UNAME_RELEASE} - exit ;; - hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) - echo m68k-hades-mint${UNAME_RELEASE} - exit ;; - *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) - echo m68k-unknown-mint${UNAME_RELEASE} - exit ;; - m68k:machten:*:*) - echo m68k-apple-machten${UNAME_RELEASE} - exit ;; - powerpc:machten:*:*) - echo powerpc-apple-machten${UNAME_RELEASE} - exit ;; - RISC*:Mach:*:*) - echo mips-dec-mach_bsd4.3 - exit ;; - RISC*:ULTRIX:*:*) - echo mips-dec-ultrix${UNAME_RELEASE} - exit ;; - VAX*:ULTRIX*:*:*) - echo vax-dec-ultrix${UNAME_RELEASE} - exit ;; - 2020:CLIX:*:* | 2430:CLIX:*:*) - echo clipper-intergraph-clix${UNAME_RELEASE} - exit ;; - mips:*:*:UMIPS | mips:*:*:RISCos) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c -#ifdef __cplusplus -#include /* for printf() prototype */ - int main (int argc, char *argv[]) { -#else - int main (argc, argv) int argc; char *argv[]; { -#endif - #if defined (host_mips) && defined (MIPSEB) - #if defined (SYSTYPE_SYSV) - printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_SVR4) - printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); - #endif - #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) - printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); - #endif - #endif - exit (-1); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && - dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` && - SYSTEM_NAME=`$dummy $dummyarg` && - { echo "$SYSTEM_NAME"; exit; } - echo mips-mips-riscos${UNAME_RELEASE} - exit ;; - Motorola:PowerMAX_OS:*:*) - echo powerpc-motorola-powermax - exit ;; - Motorola:*:4.3:PL8-*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*) - echo powerpc-harris-powermax - exit ;; - Night_Hawk:Power_UNIX:*:*) - echo powerpc-harris-powerunix - exit ;; - m88k:CX/UX:7*:*) - echo m88k-harris-cxux7 - exit ;; - m88k:*:4*:R4*) - echo m88k-motorola-sysv4 - exit ;; - m88k:*:3*:R3*) - echo m88k-motorola-sysv3 - exit ;; - AViiON:dgux:*:*) - # DG/UX returns AViiON for all architectures - UNAME_PROCESSOR=`/usr/bin/uname -p` - if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] - then - if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ - [ ${TARGET_BINARY_INTERFACE}x = x ] - then - echo m88k-dg-dgux${UNAME_RELEASE} - else - echo m88k-dg-dguxbcs${UNAME_RELEASE} - fi - else - echo i586-dg-dgux${UNAME_RELEASE} - fi - exit ;; - M88*:DolphinOS:*:*) # DolphinOS (SVR3) - echo m88k-dolphin-sysv3 - exit ;; - M88*:*:R3*:*) - # Delta 88k system running SVR3 - echo m88k-motorola-sysv3 - exit ;; - XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) - echo m88k-tektronix-sysv3 - exit ;; - Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) - echo m68k-tektronix-bsd - exit ;; - *:IRIX*:*:*) - echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` - exit ;; - ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. - echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id - exit ;; # Note that: echo "'`uname -s`'" gives 'AIX ' - i*86:AIX:*:*) - echo i386-ibm-aix - exit ;; - ia64:AIX:*:*) - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} - exit ;; - *:AIX:2:3) - if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - - main() - { - if (!__power_pc()) - exit(1); - puts("powerpc-ibm-aix3.2.5"); - exit(0); - } -EOF - if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` - then - echo "$SYSTEM_NAME" - else - echo rs6000-ibm-aix3.2.5 - fi - elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then - echo rs6000-ibm-aix3.2.4 - else - echo rs6000-ibm-aix3.2 - fi - exit ;; - *:AIX:*:[45]) - IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'` - if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then - IBM_ARCH=rs6000 - else - IBM_ARCH=powerpc - fi - if [ -x /usr/bin/oslevel ] ; then - IBM_REV=`/usr/bin/oslevel` - else - IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} - fi - echo ${IBM_ARCH}-ibm-aix${IBM_REV} - exit ;; - *:AIX:*:*) - echo rs6000-ibm-aix - exit ;; - ibmrt:4.4BSD:*|romp-ibm:BSD:*) - echo romp-ibm-bsd4.4 - exit ;; - ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and - echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to - exit ;; # report: romp-ibm BSD 4.3 - *:BOSX:*:*) - echo rs6000-bull-bosx - exit ;; - DPX/2?00:B.O.S.:*:*) - echo m68k-bull-sysv3 - exit ;; - 9000/[34]??:4.3bsd:1.*:*) - echo m68k-hp-bsd - exit ;; - hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) - echo m68k-hp-bsd4.4 - exit ;; - 9000/[34678]??:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - case "${UNAME_MACHINE}" in - 9000/31? ) HP_ARCH=m68000 ;; - 9000/[34]?? ) HP_ARCH=m68k ;; - 9000/[678][0-9][0-9]) - if [ -x /usr/bin/getconf ]; then - sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` - sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` - case "${sc_cpu_version}" in - 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 - 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 - 532) # CPU_PA_RISC2_0 - case "${sc_kernel_bits}" in - 32) HP_ARCH="hppa2.0n" ;; - 64) HP_ARCH="hppa2.0w" ;; - '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20 - esac ;; - esac - fi - if [ "${HP_ARCH}" = "" ]; then - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - - #define _HPUX_SOURCE - #include - #include - - int main () - { - #if defined(_SC_KERNEL_BITS) - long bits = sysconf(_SC_KERNEL_BITS); - #endif - long cpu = sysconf (_SC_CPU_VERSION); - - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1"); break; - case CPU_PA_RISC2_0: - #if defined(_SC_KERNEL_BITS) - switch (bits) - { - case 64: puts ("hppa2.0w"); break; - case 32: puts ("hppa2.0n"); break; - default: puts ("hppa2.0"); break; - } break; - #else /* !defined(_SC_KERNEL_BITS) */ - puts ("hppa2.0"); break; - #endif - default: puts ("hppa1.0"); break; - } - exit (0); - } -EOF - (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy` - test -z "$HP_ARCH" && HP_ARCH=hppa - fi ;; - esac - if [ ${HP_ARCH} = "hppa2.0w" ] - then - eval $set_cc_for_build - - # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating - # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler - # generating 64-bit code. GNU and HP use different nomenclature: - # - # $ CC_FOR_BUILD=cc ./config.guess - # => hppa2.0w-hp-hpux11.23 - # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess - # => hppa64-hp-hpux11.23 - - if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | - grep __LP64__ >/dev/null - then - HP_ARCH="hppa2.0w" - else - HP_ARCH="hppa64" - fi - fi - echo ${HP_ARCH}-hp-hpux${HPUX_REV} - exit ;; - ia64:HP-UX:*:*) - HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` - echo ia64-hp-hpux${HPUX_REV} - exit ;; - 3050*:HI-UX:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - int - main () - { - long cpu = sysconf (_SC_CPU_VERSION); - /* The order matters, because CPU_IS_HP_MC68K erroneously returns - true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct - results, however. */ - if (CPU_IS_PA_RISC (cpu)) - { - switch (cpu) - { - case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; - case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; - case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; - default: puts ("hppa-hitachi-hiuxwe2"); break; - } - } - else if (CPU_IS_HP_MC68K (cpu)) - puts ("m68k-hitachi-hiuxwe2"); - else puts ("unknown-hitachi-hiuxwe2"); - exit (0); - } -EOF - $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - echo unknown-hitachi-hiuxwe2 - exit ;; - 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) - echo hppa1.1-hp-bsd - exit ;; - 9000/8??:4.3bsd:*:*) - echo hppa1.0-hp-bsd - exit ;; - *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*) - echo hppa1.0-hp-mpeix - exit ;; - hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) - echo hppa1.1-hp-osf - exit ;; - hp8??:OSF1:*:*) - echo hppa1.0-hp-osf - exit ;; - i*86:OSF1:*:*) - if [ -x /usr/sbin/sysversion ] ; then - echo ${UNAME_MACHINE}-unknown-osf1mk - else - echo ${UNAME_MACHINE}-unknown-osf1 - fi - exit ;; - parisc*:Lites*:*:*) - echo hppa1.1-hp-lites - exit ;; - C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) - echo c1-convex-bsd - exit ;; - C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) - echo c34-convex-bsd - exit ;; - C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) - echo c38-convex-bsd - exit ;; - C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) - echo c4-convex-bsd - exit ;; - CRAY*Y-MP:*:*:*) - echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*[A-Z]90:*:*:*) - echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ - | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ - -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \ - -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*TS:*:*:*) - echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*T3E:*:*:*) - echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - CRAY*SV1:*:*:*) - echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - *:UNICOS/mp:*:*) - echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' - exit ;; - F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) - FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` - echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - 5000:UNIX_System_V:4.*:*) - FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` - FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'` - echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" - exit ;; - i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) - echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} - exit ;; - sparc*:BSD/OS:*:*) - echo sparc-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:BSD/OS:*:*) - echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} - exit ;; - *:FreeBSD:*:*) - case ${UNAME_MACHINE} in - pc98) - echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - amd64) - echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - *) - echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;; - esac - exit ;; - i*:CYGWIN*:*) - echo ${UNAME_MACHINE}-pc-cygwin - exit ;; - i*:MINGW*:*) - echo ${UNAME_MACHINE}-pc-mingw32 - exit ;; - i*:windows32*:*) - # uname -m includes "-pc" on this system. - echo ${UNAME_MACHINE}-mingw32 - exit ;; - i*:PW*:*) - echo ${UNAME_MACHINE}-pc-pw32 - exit ;; - x86:Interix*:[3456]*) - echo i586-pc-interix${UNAME_RELEASE} - exit ;; - EM64T:Interix*:[3456]*) - echo x86_64-unknown-interix${UNAME_RELEASE} - exit ;; - [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*) - echo i${UNAME_MACHINE}-pc-mks - exit ;; - i*:Windows_NT*:* | Pentium*:Windows_NT*:*) - # How do we know it's Interix rather than the generic POSIX subsystem? - # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we - # UNAME_MACHINE based on the output of uname instead of i386? - echo i586-pc-interix - exit ;; - i*:UWIN*:*) - echo ${UNAME_MACHINE}-pc-uwin - exit ;; - amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*) - echo x86_64-unknown-cygwin - exit ;; - p*:CYGWIN*:*) - echo powerpcle-unknown-cygwin - exit ;; - prep*:SunOS:5.*:*) - echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` - exit ;; - *:GNU:*:*) - # the GNU system - echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` - exit ;; - *:GNU/*:*:*) - # other systems with GNU libc and userland - echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu - exit ;; - i*86:Minix:*:*) - echo ${UNAME_MACHINE}-pc-minix - exit ;; - arm*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - avr32*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - cris:Linux:*:*) - echo cris-axis-linux-gnu - exit ;; - crisv32:Linux:*:*) - echo crisv32-axis-linux-gnu - exit ;; - frv:Linux:*:*) - echo frv-unknown-linux-gnu - exit ;; - ia64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m32r*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - m68*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - mips:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips - #undef mipsel - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mipsel - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - mips64:Linux:*:*) - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #undef CPU - #undef mips64 - #undef mips64el - #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL) - CPU=mips64el - #else - #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB) - CPU=mips64 - #else - CPU= - #endif - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^CPU/{ - s: ::g - p - }'`" - test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; } - ;; - or32:Linux:*:*) - echo or32-unknown-linux-gnu - exit ;; - ppc:Linux:*:*) - echo powerpc-unknown-linux-gnu - exit ;; - ppc64:Linux:*:*) - echo powerpc64-unknown-linux-gnu - exit ;; - alpha:Linux:*:*) - case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in - EV5) UNAME_MACHINE=alphaev5 ;; - EV56) UNAME_MACHINE=alphaev56 ;; - PCA56) UNAME_MACHINE=alphapca56 ;; - PCA57) UNAME_MACHINE=alphapca56 ;; - EV6) UNAME_MACHINE=alphaev6 ;; - EV67) UNAME_MACHINE=alphaev67 ;; - EV68*) UNAME_MACHINE=alphaev68 ;; - esac - objdump --private-headers /bin/sh | grep ld.so.1 >/dev/null - if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi - echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} - exit ;; - parisc:Linux:*:* | hppa:Linux:*:*) - # Look for CPU level - case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in - PA7*) echo hppa1.1-unknown-linux-gnu ;; - PA8*) echo hppa2.0-unknown-linux-gnu ;; - *) echo hppa-unknown-linux-gnu ;; - esac - exit ;; - parisc64:Linux:*:* | hppa64:Linux:*:*) - echo hppa64-unknown-linux-gnu - exit ;; - s390:Linux:*:* | s390x:Linux:*:*) - echo ${UNAME_MACHINE}-ibm-linux - exit ;; - sh64*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sh*:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - sparc:Linux:*:* | sparc64:Linux:*:*) - echo ${UNAME_MACHINE}-unknown-linux-gnu - exit ;; - vax:Linux:*:*) - echo ${UNAME_MACHINE}-dec-linux-gnu - exit ;; - x86_64:Linux:*:*) - echo x86_64-unknown-linux-gnu - exit ;; - i*86:Linux:*:*) - # The BFD linker knows what the default object file format is, so - # first see if it will tell us. cd to the root directory to prevent - # problems with other programs or directories called `ld' in the path. - # Set LC_ALL=C to ensure ld outputs messages in English. - ld_supported_targets=`cd /; LC_ALL=C ld --help 2>&1 \ - | sed -ne '/supported targets:/!d - s/[ ][ ]*/ /g - s/.*supported targets: *// - s/ .*// - p'` - case "$ld_supported_targets" in - elf32-i386) - TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" - ;; - a.out-i386-linux) - echo "${UNAME_MACHINE}-pc-linux-gnuaout" - exit ;; - coff-i386) - echo "${UNAME_MACHINE}-pc-linux-gnucoff" - exit ;; - "") - # Either a pre-BFD a.out linker (linux-gnuoldld) or - # one that does not give us useful --help. - echo "${UNAME_MACHINE}-pc-linux-gnuoldld" - exit ;; - esac - # Determine whether the default compiler is a.out or elf - eval $set_cc_for_build - sed 's/^ //' << EOF >$dummy.c - #include - #ifdef __ELF__ - # ifdef __GLIBC__ - # if __GLIBC__ >= 2 - LIBC=gnu - # else - LIBC=gnulibc1 - # endif - # else - LIBC=gnulibc1 - # endif - #else - #if defined(__INTEL_COMPILER) || defined(__PGI) || defined(__SUNPRO_C) || defined(__SUNPRO_CC) - LIBC=gnu - #else - LIBC=gnuaout - #endif - #endif - #ifdef __dietlibc__ - LIBC=dietlibc - #endif -EOF - eval "`$CC_FOR_BUILD -E $dummy.c 2>/dev/null | sed -n ' - /^LIBC/{ - s: ::g - p - }'`" - test x"${LIBC}" != x && { - echo "${UNAME_MACHINE}-pc-linux-${LIBC}" - exit - } - test x"${TENTATIVE}" != x && { echo "${TENTATIVE}"; exit; } - ;; - i*86:DYNIX/ptx:4*:*) - # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. - # earlier versions are messed up and put the nodename in both - # sysname and nodename. - echo i386-sequent-sysv4 - exit ;; - i*86:UNIX_SV:4.2MP:2.*) - # Unixware is an offshoot of SVR4, but it has its own version - # number series starting with 2... - # I am not positive that other SVR4 systems won't match this, - # I just have to hope. -- rms. - # Use sysv4.2uw... so that sysv4* matches it. - echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} - exit ;; - i*86:OS/2:*:*) - # If we were able to find `uname', then EMX Unix compatibility - # is probably installed. - echo ${UNAME_MACHINE}-pc-os2-emx - exit ;; - i*86:XTS-300:*:STOP) - echo ${UNAME_MACHINE}-unknown-stop - exit ;; - i*86:atheos:*:*) - echo ${UNAME_MACHINE}-unknown-atheos - exit ;; - i*86:syllable:*:*) - echo ${UNAME_MACHINE}-pc-syllable - exit ;; - i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.0*:*) - echo i386-unknown-lynxos${UNAME_RELEASE} - exit ;; - i*86:*DOS:*:*) - echo ${UNAME_MACHINE}-pc-msdosdjgpp - exit ;; - i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*) - UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` - if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then - echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} - else - echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} - fi - exit ;; - i*86:*:5:[678]*) - # UnixWare 7.x, OpenUNIX and OpenServer 6. - case `/bin/uname -X | grep "^Machine"` in - *486*) UNAME_MACHINE=i486 ;; - *Pentium) UNAME_MACHINE=i586 ;; - *Pent*|*Celeron) UNAME_MACHINE=i686 ;; - esac - echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION} - exit ;; - i*86:*:3.2:*) - if test -f /usr/options/cb.name; then - UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then - UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')` - (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486 - (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \ - && UNAME_MACHINE=i586 - (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \ - && UNAME_MACHINE=i686 - (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \ - && UNAME_MACHINE=i686 - echo ${UNAME_MACHINE}-pc-sco$UNAME_REL - else - echo ${UNAME_MACHINE}-pc-sysv32 - fi - exit ;; - pc:*:*:*) - # Left here for compatibility: - # uname -m prints for DJGPP always 'pc', but it prints nothing about - # the processor, so we play safe by assuming i386. - echo i386-pc-msdosdjgpp - exit ;; - Intel:Mach:3*:*) - echo i386-pc-mach3 - exit ;; - paragon:*:*:*) - echo i860-intel-osf1 - exit ;; - i860:*:4.*:*) # i860-SVR4 - if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then - echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 - else # Add other i860-SVR4 vendors below as they are discovered. - echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 - fi - exit ;; - mini*:CTIX:SYS*5:*) - # "miniframe" - echo m68010-convergent-sysv - exit ;; - mc68k:UNIX:SYSTEM5:3.51m) - echo m68k-convergent-sysv - exit ;; - M680?0:D-NIX:5.3:*) - echo m68k-diab-dnix - exit ;; - M68*:*:R3V[5678]*:*) - test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;; - 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0) - OS_REL='' - test -r /etc/.relid \ - && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4.3${OS_REL}; exit; } - /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ - && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;; - 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) - /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ - && { echo i486-ncr-sysv4; exit; } ;; - m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*) - echo m68k-unknown-lynxos${UNAME_RELEASE} - exit ;; - mc68030:UNIX_System_V:4.*:*) - echo m68k-atari-sysv4 - exit ;; - TSUNAMI:LynxOS:2.*:*) - echo sparc-unknown-lynxos${UNAME_RELEASE} - exit ;; - rs6000:LynxOS:2.*:*) - echo rs6000-unknown-lynxos${UNAME_RELEASE} - exit ;; - PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.0*:*) - echo powerpc-unknown-lynxos${UNAME_RELEASE} - exit ;; - SM[BE]S:UNIX_SV:*:*) - echo mips-dde-sysv${UNAME_RELEASE} - exit ;; - RM*:ReliantUNIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - RM*:SINIX-*:*:*) - echo mips-sni-sysv4 - exit ;; - *:SINIX-*:*:*) - if uname -p 2>/dev/null >/dev/null ; then - UNAME_MACHINE=`(uname -p) 2>/dev/null` - echo ${UNAME_MACHINE}-sni-sysv4 - else - echo ns32k-sni-sysv - fi - exit ;; - PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort - # says - echo i586-unisys-sysv4 - exit ;; - *:UNIX_System_V:4*:FTX*) - # From Gerald Hewes . - # How about differentiating between stratus architectures? -djm - echo hppa1.1-stratus-sysv4 - exit ;; - *:*:*:FTX*) - # From seanf@swdc.stratus.com. - echo i860-stratus-sysv4 - exit ;; - i*86:VOS:*:*) - # From Paul.Green@stratus.com. - echo ${UNAME_MACHINE}-stratus-vos - exit ;; - *:VOS:*:*) - # From Paul.Green@stratus.com. - echo hppa1.1-stratus-vos - exit ;; - mc68*:A/UX:*:*) - echo m68k-apple-aux${UNAME_RELEASE} - exit ;; - news*:NEWS-OS:6*:*) - echo mips-sony-newsos6 - exit ;; - R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) - if [ -d /usr/nec ]; then - echo mips-nec-sysv${UNAME_RELEASE} - else - echo mips-unknown-sysv${UNAME_RELEASE} - fi - exit ;; - BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. - echo powerpc-be-beos - exit ;; - BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. - echo powerpc-apple-beos - exit ;; - BePC:BeOS:*:*) # BeOS running on Intel PC compatible. - echo i586-pc-beos - exit ;; - SX-4:SUPER-UX:*:*) - echo sx4-nec-superux${UNAME_RELEASE} - exit ;; - SX-5:SUPER-UX:*:*) - echo sx5-nec-superux${UNAME_RELEASE} - exit ;; - SX-6:SUPER-UX:*:*) - echo sx6-nec-superux${UNAME_RELEASE} - exit ;; - Power*:Rhapsody:*:*) - echo powerpc-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Rhapsody:*:*) - echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} - exit ;; - *:Darwin:*:*) - UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown - case $UNAME_PROCESSOR in - unknown) UNAME_PROCESSOR=powerpc ;; - esac - echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE} - exit ;; - *:procnto*:*:* | *:QNX:[0123456789]*:*) - UNAME_PROCESSOR=`uname -p` - if test "$UNAME_PROCESSOR" = "x86"; then - UNAME_PROCESSOR=i386 - UNAME_MACHINE=pc - fi - echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE} - exit ;; - *:QNX:*:4*) - echo i386-pc-qnx - exit ;; - NSE-?:NONSTOP_KERNEL:*:*) - echo nse-tandem-nsk${UNAME_RELEASE} - exit ;; - NSR-?:NONSTOP_KERNEL:*:*) - echo nsr-tandem-nsk${UNAME_RELEASE} - exit ;; - *:NonStop-UX:*:*) - echo mips-compaq-nonstopux - exit ;; - BS2000:POSIX*:*:*) - echo bs2000-siemens-sysv - exit ;; - DS/*:UNIX_System_V:*:*) - echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} - exit ;; - *:Plan9:*:*) - # "uname -m" is not consistent, so use $cputype instead. 386 - # is converted to i386 for consistency with other x86 - # operating systems. - if test "$cputype" = "386"; then - UNAME_MACHINE=i386 - else - UNAME_MACHINE="$cputype" - fi - echo ${UNAME_MACHINE}-unknown-plan9 - exit ;; - *:TOPS-10:*:*) - echo pdp10-unknown-tops10 - exit ;; - *:TENEX:*:*) - echo pdp10-unknown-tenex - exit ;; - KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) - echo pdp10-dec-tops20 - exit ;; - XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) - echo pdp10-xkl-tops20 - exit ;; - *:TOPS-20:*:*) - echo pdp10-unknown-tops20 - exit ;; - *:ITS:*:*) - echo pdp10-unknown-its - exit ;; - SEI:*:*:SEIUX) - echo mips-sei-seiux${UNAME_RELEASE} - exit ;; - *:DragonFly:*:*) - echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` - exit ;; - *:*VMS:*:*) - UNAME_MACHINE=`(uname -p) 2>/dev/null` - case "${UNAME_MACHINE}" in - A*) echo alpha-dec-vms ; exit ;; - I*) echo ia64-dec-vms ; exit ;; - V*) echo vax-dec-vms ; exit ;; - esac ;; - *:XENIX:*:SysV) - echo i386-pc-xenix - exit ;; - i*86:skyos:*:*) - echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//' - exit ;; - i*86:rdos:*:*) - echo ${UNAME_MACHINE}-pc-rdos - exit ;; -esac - -#echo '(No uname command or uname output not recognized.)' 1>&2 -#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 - -eval $set_cc_for_build -cat >$dummy.c < -# include -#endif -main () -{ -#if defined (sony) -#if defined (MIPSEB) - /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, - I don't know.... */ - printf ("mips-sony-bsd\n"); exit (0); -#else -#include - printf ("m68k-sony-newsos%s\n", -#ifdef NEWSOS4 - "4" -#else - "" -#endif - ); exit (0); -#endif -#endif - -#if defined (__arm) && defined (__acorn) && defined (__unix) - printf ("arm-acorn-riscix\n"); exit (0); -#endif - -#if defined (hp300) && !defined (hpux) - printf ("m68k-hp-bsd\n"); exit (0); -#endif - -#if defined (NeXT) -#if !defined (__ARCHITECTURE__) -#define __ARCHITECTURE__ "m68k" -#endif - int version; - version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; - if (version < 4) - printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); - else - printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); - exit (0); -#endif - -#if defined (MULTIMAX) || defined (n16) -#if defined (UMAXV) - printf ("ns32k-encore-sysv\n"); exit (0); -#else -#if defined (CMU) - printf ("ns32k-encore-mach\n"); exit (0); -#else - printf ("ns32k-encore-bsd\n"); exit (0); -#endif -#endif -#endif - -#if defined (__386BSD__) - printf ("i386-pc-bsd\n"); exit (0); -#endif - -#if defined (sequent) -#if defined (i386) - printf ("i386-sequent-dynix\n"); exit (0); -#endif -#if defined (ns32000) - printf ("ns32k-sequent-dynix\n"); exit (0); -#endif -#endif - -#if defined (_SEQUENT_) - struct utsname un; - - uname(&un); - - if (strncmp(un.version, "V2", 2) == 0) { - printf ("i386-sequent-ptx2\n"); exit (0); - } - if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ - printf ("i386-sequent-ptx1\n"); exit (0); - } - printf ("i386-sequent-ptx\n"); exit (0); - -#endif - -#if defined (vax) -# if !defined (ultrix) -# include -# if defined (BSD) -# if BSD == 43 - printf ("vax-dec-bsd4.3\n"); exit (0); -# else -# if BSD == 199006 - printf ("vax-dec-bsd4.3reno\n"); exit (0); -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# endif -# else - printf ("vax-dec-bsd\n"); exit (0); -# endif -# else - printf ("vax-dec-ultrix\n"); exit (0); -# endif -#endif - -#if defined (alliant) && defined (i860) - printf ("i860-alliant-bsd\n"); exit (0); -#endif - - exit (1); -} -EOF - -$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` && - { echo "$SYSTEM_NAME"; exit; } - -# Apollos put the system type in the environment. - -test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; } - -# Convex versions that predate uname can use getsysinfo(1) - -if [ -x /usr/convex/getsysinfo ] -then - case `getsysinfo -f cpu_type` in - c1*) - echo c1-convex-bsd - exit ;; - c2*) - if getsysinfo -f scalar_acc - then echo c32-convex-bsd - else echo c2-convex-bsd - fi - exit ;; - c34*) - echo c34-convex-bsd - exit ;; - c38*) - echo c38-convex-bsd - exit ;; - c4*) - echo c4-convex-bsd - exit ;; - esac -fi - -cat >&2 < in order to provide the needed -information to handle your system. - -config.guess timestamp = $timestamp - -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null` - -hostinfo = `(hostinfo) 2>/dev/null` -/bin/universe = `(/bin/universe) 2>/dev/null` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` -/bin/arch = `(/bin/arch) 2>/dev/null` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` - -UNAME_MACHINE = ${UNAME_MACHINE} -UNAME_RELEASE = ${UNAME_RELEASE} -UNAME_SYSTEM = ${UNAME_SYSTEM} -UNAME_VERSION = ${UNAME_VERSION} -EOF - -exit 1 - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/config.h.in b/config.h.in index 1b7ac287db54..3a36434868cb 100644 --- a/config.h.in +++ b/config.h.in @@ -93,6 +93,9 @@ /* Define to 1 if you have the `strtoul' function. */ #undef HAVE_STRTOUL +/* HAVE_STRUCT_OPTION */ +#undef HAVE_STRUCT_OPTION + /* Define to 1 if `st_rdev' is member of `struct stat'. */ #undef HAVE_STRUCT_STAT_ST_RDEV diff --git a/config.sub b/config.sub deleted file mode 100755 index 5b2ab48217c3..000000000000 --- a/config.sub +++ /dev/null @@ -1,1622 +0,0 @@ -#! /bin/sh -# -# $NetBSD: config.sub,v 1.8 2006/10/29 23:52:55 wiz Exp $ -# -# Configuration validation subroutine script. -# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, -# 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, -# Inc. - -timestamp='2006-09-20' - -# This file is (in principle) common to ALL GNU software. -# The presence of a machine in this file suggests that SOME GNU software -# can handle that machine. It does not imply ALL GNU software can. -# -# This file is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA -# 02110-1301, USA. -# -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - - -# Please send patches to . Submit a context -# diff and a properly formatted ChangeLog entry. -# -# Configuration subroutine to validate and canonicalize a configuration type. -# Supply the specified configuration type as an argument. -# If it is invalid, we print an error message on stderr and exit with code 1. -# Otherwise, we print the canonical config type on stdout and succeed. - -# This file is supposed to be the same for all GNU packages -# and recognize all the CPU types, system types and aliases -# that are meaningful with *any* GNU software. -# Each package is responsible for reporting which valid configurations -# it does not support. The user should be able to distinguish -# a failure to support a valid configuration from a meaningless -# configuration. - -# The goal of this file is to map all the various variations of a given -# machine specification into a single specification in the form: -# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM -# or in some cases, the newer four-part form: -# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM -# It is wrong to echo any other type of specification. - -me=`echo "$0" | sed -e 's,.*/,,'` - -usage="\ -Usage: $0 [OPTION] CPU-MFR-OPSYS - $0 [OPTION] ALIAS - -Canonicalize a configuration name. - -Operation modes: - -h, --help print this help, then exit - -t, --time-stamp print date of last modification, then exit - -v, --version print version number, then exit - -Report bugs and patches to ." - -version="\ -GNU config.sub ($timestamp) - -Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 -Free Software Foundation, Inc. - -This is free software; see the source for copying conditions. There is NO -warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." - -help=" -Try \`$me --help' for more information." - -# Parse command line -while test $# -gt 0 ; do - case $1 in - --time-stamp | --time* | -t ) - echo "$timestamp" ; exit ;; - --version | -v ) - echo "$version" ; exit ;; - --help | --h* | -h ) - echo "$usage"; exit ;; - -- ) # Stop option processing - shift; break ;; - - ) # Use stdin as input. - break ;; - -* ) - echo "$me: invalid option $1$help" - exit 1 ;; - - *local*) - # First pass through any local machine types. - echo $1 - exit ;; - - * ) - break ;; - esac -done - -case $# in - 0) echo "$me: missing argument$help" >&2 - exit 1;; - 1) ;; - *) echo "$me: too many arguments$help" >&2 - exit 1;; -esac - -# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). -# Here we must recognize all the valid KERNEL-OS combinations. -maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` -case $maybe_os in - nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \ - uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \ - storm-chaos* | os2-emx* | rtmk-nova*) - os=-$maybe_os - basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` - ;; - *) - basic_machine=`echo $1 | sed 's/-[^-]*$//'` - if [ $basic_machine != $1 ] - then os=`echo $1 | sed 's/.*-/-/'` - else os=; fi - ;; -esac - -### Let's recognize common machines as not being operating systems so -### that things like config.sub decstation-3100 work. We also -### recognize some manufacturers as not being operating systems, so we -### can provide default operating systems below. -case $os in - -sun*os*) - # Prevent following clause from handling this invalid input. - ;; - -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ - -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ - -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ - -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ - -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ - -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ - -apple | -axis | -knuth | -cray) - os= - basic_machine=$1 - ;; - -sim | -cisco | -oki | -wec | -winbond) - os= - basic_machine=$1 - ;; - -scout) - ;; - -wrs) - os=-vxworks - basic_machine=$1 - ;; - -chorusos*) - os=-chorusos - basic_machine=$1 - ;; - -chorusrdb) - os=-chorusrdb - basic_machine=$1 - ;; - -hiux*) - os=-hiuxwe2 - ;; - -sco6) - os=-sco5v6 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5) - os=-sco3.2v5 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco4) - os=-sco3.2v4 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2.[4-9]*) - os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco3.2v[4-9]*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco5v6*) - # Don't forget version if it is 3.2v4 or newer. - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -sco*) - os=-sco3.2v2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -udk*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -isc) - os=-isc2.2 - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -clix*) - basic_machine=clipper-intergraph - ;; - -isc*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` - ;; - -lynx*) - os=-lynxos - ;; - -ptx*) - basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` - ;; - -windowsnt*) - os=`echo $os | sed -e 's/windowsnt/winnt/'` - ;; - -psos*) - os=-psos - ;; - -mint | -mint[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; -esac - -# Decode aliases for certain CPU-COMPANY combinations. -case $basic_machine in - # Recognize the basic CPU types without company name. - # Some are omitted here because they have special meanings below. - 1750a | 580 \ - | a29k \ - | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \ - | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \ - | am33_2.0 \ - | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \ - | bfin \ - | c4x | clipper \ - | d10v | d30v | dlx | dsp16xx \ - | fr30 | frv \ - | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \ - | i370 | i860 | i960 | ia64 \ - | ip2k | iq2000 \ - | m32c | m32r | m32rle | m68000 | m68k | m88k \ - | maxq | mb | microblaze | mcore \ - | mips | mipsbe | mipseb | mipsel | mipsle \ - | mips16 \ - | mips64 | mips64el \ - | mips64vr | mips64vrel \ - | mips64orion | mips64orionel \ - | mips64vr4100 | mips64vr4100el \ - | mips64vr4300 | mips64vr4300el \ - | mips64vr5000 | mips64vr5000el \ - | mips64vr5900 | mips64vr5900el \ - | mipsisa32 | mipsisa32el \ - | mipsisa32r2 | mipsisa32r2el \ - | mipsisa64 | mipsisa64el \ - | mipsisa64r2 | mipsisa64r2el \ - | mipsisa64sb1 | mipsisa64sb1el \ - | mipsisa64sr71k | mipsisa64sr71kel \ - | mipstx39 | mipstx39el \ - | mn10200 | mn10300 \ - | mt \ - | msp430 \ - | nios | nios2 \ - | ns16k | ns32k \ - | or32 \ - | pdp10 | pdp11 | pj | pjl \ - | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \ - | pyramid \ - | score \ - | sh | sh[1234] | sh[24]a | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \ - | sh64 | sh64le \ - | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \ - | sparcv8 | sparcv9 | sparcv9b | sparcv9v \ - | spu | strongarm \ - | tahoe | thumb | tic4x | tic80 | tron \ - | v850 | v850e \ - | we32k \ - | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \ - | z8k) - basic_machine=$basic_machine-unknown - ;; - m6811 | m68hc11 | m6812 | m68hc12) - # Motorola 68HC11/12. - basic_machine=$basic_machine-unknown - os=-none - ;; - m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k) - ;; - ms1) - basic_machine=mt-unknown - ;; - - # We use `pc' rather than `unknown' - # because (1) that's what they normally are, and - # (2) the word "unknown" tends to confuse beginning users. - i*86 | x86_64) - basic_machine=$basic_machine-pc - ;; - # Object if more than one company name word. - *-*-*) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; - # Recognize the basic CPU types with company name. - 580-* \ - | a29k-* \ - | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \ - | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \ - | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \ - | arm-* | armbe-* | armle-* | armeb-* | armv*-* \ - | avr-* | avr32-* \ - | bfin-* | bs2000-* \ - | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \ - | clipper-* | craynv-* | cydra-* \ - | d10v-* | d30v-* | dlx-* \ - | elxsi-* \ - | f30[01]-* | f700-* | fr30-* | frv-* | fx80-* \ - | h8300-* | h8500-* \ - | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \ - | i*86-* | i860-* | i960-* | ia64-* \ - | ip2k-* | iq2000-* \ - | m32c-* | m32r-* | m32rle-* \ - | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \ - | m88110-* | m88k-* | maxq-* | mcore-* \ - | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \ - | mips16-* \ - | mips64-* | mips64el-* \ - | mips64vr-* | mips64vrel-* \ - | mips64orion-* | mips64orionel-* \ - | mips64vr4100-* | mips64vr4100el-* \ - | mips64vr4300-* | mips64vr4300el-* \ - | mips64vr5000-* | mips64vr5000el-* \ - | mips64vr5900-* | mips64vr5900el-* \ - | mipsisa32-* | mipsisa32el-* \ - | mipsisa32r2-* | mipsisa32r2el-* \ - | mipsisa64-* | mipsisa64el-* \ - | mipsisa64r2-* | mipsisa64r2el-* \ - | mipsisa64sb1-* | mipsisa64sb1el-* \ - | mipsisa64sr71k-* | mipsisa64sr71kel-* \ - | mipstx39-* | mipstx39el-* \ - | mmix-* \ - | mt-* \ - | msp430-* \ - | nios-* | nios2-* \ - | none-* | np1-* | ns16k-* | ns32k-* \ - | orion-* \ - | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \ - | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \ - | pyramid-* \ - | romp-* | rs6000-* \ - | sh-* | sh[1234]-* | sh[24]a-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \ - | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \ - | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \ - | sparclite-* \ - | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \ - | tahoe-* | thumb-* \ - | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \ - | tron-* \ - | v850-* | v850e-* | vax-* \ - | we32k-* \ - | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \ - | xstormy16-* | xtensa-* \ - | ymp-* \ - | z8k-*) - ;; - # Recognize the various machine names and aliases which stand - # for a CPU type and a company and sometimes even an OS. - 386bsd) - basic_machine=i386-unknown - os=-bsd - ;; - 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) - basic_machine=m68000-att - ;; - 3b*) - basic_machine=we32k-att - ;; - a29khif) - basic_machine=a29k-amd - os=-udi - ;; - abacus) - basic_machine=abacus-unknown - ;; - adobe68k) - basic_machine=m68010-adobe - os=-scout - ;; - alliant | fx80) - basic_machine=fx80-alliant - ;; - altos | altos3068) - basic_machine=m68k-altos - ;; - am29k) - basic_machine=a29k-none - os=-bsd - ;; - amd64) - basic_machine=x86_64-pc - ;; - amd64-*) - basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - amdahl) - basic_machine=580-amdahl - os=-sysv - ;; - amiga | amiga-*) - basic_machine=m68k-unknown - ;; - amigaos | amigados) - basic_machine=m68k-unknown - os=-amigaos - ;; - amigaunix | amix) - basic_machine=m68k-unknown - os=-sysv4 - ;; - apollo68) - basic_machine=m68k-apollo - os=-sysv - ;; - apollo68bsd) - basic_machine=m68k-apollo - os=-bsd - ;; - aux) - basic_machine=m68k-apple - os=-aux - ;; - balance) - basic_machine=ns32k-sequent - os=-dynix - ;; - c90) - basic_machine=c90-cray - os=-unicos - ;; - convex-c1) - basic_machine=c1-convex - os=-bsd - ;; - convex-c2) - basic_machine=c2-convex - os=-bsd - ;; - convex-c32) - basic_machine=c32-convex - os=-bsd - ;; - convex-c34) - basic_machine=c34-convex - os=-bsd - ;; - convex-c38) - basic_machine=c38-convex - os=-bsd - ;; - cray | j90) - basic_machine=j90-cray - os=-unicos - ;; - craynv) - basic_machine=craynv-cray - os=-unicosmp - ;; - cr16c) - basic_machine=cr16c-unknown - os=-elf - ;; - crds | unos) - basic_machine=m68k-crds - ;; - crisv32 | crisv32-* | etraxfs*) - basic_machine=crisv32-axis - ;; - cris | cris-* | etrax*) - basic_machine=cris-axis - ;; - crx) - basic_machine=crx-unknown - os=-elf - ;; - da30 | da30-*) - basic_machine=m68k-da30 - ;; - decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) - basic_machine=mips-dec - ;; - decsystem10* | dec10*) - basic_machine=pdp10-dec - os=-tops10 - ;; - decsystem20* | dec20*) - basic_machine=pdp10-dec - os=-tops20 - ;; - delta | 3300 | motorola-3300 | motorola-delta \ - | 3300-motorola | delta-motorola) - basic_machine=m68k-motorola - ;; - delta88) - basic_machine=m88k-motorola - os=-sysv3 - ;; - djgpp) - basic_machine=i586-pc - os=-msdosdjgpp - ;; - dpx20 | dpx20-*) - basic_machine=rs6000-bull - os=-bosx - ;; - dpx2* | dpx2*-bull) - basic_machine=m68k-bull - os=-sysv3 - ;; - ebmon29k) - basic_machine=a29k-amd - os=-ebmon - ;; - elxsi) - basic_machine=elxsi-elxsi - os=-bsd - ;; - encore | umax | mmax) - basic_machine=ns32k-encore - ;; - es1800 | OSE68k | ose68k | ose | OSE) - basic_machine=m68k-ericsson - os=-ose - ;; - fx2800) - basic_machine=i860-alliant - ;; - genix) - basic_machine=ns32k-ns - ;; - gmicro) - basic_machine=tron-gmicro - os=-sysv - ;; - go32) - basic_machine=i386-pc - os=-go32 - ;; - h3050r* | hiux*) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - h8300hms) - basic_machine=h8300-hitachi - os=-hms - ;; - h8300xray) - basic_machine=h8300-hitachi - os=-xray - ;; - h8500hms) - basic_machine=h8500-hitachi - os=-hms - ;; - harris) - basic_machine=m88k-harris - os=-sysv3 - ;; - hp300-*) - basic_machine=m68k-hp - ;; - hp300bsd) - basic_machine=m68k-hp - os=-bsd - ;; - hp300hpux) - basic_machine=m68k-hp - os=-hpux - ;; - hp3k9[0-9][0-9] | hp9[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k2[0-9][0-9] | hp9k31[0-9]) - basic_machine=m68000-hp - ;; - hp9k3[2-9][0-9]) - basic_machine=m68k-hp - ;; - hp9k6[0-9][0-9] | hp6[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hp9k7[0-79][0-9] | hp7[0-79][0-9]) - basic_machine=hppa1.1-hp - ;; - hp9k78[0-9] | hp78[0-9]) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) - # FIXME: really hppa2.0-hp - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][13679] | hp8[0-9][13679]) - basic_machine=hppa1.1-hp - ;; - hp9k8[0-9][0-9] | hp8[0-9][0-9]) - basic_machine=hppa1.0-hp - ;; - hppa-next) - os=-nextstep3 - ;; - hppaosf) - basic_machine=hppa1.1-hp - os=-osf - ;; - hppro) - basic_machine=hppa1.1-hp - os=-proelf - ;; - i370-ibm* | ibm*) - basic_machine=i370-ibm - ;; -# I'm not sure what "Sysv32" means. Should this be sysv3.2? - i*86v32) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv32 - ;; - i*86v4*) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv4 - ;; - i*86v) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-sysv - ;; - i*86sol2) - basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` - os=-solaris2 - ;; - i386mach) - basic_machine=i386-mach - os=-mach - ;; - i386-vsta | vsta) - basic_machine=i386-unknown - os=-vsta - ;; - iris | iris4d) - basic_machine=mips-sgi - case $os in - -irix*) - ;; - *) - os=-irix4 - ;; - esac - ;; - isi68 | isi) - basic_machine=m68k-isi - os=-sysv - ;; - m88k-omron*) - basic_machine=m88k-omron - ;; - magnum | m3230) - basic_machine=mips-mips - os=-sysv - ;; - merlin) - basic_machine=ns32k-utek - os=-sysv - ;; - mingw32) - basic_machine=i386-pc - os=-mingw32 - ;; - miniframe) - basic_machine=m68000-convergent - ;; - *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) - basic_machine=m68k-atari - os=-mint - ;; - mips3*-*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` - ;; - mips3*) - basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown - ;; - monitor) - basic_machine=m68k-rom68k - os=-coff - ;; - morphos) - basic_machine=powerpc-unknown - os=-morphos - ;; - msdos) - basic_machine=i386-pc - os=-msdos - ;; - ms1-*) - basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'` - ;; - mvs) - basic_machine=i370-ibm - os=-mvs - ;; - ncr3000) - basic_machine=i486-ncr - os=-sysv4 - ;; - netbsd386) - basic_machine=i386-unknown - os=-netbsd - ;; - netwinder) - basic_machine=armv4l-rebel - os=-linux - ;; - news | news700 | news800 | news900) - basic_machine=m68k-sony - os=-newsos - ;; - news1000) - basic_machine=m68030-sony - os=-newsos - ;; - news-3600 | risc-news) - basic_machine=mips-sony - os=-newsos - ;; - necv70) - basic_machine=v70-nec - os=-sysv - ;; - next | m*-next ) - basic_machine=m68k-next - case $os in - -nextstep* ) - ;; - -ns2*) - os=-nextstep2 - ;; - *) - os=-nextstep3 - ;; - esac - ;; - nh3000) - basic_machine=m68k-harris - os=-cxux - ;; - nh[45]000) - basic_machine=m88k-harris - os=-cxux - ;; - nindy960) - basic_machine=i960-intel - os=-nindy - ;; - mon960) - basic_machine=i960-intel - os=-mon960 - ;; - nonstopux) - basic_machine=mips-compaq - os=-nonstopux - ;; - np1) - basic_machine=np1-gould - ;; - nsr-tandem) - basic_machine=nsr-tandem - ;; - op50n-* | op60c-*) - basic_machine=hppa1.1-oki - os=-proelf - ;; - openrisc | openrisc-*) - basic_machine=or32-unknown - ;; - os400) - basic_machine=powerpc-ibm - os=-os400 - ;; - OSE68000 | ose68000) - basic_machine=m68000-ericsson - os=-ose - ;; - os68k) - basic_machine=m68k-none - os=-os68k - ;; - pa-hitachi) - basic_machine=hppa1.1-hitachi - os=-hiuxwe2 - ;; - paragon) - basic_machine=i860-intel - os=-osf - ;; - pbd) - basic_machine=sparc-tti - ;; - pbb) - basic_machine=m68k-tti - ;; - pc532 | pc532-*) - basic_machine=ns32k-pc532 - ;; - pc98) - basic_machine=i386-pc - ;; - pc98-*) - basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium | p5 | k5 | k6 | nexgen | viac3) - basic_machine=i586-pc - ;; - pentiumpro | p6 | 6x86 | athlon | athlon_*) - basic_machine=i686-pc - ;; - pentiumii | pentium2 | pentiumiii | pentium3) - basic_machine=i686-pc - ;; - pentium4) - basic_machine=i786-pc - ;; - pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*) - basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumpro-* | p6-* | 6x86-* | athlon-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*) - basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pentium4-*) - basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - pn) - basic_machine=pn-gould - ;; - power) basic_machine=power-ibm - ;; - ppc) basic_machine=powerpc-unknown - ;; - ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppcle | powerpclittle | ppc-le | powerpc-little) - basic_machine=powerpcle-unknown - ;; - ppcle-* | powerpclittle-*) - basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64) basic_machine=powerpc64-unknown - ;; - ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ppc64le | powerpc64little | ppc64-le | powerpc64-little) - basic_machine=powerpc64le-unknown - ;; - ppc64le-* | powerpc64little-*) - basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'` - ;; - ps2) - basic_machine=i386-ibm - ;; - pw32) - basic_machine=i586-unknown - os=-pw32 - ;; - rdos) - basic_machine=i386-pc - os=-rdos - ;; - rom68k) - basic_machine=m68k-rom68k - os=-coff - ;; - rm[46]00) - basic_machine=mips-siemens - ;; - rtpc | rtpc-*) - basic_machine=romp-ibm - ;; - s390 | s390-*) - basic_machine=s390-ibm - ;; - s390x | s390x-*) - basic_machine=s390x-ibm - ;; - sa29200) - basic_machine=a29k-amd - os=-udi - ;; - sb1) - basic_machine=mipsisa64sb1-unknown - ;; - sb1el) - basic_machine=mipsisa64sb1el-unknown - ;; - sde) - basic_machine=mipsisa32-sde - os=-elf - ;; - sei) - basic_machine=mips-sei - os=-seiux - ;; - sequent) - basic_machine=i386-sequent - ;; - sh) - basic_machine=sh-hitachi - os=-hms - ;; - sh5el) - basic_machine=sh5le-unknown - ;; - sh64) - basic_machine=sh64-unknown - ;; - sparclite-wrs | simso-wrs) - basic_machine=sparclite-wrs - os=-vxworks - ;; - sps7) - basic_machine=m68k-bull - os=-sysv2 - ;; - spur) - basic_machine=spur-unknown - ;; - st2000) - basic_machine=m68k-tandem - ;; - stratus) - basic_machine=i860-stratus - os=-sysv4 - ;; - sun2) - basic_machine=m68000-sun - ;; - sun2os3) - basic_machine=m68000-sun - os=-sunos3 - ;; - sun2os4) - basic_machine=m68000-sun - os=-sunos4 - ;; - sun3os3) - basic_machine=m68k-sun - os=-sunos3 - ;; - sun3os4) - basic_machine=m68k-sun - os=-sunos4 - ;; - sun4os3) - basic_machine=sparc-sun - os=-sunos3 - ;; - sun4os4) - basic_machine=sparc-sun - os=-sunos4 - ;; - sun4sol2) - basic_machine=sparc-sun - os=-solaris2 - ;; - sun3 | sun3-*) - basic_machine=m68k-sun - ;; - sun4) - basic_machine=sparc-sun - ;; - sun386 | sun386i | roadrunner) - basic_machine=i386-sun - ;; - sv1) - basic_machine=sv1-cray - os=-unicos - ;; - symmetry) - basic_machine=i386-sequent - os=-dynix - ;; - t3e) - basic_machine=alphaev5-cray - os=-unicos - ;; - t90) - basic_machine=t90-cray - os=-unicos - ;; - tic54x | c54x*) - basic_machine=tic54x-unknown - os=-coff - ;; - tic55x | c55x*) - basic_machine=tic55x-unknown - os=-coff - ;; - tic6x | c6x*) - basic_machine=tic6x-unknown - os=-coff - ;; - tx39) - basic_machine=mipstx39-unknown - ;; - tx39el) - basic_machine=mipstx39el-unknown - ;; - toad1) - basic_machine=pdp10-xkl - os=-tops20 - ;; - tower | tower-32) - basic_machine=m68k-ncr - ;; - tpf) - basic_machine=s390x-ibm - os=-tpf - ;; - udi29k) - basic_machine=a29k-amd - os=-udi - ;; - ultra3) - basic_machine=a29k-nyu - os=-sym1 - ;; - v810 | necv810) - basic_machine=v810-nec - os=-none - ;; - vaxv) - basic_machine=vax-dec - os=-sysv - ;; - vms) - basic_machine=vax-dec - os=-vms - ;; - vpp*|vx|vx-*) - basic_machine=f301-fujitsu - ;; - vxworks960) - basic_machine=i960-wrs - os=-vxworks - ;; - vxworks68) - basic_machine=m68k-wrs - os=-vxworks - ;; - vxworks29k) - basic_machine=a29k-wrs - os=-vxworks - ;; - w65*) - basic_machine=w65-wdc - os=-none - ;; - w89k-*) - basic_machine=hppa1.1-winbond - os=-proelf - ;; - xbox) - basic_machine=i686-pc - os=-mingw32 - ;; - xps | xps100) - basic_machine=xps100-honeywell - ;; - ymp) - basic_machine=ymp-cray - os=-unicos - ;; - z8k-*-coff) - basic_machine=z8k-unknown - os=-sim - ;; - none) - basic_machine=none-none - os=-none - ;; - -# Here we handle the default manufacturer of certain CPU types. It is in -# some cases the only manufacturer, in others, it is the most popular. - w89k) - basic_machine=hppa1.1-winbond - ;; - op50n) - basic_machine=hppa1.1-oki - ;; - op60c) - basic_machine=hppa1.1-oki - ;; - romp) - basic_machine=romp-ibm - ;; - mmix) - basic_machine=mmix-knuth - ;; - rs6000) - basic_machine=rs6000-ibm - ;; - vax) - basic_machine=vax-dec - ;; - pdp10) - # there are many clones, so DEC is not a safe bet - basic_machine=pdp10-unknown - ;; - pdp11) - basic_machine=pdp11-dec - ;; - we32k) - basic_machine=we32k-att - ;; - sh[1234] | sh[24]a | sh[34]eb | sh[1234]le | sh[23]ele) - basic_machine=sh-unknown - ;; - sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v) - basic_machine=sparc-sun - ;; - cydra) - basic_machine=cydra-cydrome - ;; - orion) - basic_machine=orion-highlevel - ;; - orion105) - basic_machine=clipper-highlevel - ;; - mac | mpw | mac-mpw) - basic_machine=m68k-apple - ;; - pmac | pmac-mpw) - basic_machine=powerpc-apple - ;; - *-unknown) - # Make sure to match an already-canonicalized machine name. - ;; - *) - echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 - exit 1 - ;; -esac - -# Here we canonicalize certain aliases for manufacturers. -case $basic_machine in - *-digital*) - basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` - ;; - *-commodore*) - basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` - ;; - *) - ;; -esac - -# Decode manufacturer-specific aliases for certain operating systems. - -if [ x"$os" != x"" ] -then -case $os in - # First match some system type aliases - # that might get confused with valid system types. - # -solaris* is a basic system type, with this one exception. - -solaris1 | -solaris1.*) - os=`echo $os | sed -e 's|solaris1|sunos4|'` - ;; - -solaris) - os=-solaris2 - ;; - -svr4*) - os=-sysv4 - ;; - -unixware*) - os=-sysv4.2uw - ;; - -gnu/linux*) - os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` - ;; - # First accept the basic system types. - # The portable systems comes first. - # Each alternative MUST END IN A *, to match a version number. - # -sysv* is not here because it comes later, after sysvr4. - -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ - | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ - | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ - | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ - | -aos* \ - | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ - | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ - | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \ - | -openbsd* | -solidbsd* \ - | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \ - | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ - | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ - | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ - | -chorusos* | -chorusrdb* \ - | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ - | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \ - | -uxpv* | -beos* | -mpeix* | -udk* \ - | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \ - | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ - | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \ - | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \ - | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \ - | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \ - | -skyos* | -haiku* | -rdos* | -toppers*) - # Remember, each alternative MUST END IN *, to match a version number. - ;; - -qnx*) - case $basic_machine in - x86-* | i*86-*) - ;; - *) - os=-nto$os - ;; - esac - ;; - -nto-qnx*) - ;; - -nto*) - os=`echo $os | sed -e 's|nto|nto-qnx|'` - ;; - -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ - | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \ - | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) - ;; - -mac*) - os=`echo $os | sed -e 's|mac|macos|'` - ;; - -linux-dietlibc) - os=-linux-dietlibc - ;; - -linux*) - os=`echo $os | sed -e 's|linux|linux-gnu|'` - ;; - -sunos5*) - os=`echo $os | sed -e 's|sunos5|solaris2|'` - ;; - -sunos6*) - os=`echo $os | sed -e 's|sunos6|solaris3|'` - ;; - -opened*) - os=-openedition - ;; - -os400*) - os=-os400 - ;; - -wince*) - os=-wince - ;; - -osfrose*) - os=-osfrose - ;; - -osf*) - os=-osf - ;; - -utek*) - os=-bsd - ;; - -dynix*) - os=-bsd - ;; - -acis*) - os=-aos - ;; - -atheos*) - os=-atheos - ;; - -syllable*) - os=-syllable - ;; - -386bsd) - os=-bsd - ;; - -ctix* | -uts*) - os=-sysv - ;; - -nova*) - os=-rtmk-nova - ;; - -ns2 ) - os=-nextstep2 - ;; - -nsk*) - os=-nsk - ;; - # Preserve the version number of sinix5. - -sinix5.*) - os=`echo $os | sed -e 's|sinix|sysv|'` - ;; - -sinix*) - os=-sysv4 - ;; - -tpf*) - os=-tpf - ;; - -triton*) - os=-sysv3 - ;; - -oss*) - os=-sysv3 - ;; - -svr4) - os=-sysv4 - ;; - -svr3) - os=-sysv3 - ;; - -sysvr4) - os=-sysv4 - ;; - # This must come after -sysvr4. - -sysv*) - ;; - -ose*) - os=-ose - ;; - -es1800*) - os=-ose - ;; - -xenix) - os=-xenix - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - os=-mint - ;; - -aros*) - os=-aros - ;; - -kaos*) - os=-kaos - ;; - -zvmoe) - os=-zvmoe - ;; - -none) - ;; - *) - # Get rid of the `-' at the beginning of $os. - os=`echo $os | sed 's/[^-]*-//'` - echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 - exit 1 - ;; -esac -else - -# Here we handle the default operating systems that come with various machines. -# The value should be what the vendor currently ships out the door with their -# machine or put another way, the most popular os provided with the machine. - -# Note that if you're going to try to match "-MANUFACTURER" here (say, -# "-sun"), then you have to tell the case statement up towards the top -# that MANUFACTURER isn't an operating system. Otherwise, code above -# will signal an error saying that MANUFACTURER isn't an operating -# system, and we'll never get to this point. - -case $basic_machine in - score-*) - os=-elf - ;; - spu-*) - os=-elf - ;; - *-acorn) - os=-riscix1.2 - ;; - arm*-rebel) - os=-linux - ;; - arm*-semi) - os=-aout - ;; - c4x-* | tic4x-*) - os=-coff - ;; - # This must come before the *-dec entry. - pdp10-*) - os=-tops20 - ;; - pdp11-*) - os=-none - ;; - *-dec | vax-*) - os=-ultrix4.2 - ;; - m68*-apollo) - os=-domain - ;; - i386-sun) - os=-sunos4.0.2 - ;; - m68000-sun) - os=-sunos3 - # This also exists in the configure program, but was not the - # default. - # os=-sunos4 - ;; - m68*-cisco) - os=-aout - ;; - mips*-cisco) - os=-elf - ;; - mips*-*) - os=-elf - ;; - or32-*) - os=-coff - ;; - *-tti) # must be before sparc entry or we get the wrong os. - os=-sysv3 - ;; - sparc-* | *-sun) - os=-sunos4.1.1 - ;; - *-be) - os=-beos - ;; - *-haiku) - os=-haiku - ;; - *-ibm) - os=-aix - ;; - *-knuth) - os=-mmixware - ;; - *-wec) - os=-proelf - ;; - *-winbond) - os=-proelf - ;; - *-oki) - os=-proelf - ;; - *-hp) - os=-hpux - ;; - *-hitachi) - os=-hiux - ;; - i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) - os=-sysv - ;; - *-cbm) - os=-amigaos - ;; - *-dg) - os=-dgux - ;; - *-dolphin) - os=-sysv3 - ;; - m68k-ccur) - os=-rtu - ;; - m88k-omron*) - os=-luna - ;; - *-next ) - os=-nextstep - ;; - *-sequent) - os=-ptx - ;; - *-crds) - os=-unos - ;; - *-ns) - os=-genix - ;; - i370-*) - os=-mvs - ;; - *-next) - os=-nextstep3 - ;; - *-gould) - os=-sysv - ;; - *-highlevel) - os=-bsd - ;; - *-encore) - os=-bsd - ;; - *-sgi) - os=-irix - ;; - *-siemens) - os=-sysv4 - ;; - *-masscomp) - os=-rtu - ;; - f30[01]-fujitsu | f700-fujitsu) - os=-uxpv - ;; - *-rom68k) - os=-coff - ;; - *-*bug) - os=-coff - ;; - *-apple) - os=-macos - ;; - *-atari*) - os=-mint - ;; - *) - os=-none - ;; -esac -fi - -# Here we handle the case where we know the os, and the CPU type, but not the -# manufacturer. We pick the logical manufacturer. -vendor=unknown -case $basic_machine in - *-unknown) - case $os in - -riscix*) - vendor=acorn - ;; - -sunos*) - vendor=sun - ;; - -aix*) - vendor=ibm - ;; - -beos*) - vendor=be - ;; - -hpux*) - vendor=hp - ;; - -mpeix*) - vendor=hp - ;; - -hiux*) - vendor=hitachi - ;; - -unos*) - vendor=crds - ;; - -dgux*) - vendor=dg - ;; - -luna*) - vendor=omron - ;; - -genix*) - vendor=ns - ;; - -mvs* | -opened*) - vendor=ibm - ;; - -os400*) - vendor=ibm - ;; - -ptx*) - vendor=sequent - ;; - -tpf*) - vendor=ibm - ;; - -vxsim* | -vxworks* | -windiss*) - vendor=wrs - ;; - -aux*) - vendor=apple - ;; - -hms*) - vendor=hitachi - ;; - -mpw* | -macos*) - vendor=apple - ;; - -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) - vendor=atari - ;; - -vos*) - vendor=stratus - ;; - esac - basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` - ;; -esac - -echo $basic_machine$os -exit - -# Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "timestamp='" -# time-stamp-format: "%:y-%02m-%02d" -# time-stamp-end: "'" -# End: diff --git a/configure b/configure index 6b51d2925153..a6e812b68c6c 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for file 5.00. +# Generated by GNU Autoconf 2.61 for file 5.03. # # Report bugs to . # @@ -595,8 +595,8 @@ if test "X${echo_test_string+set}" != Xset; then # find a string as large as possible, as long as the shell can cope with it for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if (echo_test_string="`eval $cmd`") 2>/dev/null && - echo_test_string="`eval $cmd`" && + if (echo_test_string=`eval $cmd`) 2>/dev/null && + echo_test_string=`eval $cmd` && (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null then break @@ -728,8 +728,8 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='file' PACKAGE_TARNAME='file' -PACKAGE_VERSION='5.00' -PACKAGE_STRING='file 5.00' +PACKAGE_VERSION='5.03' +PACKAGE_STRING='file 5.03' PACKAGE_BUGREPORT='christos@astron.com' # Factoring default headers for most tests. @@ -827,6 +827,7 @@ am__leading_dot AMTAR am__tar am__untar +pkgdatadir fsect FSECT5_TRUE FSECT5_FALSE @@ -856,11 +857,14 @@ host host_cpu host_vendor host_os +SED GREP EGREP ECHO AR RANLIB +DSYMUTIL +NMEDIT CPP CXX CXXFLAGS @@ -1395,7 +1399,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures file 5.00 to adapt to many kinds of systems. +\`configure' configures file 5.03 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1465,7 +1469,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of file 5.00:";; + short | recursive ) echo "Configuration of file 5.03:";; esac cat <<\_ACEOF @@ -1572,7 +1576,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -file configure 5.00 +file configure 5.03 generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, @@ -1586,7 +1590,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by file $as_me 5.00, which was +It was created by file $as_me 5.03, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ @@ -2276,7 +2280,7 @@ fi # Define the identity of the package. PACKAGE='file' - VERSION='5.00' + VERSION='5.03' cat >>confdefs.h <<_ACEOF @@ -2424,6 +2428,7 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h" +#AC_CONFIG_MACRO_DIR([m4]) { echo "$as_me:$LINENO: checking for builtin ELF support" >&5 echo $ECHO_N "checking for builtin ELF support... $ECHO_C" >&6; } @@ -2508,6 +2513,8 @@ echo "${ECHO_T}no" >&6; } fi +pkgdatadir='$(datadir)/misc' + if test x$fsect = x5; then FSECT5_TRUE= @@ -4001,12 +4008,13 @@ do test -z "$as_dir" && as_dir=. for lt_ac_prog in sed gsed; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then + if { test -f "$as_dir/$lt_ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$lt_ac_prog$ac_exec_ext"; }; then lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" fi done done done +IFS=$as_save_IFS lt_ac_max=0 lt_ac_count=0 # Add /usr/xpg4/bin/sed as it is typically found on Solaris @@ -4041,6 +4049,7 @@ done fi SED=$lt_cv_path_SED + { echo "$as_me:$LINENO: result: $SED" >&5 echo "${ECHO_T}$SED" >&6; } @@ -4264,7 +4273,7 @@ else if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. + # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 &1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" + lt_nm_to_check="${ac_tool_prefix}nm" + if test -n "$ac_tool_prefix" && test "$build" = "$host"; then + lt_nm_to_check="$lt_nm_to_check nm" + fi + for lt_tmp_nm in $lt_nm_to_check; do + lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR + for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do + IFS="$lt_save_ifs" + test -z "$ac_dir" && ac_dir=. + tmp_nm="$ac_dir/$lt_tmp_nm" + if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + # Tru64's nm complains that /dev/null is an invalid object file + case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in + */dev/null* | *'Invalid file or object type'*) + lt_cv_path_NM="$tmp_nm -B" break ;; *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags + case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + */dev/null*) + lt_cv_path_NM="$tmp_nm -p" + break + ;; + *) + lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + ;; + esac ;; esac - esac - fi + fi + done + IFS="$lt_save_ifs" done - IFS="$lt_save_ifs" test -z "$lt_cv_path_NM" && lt_cv_path_NM=nm fi fi @@ -4384,8 +4400,8 @@ fi echo "${ECHO_T}$lt_cv_path_NM" >&6; } NM="$lt_cv_path_NM" -{ echo "$as_me:$LINENO: checking how to recognise dependent libraries" >&5 -echo $ECHO_N "checking how to recognise dependent libraries... $ECHO_C" >&6; } +{ echo "$as_me:$LINENO: checking how to recognize dependent libraries" >&5 +echo $ECHO_N "checking how to recognize dependent libraries... $ECHO_C" >&6; } if test "${lt_cv_deplibs_check_method+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -4404,7 +4420,7 @@ lt_cv_deplibs_check_method='unknown' # whether `pass_all' will *always* work, you probably want this one. case $host_os in -aix4* | aix5*) +aix[4-9]*) lt_cv_deplibs_check_method=pass_all ;; @@ -4426,16 +4442,22 @@ cygwin*) mingw* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump'. - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' + # func_win32_libid shell function, so use a weaker test based on 'objdump', + # unless we find 'file', for example because we are cross-compiling. + if ( file / ) >/dev/null 2>&1; then + lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' + lt_cv_file_magic_cmd='func_win32_libid' + else + lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + lt_cv_file_magic_cmd='$OBJDUMP -f' + fi ;; darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | kfreebsd*-gnu | dragonfly*) +freebsd* | dragonfly*) if echo __ELF__ | $CC -E - | grep __ELF__ > /dev/null; then case $host_cpu in i*86 ) @@ -4457,7 +4479,7 @@ gnu*) hpux10.20* | hpux11*) lt_cv_file_magic_cmd=/usr/bin/file - case "$host_cpu" in + case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so @@ -4473,6 +4495,11 @@ hpux10.20* | hpux11*) esac ;; +interix[3-9]*) + # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here + lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' + ;; + irix5* | irix6* | nonstopux*) case $LD in *-32|*"-32 ") libmagic=32-bit;; @@ -4484,7 +4511,7 @@ irix5* | irix6* | nonstopux*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) lt_cv_deplibs_check_method=pass_all ;; @@ -4518,7 +4545,7 @@ osf3* | osf4* | osf5*) lt_cv_deplibs_check_method=pass_all ;; -sco3.2v5*) +rdos*) lt_cv_deplibs_check_method=pass_all ;; @@ -4526,7 +4553,7 @@ solaris*) lt_cv_deplibs_check_method=pass_all ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) case $host_vendor in motorola) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' @@ -4547,10 +4574,13 @@ sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) siemens) lt_cv_deplibs_check_method=pass_all ;; + pc) + lt_cv_deplibs_check_method=pass_all + ;; esac ;; -sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7* | sysv4*uw2*) +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) lt_cv_deplibs_check_method=pass_all ;; esac @@ -4568,6 +4598,9 @@ test -z "$deplibs_check_method" && deplibs_check_method=unknown # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC @@ -4603,7 +4636,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 4606 "configure"' > conftest.$ac_ext + echo '#line 4639 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -4638,7 +4671,8 @@ ia64-*-hpux*) rm -rf conftest* ;; -x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) +x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ +s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 @@ -4646,9 +4680,12 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then - case "`/usr/bin/file conftest.o`" in + case `/usr/bin/file conftest.o` in *32-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_i386_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_i386" ;; @@ -4665,6 +4702,9 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) ;; *64-bit*) case $host in + x86_64-*kfreebsd*-gnu) + LD="${LD-ld} -m elf_x86_64_fbsd" + ;; x86_64-*linux*) LD="${LD-ld} -m elf_x86_64" ;; @@ -4756,6 +4796,30 @@ echo "${ECHO_T}$lt_cv_cc_needs_belf" >&6; } CFLAGS="$SAVE_CFLAGS" fi ;; +sparc*-*solaris*) + # Find out which ABI we are using. + echo 'int i;' > conftest.$ac_ext + if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 + (eval $ac_compile) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then + case `/usr/bin/file conftest.o` in + *64-bit*) + case $lt_cv_prog_gnu_ld in + yes*) LD="${LD-ld} -m elf64_sparc" ;; + *) + if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then + LD="${LD-ld} -64" + fi + ;; + esac + ;; + esac + fi + rm -rf conftest* + ;; + esac @@ -6350,7 +6414,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu # Autoconf 2.13's AC_OBJEXT and AC_EXEEXT macros only works for C compilers! - # find the maximum length of command line arguments { echo "$as_me:$LINENO: checking the maximum length of command line arguments" >&5 echo $ECHO_N "checking the maximum length of command line arguments... $ECHO_C" >&6; } @@ -6400,12 +6463,18 @@ else elif test -x /usr/sbin/sysctl; then lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` else - lt_cv_sys_max_cmd_len=65536 # usable default for *BSD + lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs fi # And add a safety zone lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` ;; + + interix*) + # We know the value 262144 and hardcode it with a safety zone (like BSD) + lt_cv_sys_max_cmd_len=196608 + ;; + osf*) # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not @@ -6419,25 +6488,39 @@ else esac fi ;; + sco3.2v5*) + lt_cv_sys_max_cmd_len=102400 + ;; + sysv5* | sco5v6* | sysv4.2uw2*) + kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` + if test -n "$kargmax"; then + lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + else + lt_cv_sys_max_cmd_len=32768 + fi + ;; *) - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ + lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` + if test -n "$lt_cv_sys_max_cmd_len"; then + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` + else + SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} + while (test "X"`$SHELL $0 --fallback-echo "X$teststring" 2>/dev/null` \ = "XX$teststring") >/dev/null 2>&1 && - new_result=`expr "X$teststring" : ".*" 2>&1` && - lt_cv_sys_max_cmd_len=$new_result && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - teststring= - # Add a significant safety factor because C++ compilers can tack on massive - # amounts of additional arguments before passing them to the linker. - # It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + new_result=`expr "X$teststring" : ".*" 2>&1` && + lt_cv_sys_max_cmd_len=$new_result && + test $i != 17 # 1/2 MB should be enough + do + i=`expr $i + 1` + teststring=$teststring$teststring + done + teststring= + # Add a significant safety factor because C++ compilers can tack on massive + # amounts of additional arguments before passing them to the linker. + # It appears as though 1/2 is a usable value. + lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` + fi ;; esac @@ -6454,6 +6537,7 @@ fi + # Check for command to grab the raw symbol name followed by C symbol from nm. { echo "$as_me:$LINENO: checking command to parse $NM output from $compiler object" >&5 echo $ECHO_N "checking command to parse $NM output from $compiler object... $ECHO_C" >&6; } @@ -6491,7 +6575,7 @@ hpux*) # Its linker distinguishes data from code symbols lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (lt_ptr) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (lt_ptr) \&\2},/p'" ;; -linux*) +linux* | k*bsd*-gnu) if test "$host_cpu" = ia64; then symcode='[ABCDGIRSTW]' lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" @@ -6504,9 +6588,18 @@ irix* | nonstopux*) osf*) symcode='[BCDEGQRST]' ;; -solaris* | sysv5*) +solaris*) symcode='[BDRT]' ;; +sco3.2v5*) + symcode='[DT]' + ;; +sysv4.2uw2*) + symcode='[DT]' + ;; +sysv5* | sco5v6* | unixware* | OpenUNIX*) + symcode='[ABDT]' + ;; sysv4) symcode='[DFNSTU]' ;; @@ -6635,7 +6728,7 @@ EOF echo "$progname: failed program was:" >&5 cat conftest.$ac_ext >&5 fi - rm -f conftest* conftst* + rm -rf conftest* conftst* # Do not use the global_symbol_pipe unless it works. if test "$pipe_works" = yes; then @@ -6715,7 +6808,7 @@ rm="rm -f" default_ofile=libtool can_build_shared=yes -# All known linkers require a `.a' archive for static linking (except M$VC, +# All known linkers require a `.a' archive for static linking (except MSVC, # which needs '.lib'). libext=a ltmain="$ac_aux_dir/ltmain.sh" @@ -7020,6 +7113,7 @@ test -z "$AR_FLAGS" && AR_FLAGS=cru test -z "$AS" && AS=as test -z "$CC" && CC=cc test -z "$LTCC" && LTCC=$CC +test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS test -z "$DLLTOOL" && DLLTOOL=dlltool test -z "$LD" && LD=ld test -z "$LN_S" && LN_S="ln -s" @@ -7032,17 +7126,17 @@ test -z "$STRIP" && STRIP=: test -z "$ac_objext" && ac_objext=o # Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs$old_deplibs' +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then case $host_os in openbsd*) - old_postinstall_cmds="\$RANLIB -t \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" ;; *) - old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" ;; esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" @@ -7084,7 +7178,7 @@ else if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -7146,7 +7240,7 @@ else if test -n "$file_magic_test_file"; then case $deplibs_check_method in "file_magic "*) - file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` MAGIC_CMD="$lt_cv_path_MAGIC_CMD" if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | $EGREP "$file_magic_regex" > /dev/null; then @@ -7194,6 +7288,318 @@ fi ;; esac + + case $host_os in + rhapsody* | darwin*) + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. +set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_DSYMUTIL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$DSYMUTIL"; then + ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +DSYMUTIL=$ac_cv_prog_DSYMUTIL +if test -n "$DSYMUTIL"; then + { echo "$as_me:$LINENO: result: $DSYMUTIL" >&5 +echo "${ECHO_T}$DSYMUTIL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_DSYMUTIL"; then + ac_ct_DSYMUTIL=$DSYMUTIL + # Extract the first word of "dsymutil", so it can be a program name with args. +set dummy dsymutil; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_DSYMUTIL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_DSYMUTIL"; then + ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL +if test -n "$ac_ct_DSYMUTIL"; then + { echo "$as_me:$LINENO: result: $ac_ct_DSYMUTIL" >&5 +echo "${ECHO_T}$ac_ct_DSYMUTIL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_DSYMUTIL" = x; then + DSYMUTIL=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + DSYMUTIL=$ac_ct_DSYMUTIL + fi +else + DSYMUTIL="$ac_cv_prog_DSYMUTIL" +fi + + if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. +set dummy ${ac_tool_prefix}nmedit; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_NMEDIT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$NMEDIT"; then + ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +NMEDIT=$ac_cv_prog_NMEDIT +if test -n "$NMEDIT"; then + { echo "$as_me:$LINENO: result: $NMEDIT" >&5 +echo "${ECHO_T}$NMEDIT" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_NMEDIT"; then + ac_ct_NMEDIT=$NMEDIT + # Extract the first word of "nmedit", so it can be a program name with args. +set dummy nmedit; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_prog_ac_ct_NMEDIT+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + if test -n "$ac_ct_NMEDIT"; then + ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_prog_ac_ct_NMEDIT="nmedit" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + +fi +fi +ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT +if test -n "$ac_ct_NMEDIT"; then + { echo "$as_me:$LINENO: result: $ac_ct_NMEDIT" >&5 +echo "${ECHO_T}$ac_ct_NMEDIT" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + if test "x$ac_ct_NMEDIT" = x; then + NMEDIT=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&5 +echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools +whose name does not start with the host triplet. If you think this +configuration is useful to you, please write to autoconf@gnu.org." >&2;} +ac_tool_warned=yes ;; +esac + NMEDIT=$ac_ct_NMEDIT + fi +else + NMEDIT="$ac_cv_prog_NMEDIT" +fi + + + { echo "$as_me:$LINENO: checking for -single_module linker flag" >&5 +echo $ECHO_N "checking for -single_module linker flag... $ECHO_C" >&6; } +if test "${lt_cv_apple_cc_single_mod+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_apple_cc_single_mod=no + if test -z "${LT_MULTI_MODULE}"; then + # By default we will add the -single_module flag. You can override + # by either setting the environment variable LT_MULTI_MODULE + # non-empty at configure time, or by adding -multi_module to the + # link flags. + echo "int foo(void){return 1;}" > conftest.c + $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ + -dynamiclib ${wl}-single_module conftest.c + if test -f libconftest.dylib; then + lt_cv_apple_cc_single_mod=yes + rm -rf libconftest.dylib* + fi + rm conftest.c + fi +fi +{ echo "$as_me:$LINENO: result: $lt_cv_apple_cc_single_mod" >&5 +echo "${ECHO_T}$lt_cv_apple_cc_single_mod" >&6; } + { echo "$as_me:$LINENO: checking for -exported_symbols_list linker flag" >&5 +echo $ECHO_N "checking for -exported_symbols_list linker flag... $ECHO_C" >&6; } +if test "${lt_cv_ld_exported_symbols_list+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_ld_exported_symbols_list=no + save_LDFLAGS=$LDFLAGS + echo "_main" > conftest.sym + LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +int +main () +{ + + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext conftest$ac_exeext +if { (ac_try="$ac_link" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_link") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest$ac_exeext && + $as_test_x conftest$ac_exeext; then + lt_cv_ld_exported_symbols_list=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + lt_cv_ld_exported_symbols_list=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_ld_exported_symbols_list" >&5 +echo "${ECHO_T}$lt_cv_ld_exported_symbols_list" >&6; } + case $host_os in + rhapsody* | darwin1.[0123]) + _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; + darwin1.*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + darwin*) + # if running on 10.5 or later, the deployment target defaults + # to the OS version, if on x86, and 10.4, the deployment + # target defaults to 10.4. Don't you love it? + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*86*-darwin8*|10.0,*-darwin[91]*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + 10.[012]*) + _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; + 10.*) + _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; + esac + ;; + esac + if test "$lt_cv_apple_cc_single_mod" = "yes"; then + _lt_dar_single_mod='$single_module' + fi + if test "$lt_cv_ld_exported_symbols_list" = "yes"; then + _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' + else + _lt_dar_export_syms="~$NMEDIT -s \$output_objdir/\${libname}-symbols.expsym \${lib}" + fi + if test "$DSYMUTIL" != ":"; then + _lt_dsymutil="~$DSYMUTIL \$lib || :" + else + _lt_dsymutil= + fi + ;; + esac + + enable_dlopen=no enable_win32_dll=no @@ -7232,96 +7638,34 @@ objext=o objext=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}\n' +lt_simple_link_test_code='int main(){return(0);}' # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* - - -# -# Check for any special shared library compilation flags. -# -lt_prog_cc_shlib= -if test "$GCC" = no; then - case $host_os in - sco3.2v5*) - lt_prog_cc_shlib='-belf' - ;; - esac -fi -if test -n "$lt_prog_cc_shlib"; then - { echo "$as_me:$LINENO: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&5 -echo "$as_me: WARNING: \`$CC' requires \`$lt_prog_cc_shlib' to build shared libraries" >&2;} - if echo "$old_CC $old_CFLAGS " | grep "[ ]$lt_prog_cc_shlib[ ]" >/dev/null; then : - else - { echo "$as_me:$LINENO: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&5 -echo "$as_me: WARNING: add \`$lt_prog_cc_shlib' to the CC or CFLAGS env variable and reconfigure" >&2;} - lt_cv_prog_cc_can_build_shared=no - fi -fi - - -# -# Check to make sure the static flag actually works. -# -{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_prog_compiler_static works" >&5 -echo $ECHO_N "checking if $compiler static flag $lt_prog_compiler_static works... $ECHO_C" >&6; } -if test "${lt_prog_compiler_static_works+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - lt_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_prog_compiler_static" - printf "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $echo "X$_lt_linker_boilerplate" | $Xsed > conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_static_works=yes - fi - else - lt_prog_compiler_static_works=yes - fi - fi - $rm conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ echo "$as_me:$LINENO: result: $lt_prog_compiler_static_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_static_works" >&6; } - -if test x"$lt_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - +$rm -r conftest* @@ -7338,7 +7682,7 @@ if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -7346,20 +7690,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7352: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7696: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7356: \$? = $ac_status" >&5 + echo "$as_me:7700: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi @@ -7404,13 +7748,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries lt_prog_compiler_pic='-DDLL_EXPORT' ;; @@ -7420,6 +7766,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic='-fno-common' ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -7436,7 +7787,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -7473,7 +7824,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } esac ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' @@ -7483,7 +7834,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_wl='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -7506,25 +7857,41 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static='-Bstatic' ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; - pgcc* | pgf77* | pgf90*) + pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-static' + lt_prog_compiler_static='-Bstatic' ;; ccc*) lt_prog_compiler_wl='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static='-non_shared' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + esac + ;; esac ;; @@ -7534,9 +7901,8 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic='-Kpic' - lt_prog_compiler_static='-dn' + rdos*) + lt_prog_compiler_static='-non_shared' ;; solaris*) @@ -7556,7 +7922,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' @@ -7569,6 +7935,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + unicos*) lt_prog_compiler_wl='-Wl,' lt_prog_compiler_can_build_shared=no @@ -7595,12 +7967,12 @@ if test -n "$lt_prog_compiler_pic"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic works... $ECHO_C" >&6; } -if test "${lt_prog_compiler_pic_works+set}" = set; then +if test "${lt_cv_prog_compiler_pic_works+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - lt_prog_compiler_pic_works=no + lt_cv_prog_compiler_pic_works=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -7608,30 +7980,30 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7614: $lt_compile\"" >&5) + (eval echo "\"\$as_me:7986: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:7618: \$? = $ac_status" >&5 + echo "$as_me:7990: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works=yes + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes fi fi $rm conftest* fi -{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works" >&6; } +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works" >&6; } -if test x"$lt_prog_compiler_pic_works" = xyes; then +if test x"$lt_cv_prog_compiler_pic_works" = xyes; then case $lt_prog_compiler_pic in "" | " "*) ;; *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; @@ -7642,7 +8014,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic= @@ -7652,6 +8024,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works" >&6; } + +if test x"$lt_cv_prog_compiler_static_works" = xyes; then + : +else + lt_prog_compiler_static= +fi + + { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o+set}" = set; then @@ -7662,7 +8076,7 @@ else mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -7670,25 +8084,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7676: $lt_compile\"" >&5) + (eval echo "\"\$as_me:8090: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:7680: \$? = $ac_status" >&5 + echo "$as_me:8094: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -7757,12 +8171,13 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. - exclude_expsyms="_GLOBAL_OFFSET_TABLE_" + exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do @@ -7784,6 +8199,10 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -7817,7 +8236,7 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # See if GNU ld supports shared libraries. case $host_os in - aix3* | aix4* | aix5*) + aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs=no @@ -7865,10 +8284,10 @@ EOF allow_undefined_flag=unsupported always_export_symbols=no enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -7877,22 +8296,37 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs=no fi ;; - linux*) + interix[3-9]*) + hardcode_direct=no + hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; - pgf77* | pgf90* ) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -7901,13 +8335,22 @@ EOF ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac - archive_cmds='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs=no @@ -7924,7 +8367,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs=no cat <&2 @@ -7945,6 +8388,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + ;; + sunos4*) archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -7978,14 +8448,14 @@ EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct=unsupported fi ;; - aix4* | aix5*) + aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -8005,13 +8475,14 @@ EOF # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done + ;; esac exp_sym_flag='-bexport' @@ -8038,7 +8509,7 @@ EOF strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - hardcode_direct=yes + : else # We have old collect2 hardcode_direct=unsupported @@ -8049,6 +8520,7 @@ EOF hardcode_libdir_flag_spec='-L$libdir' hardcode_libdir_separator= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -8061,11 +8533,11 @@ EOF # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -8111,11 +8583,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -8128,12 +8607,12 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -8170,11 +8649,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -8191,13 +8677,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag=' ${wl}-bernotok' allow_undefined_flag=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec=' ' + whole_archive_flag_spec='$convenience' archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -8230,13 +8714,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds='true' # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib /OUT:$oldlib$oldobjs$old_deplibs' + old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes=yes ;; darwin* | rhapsody*) - case "$host_os" in + case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag='${wl}-undefined ${wl}suppress' ;; @@ -8263,19 +8747,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' - archive_cmds='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + archive_cmds='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' module_cmds='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -8315,7 +8798,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -8338,47 +8821,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + + hardcode_direct=yes + export_dynamic_flag_spec='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - ia64*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=no - hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld='+b $libdir' + hardcode_direct=no + hardcode_shlibpath_var=no ;; *) - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: hardcode_direct=yes export_dynamic_flag_spec='${wl}-E' @@ -8422,24 +8920,28 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; openbsd*) - hardcode_direct=yes - hardcode_shlibpath_var=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' + if test -f /usr/libexec/ld.so; then + hardcode_direct=yes + hardcode_shlibpath_var=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + export_dynamic_flag_spec='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec='-R$libdir' + ;; + *) + archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='${wl}-rpath,$libdir' + ;; + esac + fi else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac + ld_shlibs=no fi ;; @@ -8480,14 +8982,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator=: ;; - sco3.2v5*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag=' -z text' if test "$GCC" = yes; then @@ -8506,17 +9000,16 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; + if test "$GCC" = yes; then + whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' + fi + ;; esac link_all_deplibs=yes ;; @@ -8573,36 +9066,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag='${wl}-z,text' + archive_cmds_need_lc=no hardcode_shlibpath_var=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no ;; - sysv5*) - no_undefined_flag=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag='${wl}-z,text' + allow_undefined_flag='${wl}-z,nodefs' + archive_cmds_need_lc=no hardcode_shlibpath_var=no + hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator=':' + link_all_deplibs=yes + export_dynamic_flag_spec='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -8621,11 +9123,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi echo "${ECHO_T}$ld_shlibs" >&6; } test "$ld_shlibs" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -8646,7 +9143,7 @@ x|xyes) { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 @@ -8658,6 +9155,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl + pic_flag=$lt_prog_compiler_pic compiler_flags=-v linker_flags=-v verstring= @@ -8703,17 +9201,55 @@ shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" + if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then + case $host_os in + darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; + *) lt_awk_arg="/^libraries:/" ;; + esac + lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` + if echo "$lt_search_path_spec" | grep ';' >/dev/null ; then # if the path contains ";" then we assume it to be the separator # otherwise default to the standard path separator (i.e. ":") - it is # assumed that no part of a normal pathname contains ";" but that should # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e 's/;/ /g'` else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` + lt_search_path_spec=`echo "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` fi + # Ok, now we have the path, separated by spaces, we can step through it + # and add multilib dir if necessary. + lt_tmp_lt_search_path_spec= + lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` + for lt_sys_path in $lt_search_path_spec; do + if test -d "$lt_sys_path/$lt_multi_os_dir"; then + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" + else + test -d "$lt_sys_path" && \ + lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" + fi + done + lt_search_path_spec=`echo $lt_tmp_lt_search_path_spec | awk ' +BEGIN {RS=" "; FS="/|\n";} { + lt_foo=""; + lt_count=0; + for (lt_i = NF; lt_i > 0; lt_i--) { + if ($lt_i != "" && $lt_i != ".") { + if ($lt_i == "..") { + lt_count++; + } else { + if (lt_count == 0) { + lt_foo="/" $lt_i lt_foo; + } else { + lt_count--; + } + } + } + } + if (lt_foo != "") { lt_freq[lt_foo]++; } + if (lt_freq[lt_foo] == 1) { print lt_foo; } +}'` + sys_lib_search_path_spec=`echo $lt_search_path_spec` else sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" fi @@ -8734,7 +9270,7 @@ aix3*) soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no @@ -8818,7 +9354,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -8871,13 +9408,9 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + + sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -8894,22 +9427,17 @@ freebsd1*) dynamic_linker=no ;; -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -8931,10 +9459,15 @@ freebsd* | dragonfly*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -8954,7 +9487,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -8994,6 +9527,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -9037,7 +9582,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -9053,7 +9598,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -9066,18 +9611,6 @@ linux*) dynamic_linker='GNU/Linux ld.so' ;; -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -9115,6 +9648,7 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in @@ -9158,11 +9692,8 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH +rdos*) + dynamic_linker=no ;; solaris*) @@ -9190,7 +9721,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -9223,6 +9754,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -9238,6 +9792,26 @@ esac echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action= @@ -9290,6 +9864,7 @@ else darwin*) if test -n "$STRIP" ; then striplib="$STRIP -x" + old_striplib="$STRIP -S" { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } else @@ -9551,7 +10126,7 @@ fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" else { echo "$as_me:$LINENO: checking for dlopen" >&5 echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } @@ -9827,7 +10402,7 @@ fi { echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" fi @@ -9860,7 +10435,7 @@ fi test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" save_LIBS="$LIBS" LIBS="$lt_cv_dlopen_libs $LIBS" @@ -9876,7 +10451,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; esac else : # compilation failed @@ -9962,7 +10539,7 @@ fi echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" + wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } if test "${lt_cv_dlopen_self_static+set}" = set; then @@ -9974,7 +10551,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null + (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; + x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; esac else : # compilation failed @@ -10078,7 +10657,7 @@ echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } fi -# Report which librarie types wil actually be built +# Report which library types will actually be built { echo "$as_me:$LINENO: checking if libtool supports shared libraries" >&5 echo $ECHO_N "checking if libtool supports shared libraries... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $can_build_shared" >&5 @@ -10090,7 +10669,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -10099,7 +10678,7 @@ aix3*) fi ;; -aix4* | aix5*) +aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -10128,7 +10707,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -10155,6 +10734,7 @@ if test -f "$ltmain"; then predeps \ postdeps \ compiler_lib_search_path \ + compiler_lib_search_dirs \ archive_cmds \ archive_expsym_cmds \ postinstall_cmds \ @@ -10170,6 +10750,7 @@ if test -f "$ltmain"; then module_cmds \ module_expsym_cmds \ lt_cv_prog_compiler_c_o \ + fix_srcfile_path \ exclude_expsyms \ include_expsyms; do @@ -10214,7 +10795,7 @@ echo "$as_me: creating $ofile" >&6;} # Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) # NOTE: Changes made to this file will be lost: look at ltmain.sh. # -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 +# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 # Free Software Foundation, Inc. # # This file is part of GNU Libtool: @@ -10294,6 +10875,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler @@ -10447,6 +11031,10 @@ predeps=$lt_predeps # shared library. postdeps=$lt_postdeps +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path @@ -10535,7 +11123,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols @@ -10624,6 +11212,9 @@ echo "$as_me: WARNING: output file \`$ofile' does not look like a libtool script echo "$as_me: WARNING: using \`LTCC=$LTCC', extracted from \`$ofile'" >&2;} fi fi + if test -z "$LTCFLAGS"; then + eval "`$SHELL ${ofile} --config | grep '^LTCFLAGS='`" + fi # Extract list of available tagged configurations in $ofile. # Note that this assumes the entire list is on one line. @@ -10676,6 +11267,7 @@ hardcode_libdir_flag_spec_CXX= hardcode_libdir_flag_spec_ld_CXX= hardcode_libdir_separator_CXX= hardcode_minus_L_CXX=no +hardcode_shlibpath_var_CXX=unsupported hardcode_automatic_CXX=no module_cmds_CXX= module_expsym_cmds_CXX= @@ -10691,41 +11283,45 @@ postdep_objects_CXX= predeps_CXX= postdeps_CXX= compiler_lib_search_path_CXX= +compiler_lib_search_dirs_CXX= # Source file extension for C++ test sources. -ac_ext=cc +ac_ext=cpp # Object file extension for compiled C++ test sources. objext=o objext_CXX=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;\n" +lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(int, char *) { return(0); }\n' +lt_simple_link_test_code='int main(int, char *[]) { return(0); }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* # Allow CC to be a program name with arguments. @@ -10738,12 +11334,12 @@ lt_save_path_LD=$lt_cv_path_LD if test -n "${lt_cv_prog_gnu_ldcxx+set}"; then lt_cv_prog_gnu_ld=$lt_cv_prog_gnu_ldcxx else - unset lt_cv_prog_gnu_ld + $as_unset lt_cv_prog_gnu_ld fi if test -n "${lt_cv_path_LDCXX+set}"; then lt_cv_path_LD=$lt_cv_path_LDCXX else - unset lt_cv_path_LD + $as_unset lt_cv_path_LD fi test -z "${LDCXX+set}" || LD=$LDCXX CC=${CXX-"c++"} @@ -10829,7 +11425,7 @@ else if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then lt_cv_path_LD="$ac_dir/$ac_prog" # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some GNU ld's only accept -v. + # but apparently some variants of GNU ld only accept -v. # Break only if it was the GNU/non-GNU ld that we prefer. case `"$lt_cv_path_LD" -v 2>&1 &6; } if test "${lt_cv_prog_gnu_ld+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - # I'd rather use --version here, but apparently some GNU ld's only accept -v. + # I'd rather use --version here, but apparently some GNU lds only accept -v. case `$LD -v 2>&1 /dev/null then # We have reworked collect2 - hardcode_direct_CXX=yes + : else # We have old collect2 hardcode_direct_CXX=unsupported @@ -10991,6 +11588,7 @@ case $host_os in hardcode_libdir_flag_spec_CXX='-L$libdir' hardcode_libdir_separator_CXX= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -11053,11 +11651,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -11071,12 +11676,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -11113,11 +11718,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -11134,16 +11746,26 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_CXX=' ${wl}-bernotok' allow_undefined_flag_CXX=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_CXX=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_CXX=' ' + whole_archive_flag_spec_CXX='$convenience' archive_cmds_need_lc_CXX=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; + + beos*) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag_CXX=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds_CXX='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs_CXX=no + fi + ;; + chorus*) case $cc_basename in *) @@ -11153,7 +11775,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi esac ;; - cygwin* | mingw* | pw32*) # _LT_AC_TAGVAR(hardcode_libdir_flag_spec, CXX) is actually meaningless, # as there is no search path for DLLs. @@ -11163,7 +11784,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi enable_shared_with_static_runtimes_CXX=yes if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_CXX='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_CXX='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -11172,65 +11793,37 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared -nostdlib $output_objdir/$soname.def $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_CXX=no fi ;; darwin* | rhapsody*) - case "$host_os" in - rhapsody* | darwin1.[012]) - allow_undefined_flag_CXX='${wl}-undefined ${wl}suppress' - ;; - *) # Darwin 1.3 on - if test -z ${MACOSX_DEPLOYMENT_TARGET} ; then - allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - else - case ${MACOSX_DEPLOYMENT_TARGET} in - 10.[012]) - allow_undefined_flag_CXX='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' - ;; - 10.*) - allow_undefined_flag_CXX='${wl}-undefined ${wl}dynamic_lookup' - ;; - esac - fi - ;; - esac archive_cmds_need_lc_CXX=no hardcode_direct_CXX=no hardcode_automatic_CXX=yes hardcode_shlibpath_var_CXX=unsupported whole_archive_flag_spec_CXX='' link_all_deplibs_CXX=yes - - if test "$GXX" = yes ; then - lt_int_apple_cc_single_mod=no + allow_undefined_flag_CXX="$_lt_dar_allow_undefined" + if test "$GXX" = yes ; then output_verbose_link_cmd='echo' - if $CC -dumpspecs 2>&1 | $EGREP 'single_module' >/dev/null ; then - lt_int_apple_cc_single_mod=yes + archive_cmds_CXX="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_CXX="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_CXX="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" + if test "$lt_cv_apple_cc_single_mod" != "yes"; then + archive_cmds_CXX="\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dsymutil}" + archive_expsym_cmds_CXX="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \${lib}-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \${lib}-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring${_lt_dar_export_syms}${_lt_dsymutil}" fi - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_cmds_CXX='$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - else - archive_cmds_CXX='$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - fi - module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - if test "X$lt_int_apple_cc_single_mod" = Xyes ; then - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib -single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - else - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -r -keep_private_externs -nostdlib -o ${lib}-master.o $libobjs~$CC -dynamiclib $allow_undefined_flag -o $lib ${lib}-master.o $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + archive_cmds_CXX='$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' module_cmds_CXX='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj ${wl}-single_module $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_CXX='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -11264,7 +11857,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi freebsd-elf*) archive_cmds_need_lc_CXX=no ;; - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions ld_shlibs_CXX=yes @@ -11309,34 +11902,21 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; hpux10*|hpux11*) if test $with_gnu_ld = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_CXX='+b $libdir' - hardcode_libdir_separator_CXX=: - ;; - ia64*) - hardcode_libdir_flag_spec_CXX='-L$libdir' - ;; + hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_CXX=: + + case $host_cpu in + hppa*64*|ia64*) ;; *) - hardcode_libdir_flag_spec_CXX='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_CXX=: export_dynamic_flag_spec_CXX='${wl}-E' ;; esac fi - case "$host_cpu" in - hppa*64*) + case $host_cpu in + hppa*64*|ia64*) hardcode_direct_CXX=no hardcode_shlibpath_var_CXX=no ;; - ia64*) - hardcode_direct_CXX=no - hardcode_shlibpath_var_CXX=no - hardcode_minus_L_CXX=yes # Not in the search PATH, - # but as the default - # location of the library. - ;; *) hardcode_direct_CXX=yes hardcode_minus_L_CXX=yes # Not in the search PATH, @@ -11351,9 +11931,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ld_shlibs_CXX=no ;; aCC*) - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -11372,9 +11955,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi *) if test "$GXX" = yes; then if test $with_gnu_ld = no; then - case "$host_cpu" in - ia64*|hppa*64*) - archive_cmds_CXX='$LD -b +h $soname -o $lib $linker_flags $libobjs $deplibs' + case $host_cpu in + hppa*64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + ;; + ia64*) + archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' ;; *) archive_cmds_CXX='$CC -shared -nostdlib -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' @@ -11388,6 +11974,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; esac ;; + interix[3-9]*) + hardcode_direct_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + export_dynamic_flag_spec_CXX='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_CXX='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_CXX='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; irix5* | irix6*) case $cc_basename in CC*) @@ -11414,7 +12014,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_CXX='${wl}-rpath ${wl}$libdir' hardcode_libdir_separator_CXX=: ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in KCC*) # Kuck and Associates, Inc. (KAI) C++ Compiler @@ -11466,14 +12066,14 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec_CXX='${wl}--export-dynamic' whole_archive_flag_spec_CXX='${wl}--whole-archive$convenience ${wl}--no-whole-archive' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname -o $lib' archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-soname ${wl}$soname ${wl}-retain-symbols-file ${wl}$export_symbols -o $lib' hardcode_libdir_flag_spec_CXX='${wl}--rpath ${wl}$libdir' export_dynamic_flag_spec_CXX='${wl}--export-dynamic' - whole_archive_flag_spec_CXX='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec_CXX='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' ;; cxx*) # Compaq C++ @@ -11494,6 +12094,29 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # dependencies. output_verbose_link_cmd='templist=`$CC -shared $CFLAGS -v conftest.$objext 2>&1 | grep "ld"`; templist=`echo $templist | $SED "s/\(^.*ld.*\)\( .*ld .*$\)/\1/"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + no_undefined_flag_CXX=' -zdefs' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_expsym_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file ${wl}$export_symbols' + hardcode_libdir_flag_spec_CXX='-R$libdir' + whole_archive_flag_spec_CXX='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + + # Not sure whether something based on + # $CC $CFLAGS -v conftest.$objext -o libconftest$shared_ext 2>&1 + # would be better. + output_verbose_link_cmd='echo' + + # Archives containing C++ object files must be created using + # "CC -xar", where "CC" is the Sun C++ compiler. This is + # necessary to make sure instantiated templates are included + # in the archive. + old_archive_cmds_CXX='$CC -xar -o $oldlib $oldobjs' + ;; + esac + ;; esac ;; lynxos*) @@ -11532,16 +12155,20 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ld_shlibs_CXX=no ;; openbsd*) - hardcode_direct_CXX=yes - hardcode_shlibpath_var_CXX=no - archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' - hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' - export_dynamic_flag_spec_CXX='${wl}-E' - whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + if test -f /usr/libexec/ld.so; then + hardcode_direct_CXX=yes + hardcode_shlibpath_var_CXX=no + archive_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $lib' + hardcode_libdir_flag_spec_CXX='${wl}-rpath,$libdir' + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_expsym_cmds_CXX='$CC -shared $pic_flag $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags ${wl}-retain-symbols-file,$export_symbols -o $lib' + export_dynamic_flag_spec_CXX='${wl}-E' + whole_archive_flag_spec_CXX="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + fi + output_verbose_link_cmd='echo' + else + ld_shlibs_CXX=no fi - output_verbose_link_cmd='echo' ;; osf3*) case $cc_basename in @@ -11670,19 +12297,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # FIXME: insert proper C++ library support ld_shlibs_CXX=no ;; - sco*) - archive_cmds_need_lc_CXX=no - case $cc_basename in - CC*) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - *) - # FIXME: insert proper C++ library support - ld_shlibs_CXX=no - ;; - esac - ;; sunos4*) case $cc_basename in CC*) @@ -11705,38 +12319,26 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi case $cc_basename in CC*) # Sun C++ 4.2, 5.x and Centerline C++ + archive_cmds_need_lc_CXX=yes no_undefined_flag_CXX=' -zdefs' - archive_cmds_CXX='$CC -G${allow_undefined_flag} -nolib -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' + archive_cmds_CXX='$CC -G${allow_undefined_flag} -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags' archive_expsym_cmds_CXX='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -nolib ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' + $CC -G${allow_undefined_flag} ${wl}-M ${wl}$lib.exp -h$soname -o $lib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags~$rm $lib.exp' hardcode_libdir_flag_spec_CXX='-R$libdir' hardcode_shlibpath_var_CXX=no case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) - # The C++ compiler is used as linker so we must use $wl - # flag to pass the commands to the underlying system - # linker. We must also pass each convience library through - # to the system linker between allextract/defaultextract. - # The C++ compiler will combine linker options so we - # cannot just pass the convience library names through - # without $wl. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. # Supported since Solaris 2.6 (maybe 2.5.1?) - whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' + whole_archive_flag_spec_CXX='-z allextract$convenience -z defaultextract' ;; esac link_all_deplibs_CXX=yes - # Commands to make compiler produce verbose output that lists - # what "hidden" libraries, object files and flags are used when - # linking a shared library. - # - # There doesn't appear to be a way to prevent this compiler from - # explicitly linking system object files so we need to strip them - # from the output so that they don't get included in the library - # dependencies. - output_verbose_link_cmd='templist=`$CC -G $CFLAGS -v conftest.$objext 2>&1 | grep "\-[LR]"`; list=""; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; echo $list' + output_verbose_link_cmd='echo' # Archives containing C++ object files must be created using # "CC -xar", where "CC" is the Sun C++ compiler. This is @@ -11778,12 +12380,69 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi hardcode_libdir_flag_spec_CXX='${wl}-R $wl$libdir' + case $host_os in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) + whole_archive_flag_spec_CXX='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + ;; + esac fi ;; esac ;; - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_CXX='${wl}-z,text' archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac + ;; + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + # For security reasons, it is highly recommended that you always + # use absolute paths for naming shared libraries, and exclude the + # DT_RUNPATH tag from executables and libraries. But doing so + # requires that you compile everything twice, which is a pain. + # So that behaviour is only enabled if SCOABSPATH is set to a + # non-empty value in the environment. Most likely only useful for + # creating official distributions of packages. + # This is a hack until libtool officially supports absolute path + # names for shared libraries. + no_undefined_flag_CXX='${wl}-z,text' + allow_undefined_flag_CXX='${wl}-z,nodefs' + archive_cmds_need_lc_CXX=no + hardcode_shlibpath_var_CXX=no + hardcode_libdir_flag_spec_CXX='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_CXX=':' + link_all_deplibs_CXX=yes + export_dynamic_flag_spec_CXX='${wl}-Bexport' + runpath_var='LD_RUN_PATH' + + case $cc_basename in + CC*) + archive_cmds_CXX='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + *) + archive_cmds_CXX='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_CXX='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + esac ;; tandem*) case $cc_basename in @@ -11814,7 +12473,6 @@ test "$ld_shlibs_CXX" = no && can_build_shared=no GCC_CXX="$GXX" LD_CXX="$LD" - cat > conftest.$ac_ext <&5 # The `*' in the case matches for architectures that use `case' in # $output_verbose_cmd can trigger glob expansion during the loop # eval without this substitution. - output_verbose_link_cmd="`$echo \"X$output_verbose_link_cmd\" | $Xsed -e \"$no_glob_subst\"`" + output_verbose_link_cmd=`$echo "X$output_verbose_link_cmd" | $Xsed -e "$no_glob_subst"` for p in `eval $output_verbose_link_cmd`; do case $p in @@ -11916,6 +12574,66 @@ fi $rm -f confest.$objext +compiler_lib_search_dirs_CXX= +if test -n "$compiler_lib_search_path_CXX"; then + compiler_lib_search_dirs_CXX=`echo " ${compiler_lib_search_path_CXX}" | ${SED} -e 's! -L! !g' -e 's!^ !!'` +fi + +# PORTME: override above test on systems where it is broken +case $host_os in +interix[3-9]*) + # Interix 3.5 installs completely hosed .la files for C++, so rather than + # hack all around it, let's just trust "g++" to DTRT. + predep_objects_CXX= + postdep_objects_CXX= + postdeps_CXX= + ;; + +linux*) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + # + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; + +solaris*) + case $cc_basename in + CC*) + # The more standards-conforming stlport4 library is + # incompatible with the Cstd library. Avoid specifying + # it if it's in CXXFLAGS. Ignore libCrun as + # -library=stlport4 depends on it. + case " $CXX $CXXFLAGS " in + *" -library=stlport4 "*) + solaris_use_stlport4=yes + ;; + esac + + # Adding this requires a known-good setup of shared libraries for + # Sun compiler versions before 5.6, else PIC objects from an old + # archive will be linked into the output, leading to subtle bugs. + if test "$solaris_use_stlport4" != yes; then + postdeps_CXX='-library=Cstd -library=Crun' + fi + ;; + esac + ;; +esac + case " $postdeps_CXX " in *" -lc "*) archive_cmds_need_lc_CXX=no ;; esac @@ -11946,12 +12664,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } # like `-m68040'. lt_prog_compiler_pic_CXX='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | os2* | pw32*) + mingw* | cygwin* | os2* | pw32*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries lt_prog_compiler_pic_CXX='-DDLL_EXPORT' ;; darwin* | rhapsody*) @@ -11963,6 +12683,10 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } # DJGPP does not support shared libraries at all lt_prog_compiler_pic_CXX= ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; sysv4*MP*) if test -d /usr/nec; then lt_prog_compiler_pic_CXX=-Kconform_pic @@ -11971,7 +12695,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) ;; *) @@ -11985,7 +12709,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } esac else case $host_os in - aix4* | aix5*) + aix[4-9]*) # All AIX code is PIC. if test "$host_cpu" = ia64; then # AIX 5 now supports IA64 processor @@ -12025,22 +12749,22 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; esac ;; - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) case $cc_basename in CC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' if test "$host_cpu" != ia64; then lt_prog_compiler_pic_CXX='+Z' fi ;; aCC*) lt_prog_compiler_wl_CXX='-Wl,' - lt_prog_compiler_static_CXX="${ac_cv_prog_cc_wl}-a ${ac_cv_prog_cc_wl}archive" - case "$host_cpu" in + lt_prog_compiler_static_CXX='${wl}-a ${wl}archive' + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -12053,6 +12777,10 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; esac ;; + interix*) + # This is c89, which is MS Visual C++ (no shared libs) + # Anyone wants to do a port? + ;; irix5* | irix6* | nonstopux*) case $cc_basename in CC*) @@ -12064,7 +12792,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; esac ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in KCC*) # KAI C++ Compiler @@ -12077,11 +12805,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic_CXX='-KPIC' lt_prog_compiler_static_CXX='-static' ;; - pgCC*) + pgCC* | pgcpp*) # Portland Group C++ compiler. lt_prog_compiler_wl_CXX='-Wl,' lt_prog_compiler_pic_CXX='-fpic' - lt_prog_compiler_static_CXX='-static' + lt_prog_compiler_static_CXX='-Bstatic' ;; cxx*) # Compaq C++ @@ -12091,6 +12819,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_CXX='-non_shared' ;; *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C++ 5.9 + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + lt_prog_compiler_wl_CXX='-Qoption ld ' + ;; + esac ;; esac ;; @@ -12132,15 +12868,6 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; psos*) ;; - sco*) - case $cc_basename in - CC*) - lt_prog_compiler_pic_CXX='-fPIC' - ;; - *) - ;; - esac - ;; solaris*) case $cc_basename in CC*) @@ -12182,7 +12909,14 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } ;; esac ;; - unixware*) + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + case $cc_basename in + CC*) + lt_prog_compiler_wl_CXX='-Wl,' + lt_prog_compiler_pic_CXX='-KPIC' + lt_prog_compiler_static_CXX='-Bstatic' + ;; + esac ;; vxworks*) ;; @@ -12202,12 +12936,12 @@ if test -n "$lt_prog_compiler_pic_CXX"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works... $ECHO_C" >&6; } -if test "${lt_prog_compiler_pic_works_CXX+set}" = set; then +if test "${lt_cv_prog_compiler_pic_works_CXX+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - lt_prog_compiler_pic_works_CXX=no + lt_cv_prog_compiler_pic_works_CXX=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_CXX -DPIC" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -12215,30 +12949,30 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12221: $lt_compile\"" >&5) + (eval echo "\"\$as_me:12955: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:12225: \$? = $ac_status" >&5 + echo "$as_me:12959: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_CXX=yes + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_CXX=yes fi fi $rm conftest* fi -{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_CXX" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_CXX" >&6; } +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_CXX" >&6; } -if test x"$lt_prog_compiler_pic_works_CXX" = xyes; then +if test x"$lt_cv_prog_compiler_pic_works_CXX" = xyes; then case $lt_prog_compiler_pic_CXX in "" | " "*) ;; *) lt_prog_compiler_pic_CXX=" $lt_prog_compiler_pic_CXX" ;; @@ -12249,7 +12983,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_CXX= @@ -12259,6 +12993,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_CXX eval lt_tmp_static_flag=\"$lt_prog_compiler_static_CXX\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_CXX+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_CXX=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_CXX=yes + fi + else + lt_cv_prog_compiler_static_works_CXX=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_CXX" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_CXX" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_CXX" = xyes; then + : +else + lt_prog_compiler_static_CXX= +fi + + { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_CXX+set}" = set; then @@ -12269,7 +13045,7 @@ else mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -12277,25 +13053,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:12283: $lt_compile\"" >&5) + (eval echo "\"\$as_me:13059: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:12287: \$? = $ac_status" >&5 + echo "$as_me:13063: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_CXX=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -12337,7 +13113,7 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in - aix4* | aix5*) + aix[4-9]*) # If we're using GNU nm, then we don't want the "-C" option. # -C means demangle to AIX nm, but means don't demangle with GNU nm if $NM -V 2>&1 | grep 'GNU' > /dev/null; then @@ -12350,22 +13126,18 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar export_symbols_cmds_CXX="$ltdll_cmds" ;; cygwin* | mingw*) - export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/;/^.* __nm__/s/^.* __nm__\([^ ]*\) [^ ]*/\1 DATA/;/^I /d;/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;/^.*[ ]__nm__/s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' ;; *) export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' ;; esac + exclude_expsyms_CXX='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' { echo "$as_me:$LINENO: result: $ld_shlibs_CXX" >&5 echo "${ECHO_T}$ld_shlibs_CXX" >&6; } test "$ld_shlibs_CXX" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -12386,7 +13158,7 @@ x|xyes) { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 @@ -12398,6 +13170,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_CXX + pic_flag=$lt_prog_compiler_pic_CXX compiler_flags=-v linker_flags=-v verstring= @@ -12443,20 +13216,7 @@ shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi + need_lib_prefix=unknown hardcode_into_libs=no @@ -12474,7 +13234,7 @@ aix3*) soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no @@ -12558,7 +13318,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -12611,13 +13372,8 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -12634,22 +13390,17 @@ freebsd1*) dynamic_linker=no ;; -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -12671,10 +13422,15 @@ freebsd* | dragonfly*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -12694,7 +13450,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -12734,6 +13490,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -12777,7 +13545,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -12793,7 +13561,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -12806,18 +13574,6 @@ linux*) dynamic_linker='GNU/Linux ld.so' ;; -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -12855,6 +13611,7 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in @@ -12898,11 +13655,8 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH +rdos*) + dynamic_linker=no ;; solaris*) @@ -12930,7 +13684,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -12963,6 +13717,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -12978,6 +13755,26 @@ esac echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_CXX= @@ -13015,808 +13812,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - ;; - *) - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - { echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_shl_load || defined __stub___shl_load -choke me -#endif - -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_shl_load=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dld_shl_load=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - { echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_dlopen || defined __stub___dlopen -choke me -#endif - -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_svld_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dld_dld_link=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -13831,7 +13826,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -13858,6 +13853,7 @@ if test -f "$ltmain"; then predeps_CXX \ postdeps_CXX \ compiler_lib_search_path_CXX \ + compiler_lib_search_dirs_CXX \ archive_cmds_CXX \ archive_expsym_cmds_CXX \ postinstall_cmds_CXX \ @@ -13873,6 +13869,7 @@ if test -f "$ltmain"; then module_cmds_CXX \ module_expsym_cmds_CXX \ lt_cv_prog_compiler_c_o_CXX \ + fix_srcfile_path_CXX \ exclude_expsyms_CXX \ include_expsyms_CXX; do @@ -13949,6 +13946,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_CXX @@ -14102,6 +14102,10 @@ predeps=$lt_predeps_CXX # shared library. postdeps=$lt_postdeps_CXX +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_CXX + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_CXX @@ -14190,7 +14194,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_CXX" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_CXX @@ -14281,32 +14285,42 @@ objext=o objext_F77=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code=" subroutine t\n return\n end\n" +lt_simple_compile_test_code="\ + subroutine t + return + end +" # Code to be used in simple link tests -lt_simple_link_test_code=" program t\n end\n" +lt_simple_link_test_code="\ + program t + end +" # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* # Allow CC to be a program name with arguments. @@ -14336,7 +14350,7 @@ test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and # are all built from PIC. -case "$host_os" in +case $host_os in aix3*) test "$enable_shared" = yes && enable_static=no if test -n "$RANLIB"; then @@ -14344,7 +14358,7 @@ aix3*) postinstall_cmds='$RANLIB $lib' fi ;; -aix4* | aix5*) +aix[4-9]*) if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then test "$enable_shared" = yes && enable_static=no fi @@ -14360,8 +14374,6 @@ test "$enable_shared" = yes || enable_static=yes { echo "$as_me:$LINENO: result: $enable_static" >&5 echo "${ECHO_T}$enable_static" >&6; } -test "$ld_shlibs_F77" = no && can_build_shared=no - GCC_F77="$G77" LD_F77="$LD" @@ -14392,13 +14404,15 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic_F77='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries lt_prog_compiler_pic_F77='-DDLL_EXPORT' ;; @@ -14408,6 +14422,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic_F77='-fno-common' ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -14424,7 +14443,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -14461,7 +14480,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } esac ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic_F77='-DDLL_EXPORT' @@ -14471,7 +14490,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_wl_F77='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -14494,25 +14513,41 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_F77='-Bstatic' ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-static' ;; - pgcc* | pgf77* | pgf90*) + pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-fpic' - lt_prog_compiler_static_F77='-static' + lt_prog_compiler_static_F77='-Bstatic' ;; ccc*) lt_prog_compiler_wl_F77='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_F77='-non_shared' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + lt_prog_compiler_wl_F77='' + ;; + esac + ;; esac ;; @@ -14522,9 +14557,8 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_F77='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic_F77='-Kpic' - lt_prog_compiler_static_F77='-dn' + rdos*) + lt_prog_compiler_static_F77='-non_shared' ;; solaris*) @@ -14544,7 +14578,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_F77='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_pic_F77='-KPIC' lt_prog_compiler_static_F77='-Bstatic' @@ -14557,6 +14591,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_F77='-Wl,' + lt_prog_compiler_pic_F77='-KPIC' + lt_prog_compiler_static_F77='-Bstatic' + ;; + unicos*) lt_prog_compiler_wl_F77='-Wl,' lt_prog_compiler_can_build_shared_F77=no @@ -14583,12 +14623,12 @@ if test -n "$lt_prog_compiler_pic_F77"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_F77 works... $ECHO_C" >&6; } -if test "${lt_prog_compiler_pic_works_F77+set}" = set; then +if test "${lt_cv_prog_compiler_pic_works_F77+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - lt_prog_compiler_pic_works_F77=no + lt_cv_prog_compiler_pic_works_F77=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_F77" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -14596,30 +14636,30 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14602: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14642: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:14606: \$? = $ac_status" >&5 + echo "$as_me:14646: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_F77=yes + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_F77=yes fi fi $rm conftest* fi -{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_F77" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_F77" >&6; } +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_F77" >&6; } -if test x"$lt_prog_compiler_pic_works_F77" = xyes; then +if test x"$lt_cv_prog_compiler_pic_works_F77" = xyes; then case $lt_prog_compiler_pic_F77 in "" | " "*) ;; *) lt_prog_compiler_pic_F77=" $lt_prog_compiler_pic_F77" ;; @@ -14630,7 +14670,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_F77= @@ -14640,6 +14680,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_F77 eval lt_tmp_static_flag=\"$lt_prog_compiler_static_F77\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_F77+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_F77=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_F77=yes + fi + else + lt_cv_prog_compiler_static_works_F77=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_F77" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_F77" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_F77" = xyes; then + : +else + lt_prog_compiler_static_F77= +fi + + { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_F77+set}" = set; then @@ -14650,7 +14732,7 @@ else mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -14658,25 +14740,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14664: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14746: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14668: \$? = $ac_status" >&5 + echo "$as_me:14750: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_F77=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -14745,12 +14827,13 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. - exclude_expsyms_F77="_GLOBAL_OFFSET_TABLE_" + exclude_expsyms_F77='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do @@ -14772,6 +14855,10 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -14805,7 +14892,7 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # See if GNU ld supports shared libraries. case $host_os in - aix3* | aix4* | aix5*) + aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_F77=no @@ -14853,10 +14940,10 @@ EOF allow_undefined_flag_F77=unsupported always_export_symbols_F77=no enable_shared_with_static_runtimes_F77=yes - export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_F77='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_F77='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -14865,22 +14952,37 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_F77=no fi ;; - linux*) + interix[3-9]*) + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_F77='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_F77='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec_F77='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; - pgf77* | pgf90* ) # Portland Group f77 and f90 compilers - whole_archive_flag_spec_F77='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_F77='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -14889,13 +14991,22 @@ EOF ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac - archive_cmds_F77='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_F77='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_F77='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_F77='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs_F77=no @@ -14912,7 +15023,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_F77=no cat <&2 @@ -14933,6 +15044,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_F77=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_F77='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_F77=no + fi + ;; + esac + ;; + sunos4*) archive_cmds_F77='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -14966,14 +15104,14 @@ EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_F77=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_F77=unsupported fi ;; - aix4* | aix5*) + aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -14993,13 +15131,14 @@ EOF # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done + ;; esac exp_sym_flag='-bexport' @@ -15026,7 +15165,7 @@ EOF strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - hardcode_direct_F77=yes + : else # We have old collect2 hardcode_direct_F77=unsupported @@ -15037,6 +15176,7 @@ EOF hardcode_libdir_flag_spec_F77='-L$libdir' hardcode_libdir_separator_F77= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -15049,11 +15189,11 @@ EOF # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -15089,11 +15229,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -15106,12 +15253,12 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_F77='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_F77="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_F77='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_F77="-z nodefs" - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -15138,11 +15285,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -15159,13 +15313,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_F77=' ${wl}-bernotok' allow_undefined_flag_F77=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_F77=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_F77=' ' + whole_archive_flag_spec_F77='$convenience' archive_cmds_need_lc_F77=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_F77="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -15198,13 +15350,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_F77='true' # FIXME: Should let the user specify the lib program. - old_archive_cmds_F77='lib /OUT:$oldlib$oldobjs$old_deplibs' + old_archive_cmds_F77='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_F77='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_F77=yes ;; darwin* | rhapsody*) - case "$host_os" in + case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_F77='${wl}-undefined ${wl}suppress' ;; @@ -15231,19 +15383,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs_F77=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' - archive_cmds_F77='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds_F77="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_F77="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_F77="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_F77="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + archive_cmds_F77='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' module_cmds_F77='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_F77='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -15283,7 +15434,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) archive_cmds_F77='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_F77='-R$libdir' hardcode_direct_F77=yes @@ -15306,47 +15457,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec_F77='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: + + hardcode_direct_F77=yes + export_dynamic_flag_spec_F77='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_F77=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds_F77='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds_F77='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_F77='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds_F77='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds_F77='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_F77='+b $libdir' - hardcode_libdir_separator_F77=: - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no - ;; - ia64*) - hardcode_libdir_flag_spec_F77='-L$libdir' - hardcode_direct_F77=no - hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_F77=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_F77=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_F77='+b $libdir' + hardcode_direct_F77=no + hardcode_shlibpath_var_F77=no ;; *) - hardcode_libdir_flag_spec_F77='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_F77=: hardcode_direct_F77=yes export_dynamic_flag_spec_F77='${wl}-E' @@ -15390,24 +15556,28 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; openbsd*) - hardcode_direct_F77=yes - hardcode_shlibpath_var_F77=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - export_dynamic_flag_spec_F77='${wl}-E' + if test -f /usr/libexec/ld.so; then + hardcode_direct_F77=yes + hardcode_shlibpath_var_F77=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + export_dynamic_flag_spec_F77='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_F77='-R$libdir' + ;; + *) + archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' + ;; + esac + fi else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_F77='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_F77='-R$libdir' - ;; - *) - archive_cmds_F77='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_F77='${wl}-rpath,$libdir' - ;; - esac + ld_shlibs_F77=no fi ;; @@ -15448,14 +15618,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator_F77=: ;; - sco3.2v5*) - archive_cmds_F77='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_F77=no - export_dynamic_flag_spec_F77='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag_F77=' -z text' if test "$GCC" = yes; then @@ -15474,17 +15636,16 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec_F77='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; + if test "$GCC" = yes; then + whole_archive_flag_spec_F77='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_F77='-z allextract$convenience -z defaultextract' + fi + ;; esac link_all_deplibs_F77=yes ;; @@ -15541,36 +15702,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds_F77='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_F77=yes - hardcode_minus_L_F77=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_F77='${wl}-z,text' + archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_F77='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds_F77='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_F77='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds_F77='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_F77='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_F77=no ;; - sysv5*) - no_undefined_flag_F77=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_F77='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_F77='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_F77= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_F77='${wl}-z,text' + allow_undefined_flag_F77='${wl}-z,nodefs' + archive_cmds_need_lc_F77=no hardcode_shlibpath_var_F77=no + hardcode_libdir_flag_spec_F77='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_F77=':' + link_all_deplibs_F77=yes + export_dynamic_flag_spec_F77='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_F77='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_F77='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_F77='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -15589,11 +15759,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi echo "${ECHO_T}$ld_shlibs_F77" >&6; } test "$ld_shlibs_F77" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -15614,7 +15779,7 @@ x|xyes) { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 @@ -15626,6 +15791,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_F77 + pic_flag=$lt_prog_compiler_pic_F77 compiler_flags=-v linker_flags=-v verstring= @@ -15671,20 +15837,7 @@ shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi + need_lib_prefix=unknown hardcode_into_libs=no @@ -15702,7 +15855,7 @@ aix3*) soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no @@ -15786,7 +15939,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -15839,13 +15993,8 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -15862,22 +16011,17 @@ freebsd1*) dynamic_linker=no ;; -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -15899,10 +16043,15 @@ freebsd* | dragonfly*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -15922,7 +16071,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -15962,6 +16111,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -16005,7 +16166,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -16021,7 +16182,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -16034,18 +16195,6 @@ linux*) dynamic_linker='GNU/Linux ld.so' ;; -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -16083,6 +16232,7 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in @@ -16126,11 +16276,8 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH +rdos*) + dynamic_linker=no ;; solaris*) @@ -16158,7 +16305,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -16191,6 +16338,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -16206,6 +16376,26 @@ esac echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_F77= @@ -16243,36 +16433,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - ;; - *) - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - ;; - esac -fi - - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -16287,7 +16447,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -16314,6 +16474,7 @@ if test -f "$ltmain"; then predeps_F77 \ postdeps_F77 \ compiler_lib_search_path_F77 \ + compiler_lib_search_dirs_F77 \ archive_cmds_F77 \ archive_expsym_cmds_F77 \ postinstall_cmds_F77 \ @@ -16329,6 +16490,7 @@ if test -f "$ltmain"; then module_cmds_F77 \ module_expsym_cmds_F77 \ lt_cv_prog_compiler_c_o_F77 \ + fix_srcfile_path_F77 \ exclude_expsyms_F77 \ include_expsyms_F77; do @@ -16405,6 +16567,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_F77 @@ -16558,6 +16723,10 @@ predeps=$lt_predeps_F77 # shared library. postdeps=$lt_postdeps_F77 +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_F77 + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_F77 @@ -16646,7 +16815,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_F77" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_F77 @@ -16704,32 +16873,35 @@ objext=o objext_GCJ=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code="class foo {}\n" +lt_simple_compile_test_code="class foo {}" # Code to be used in simple link tests -lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }\n' +lt_simple_link_test_code='public class conftest { public static void main(String[] argv) {}; }' # ltmain only uses $CC for tagged configurations so make sure $CC is set. # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* # Allow CC to be a program name with arguments. @@ -16767,7 +16939,7 @@ if test "${lt_cv_prog_compiler_rtti_exceptions+set}" = set; then else lt_cv_prog_compiler_rtti_exceptions=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-fno-rtti -fno-exceptions" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -16775,20 +16947,20 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:16781: $lt_compile\"" >&5) + (eval echo "\"\$as_me:16953: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:16785: \$? = $ac_status" >&5 + echo "$as_me:16957: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then lt_cv_prog_compiler_rtti_exceptions=yes fi fi @@ -16833,14 +17005,16 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic_GCJ='-m68020 -resident32 -malways-restore-a4' ;; - beos* | cygwin* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + ;; darwin* | rhapsody*) @@ -16849,6 +17023,11 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_pic_GCJ='-fno-common' ;; + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + msdosdjgpp*) # Just because we use GCC doesn't mean we suddenly get shared libraries # on systems that don't support them. @@ -16865,7 +17044,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } hpux*) # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -16902,17 +17081,17 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } esac ;; - mingw* | pw32* | os2*) + mingw* | cygwin* | pw32* | os2*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic_GCJ='-DDLL_EXPORT' + ;; hpux9* | hpux10* | hpux11*) lt_prog_compiler_wl_GCJ='-Wl,' # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but # not for PA HP-UX. - case "$host_cpu" in + case $host_cpu in hppa*64*|ia64*) # +Z the default ;; @@ -16935,25 +17114,41 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_GCJ='-Bstatic' ;; - linux*) + linux* | k*bsd*-gnu) case $cc_basename in icc* | ecc*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-static' ;; - pgcc* | pgf77* | pgf90*) + pgcc* | pgf77* | pgf90* | pgf95*) # Portland Group compilers (*not* the Pentium gcc compiler, # which looks to be a dead project) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-fpic' - lt_prog_compiler_static_GCJ='-static' + lt_prog_compiler_static_GCJ='-Bstatic' ;; ccc*) lt_prog_compiler_wl_GCJ='-Wl,' # All Alpha code is PIC. lt_prog_compiler_static_GCJ='-non_shared' ;; + *) + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='-Wl,' + ;; + *Sun\ F*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + lt_prog_compiler_wl_GCJ='' + ;; + esac + ;; esac ;; @@ -16963,9 +17158,8 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_GCJ='-non_shared' ;; - sco3.2v5*) - lt_prog_compiler_pic_GCJ='-Kpic' - lt_prog_compiler_static_GCJ='-dn' + rdos*) + lt_prog_compiler_static_GCJ='-non_shared' ;; solaris*) @@ -16985,7 +17179,7 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } lt_prog_compiler_static_GCJ='-Bstatic' ;; - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + sysv4 | sysv4.2uw2* | sysv4.3*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_pic_GCJ='-KPIC' lt_prog_compiler_static_GCJ='-Bstatic' @@ -16998,6 +17192,12 @@ echo $ECHO_N "checking for $compiler option to produce PIC... $ECHO_C" >&6; } fi ;; + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl_GCJ='-Wl,' + lt_prog_compiler_pic_GCJ='-KPIC' + lt_prog_compiler_static_GCJ='-Bstatic' + ;; + unicos*) lt_prog_compiler_wl_GCJ='-Wl,' lt_prog_compiler_can_build_shared_GCJ=no @@ -17024,12 +17224,12 @@ if test -n "$lt_prog_compiler_pic_GCJ"; then { echo "$as_me:$LINENO: checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works" >&5 echo $ECHO_N "checking if $compiler PIC flag $lt_prog_compiler_pic_GCJ works... $ECHO_C" >&6; } -if test "${lt_prog_compiler_pic_works_GCJ+set}" = set; then +if test "${lt_cv_prog_compiler_pic_works_GCJ+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else - lt_prog_compiler_pic_works_GCJ=no + lt_cv_prog_compiler_pic_works_GCJ=no ac_outfile=conftest.$ac_objext - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="$lt_prog_compiler_pic_GCJ" # Insert the option either (1) after the last *FLAGS variable, or # (2) before a word containing "conftest.", or (3) at the end. @@ -17037,30 +17237,30 @@ else # with a dollar sign (not a hyphen), so the echo should work correctly. # The option is referenced via a variable to avoid confusing sed. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17043: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17243: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:17047: \$? = $ac_status" >&5 + echo "$as_me:17247: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. - $echo "X$_lt_compiler_boilerplate" | $Xsed >conftest.exp - $SED '/^$/d' conftest.err >conftest.er2 - if test ! -s conftest.err || diff conftest.exp conftest.er2 >/dev/null; then - lt_prog_compiler_pic_works_GCJ=yes + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works_GCJ=yes fi fi $rm conftest* fi -{ echo "$as_me:$LINENO: result: $lt_prog_compiler_pic_works_GCJ" >&5 -echo "${ECHO_T}$lt_prog_compiler_pic_works_GCJ" >&6; } +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_pic_works_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_pic_works_GCJ" >&6; } -if test x"$lt_prog_compiler_pic_works_GCJ" = xyes; then +if test x"$lt_cv_prog_compiler_pic_works_GCJ" = xyes; then case $lt_prog_compiler_pic_GCJ in "" | " "*) ;; *) lt_prog_compiler_pic_GCJ=" $lt_prog_compiler_pic_GCJ" ;; @@ -17071,7 +17271,7 @@ else fi fi -case "$host_os" in +case $host_os in # For platforms which do not support PIC, -DPIC is meaningless: *djgpp*) lt_prog_compiler_pic_GCJ= @@ -17081,6 +17281,48 @@ case "$host_os" in ;; esac +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl_GCJ eval lt_tmp_static_flag=\"$lt_prog_compiler_static_GCJ\" +{ echo "$as_me:$LINENO: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +echo $ECHO_N "checking if $compiler static flag $lt_tmp_static_flag works... $ECHO_C" >&6; } +if test "${lt_cv_prog_compiler_static_works_GCJ+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_prog_compiler_static_works_GCJ=no + save_LDFLAGS="$LDFLAGS" + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $echo "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works_GCJ=yes + fi + else + lt_cv_prog_compiler_static_works_GCJ=yes + fi + fi + $rm -r conftest* + LDFLAGS="$save_LDFLAGS" + +fi +{ echo "$as_me:$LINENO: result: $lt_cv_prog_compiler_static_works_GCJ" >&5 +echo "${ECHO_T}$lt_cv_prog_compiler_static_works_GCJ" >&6; } + +if test x"$lt_cv_prog_compiler_static_works_GCJ" = xyes; then + : +else + lt_prog_compiler_static_GCJ= +fi + + { echo "$as_me:$LINENO: checking if $compiler supports -c -o file.$ac_objext" >&5 echo $ECHO_N "checking if $compiler supports -c -o file.$ac_objext... $ECHO_C" >&6; } if test "${lt_cv_prog_compiler_c_o_GCJ+set}" = set; then @@ -17091,7 +17333,7 @@ else mkdir conftest cd conftest mkdir out - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext lt_compiler_flag="-o out/conftest2.$ac_objext" # Insert the option either (1) after the last *FLAGS variable, or @@ -17099,25 +17341,25 @@ else # Note that $ac_compile itself does not contain backslashes and begins # with a dollar sign (not a hyphen), so the echo should work correctly. lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}? :&$lt_compiler_flag :; t' \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:17105: $lt_compile\"" >&5) + (eval echo "\"\$as_me:17347: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:17109: \$? = $ac_status" >&5 + echo "$as_me:17351: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings - $echo "X$_lt_compiler_boilerplate" | $Xsed > out/conftest.exp - $SED '/^$/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.err || diff out/conftest.exp out/conftest.er2 >/dev/null; then + $echo "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp + $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 + if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then lt_cv_prog_compiler_c_o_GCJ=yes fi fi - chmod u+w . + chmod u+w . 2>&5 $rm conftest* # SGI C++ compiler will create directory out/ii_files/ for # template instantiation @@ -17186,12 +17428,13 @@ echo $ECHO_N "checking whether the $compiler linker ($LD) supports shared librar # it will be wrapped by ` (' and `)$', so one must not match beginning or # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', # as well as any symbol that contains `d'. - exclude_expsyms_GCJ="_GLOBAL_OFFSET_TABLE_" + exclude_expsyms_GCJ='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out # platforms (ab)use it in PIC code, but their linkers get confused if # the symbol is explicitly referenced. Since portable code cannot # rely on this symbol name, it's probably fine to never include it in # preloaded symbol tables. + # Exclude shared library initialization/finalization symbols. extract_expsyms_cmds= # Just being paranoid about ensuring that cc_basename is set. for cc_temp in $compiler""; do @@ -17213,6 +17456,10 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` with_gnu_ld=no fi ;; + interix*) + # we just hope/assume this is gcc and not c89 (= MSVC++) + with_gnu_ld=yes + ;; openbsd*) with_gnu_ld=no ;; @@ -17246,7 +17493,7 @@ cc_basename=`$echo "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` # See if GNU ld supports shared libraries. case $host_os in - aix3* | aix4* | aix5*) + aix[3-9]*) # On AIX/PPC, the GNU linker is very broken if test "$host_cpu" != ia64; then ld_shlibs_GCJ=no @@ -17294,10 +17541,10 @@ EOF allow_undefined_flag_GCJ=unsupported always_export_symbols_GCJ=no enable_shared_with_static_runtimes_GCJ=yes - export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS] /s/.* \([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW] /s/.* //'\'' | sort | uniq > $export_symbols' + export_symbols_cmds_GCJ='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then - archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' # If the export-symbols file already is a .def file (1st line # is EXPORTS), use it as is; otherwise, prepend... archive_expsym_cmds_GCJ='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then @@ -17306,22 +17553,37 @@ EOF echo EXPORTS > $output_objdir/$soname.def; cat $export_symbols >> $output_objdir/$soname.def; fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--image-base=0x10000000 ${wl}--out-implib,$lib' + $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' else ld_shlibs_GCJ=no fi ;; - linux*) + interix[3-9]*) + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. + # Instead, shared libraries are loaded at an image base (0x10000000 by + # default) and relocated if they conflict, which is a slow very memory + # consuming and fragmenting process. To avoid this, we pick a random, + # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link + # time. Moving up from 0x10000000 also allows more sbrk(2) space. + archive_cmds_GCJ='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds_GCJ='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + ;; + + gnu* | linux* | k*bsd*-gnu) if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then tmp_addflag= case $cc_basename,$host_cpu in pgcc*) # Portland Group C compiler - whole_archive_flag_spec_GCJ='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag' ;; - pgf77* | pgf90* ) # Portland Group f77 and f90 compilers - whole_archive_flag_spec_GCJ='${wl}--whole-archive,`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers + whole_archive_flag_spec_GCJ='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' tmp_addflag=' $pic_flag -Mnomain' ;; ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 tmp_addflag=' -i_dynamic' ;; @@ -17330,13 +17592,22 @@ EOF ifc* | ifort*) # Intel Fortran compiler tmp_addflag=' -nofor_main' ;; esac - archive_cmds_GCJ='$CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' + case `$CC -V 2>&1 | sed 5q` in + *Sun\ C*) # Sun C 5.9 + whole_archive_flag_spec_GCJ='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}--no-whole-archive' + tmp_sharedflag='-G' ;; + *Sun\ F*) # Sun Fortran 8.3 + tmp_sharedflag='-G' ;; + *) + tmp_sharedflag='-shared' ;; + esac + archive_cmds_GCJ='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' if test $supports_anon_versioning = yes; then archive_expsym_cmds_GCJ='$echo "{ global:" > $output_objdir/$libname.ver~ cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ $echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC -shared'"$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' + $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' fi else ld_shlibs_GCJ=no @@ -17353,7 +17624,7 @@ EOF fi ;; - solaris* | sysv5*) + solaris*) if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then ld_shlibs_GCJ=no cat <&2 @@ -17374,6 +17645,33 @@ EOF fi ;; + sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) + case `$LD -v 2>&1` in + *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) + ld_shlibs_GCJ=no + cat <<_LT_EOF 1>&2 + +*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not +*** reliably create shared libraries on SCO systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.16.91.0.3 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +_LT_EOF + ;; + *) + if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`' + archive_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib' + archive_expsym_cmds_GCJ='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname,\${SCOABSPATH:+${install_libdir}/}$soname,-retain-symbols-file,$export_symbols -o $lib' + else + ld_shlibs_GCJ=no + fi + ;; + esac + ;; + sunos4*) archive_cmds_GCJ='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' wlarc= @@ -17407,14 +17705,14 @@ EOF # Note: this linker hardcodes the directories in LIBPATH if there # are no directories specified by -L. hardcode_minus_L_GCJ=yes - if test "$GCC" = yes && test -z "$link_static_flag"; then + if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then # Neither direct hardcoding nor static linking is supported with a # broken collect2. hardcode_direct_GCJ=unsupported fi ;; - aix4* | aix5*) + aix[4-9]*) if test "$host_cpu" = ia64; then # On IA64, the linker does run time linking by default, so we don't # have to do anything special. @@ -17434,13 +17732,14 @@ EOF # Test if we are trying to use run time linking or normal # AIX style linking. If -brtl is somewhere in LDFLAGS, we # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix5*) + case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) for ld_flag in $LDFLAGS; do if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then aix_use_runtimelinking=yes break fi done + ;; esac exp_sym_flag='-bexport' @@ -17467,7 +17766,7 @@ EOF strings "$collect2name" | grep resolve_lib_name >/dev/null then # We have reworked collect2 - hardcode_direct_GCJ=yes + : else # We have old collect2 hardcode_direct_GCJ=unsupported @@ -17478,6 +17777,7 @@ EOF hardcode_libdir_flag_spec_GCJ='-L$libdir' hardcode_libdir_separator_GCJ= fi + ;; esac shared_flag='-shared' if test "$aix_use_runtimelinking" = yes; then @@ -17490,11 +17790,11 @@ EOF # chokes on -Wl,-G. The following line is correct: shared_flag='-G' else - if test "$aix_use_runtimelinking" = yes; then + if test "$aix_use_runtimelinking" = yes; then shared_flag='${wl}-G' else shared_flag='${wl}-bM:SRE' - fi + fi fi fi @@ -17540,11 +17840,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -17557,12 +17864,12 @@ rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_flag_spec_GCJ='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols $shared_flag" + archive_expsym_cmds_GCJ="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" else if test "$host_cpu" = ia64; then hardcode_libdir_flag_spec_GCJ='${wl}-R $libdir:/usr/lib:/lib' allow_undefined_flag_GCJ="-z nodefs" - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$no_entry_flag \${wl}$exp_sym_flag:\$export_symbols" + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" else # Determine the default libpath from the value encoded in an empty executable. cat >conftest.$ac_ext <<_ACEOF @@ -17599,11 +17906,18 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` +lt_aix_libpath_sed=' + /Import File Strings/,/^$/ { + /^0/ { + s/^0 *\(.*\)$/\1/ + p + } + }' +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` # Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi +if test -z "$aix_libpath"; then + aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` +fi else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -17620,13 +17934,11 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # -berok will link without error, but may produce a broken library. no_undefined_flag_GCJ=' ${wl}-bernotok' allow_undefined_flag_GCJ=' ${wl}-berok' - # -bexpall does not export symbols beginning with underscore (_) - always_export_symbols_GCJ=yes # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec_GCJ=' ' + whole_archive_flag_spec_GCJ='$convenience' archive_cmds_need_lc_GCJ=yes - # This is similar to how AIX traditionally builds it's shared libraries. - archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs $compiler_flags ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' + # This is similar to how AIX traditionally builds its shared libraries. + archive_expsym_cmds_GCJ="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' fi fi ;; @@ -17659,13 +17971,13 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # The linker will automatically build a .lib file if we build a DLL. old_archive_From_new_cmds_GCJ='true' # FIXME: Should let the user specify the lib program. - old_archive_cmds_GCJ='lib /OUT:$oldlib$oldobjs$old_deplibs' + old_archive_cmds_GCJ='lib -OUT:$oldlib$oldobjs$old_deplibs' fix_srcfile_path_GCJ='`cygpath -w "$srcfile"`' enable_shared_with_static_runtimes_GCJ=yes ;; darwin* | rhapsody*) - case "$host_os" in + case $host_os in rhapsody* | darwin1.[012]) allow_undefined_flag_GCJ='${wl}-undefined ${wl}suppress' ;; @@ -17692,19 +18004,18 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi link_all_deplibs_GCJ=yes if test "$GCC" = yes ; then output_verbose_link_cmd='echo' - archive_cmds_GCJ='$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring' - module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' - module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + archive_cmds_GCJ="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" + module_cmds_GCJ="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" + archive_expsym_cmds_GCJ="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" + module_expsym_cmds_GCJ="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" else case $cc_basename in xlc*) output_verbose_link_cmd='echo' - archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $verstring' + archive_cmds_GCJ='$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}`echo $rpath/$soname` $xlcverstring' module_cmds_GCJ='$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags' - # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin ld's - archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $verstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' + # Don't fix this by using the ld -exported_symbols_list flag, it doesn't exist in older darwin lds + archive_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC -qmkshrobj $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-install_name ${wl}$rpath/$soname $xlcverstring~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' module_expsym_cmds_GCJ='sed -e "s,#.*,," -e "s,^[ ]*,," -e "s,^\(..*\),_&," < $export_symbols > $output_objdir/${libname}-symbols.expsym~$CC $allow_undefined_flag -o $lib -bundle $libobjs $deplibs$compiler_flags~nmedit -s $output_objdir/${libname}-symbols.expsym ${lib}' ;; *) @@ -17744,7 +18055,7 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | kfreebsd*-gnu | dragonfly*) + freebsd* | dragonfly*) archive_cmds_GCJ='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec_GCJ='-R$libdir' hardcode_direct_GCJ=yes @@ -17767,47 +18078,62 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi export_dynamic_flag_spec_GCJ='${wl}-E' ;; - hpux10* | hpux11*) + hpux10*) if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*|ia64*) + archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + fi + if test "$with_gnu_ld" = no; then + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: + + hardcode_direct_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-E' + + # hardcode_minus_L: Not really in the search PATH, + # but as the default location of the library. + hardcode_minus_L_GCJ=yes + fi + ;; + + hpux11*) + if test "$GCC" = yes -a "$with_gnu_ld" = no; then + case $host_cpu in + hppa*64*) archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' ;; + ia64*) + archive_cmds_GCJ='$CC -shared ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' + ;; *) archive_cmds_GCJ='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac else - case "$host_cpu" in - hppa*64*|ia64*) - archive_cmds_GCJ='$LD -b +h $soname -o $lib $libobjs $deplibs $linker_flags' + case $host_cpu in + hppa*64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + ;; + ia64*) + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' ;; *) - archive_cmds_GCJ='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' + archive_cmds_GCJ='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' ;; esac fi if test "$with_gnu_ld" = no; then - case "$host_cpu" in - hppa*64*) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' - hardcode_libdir_separator_GCJ=: - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no - ;; - ia64*) - hardcode_libdir_flag_spec_GCJ='-L$libdir' - hardcode_direct_GCJ=no - hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' + hardcode_libdir_separator_GCJ=: - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L_GCJ=yes + case $host_cpu in + hppa*64*|ia64*) + hardcode_libdir_flag_spec_ld_GCJ='+b $libdir' + hardcode_direct_GCJ=no + hardcode_shlibpath_var_GCJ=no ;; *) - hardcode_libdir_flag_spec_GCJ='${wl}+b ${wl}$libdir' - hardcode_libdir_separator_GCJ=: hardcode_direct_GCJ=yes export_dynamic_flag_spec_GCJ='${wl}-E' @@ -17851,24 +18177,28 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi ;; openbsd*) - hardcode_direct_GCJ=yes - hardcode_shlibpath_var_GCJ=no - if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - export_dynamic_flag_spec_GCJ='${wl}-E' + if test -f /usr/libexec/ld.so; then + hardcode_direct_GCJ=yes + hardcode_shlibpath_var_GCJ=no + if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + export_dynamic_flag_spec_GCJ='${wl}-E' + else + case $host_os in + openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) + archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' + hardcode_libdir_flag_spec_GCJ='-R$libdir' + ;; + *) + archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' + ;; + esac + fi else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds_GCJ='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec_GCJ='-R$libdir' - ;; - *) - archive_cmds_GCJ='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec_GCJ='${wl}-rpath,$libdir' - ;; - esac + ld_shlibs_GCJ=no fi ;; @@ -17909,14 +18239,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi hardcode_libdir_separator_GCJ=: ;; - sco3.2v5*) - archive_cmds_GCJ='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var_GCJ=no - export_dynamic_flag_spec_GCJ='${wl}-Bexport' - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ;; - solaris*) no_undefined_flag_GCJ=' -z text' if test "$GCC" = yes; then @@ -17935,17 +18257,16 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi case $host_os in solaris2.[0-5] | solaris2.[0-5].*) ;; *) - # The compiler driver will combine linker options so we - # cannot just pass the convience library names through - # without $wl, iff we do not link with $LD. - # Luckily, gcc supports the same syntax we need for Sun Studio. + # The compiler driver will combine and reorder linker options, + # but understands `-z linker_flag'. GCC discards it without `$wl', + # but is careful enough not to reorder. # Supported since Solaris 2.6 (maybe 2.5.1?) - case $wlarc in - '') - whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' ;; - *) - whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $echo \"$new_convenience\"` ${wl}-z ${wl}defaultextract' ;; - esac ;; + if test "$GCC" = yes; then + whole_archive_flag_spec_GCJ='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' + else + whole_archive_flag_spec_GCJ='-z allextract$convenience -z defaultextract' + fi + ;; esac link_all_deplibs_GCJ=yes ;; @@ -18002,36 +18323,45 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi fi ;; - sysv4.2uw2*) - archive_cmds_GCJ='$LD -G -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct_GCJ=yes - hardcode_minus_L_GCJ=no + sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) + no_undefined_flag_GCJ='${wl}-z,text' + archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no - hardcode_runpath_var=yes - runpath_var=LD_RUN_PATH - ;; + runpath_var='LD_RUN_PATH' - sysv5OpenUNIX8* | sysv5UnixWare7* | sysv5uw[78]* | unixware7*) - no_undefined_flag_GCJ='${wl}-z ${wl}text' if test "$GCC" = yes; then - archive_cmds_GCJ='$CC -shared ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_GCJ='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' else - archive_cmds_GCJ='$CC -G ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_cmds_GCJ='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' fi - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var_GCJ=no ;; - sysv5*) - no_undefined_flag_GCJ=' -z text' - # $CC -shared without GNU ld will not create a library from C++ - # object files and a static libstdc++, better avoid it by now - archive_cmds_GCJ='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds_GCJ='$echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$rm $lib.exp' - hardcode_libdir_flag_spec_GCJ= + sysv5* | sco3.2v5* | sco5v6*) + # Note: We can NOT use -z defs as we might desire, because we do not + # link with -lc, and that would cause any symbols used from libc to + # always be unresolved, which means just about no library would + # ever link correctly. If we're not using GNU ld we use -z text + # though, which does catch some bad symbols but isn't as heavy-handed + # as -z defs. + no_undefined_flag_GCJ='${wl}-z,text' + allow_undefined_flag_GCJ='${wl}-z,nodefs' + archive_cmds_need_lc_GCJ=no hardcode_shlibpath_var_GCJ=no + hardcode_libdir_flag_spec_GCJ='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`' + hardcode_libdir_separator_GCJ=':' + link_all_deplibs_GCJ=yes + export_dynamic_flag_spec_GCJ='${wl}-Bexport' runpath_var='LD_RUN_PATH' + + if test "$GCC" = yes; then + archive_cmds_GCJ='$CC -shared ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + else + archive_cmds_GCJ='$CC -G ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + archive_expsym_cmds_GCJ='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,\${SCOABSPATH:+${install_libdir}/}$soname -o $lib $libobjs $deplibs $compiler_flags' + fi ;; uts4*) @@ -18050,11 +18380,6 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi echo "${ECHO_T}$ld_shlibs_GCJ" >&6; } test "$ld_shlibs_GCJ" = no && can_build_shared=no -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - # # Do we need to explicitly link libc? # @@ -18075,7 +18400,7 @@ x|xyes) { echo "$as_me:$LINENO: checking whether -lc should be explicitly linked in" >&5 echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >&6; } $rm conftest* - printf "$lt_simple_compile_test_code" > conftest.$ac_ext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 @@ -18087,6 +18412,7 @@ echo $ECHO_N "checking whether -lc should be explicitly linked in... $ECHO_C" >& libobjs=conftest.$ac_objext deplibs= wl=$lt_prog_compiler_wl_GCJ + pic_flag=$lt_prog_compiler_pic_GCJ compiler_flags=-v linker_flags=-v verstring= @@ -18132,20 +18458,7 @@ shlibpath_overrides_runpath=unknown version_type=none dynamic_linker="$host_os ld.so" sys_lib_dlsearch_path_spec="/lib /usr/lib" -if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | grep "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if echo "$sys_lib_search_path_spec" | grep ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`echo "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi + need_lib_prefix=unknown hardcode_into_libs=no @@ -18163,7 +18476,7 @@ aix3*) soname_spec='${libname}${release}${shared_ext}$major' ;; -aix4* | aix5*) +aix[4-9]*) version_type=linux need_lib_prefix=no need_version=no @@ -18247,7 +18560,8 @@ cygwin* | mingw* | pw32*) dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i;echo \$dlname'\''`~ dldir=$destdir/`dirname \$dlpath`~ test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname' + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname' postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $rm \$dlpath' @@ -18300,13 +18614,8 @@ darwin* | rhapsody*) soname_spec='${libname}${release}${major}$shared_ext' shlibpath_overrides_runpath=yes shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='$(test .$module = .yes && echo .so || echo .dylib)' - # Apple's gcc prints 'gcc -print-search-dirs' doesn't operate the same. - if test "$GCC" = yes; then - sys_lib_search_path_spec=`$CC -print-search-dirs | tr "\n" "$PATH_SEPARATOR" | sed -e 's/libraries:/@libraries:/' | tr "@" "\n" | grep "^libraries:" | sed -e "s/^libraries://" -e "s,=/,/,g" -e "s,$PATH_SEPARATOR, ,g" -e "s,.*,& /lib /usr/lib /usr/local/lib,g"` - else - sys_lib_search_path_spec='/lib /usr/lib /usr/local/lib' - fi + shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' + sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' ;; @@ -18323,22 +18632,17 @@ freebsd1*) dynamic_linker=no ;; -kfreebsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - freebsd* | dragonfly*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. - objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + if test -x /usr/bin/objformat; then + objformat=`/usr/bin/objformat` + else + case $host_os in + freebsd[123]*) objformat=aout ;; + *) objformat=elf ;; + esac + fi version_type=freebsd-$objformat case $version_type in freebsd-elf*) @@ -18360,10 +18664,15 @@ freebsd* | dragonfly*) shlibpath_overrides_runpath=yes hardcode_into_libs=yes ;; - *) # from 3.2 on + freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ + freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) shlibpath_overrides_runpath=no hardcode_into_libs=yes ;; + *) # from 4.6 on, and DragonFly + shlibpath_overrides_runpath=yes + hardcode_into_libs=yes + ;; esac ;; @@ -18383,7 +18692,7 @@ hpux9* | hpux10* | hpux11*) version_type=sunos need_lib_prefix=no need_version=no - case "$host_cpu" in + case $host_cpu in ia64*) shrext_cmds='.so' hardcode_into_libs=yes @@ -18423,6 +18732,18 @@ hpux9* | hpux10* | hpux11*) postinstall_cmds='chmod 555 $lib' ;; +interix[3-9]*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + irix5* | irix6* | nonstopux*) case $host_os in nonstopux*) version_type=nonstopux ;; @@ -18466,7 +18787,7 @@ linux*oldld* | linux*aout* | linux*coff*) ;; # This must be Linux ELF. -linux*) +linux* | k*bsd*-gnu) version_type=linux need_lib_prefix=no need_version=no @@ -18482,7 +18803,7 @@ linux*) # Append ld.so.conf contents to the search path if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` + lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" fi @@ -18495,18 +18816,6 @@ linux*) dynamic_linker='GNU/Linux ld.so' ;; -knetbsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='GNU ld.so' - ;; - netbsd*) version_type=sunos need_lib_prefix=no @@ -18544,6 +18853,7 @@ nto-qnx*) openbsd*) version_type=sunos + sys_lib_dlsearch_path_spec="/usr/lib" need_lib_prefix=no # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. case $host_os in @@ -18587,11 +18897,8 @@ osf3* | osf4* | osf5*) sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" ;; -sco3.2v5*) - version_type=osf - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH +rdos*) + dynamic_linker=no ;; solaris*) @@ -18619,7 +18926,7 @@ sunos4*) need_version=yes ;; -sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) +sysv4 | sysv4.3*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' soname_spec='${libname}${release}${shared_ext}$major' @@ -18652,6 +18959,29 @@ sysv4*MP*) fi ;; +sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) + version_type=freebsd-elf + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' + soname_spec='${libname}${release}${shared_ext}$major' + shlibpath_var=LD_LIBRARY_PATH + hardcode_into_libs=yes + if test "$with_gnu_ld" = yes; then + sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' + shlibpath_overrides_runpath=no + else + sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' + shlibpath_overrides_runpath=yes + case $host_os in + sco3.2v5*) + sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" + ;; + esac + fi + sys_lib_dlsearch_path_spec='/usr/lib' + ;; + uts4*) version_type=linux library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' @@ -18667,6 +18997,26 @@ esac echo "${ECHO_T}$dynamic_linker" >&6; } test "$dynamic_linker" = no && can_build_shared=no +if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_search_path_spec="$sys_lib_search_path_spec" +fi + +sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" +if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + lt_cv_sys_lib_dlsearch_path_spec="$sys_lib_dlsearch_path_spec" +fi + +sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test "$GCC" = yes; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + { echo "$as_me:$LINENO: checking how to hardcode library paths into programs" >&5 echo $ECHO_N "checking how to hardcode library paths into programs... $ECHO_C" >&6; } hardcode_action_GCJ= @@ -18704,808 +19054,6 @@ elif test "$shlibpath_overrides_runpath" = yes || enable_fast_install=needless fi -striplib= -old_striplib= -{ echo "$as_me:$LINENO: checking whether stripping libraries is possible" >&5 -echo $ECHO_N "checking whether stripping libraries is possible... $ECHO_C" >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - { echo "$as_me:$LINENO: result: yes" >&5 -echo "${ECHO_T}yes" >&6; } - else - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } -fi - ;; - *) - { echo "$as_me:$LINENO: result: no" >&5 -echo "${ECHO_T}no" >&6; } - ;; - esac -fi - -if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - { echo "$as_me:$LINENO: checking for shl_load" >&5 -echo $ECHO_N "checking for shl_load... $ECHO_C" >&6; } -if test "${ac_cv_func_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define shl_load to an innocuous variant, in case declares shl_load. - For example, HP-UX 11i declares gettimeofday. */ -#define shl_load innocuous_shl_load - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char shl_load (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef shl_load - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_shl_load || defined __stub___shl_load -choke me -#endif - -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_shl_load=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 -echo "${ECHO_T}$ac_cv_func_shl_load" >&6; } -if test $ac_cv_func_shl_load = yes; then - lt_cv_dlopen="shl_load" -else - { echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5 -echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6; } -if test "${ac_cv_lib_dld_shl_load+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dld_shl_load=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dld_shl_load=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6; } -if test $ac_cv_lib_dld_shl_load = yes; then - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-dld" -else - { echo "$as_me:$LINENO: checking for dlopen" >&5 -echo $ECHO_N "checking for dlopen... $ECHO_C" >&6; } -if test "${ac_cv_func_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -/* Define dlopen to an innocuous variant, in case declares dlopen. - For example, HP-UX 11i declares gettimeofday. */ -#define dlopen innocuous_dlopen - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char dlopen (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef dlopen - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_dlopen || defined __stub___dlopen -choke me -#endif - -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_func_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_func_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -fi -{ echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 -echo "${ECHO_T}$ac_cv_func_dlopen" >&6; } -if test $ac_cv_func_dlopen = yes; then - lt_cv_dlopen="dlopen" -else - { echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5 -echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6; } -if test "${ac_cv_lib_dl_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dl_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dl_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6; } -if test $ac_cv_lib_dl_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { echo "$as_me:$LINENO: checking for dlopen in -lsvld" >&5 -echo $ECHO_N "checking for dlopen in -lsvld... $ECHO_C" >&6; } -if test "${ac_cv_lib_svld_dlopen+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_svld_dlopen=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_svld_dlopen=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_svld_dlopen" >&5 -echo "${ECHO_T}$ac_cv_lib_svld_dlopen" >&6; } -if test $ac_cv_lib_svld_dlopen = yes; then - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { echo "$as_me:$LINENO: checking for dld_link in -ldld" >&5 -echo $ECHO_N "checking for dld_link in -ldld... $ECHO_C" >&6; } -if test "${ac_cv_lib_dld_dld_link+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -rm -f conftest.$ac_objext conftest$ac_exeext -if { (ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 - (eval "$ac_link") 2>conftest.er1 - ac_status=$? - grep -v '^ *+' conftest.er1 >conftest.err - rm -f conftest.er1 - cat conftest.err >&5 - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_dld_dld_link=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_lib_dld_dld_link=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_dld_dld_link" >&5 -echo "${ECHO_T}$ac_cv_lib_dld_dld_link" >&6; } -if test $ac_cv_lib_dld_dld_link = yes; then - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-dld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { echo "$as_me:$LINENO: checking whether a program can dlopen itself" >&5 -echo $ECHO_N "checking whether a program can dlopen itself... $ECHO_C" >&6; } -if test "${lt_cv_dlopen_self+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - LDFLAGS="$LDFLAGS $link_static_flag" - { echo "$as_me:$LINENO: checking whether a statically linked program can dlopen itself" >&5 -echo $ECHO_N "checking whether a statically linked program can dlopen itself... $ECHO_C" >&6; } -if test "${lt_cv_dlopen_self_static+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext < -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -#ifdef __cplusplus -extern "C" void exit (int); -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - - exit (status); -} -EOF - if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 - (eval $ac_link) 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_unknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ echo "$as_me:$LINENO: result: $lt_cv_dlopen_self_static" >&5 -echo "${ECHO_T}$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - # The else clause should only fire when bootstrapping the # libtool distribution, otherwise you forgot to ship ltmain.sh @@ -19520,7 +19068,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -19547,6 +19095,7 @@ if test -f "$ltmain"; then predeps_GCJ \ postdeps_GCJ \ compiler_lib_search_path_GCJ \ + compiler_lib_search_dirs_GCJ \ archive_cmds_GCJ \ archive_expsym_cmds_GCJ \ postinstall_cmds_GCJ \ @@ -19562,6 +19111,7 @@ if test -f "$ltmain"; then module_cmds_GCJ \ module_expsym_cmds_GCJ \ lt_cv_prog_compiler_c_o_GCJ \ + fix_srcfile_path_GCJ \ exclude_expsyms_GCJ \ include_expsyms_GCJ; do @@ -19638,6 +19188,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_GCJ @@ -19791,6 +19344,10 @@ predeps=$lt_predeps_GCJ # shared library. postdeps=$lt_postdeps_GCJ +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_GCJ + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ @@ -19879,7 +19436,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_GCJ" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_GCJ @@ -19936,7 +19493,7 @@ objext=o objext_RC=$objext # Code to be used in simple compile tests -lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }\n' +lt_simple_compile_test_code='sample MENU { MENUITEM "&Soup", 100, CHECKED }' # Code to be used in simple link tests lt_simple_link_test_code="$lt_simple_compile_test_code" @@ -19946,22 +19503,25 @@ lt_simple_link_test_code="$lt_simple_compile_test_code" # If no C compiler was specified, use CC. LTCC=${LTCC-"$CC"} +# If no C compiler flags were specified, use CFLAGS. +LTCFLAGS=${LTCFLAGS-"$CFLAGS"} + # Allow CC to be a program name with arguments. compiler=$CC # save warnings/boilerplate of simple test code ac_outfile=conftest.$ac_objext -printf "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_compile_test_code" >conftest.$ac_ext +eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_compiler_boilerplate=`cat conftest.err` $rm conftest* ac_outfile=conftest.$ac_objext -printf "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d' >conftest.err +echo "$lt_simple_link_test_code" >conftest.$ac_ext +eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err _lt_linker_boilerplate=`cat conftest.err` -$rm conftest* +$rm -r conftest* # Allow CC to be a program name with arguments. @@ -19994,7 +19554,7 @@ if test -f "$ltmain"; then # Now quote all the things that may contain metacharacters while being # careful not to overquote the AC_SUBSTed values. We take copies of the # variables and quote the copies for generation of the libtool script. - for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC NM \ + for var in echo old_CC old_CFLAGS AR AR_FLAGS EGREP RANLIB LN_S LTCC LTCFLAGS NM \ SED SHELL STRIP \ libname_spec library_names_spec soname_spec extract_expsyms_cmds \ old_striplib striplib file_magic_cmd finish_cmds finish_eval \ @@ -20021,6 +19581,7 @@ if test -f "$ltmain"; then predeps_RC \ postdeps_RC \ compiler_lib_search_path_RC \ + compiler_lib_search_dirs_RC \ archive_cmds_RC \ archive_expsym_cmds_RC \ postinstall_cmds_RC \ @@ -20036,6 +19597,7 @@ if test -f "$ltmain"; then module_cmds_RC \ module_expsym_cmds_RC \ lt_cv_prog_compiler_c_o_RC \ + fix_srcfile_path_RC \ exclude_expsyms_RC \ include_expsyms_RC; do @@ -20112,6 +19674,9 @@ AR_FLAGS=$lt_AR_FLAGS # A C compiler. LTCC=$lt_LTCC +# LTCC compiler flags. +LTCFLAGS=$lt_LTCFLAGS + # A language-specific compiler. CC=$lt_compiler_RC @@ -20265,6 +19830,10 @@ predeps=$lt_predeps_RC # shared library. postdeps=$lt_postdeps_RC +# The directories searched by this compiler when creating a shared +# library +compiler_lib_search_dirs=$lt_compiler_lib_search_dirs_RC + # The library search path used internally by the compiler when linking # a shared library. compiler_lib_search_path=$lt_compiler_lib_search_path_RC @@ -20353,7 +19922,7 @@ sys_lib_search_path_spec=$lt_sys_lib_search_path_spec sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec # Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path="$fix_srcfile_path_RC" +fix_srcfile_path=$lt_fix_srcfile_path # Set to yes if exported symbols are required. always_export_symbols=$always_export_symbols_RC @@ -22426,6 +21995,7 @@ cat >>confdefs.h <<\_ACEOF _ACEOF fi + { echo "$as_me:$LINENO: checking for tzname" >&5 echo $ECHO_N "checking for tzname... $ECHO_C" >&6; } if test "${ac_cv_var_tzname+set}" = set; then @@ -22545,6 +22115,7 @@ cat >>confdefs.h <<\_ACEOF _ACEOF fi + { echo "$as_me:$LINENO: checking for daylight" >&5 echo $ECHO_N "checking for daylight... $ECHO_C" >&6; } if test "${ac_cv_var_daylight+set}" = set; then @@ -23141,6 +22712,64 @@ _ACEOF fi +{ echo "$as_me:$LINENO: checking for struct option in getopt" >&5 +echo $ECHO_N "checking for struct option in getopt... $ECHO_C" >&6; } +if test "${ac_cv_struct_option_getopt_h+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include +int +main () +{ +struct option op; op.name; + ; + return 0; +} +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +case "(($ac_try" in + *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; + *) ac_try_echo=$ac_try;; +esac +eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 + (eval "$ac_compile") 2>conftest.er1 + ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } && { + test -z "$ac_c_werror_flag" || + test ! -s conftest.err + } && test -s conftest.$ac_objext; then + ac_cv_struct_option_getopt_h=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_cv_struct_option_getopt_h=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +fi +{ echo "$as_me:$LINENO: result: $ac_cv_struct_option_getopt_h" >&5 +echo "${ECHO_T}$ac_cv_struct_option_getopt_h" >&6; } +if test "$ac_cv_struct_option_getopt_h" = yes; then + +cat >>confdefs.h <<\_ACEOF +#define HAVE_STRUCT_OPTION 1 +_ACEOF + +fi + + { echo "$as_me:$LINENO: checking for uint8_t" >&5 echo $ECHO_N "checking for uint8_t... $ECHO_C" >&6; } if test "${ac_cv_type_uint8_t+set}" = set; then @@ -23920,7 +23549,7 @@ _ACEOF echo $ECHO_N "checking for gcc compiler warnings... $ECHO_C" >&6; } # Check whether --enable-warnings was given. if test "${enable_warnings+set}" = set; then - enableval=$enable_warnings; if test "${enableval}" = no -o $GCC = no; then + enableval=$enable_warnings; if test "${enableval}" = no -o "$GCC" = no; then { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } WARNINGS= @@ -23934,7 +23563,7 @@ echo "${ECHO_T}yes" >&6; } fi else -if test $GCC = no; then +if test "$GCC" = no; then WARNINGS= { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } @@ -24674,7 +24303,7 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by file $as_me 5.00, which was +This file was extended by file $as_me 5.03, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -24727,7 +24356,7 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -file config.status 5.00 +file config.status 5.03 configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" @@ -24970,6 +24599,7 @@ am__leading_dot!$am__leading_dot$ac_delim AMTAR!$AMTAR$ac_delim am__tar!$am__tar$ac_delim am__untar!$am__untar$ac_delim +pkgdatadir!$pkgdatadir$ac_delim fsect!$fsect$ac_delim FSECT5_TRUE!$FSECT5_TRUE$ac_delim FSECT5_FALSE!$FSECT5_FALSE$ac_delim @@ -24999,15 +24629,14 @@ host!$host$ac_delim host_cpu!$host_cpu$ac_delim host_vendor!$host_vendor$ac_delim host_os!$host_os$ac_delim +SED!$SED$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim ECHO!$ECHO$ac_delim AR!$AR$ac_delim RANLIB!$RANLIB$ac_delim -CPP!$CPP$ac_delim -CXX!$CXX$ac_delim -CXXFLAGS!$CXXFLAGS$ac_delim -ac_ct_CXX!$ac_ct_CXX$ac_delim +DSYMUTIL!$DSYMUTIL$ac_delim +NMEDIT!$NMEDIT$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then @@ -25049,6 +24678,10 @@ _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF +CPP!$CPP$ac_delim +CXX!$CXX$ac_delim +CXXFLAGS!$CXXFLAGS$ac_delim +ac_ct_CXX!$ac_ct_CXX$ac_delim CXXDEPMODE!$CXXDEPMODE$ac_delim am__fastdepCXX_TRUE!$am__fastdepCXX_TRUE$ac_delim am__fastdepCXX_FALSE!$am__fastdepCXX_FALSE$ac_delim @@ -25063,7 +24696,7 @@ IS_CROSS_COMPILE_FALSE!$IS_CROSS_COMPILE_FALSE$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF - if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 12; then + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 16; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 diff --git a/configure.ac b/configure.ac index 071ee28124ce..5fc7b3cfd954 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,8 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT(file, 5.00, christos@astron.com) +AC_INIT(file, 5.03, christos@astron.com) AM_INIT_AUTOMAKE AM_CONFIG_HEADER(config.h) +#AC_CONFIG_MACRO_DIR([m4]) AC_MSG_CHECKING(for builtin ELF support) AC_ARG_ENABLE(elf, @@ -46,6 +47,7 @@ fi], [ fsect=4 ]) +AC_SUBST([pkgdatadir], ['$(datadir)/misc']) AC_SUBST(fsect) AM_CONDITIONAL(FSECT5, test x$fsect = x5) @@ -82,6 +84,8 @@ AC_SYS_LARGEFILE AC_FUNC_FSEEKO AC_TYPE_MBSTATE_T +AC_STRUCT_OPTION_GETOPT_H + AC_CHECK_TYPES([uint8_t, uint16_t, uint32_t, int32_t, uint64_t, int64_t]) AC_CHECK_SIZEOF(long long) AH_BOTTOM([ @@ -116,7 +120,7 @@ typedef long int64_t; AC_MSG_CHECKING(for gcc compiler warnings) AC_ARG_ENABLE(warnings, [ --disable-warnings disable compiler warnings], -[if test "${enableval}" = no -o $GCC = no; then +[if test "${enableval}" = no -o "$GCC" = no; then AC_MSG_RESULT(no) WARNINGS= else @@ -126,7 +130,7 @@ else -Wsign-compare -Wreturn-type -Wswitch -Wshadow \ -Wcast-qual -Wwrite-strings -Wextra -Wunused-parameter" fi], [ -if test $GCC = no; then +if test "$GCC" = no; then WARNINGS= AC_MSG_RESULT(no) else diff --git a/file.c b/file.c index 9b4747b2ec6d..34aa44c854a4 100644 --- a/file.c +++ b/file.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: file.c,v 1.131 2009/02/13 18:48:05 christos Exp $") #endif /* lint */ #include "magic.h" @@ -61,7 +61,7 @@ FILE_RCSID("@(#)$File: file.c,v 1.130 2009/02/03 20:27:51 christos Exp $") #include #endif -#ifdef HAVE_GETOPT_H +#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION) #include #else #include "mygetopt.h" diff --git a/file.h b/file.h index 204f49871380..ce12e64cbb7a 100644 --- a/file.h +++ b/file.h @@ -27,7 +27,7 @@ */ /* * file.h - definitions for file(1) program - * @(#)$File: file.h,v 1.118 2009/02/03 20:27:51 christos Exp $ + * @(#)$File: file.h,v 1.119 2009/02/04 18:24:32 christos Exp $ */ #ifndef __file_h__ @@ -387,7 +387,13 @@ protected size_t file_mbswidth(const char *); protected const char *file_getbuffer(struct magic_set *); protected ssize_t sread(int, void *, size_t, int); protected int file_check_mem(struct magic_set *, unsigned int); -protected int file_looks_utf8(const unsigned char *, size_t, unichar *, size_t *); +protected int file_looks_utf8(const unsigned char *, size_t, unichar *, + size_t *); +#ifdef __EMX__ +protected int file_os2_apptype(struct magic_set *, const char *, const void *, + size_t); +#endif /* __EMX__ */ + #ifndef COMPILE_ONLY extern const char *file_names[]; diff --git a/funcs.c b/funcs.c index af10688e3b99..c6f0d09c5497 100644 --- a/funcs.c +++ b/funcs.c @@ -27,7 +27,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: funcs.c,v 1.51 2008/11/07 18:57:28 christos Exp $") +FILE_RCSID("@(#)$File: funcs.c,v 1.53 2009/04/07 11:07:00 christos Exp $") #endif /* lint */ #include "magic.h" @@ -303,7 +303,14 @@ file_reset(struct magic_set *ms) file_error(ms, 0, "no magic files loaded"); return -1; } - ms->o.buf = NULL; + if (ms->o.buf) { + free(ms->o.buf); + ms->o.buf = NULL; + } + if (ms->o.pbuf) { + free(ms->o.pbuf); + ms->o.pbuf = NULL; + } ms->event_flags &= ~EVENT_HAD_ERR; ms->error = -1; return 0; diff --git a/getopt_long.c b/getopt_long.c index 2ad5b4de0a8d..d357dc30f444 100644 --- a/getopt_long.c +++ b/getopt_long.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: getopt_long.c,v 1.6 2009/02/13 18:48:05 christos Exp $") #endif /* lint */ #include @@ -42,7 +42,7 @@ FILE_RCSID("@(#)$File: getopt_long.c,v 1.5 2009/02/03 20:27:51 christos Exp $") #define warnx printf #endif #include -#ifdef HAVE_GETOPT_H +#if defined(HAVE_GETOPT_H) && defined(HAVE_STRUCT_OPTION) #include #else #include "mygetopt.h" diff --git a/magic.c b/magic.c index 26b7b864d832..b89989b33879 100644 --- a/magic.c +++ b/magic.c @@ -28,7 +28,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: magic.c,v 1.62 2009/03/20 21:25:41 christos Exp $") #endif /* lint */ #include "magic.h" @@ -57,10 +57,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $") #include /* for read() */ #endif -#ifdef HAVE_LOCALE_H -#include -#endif - #include /* for byte swapping */ #include "patchlevel.h" @@ -74,12 +70,6 @@ FILE_RCSID("@(#)$File: magic.c,v 1.59 2009/02/03 20:27:51 christos Exp $") #endif #endif -#ifdef __EMX__ -private char *apptypeName = NULL; -protected int file_os2_apptype(struct magic_set *ms, const char *fn, - const void *buf, size_t nb); -#endif /* __EMX__ */ - private void free_mlist(struct mlist *); private void close_and_restore(const struct magic_set *, const char *, int, const struct stat *); @@ -297,26 +287,10 @@ file_or_fd(struct magic_set *ms, const char *inname, int fd) errno = 0; if ((fd = open(inname, flags)) < 0) { -#ifdef __CYGWIN__ - /* FIXME: Do this with EXEEXT from autotools */ - size_t len = strlen(inname) + 5; - char *tmp = alloca(len); - (void)strlcat(strlcpy(tmp, inname, len), ".exe", len); - if ((fd = open(tmp, flags)) < 0) { -#endif - if (unreadable_info(ms, sb.st_mode, -#ifdef __CYGWIN - tmp -#else - inname -#endif - ) == -1) - goto done; - rv = 0; + if (unreadable_info(ms, sb.st_mode, inname) == -1) goto done; -#ifdef __CYGWIN__ - } -#endif + rv = 0; + goto done; } #ifdef O_NONBLOCK if ((flags = fcntl(fd, F_GETFL)) != -1) { diff --git a/patchlevel.h b/patchlevel.h index b03a8d51017e..472cca3ccda9 100644 --- a/patchlevel.h +++ b/patchlevel.h @@ -1,11 +1,20 @@ #define FILE_VERSION_MAJOR 5 -#define patchlevel 0 +#define patchlevel 3 /* * Patchlevel file for Ian Darwin's MAGIC command. - * $File: patchlevel.h,v 1.71 2009/01/21 19:09:42 christos Exp $ + * $File: patchlevel.h,v 1.74 2009/05/06 20:32:48 christos Exp $ * * $Log: patchlevel.h,v $ + * Revision 1.74 2009/05/06 20:32:48 christos + * welcome to 5.03 + * + * Revision 1.73 2009/05/04 15:15:13 christos + * 5.02... + * + * Revision 1.72 2009/04/30 21:20:15 christos + * 5.01 we are almost here. + * * Revision 1.71 2009/01/21 19:09:42 christos * file 5.0 * diff --git a/readcdf.c b/readcdf.c index 27031dbd9dd3..15f53fe7a676 100644 --- a/readcdf.c +++ b/readcdf.c @@ -26,7 +26,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: readcdf.c,v 1.11 2009/02/03 20:27:51 christos Exp $") +FILE_RCSID("@(#)$File: readcdf.c,v 1.18 2009/05/06 20:48:22 christos Exp $") #endif #include @@ -75,9 +75,23 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, if (len > 1) { s = info[i].pi_str.s_buf; if (NOTMIME(ms)) { - if (file_printf(ms, ", %s: %.*s", buf, - len, s) == -1) - return -1; + char vbuf[1024]; + size_t j; + for (j = 0; j < sizeof(vbuf) && len--; + j++, s++) { + if (*s == '\0') + break; + if (isprint((unsigned char)*s)) + vbuf[j] = *s; + } + if (j == sizeof(vbuf)) + --j; + vbuf[j] = '\0'; + if (vbuf[0]) { + if (file_printf(ms, ", %s: %s", + buf, vbuf) == -1) + return -1; + } } else if (info[i].pi_id == CDF_PROPERTY_NAME_OF_APPLICATION) { if (strstr(s, "Word")) @@ -115,7 +129,6 @@ cdf_file_property_info(struct magic_set *ms, const cdf_property_info_t *info, case CDF_CLIPBOARD: break; default: - file_error(ms, 0, "Internal parsing error"); return -1; } } @@ -134,15 +147,8 @@ cdf_file_summary_info(struct magic_set *ms, const cdf_stream_t *sst) size_t count; int m; - if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) { - if (si.si_byte_order != 0xfffe) - return 0; - else - return -1; - } - - if (si.si_byte_order != 0xfffe) - return 0; + if (cdf_unpack_summary_info(sst, &si, &info, &count) == -1) + return -1; if (NOTMIME(ms)) { if (file_printf(ms, "CDF V2 Document") == -1) @@ -183,66 +189,64 @@ protected int file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, size_t nbytes) { + cdf_info_t info; cdf_header_t h; cdf_sat_t sat, ssat; cdf_stream_t sst, scn; cdf_dir_t dir; int i; - (void)&nbytes; - (void)&buf; + const char *expn = ""; + info.i_fd = fd; + info.i_buf = buf; + info.i_len = nbytes; if (ms->flags & MAGIC_APPLE) return 0; - if (cdf_read_header(fd, &h) == -1) + if (cdf_read_header(&info, &h) == -1) return 0; #ifdef CDF_DEBUG cdf_dump_header(&h); #endif - if (cdf_read_sat(fd, &h, &sat) == -1) { - file_error(ms, errno, "Can't read SAT"); - return -1; + if ((i = cdf_read_sat(&info, &h, &sat)) == -1) { + expn = "Can't read SAT"; + goto out0; } #ifdef CDF_DEBUG - cdf_dump_sat("SAT", &h, &sat); + cdf_dump_sat("SAT", &sat, CDF_SEC_SIZE(&h)); #endif - if ((i = cdf_read_ssat(fd, &h, &sat, &ssat)) == -1) { - file_error(ms, errno, "Can't read SAT"); + if ((i = cdf_read_ssat(&info, &h, &sat, &ssat)) == -1) { + expn = "Can't read SSAT"; goto out1; } #ifdef CDF_DEBUG - cdf_dump_sat("SSAT", &h, &ssat); + cdf_dump_sat("SSAT", &ssat, CDF_SHORT_SEC_SIZE(&h)); #endif - if ((i = cdf_read_dir(fd, &h, &sat, &dir)) == -1) { - file_error(ms, errno, "Can't read directory"); + if ((i = cdf_read_dir(&info, &h, &sat, &dir)) == -1) { + expn = "Can't read directory"; goto out2; } - if ((i = cdf_read_short_stream(fd, &h, &sat, &dir, &sst)) == -1) { - file_error(ms, errno, "Cannot read short stream"); + if ((i = cdf_read_short_stream(&info, &h, &sat, &dir, &sst)) == -1) { + expn = "Cannot read short stream"; goto out3; } - #ifdef CDF_DEBUG - cdf_dump_dir(fd, &h, &sat, &ssat, &sst, &dir); -#endif - if ((i = cdf_read_summary_info(fd, &h, &sat, &ssat, &sst, &dir, &scn)) - == -1) { - /* Some files don't have summary info! */ -#ifdef notyet - file_error(ms, errno, "Can't read summary_info"); -#else - i = 0; + cdf_dump_dir(&info, &h, &sat, &ssat, &sst, &dir); #endif + + if ((i = cdf_read_summary_info(&info, &h, &sat, &ssat, &sst, &dir, + &scn)) == -1) { + expn = "Cannot read summary info"; goto out4; } #ifdef CDF_DEBUG cdf_dump_summary_info(&h, &scn); #endif if ((i = cdf_file_summary_info(ms, &scn)) == -1) - file_error(ms, errno, "Can't expand summary_info"); + expn = "Can't expand summary_info"; free(scn.sst_tab); out4: free(sst.sst_tab); @@ -252,5 +256,14 @@ file_trycdf(struct magic_set *ms, int fd, const unsigned char *buf, free(ssat.sat_tab); out1: free(sat.sat_tab); +out0: + if (i != 1) { + if (file_printf(ms, "CDF V2 Document") == -1) + return -1; + if (*expn) + if (file_printf(ms, ", corrupt: %s", expn) == -1) + return -1; + i = 1; + } return i; } diff --git a/softmagic.c b/softmagic.c index daf9ccd6d506..88f5214500db 100644 --- a/softmagic.c +++ b/softmagic.c @@ -32,7 +32,7 @@ #include "file.h" #ifndef lint -FILE_RCSID("@(#)$File: softmagic.c,v 1.133 2008/11/07 22:50:37 christos Exp $") +FILE_RCSID("@(#)$File: softmagic.c,v 1.135 2009/03/27 22:42:49 christos Exp $") #endif /* lint */ #include "magic.h" @@ -256,11 +256,14 @@ match(struct magic_set *ms, struct magic *magic, uint32_t nmagic, * make sure that we have a separator first. */ if (*m->desc) { - printed_something = 1; if ((e = handle_annotation(ms, m)) != 0) return e; - if (print_sep(ms, firstline) == -1) - return -1; + if (!printed_something) { + printed_something = 1; + if (print_sep(ms, firstline) + == -1) + return -1; + } } /* * This continuation matched. Print @@ -338,14 +341,13 @@ strndup(const char *str, size_t n) size_t len; char *copy; - len = strlen(str); - if (len > n) - len = n; - if (!(copy = malloc(len + 1))) - return (NULL); - (void) memcpy(copy, str, len + 1); + for (len = 0; len < n && str[len]; len++) + continue; + if ((copy = malloc(len + 1)) == NULL) + return NULL; + (void)memcpy(copy, str, len); copy[len] = '\0'; - return (copy); + return copy; } #endif /* HAVE_STRNDUP */ diff --git a/strlcat.c b/strlcat.c new file mode 100644 index 000000000000..9692bc10dff0 --- /dev/null +++ b/strlcat.c @@ -0,0 +1,58 @@ +/* $OpenBSD: strlcat.c,v 1.13 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcat.c */ +#include "file.h" + +#include +#include + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t +strlcat(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/strlcpy.c b/strlcpy.c new file mode 100644 index 000000000000..992501c86287 --- /dev/null +++ b/strlcpy.c @@ -0,0 +1,54 @@ +/* $OpenBSD: strlcpy.c,v 1.10 2005/08/08 08:05:37 espie Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/string/strlcpy.c */ +#include "file.h" + +#include +#include + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t +strlcpy(char *dst, const char *src, size_t siz) +{ + char *d = dst; + const char *s = src; + size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff --git a/tests/Makefile.in b/tests/Makefile.in index 5d9de025cd17..089acee6d050 100644 --- a/tests/Makefile.in +++ b/tests/Makefile.in @@ -14,7 +14,6 @@ @SET_MAKE@ VPATH = @srcdir@ -pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd @@ -62,6 +61,7 @@ DIST_SOURCES = test.c ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +pkgdatadir = @pkgdatadir@ ACLOCAL = @ACLOCAL@ AMTAR = @AMTAR@ AR = @AR@ @@ -81,6 +81,7 @@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ +DSYMUTIL = @DSYMUTIL@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ @@ -103,6 +104,7 @@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAKEINFO = @MAKEINFO@ MKDIR_P = @MKDIR_P@ +NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ @@ -112,6 +114,7 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ RANLIB = @RANLIB@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ From 75ac4f3d32972ed463e134522eba317b6c34d17f Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Mon, 18 May 2009 22:34:44 +0000 Subject: [PATCH 292/544] Revert the logical change of r192341. net.inet.ip.fw.one_pass is a classic ip_input.c variable and is used in the pfil and bridge code as well. As ipfw is loadable we need to always provide it. That is the reason why it lives in struct vnet_inet and not in struct vnet_ipfw. --- sys/netinet/ip_fw2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/ip_fw2.c b/sys/netinet/ip_fw2.c index ab238c01759a..965cddb32cf3 100644 --- a/sys/netinet/ip_fw2.c +++ b/sys/netinet/ip_fw2.c @@ -182,7 +182,7 @@ SYSCTL_V_PROC(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, enable, ipfw_chg_hook, "I", "Enable ipfw"); SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, autoinc_step, CTLFLAG_RW, autoinc_step, 0, "Rule number auto-increment step"); -SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, one_pass, +SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip_fw, OID_AUTO, one_pass, CTLFLAG_RW | CTLFLAG_SECURE3, fw_one_pass, 0, "Only do a single pass through ipfw when using dummynet(4)"); SYSCTL_V_INT(V_NET, vnet_ipfw, _net_inet_ip_fw, OID_AUTO, verbose, From 946995fdc20934db25154814fab245076c28dc3e Mon Sep 17 00:00:00 2001 From: Xin LI Date: Mon, 18 May 2009 22:46:59 +0000 Subject: [PATCH 293/544] FILE has been upgraded from 4.23 to 5.03. --- release/doc/en_US.ISO8859-1/relnotes/article.sgml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/release/doc/en_US.ISO8859-1/relnotes/article.sgml b/release/doc/en_US.ISO8859-1/relnotes/article.sgml index babbd3d402c2..46819186d9e8 100644 --- a/release/doc/en_US.ISO8859-1/relnotes/article.sgml +++ b/release/doc/en_US.ISO8859-1/relnotes/article.sgml @@ -443,6 +443,9 @@ CVS has been updated from 1.11.17 to a post-1.11.22 snapshot from 10 March 2008. + FILE has been updated from 4.23 + to 5.03. + hostapd has been updated from 0.5.8 to 0.5.10. From e95d34711b1b854a0a5aa9a873d02a9e69a3bf07 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Tue, 19 May 2009 01:14:37 +0000 Subject: [PATCH 294/544] - back out direct map hack - it is no longer needed --- .../opensolaris/uts/common/fs/zfs/arc.c | 22 ++--- .../opensolaris/uts/common/fs/zfs/zio.c | 93 +------------------ sys/vm/vm_contig.c | 7 +- 3 files changed, 13 insertions(+), 109 deletions(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c index 871135583ffb..a3e25803933f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/arc.c @@ -172,7 +172,6 @@ uint64_t zfs_arc_max; uint64_t zfs_arc_min; uint64_t zfs_arc_meta_limit = 0; int zfs_mdcomp_disable = 0; -int arc_large_memory_enabled = 0; TUNABLE_QUAD("vfs.zfs.arc_max", &zfs_arc_max); TUNABLE_QUAD("vfs.zfs.arc_min", &zfs_arc_min); @@ -3430,13 +3429,17 @@ arc_init(void) arc_min_prefetch_lifespan = 1 * hz; /* Start out with 1/8 of all memory */ -#if defined(_KERNEL) && (__amd64__) - arc_c = physmem*PAGE_SIZE / 8; - if (physmem*PAGE_SIZE > kmem_size() && (physmem > (1UL<<31))) - arc_large_memory_enabled = 1; -#else arc_c = kmem_size() / 8; -#endif +#if 0 +#ifdef _KERNEL + /* + * On architectures where the physical memory can be larger + * than the addressable space (intel in 32-bit mode), we may + * need to limit the cache to 1/8 of VM size. + */ + arc_c = MIN(arc_c, vmem_size(heap_arena, VMEM_ALLOC | VMEM_FREE) / 8); +#endif +#endif /* set min cache to 1/32 of all memory, or 16MB, whichever is more */ arc_c_min = MAX(arc_c / 4, 64<<18); /* set max to 1/2 of all memory, or all but 1GB, whichever is more */ @@ -3450,13 +3453,8 @@ arc_init(void) * Allow the tunables to override our calculations if they are * reasonable (ie. over 16MB) */ -#if defined(_KERNEL) && defined(__amd64__) - if (zfs_arc_max >= 64<<18) - arc_c_max = zfs_arc_max; -#else if (zfs_arc_max >= 64<<18 && zfs_arc_max < kmem_size()) arc_c_max = zfs_arc_max; -#endif if (zfs_arc_min >= 64<<18 && zfs_arc_min <= arc_c_max) arc_c_min = zfs_arc_min; #endif diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 6ac642edf33e..4650d42b7c2f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -33,9 +33,6 @@ #include #include -#if defined(_KERNEL) && defined(__amd64__) -#include -#endif /* * ========================================================================== * I/O priority table @@ -88,8 +85,6 @@ extern vmem_t *zio_alloc_arena; #define IO_IS_ALLOCATING(zio) \ ((zio)->io_orig_pipeline & (1U << ZIO_STAGE_DVA_ALLOCATE)) -extern int arc_large_memory_enabled; - void zio_init(void) { @@ -210,80 +205,6 @@ zio_buf_alloc(size_t size) #endif } -#if defined(_KERNEL) && defined(__amd64__) -extern int vm_contig_launder(int queue); - -static void * -zio_large_malloc(size_t size) -{ - void *ret; - vm_page_t pages; - unsigned long npgs; - int actl, actmax, inactl, inactmax, tries; - int flags = M_WAITOK; - vm_paddr_t low = (1UL<<29); /* leave lower 512MB untouched */ - vm_paddr_t high = ~(vm_paddr_t)0; - unsigned long alignment = 1; - unsigned long boundary = 0; - - npgs = round_page(size) >> PAGE_SHIFT; - tries = 0; -retry: - pages = vm_phys_alloc_contig(npgs, low, high, alignment, boundary); - if (pages == NULL) { - if (tries < ((flags & M_NOWAIT) != 0 ? 1 : 3)) { - vm_page_lock_queues(); - inactl = 0; - inactmax = tries < 1 ? 0 : cnt.v_inactive_count; - actl = 0; - actmax = tries < 2 ? 0 : cnt.v_active_count; -again: - if (inactl < inactmax && - vm_contig_launder(PQ_INACTIVE)) { - inactl++; - goto again; - } - if (actl < actmax && - vm_contig_launder(PQ_ACTIVE)) { - actl++; - goto again; - } - vm_page_unlock_queues(); - tries++; - goto retry; - } - - ret = NULL; - } else { - int i; - - vm_page_lock_queues(); - for (i = 0; i < npgs; i++) - vm_page_wire(&pages[i]); - vm_page_unlock_queues(); - - return (void *)PHYS_TO_DMAP(VM_PAGE_TO_PHYS(pages)); - } - return (ret); -} - -static void -zio_large_free(void *buf, size_t size) -{ - int npgs = round_page(size) >> PAGE_SHIFT; - int i; - vm_page_t m; - - m = PHYS_TO_VM_PAGE(DMAP_TO_PHYS((vm_offset_t)buf)); - vm_page_lock_queues(); - for (i = 0; i < npgs; i++, m++) { - vm_page_unwire(m, 0); - vm_page_free(m); - } - vm_page_unlock_queues(); -} -#endif - /* * Use zio_data_buf_alloc to allocate data. The data will not appear in a * crashdump if the kernel panics. This exists so that we will limit the amount @@ -300,12 +221,7 @@ zio_data_buf_alloc(size_t size) return (kmem_cache_alloc(zio_data_buf_cache[c], KM_PUSHPAGE)); #else -#if defined(_KERNEL) && defined(__amd64__) - if (arc_large_memory_enabled && (size > PAGE_SIZE)) - return (zio_large_malloc(size)); - else -#endif - return (kmem_alloc(size, KM_SLEEP)); + return (kmem_alloc(size, KM_SLEEP)); #endif } @@ -333,12 +249,7 @@ zio_data_buf_free(void *buf, size_t size) kmem_cache_free(zio_data_buf_cache[c], buf); #else -#if defined (_KERNEL) && defined(__amd64__) - if (arc_large_memory_enabled && (size > PAGE_SIZE)) - zio_large_free(buf, size); - else -#endif - kmem_free(buf, size); + kmem_free(buf, size); #endif } diff --git a/sys/vm/vm_contig.c b/sys/vm/vm_contig.c index 9a5220d72b3f..8fec101d2e03 100644 --- a/sys/vm/vm_contig.c +++ b/sys/vm/vm_contig.c @@ -87,11 +87,6 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * Only available as a band-aid to ZFS - */ -int vm_contig_launder(int queue); - static int vm_contig_launder_page(vm_page_t m, vm_page_t *next) { @@ -151,7 +146,7 @@ vm_contig_launder_page(vm_page_t m, vm_page_t *next) return (0); } -int +static int vm_contig_launder(int queue) { vm_page_t m, next; From 7b6d3d4c7b7c16d1a05841e8f262af02ed0ebe26 Mon Sep 17 00:00:00 2001 From: Scott Long Date: Tue, 19 May 2009 01:41:11 +0000 Subject: [PATCH 295/544] Updated PCI ID's from the vendor --- sys/dev/ciss/ciss.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index 208edcaa70aa..f2b89f80965d 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -314,17 +314,20 @@ static struct { 0x103C, 0x3234, CISS_BOARD_SA5, "HP Smart Array P400" }, { 0x103C, 0x3235, CISS_BOARD_SA5, "HP Smart Array P400i" }, { 0x103C, 0x3236, CISS_BOARD_SA5, "HP Smart Array" }, - { 0x103C, 0x3237, CISS_BOARD_SA5, "HP Smart Array" }, + { 0x103C, 0x3237, CISS_BOARD_SA5, "HP Smart Array E500" }, { 0x103C, 0x3238, CISS_BOARD_SA5, "HP Smart Array" }, { 0x103C, 0x3239, CISS_BOARD_SA5, "HP Smart Array" }, { 0x103C, 0x323A, CISS_BOARD_SA5, "HP Smart Array" }, { 0x103C, 0x323B, CISS_BOARD_SA5, "HP Smart Array" }, { 0x103C, 0x323C, CISS_BOARD_SA5, "HP Smart Array" }, + { 0x103C, 0x323D, CISS_BOARD_SA5, "HP Smart Array P700m" }, { 0x103C, 0x3241, CISS_BOARD_SA5, "HP Smart Array P212" }, { 0x103C, 0x3243, CISS_BOARD_SA5, "HP Smart Array P410" }, { 0x103C, 0x3245, CISS_BOARD_SA5, "HP Smart Array P410i" }, { 0x103C, 0x3247, CISS_BOARD_SA5, "HP Smart Array P411" }, { 0x103C, 0x3249, CISS_BOARD_SA5, "HP Smart Array P812" }, + { 0x103C, 0x324A, CISS_BOARD_SA5, "HP Smart Array P712m" }, + { 0x103C, 0x324B, CISS_BOARD_SA5, "HP Smart Array" }, { 0, 0, 0, NULL } }; From ea7b81d2bd220926be752b6ca59c6396cbeddffd Mon Sep 17 00:00:00 2001 From: Dmitry Chagin Date: Tue, 19 May 2009 09:10:53 +0000 Subject: [PATCH 296/544] Validate user-supplied arguments values. Args argument is a pointer to the structure located in user space in which the socketcall arguments are packed. The structure must be copied to the kernel instead of direct dereferencing. Approved by: kib (mentor) MFC after: 1 week --- sys/compat/linux/linux_socket.c | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 114a6d5e7de9..1ab5bdff5522 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -1467,11 +1467,38 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) return (error); } +/* Argument list sizes for linux_socketcall */ + +#define LINUX_AL(x) ((x) * sizeof(l_ulong)) + +static const unsigned char lxs_args[] = { + LINUX_AL(0) /* unused*/, LINUX_AL(3) /* socket */, + LINUX_AL(3) /* bind */, LINUX_AL(3) /* connect */, + LINUX_AL(2) /* listen */, LINUX_AL(3) /* accept */, + LINUX_AL(3) /* getsockname */, LINUX_AL(3) /* getpeername */, + LINUX_AL(4) /* socketpair */, LINUX_AL(4) /* send */, + LINUX_AL(4) /* recv */, LINUX_AL(6) /* sendto */, + LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */, + LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */, + LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */ +}; + +#define LINUX_AL_SIZE sizeof(lxs_args) / sizeof(lxs_args[0]) - 1 + int linux_socketcall(struct thread *td, struct linux_socketcall_args *args) { - void *arg = (void *)(intptr_t)args->args; + l_ulong a[6]; + void *arg; + int error; + if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE) + return (EINVAL); + error = copyin(PTRIN(args->args), a, lxs_args[args->what]); + if (error) + return (error); + + arg = a; switch (args->what) { case LINUX_SOCKET: return (linux_socket(td, arg)); From a7c13ccc014c5ac69dff8a2455d2afb4430b8102 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 19 May 2009 12:10:48 +0000 Subject: [PATCH 297/544] Add links to libgeom(3) where appropriate. --- lib/libgeom/Makefile | 2 ++ sbin/geom/core/geom.8 | 1 + share/man/man4/geom.4 | 1 + 3 files changed, 4 insertions(+) diff --git a/lib/libgeom/Makefile b/lib/libgeom/Makefile index 7535e1ed3752..b19faf6198ec 100644 --- a/lib/libgeom/Makefile +++ b/lib/libgeom/Makefile @@ -35,12 +35,14 @@ MLINKS+= \ libgeom.3 gctl_dump.3 \ libgeom.3 g_close.3 \ libgeom.3 g_delete.3 \ + libgeom.3 g_device_path.3 \ libgeom.3 g_flush.3 \ libgeom.3 g_get_ident.3 \ libgeom.3 g_get_name.3 \ libgeom.3 g_mediasize.3 \ libgeom.3 g_open.3 \ libgeom.3 g_open_by_ident.3 \ + libgeom.3 g_providername.3 \ libgeom.3 g_sectorsize.3 .include diff --git a/sbin/geom/core/geom.8 b/sbin/geom/core/geom.8 index ddf6cd1a12b6..8477205244b6 100644 --- a/sbin/geom/core/geom.8 +++ b/sbin/geom/core/geom.8 @@ -164,6 +164,7 @@ Unload a kernel module which implements the MD class: geom md unload .Ed .Sh SEE ALSO +.Xr libgeom 3 , .Xr geom 4 , .\" .Xr gcache 8 , .Xr gconcat 8 , diff --git a/share/man/man4/geom.4 b/share/man/man4/geom.4 index ec8b6b96d072..38573893357f 100644 --- a/share/man/man4/geom.4 +++ b/share/man/man4/geom.4 @@ -432,6 +432,7 @@ This is unused at this time. Dump contents of gctl requests. .El .Sh SEE ALSO +.Xr libgeom 3 , .Xr disk 9 , .Xr DECLARE_GEOM_CLASS 9 , .Xr g_access 9 , From 51ca6cd6df0db322e57b18398fde69e2f7c69556 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 19 May 2009 14:08:21 +0000 Subject: [PATCH 298/544] sysctl_rman: report shared resources to devinfo shared uses of a resource are recorded on a sub-list hanging off a main resource object on a main resource list; without this change a shared resource (e.g. irq) is reported only once by devinfo -r/-u; with this change the resource is reported for each driver that allocates it (which is even more than what vmstat -i -a reports). Approved by: jhb (mentor) --- sys/kern/subr_rman.c | 58 ++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/sys/kern/subr_rman.c b/sys/kern/subr_rman.c index 8730a5b622d6..0e53499e0de2 100644 --- a/sys/kern/subr_rman.c +++ b/sys/kern/subr_rman.c @@ -835,6 +835,7 @@ sysctl_rman(SYSCTL_HANDLER_ARGS) int rman_idx, res_idx; struct rman *rm; struct resource_i *res; + struct resource_i *sres; struct u_rman urm; struct u_resource ures; int error; @@ -881,35 +882,44 @@ sysctl_rman(SYSCTL_HANDLER_ARGS) */ mtx_lock(rm->rm_mtx); TAILQ_FOREACH(res, &rm->rm_list, r_link) { - if (res_idx-- == 0) { - bzero(&ures, sizeof(ures)); - ures.r_handle = (uintptr_t)res; - ures.r_parent = (uintptr_t)res->r_rm; - ures.r_device = (uintptr_t)res->r_dev; - if (res->r_dev != NULL) { - if (device_get_name(res->r_dev) != NULL) { - snprintf(ures.r_devname, RM_TEXTLEN, - "%s%d", - device_get_name(res->r_dev), - device_get_unit(res->r_dev)); - } else { - strlcpy(ures.r_devname, "nomatch", - RM_TEXTLEN); + if (res->r_sharehead != NULL) { + LIST_FOREACH(sres, res->r_sharehead, r_sharelink) + if (res_idx-- == 0) { + res = sres; + goto found; } - } else { - ures.r_devname[0] = '\0'; - } - ures.r_start = res->r_start; - ures.r_size = res->r_end - res->r_start + 1; - ures.r_flags = res->r_flags; - - mtx_unlock(rm->rm_mtx); - error = SYSCTL_OUT(req, &ures, sizeof(ures)); - return (error); } + else if (res_idx-- == 0) + goto found; } mtx_unlock(rm->rm_mtx); return (ENOENT); + +found: + bzero(&ures, sizeof(ures)); + ures.r_handle = (uintptr_t)res; + ures.r_parent = (uintptr_t)res->r_rm; + ures.r_device = (uintptr_t)res->r_dev; + if (res->r_dev != NULL) { + if (device_get_name(res->r_dev) != NULL) { + snprintf(ures.r_devname, RM_TEXTLEN, + "%s%d", + device_get_name(res->r_dev), + device_get_unit(res->r_dev)); + } else { + strlcpy(ures.r_devname, "nomatch", + RM_TEXTLEN); + } + } else { + ures.r_devname[0] = '\0'; + } + ures.r_start = res->r_start; + ures.r_size = res->r_end - res->r_start + 1; + ures.r_flags = res->r_flags; + + mtx_unlock(rm->rm_mtx); + error = SYSCTL_OUT(req, &ures, sizeof(ures)); + return (error); } SYSCTL_NODE(_hw_bus, OID_AUTO, rman, CTLFLAG_RD, sysctl_rman, From 05e605b7649eaa47028b444ece1800b5ed11e6e5 Mon Sep 17 00:00:00 2001 From: Andriy Gapon Date: Tue, 19 May 2009 14:23:54 +0000 Subject: [PATCH 299/544] find: do not silently disable -L when -delete is used First of all, current behavior is not documented and confusing, and it can be very dangerous in the following sequence: find -L . -type l find -L . -type l -delete (the second line is even suggested by find(1)). Instead simply refuse to proceed when -L and -delete are both used. A descriptive error message is provided. The following command can be safely used to remove broken links: find -L . -type l -print0 | xargs rm -0 To do: update find(1) PR: bin/90687 Obtained from: Anatoli Klassen Approved by: jhb (mentor) --- usr.bin/find/function.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/usr.bin/find/function.c b/usr.bin/find/function.c index c3c90f84a18f..26412644ff46 100644 --- a/usr.bin/find/function.c +++ b/usr.bin/find/function.c @@ -427,11 +427,13 @@ f_delete(PLAN *plan __unused, FTSENT *entry) /* sanity check */ if (isdepth == 0 || /* depth off */ - (ftsoptions & FTS_NOSTAT) || /* not stat()ing */ - !(ftsoptions & FTS_PHYSICAL) || /* physical off */ - (ftsoptions & FTS_LOGICAL)) /* or finally, logical on */ + (ftsoptions & FTS_NOSTAT)) /* not stat()ing */ errx(1, "-delete: insecure options got turned on"); + if (!(ftsoptions & FTS_PHYSICAL) || /* physical off */ + (ftsoptions & FTS_LOGICAL)) /* or finally, logical on */ + errx(1, "-delete: forbidden when symlinks are followed"); + /* Potentially unsafe - do not accept relative paths whatsoever */ if (strchr(entry->fts_accpath, '/') != NULL) errx(1, "-delete: %s: relative path potentially not safe", @@ -462,8 +464,6 @@ c_delete(OPTION *option, char ***argvp __unused) { ftsoptions &= ~FTS_NOSTAT; /* no optimise */ - ftsoptions |= FTS_PHYSICAL; /* disable -follow */ - ftsoptions &= ~FTS_LOGICAL; /* disable -follow */ isoutput = 1; /* possible output */ isdepth = 1; /* -depth implied */ From aa33fa5a86d23e2989f02686d22227a5ca690a3e Mon Sep 17 00:00:00 2001 From: Florent Thoumie Date: Tue, 19 May 2009 14:26:41 +0000 Subject: [PATCH 300/544] Skip @pkgdep if there's no argument. Submitted by: pav MFC after: 1 week --- usr.sbin/pkg_install/lib/lib.h | 2 +- usr.sbin/pkg_install/lib/plist.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/usr.sbin/pkg_install/lib/lib.h b/usr.sbin/pkg_install/lib/lib.h index 422912e8d4a7..aef772bdbcc6 100644 --- a/usr.sbin/pkg_install/lib/lib.h +++ b/usr.sbin/pkg_install/lib/lib.h @@ -105,7 +105,7 @@ * Version of the package tools - increase only when some * functionality used by bsd.port.mk is changed, added or removed */ -#define PKG_INSTALL_VERSION 20090106 +#define PKG_INSTALL_VERSION 20090519 #define PKG_WRAPCONF_FNAME "/var/db/pkg_install.conf" #define main(argc, argv) real_main(argc, argv) diff --git a/usr.sbin/pkg_install/lib/plist.c b/usr.sbin/pkg_install/lib/plist.c index 283b87f9c1b1..3c87d629c1fe 100644 --- a/usr.sbin/pkg_install/lib/plist.c +++ b/usr.sbin/pkg_install/lib/plist.c @@ -285,6 +285,10 @@ read_plist(Package *pkg, FILE *fp) } if (*cp == '\0') { cp = NULL; + if (cmd == PLIST_PKGDEP) { + warnx("corrupted record (pkgdep line without argument), ignoring"); + cmd = FAIL; + } goto bottom; } if (cmd == PLIST_COMMENT && sscanf(cp, "PKG_FORMAT_REVISION:%d.%d\n", From 930034efe2379fb401aa035cf02533eb14984f80 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 14:51:48 +0000 Subject: [PATCH 301/544] AH_SUPPORT_TDMA is gone; ath now honors IEEE80211_SUPPORT_TDMA Noticed by: Jon Loeliger --- share/man/man4/ath.4 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/share/man/man4/ath.4 b/share/man/man4/ath.4 index 19171fff2c40..9d15a7bd4918 100644 --- a/share/man/man4/ath.4 +++ b/share/man/man4/ath.4 @@ -126,10 +126,8 @@ interfaces to construct a wireless repeater device. The driver also support .Cm tdma operation when compiled with -.Cd "options AH_SUPPORT_TDMA" -(and the wlan module is built with .Cd "options IEEE80211_SUPPORT_TDMA" -to enable the associated 802.11 support). +(which also enables the required 802.11 support). For more information on configuring this device, see .Xr ifconfig 8 . .Pp From 22ccc253a26ed1d687373a0e8df3f00de72102d9 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Tue, 19 May 2009 17:17:53 +0000 Subject: [PATCH 302/544] Add Dell PowerEdge R200 and R300 to the hardware section. --- share/man/man4/bge.4 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/share/man/man4/bge.4 b/share/man/man4/bge.4 index d9d3be3ab0dc..d4cc265237b7 100644 --- a/share/man/man4/bge.4 +++ b/share/man/man4/bge.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 15, 2009 +.Dd May 19, 2009 .Dt BGE 4 .Os .Sh NAME @@ -186,6 +186,10 @@ Dell PowerEdge 2550 integrated BCM5700 NIC (10/100/1000baseTX) .It Dell PowerEdge 2650 integrated BCM5703 NIC (10/100/1000baseTX) .It +Dell PowerEdge R200 integrated BCM5750 NIC (10/100/1000baseTX) +.It +Dell PowerEdge R300 integrated BCM5722 NIC (10/100/1000baseTX) +.It IBM x235 server integrated BCM5703x NIC (10/100/1000baseTX) .It HP Compaq dc7600 integrated BCM5752 NIC (10/100/1000baseTX) From 683f31342d1679bfa2719bee0200992eb51e759c Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 17:30:13 +0000 Subject: [PATCH 303/544] add HAL_CAP_INTRMASK to return the set of interrupts supported by the device --- sys/dev/ath/ath_hal/ah.c | 3 +++ sys/dev/ath/ath_hal/ah.h | 3 ++- sys/dev/ath/ath_hal/ah_internal.h | 1 + sys/dev/ath/ath_hal/ar5210/ar5210_attach.c | 5 +++++ sys/dev/ath/ath_hal/ar5211/ar5211_attach.c | 7 +++++++ sys/dev/ath/ath_hal/ar5212/ar5212_attach.c | 7 +++++++ sys/dev/ath/ath_hal/ar5416/ar5416_attach.c | 11 +++++++++++ 7 files changed, 36 insertions(+), 1 deletion(-) diff --git a/sys/dev/ath/ath_hal/ah.c b/sys/dev/ath/ath_hal/ah.c index 63165a5e6de2..616e19bd5e30 100644 --- a/sys/dev/ath/ath_hal/ah.c +++ b/sys/dev/ath/ath_hal/ah.c @@ -500,6 +500,9 @@ ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ *result = pCap->halTstampPrecision; return HAL_OK; + case HAL_CAP_INTRMASK: /* mask of supported interrupts */ + *result = pCap->halIntrMask; + return HAL_OK; default: return HAL_EINVAL; } diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index c1bff9c44ae2..e9ceaf063770 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -109,6 +109,7 @@ typedef enum { HAL_CAP_RXTSTAMP_PREC = 34, /* rx desc tstamp precision (bits) */ HAL_CAP_BB_HANG = 35, /* can baseband hang */ HAL_CAP_MAC_HANG = 36, /* can MAC hang */ + HAL_CAP_INTRMASK = 37, /* bitmask of supported interrupts */ } HAL_CAPABILITY_TYPE; /* @@ -348,8 +349,8 @@ typedef enum { | HAL_INT_RXDESC | HAL_INT_RXEOL | HAL_INT_RXORN - | HAL_INT_TXURN | HAL_INT_TXDESC + | HAL_INT_TXURN | HAL_INT_MIB | HAL_INT_RXPHY | HAL_INT_RXKCM diff --git a/sys/dev/ath/ath_hal/ah_internal.h b/sys/dev/ath/ath_hal/ah_internal.h index ef5aba5ed56e..087a8e388006 100644 --- a/sys/dev/ath/ath_hal/ah_internal.h +++ b/sys/dev/ath/ath_hal/ah_internal.h @@ -206,6 +206,7 @@ typedef struct { uint8_t halNumGpioPins; uint8_t halNumAntCfg2GHz; uint8_t halNumAntCfg5GHz; + uint32_t halIntrMask; } HAL_CAPABILITIES; struct regDomain; diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c index 13ad7119ebf4..2d601e633c1a 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c @@ -369,6 +369,11 @@ ar5210FillCapabilityInfo(struct ath_hal *ah) } pCap->halTstampPrecision = 15; /* NB: s/w extended from 13 */ + pCap->halIntrMask = HAL_INT_COMMON + | HAL_INT_RX + | HAL_INT_TX + | HAL_INT_FATAL + ; ahpriv->ah_rxornIsFatal = AH_TRUE; return AH_TRUE; diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c index e55c67afad47..ec19751769a5 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_attach.c @@ -498,6 +498,13 @@ ar5211FillCapabilityInfo(struct ath_hal *ah) } pCap->halTstampPrecision = 13; + pCap->halIntrMask = HAL_INT_COMMON + | HAL_INT_RX + | HAL_INT_TX + | HAL_INT_FATAL + | HAL_INT_BNR + | HAL_INT_TIM + ; /* XXX might be ok w/ some chip revs */ ahpriv->ah_rxornIsFatal = AH_TRUE; diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c index 300c0a3c09eb..63856a4f4f7e 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c @@ -840,6 +840,13 @@ ar5212FillCapabilityInfo(struct ath_hal *ah) AH_PRIVATE(ah)->ah_macVersion > AR_SREV_VERSION_VENICE; pCap->halTstampPrecision = 15; + pCap->halIntrMask = HAL_INT_COMMON + | HAL_INT_RX + | HAL_INT_TX + | HAL_INT_FATAL + | HAL_INT_BNR + | HAL_INT_BMISC + ; return AH_TRUE; #undef IS_COBRA diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c index 1130529fbaac..01859d05cff4 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_attach.c @@ -781,6 +781,17 @@ ar5416FillCapabilityInfo(struct ath_hal *ah) pCap->halTstampPrecision = 32; pCap->halHwPhyCounterSupport = AH_TRUE; + pCap->halIntrMask = HAL_INT_COMMON + | HAL_INT_RX + | HAL_INT_TX + | HAL_INT_FATAL + | HAL_INT_BNR + | HAL_INT_BMISC + | HAL_INT_DTIMSYNC + | HAL_INT_TSFOOR + | HAL_INT_CST + | HAL_INT_GTT + ; pCap->halFastCCSupport = AH_TRUE; pCap->halNumGpioPins = 6; From 88608a2211e9bf2aa5a823a5e6c5cb76d7220a15 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 17:35:15 +0000 Subject: [PATCH 304/544] remove special handling for BNR; it is direct mapped to the harwdare so can be added to HAL_INT_COMMON except on the 5210 where it doesn't exist --- sys/dev/ath/ath_hal/ah.h | 1 + sys/dev/ath/ath_hal/ar5210/ar5210_attach.c | 2 +- sys/dev/ath/ath_hal/ar5210/ar5210_interrupts.c | 6 +++--- sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c | 4 ---- sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c | 4 ---- sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c | 4 ---- 6 files changed, 5 insertions(+), 16 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index e9ceaf063770..faeec97b2df4 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -356,6 +356,7 @@ typedef enum { | HAL_INT_RXKCM | HAL_INT_SWBA | HAL_INT_BMISS + | HAL_INT_BNR | HAL_INT_GPIO, } HAL_INT; diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c index 2d601e633c1a..0a470ee69a4d 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c @@ -369,7 +369,7 @@ ar5210FillCapabilityInfo(struct ath_hal *ah) } pCap->halTstampPrecision = 15; /* NB: s/w extended from 13 */ - pCap->halIntrMask = HAL_INT_COMMON + pCap->halIntrMask = (HAL_INT_COMMON - HAL_INT_BNR) | HAL_INT_RX | HAL_INT_TX | HAL_INT_FATAL diff --git a/sys/dev/ath/ath_hal/ar5210/ar5210_interrupts.c b/sys/dev/ath/ath_hal/ar5210/ar5210_interrupts.c index ccc233232abd..96b1a2cb1918 100644 --- a/sys/dev/ath/ath_hal/ar5210/ar5210_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5210/ar5210_interrupts.c @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar5210_interrupts.c,v 1.4 2008/11/10 04:08:02 sam Exp $ + * $FreeBSD$ */ #include "opt_ah.h" @@ -59,7 +59,7 @@ ar5210GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) * status bits leak through that weren't requested * (e.g. RXNOFRM) and that might confuse the caller. */ - *masked = (isr & HAL_INT_COMMON) & ahp->ah_maskReg; + *masked = (isr & (HAL_INT_COMMON - HAL_INT_BNR)) & ahp->ah_maskReg; if (isr & AR_FATAL_INT) *masked |= HAL_INT_FATAL; @@ -105,7 +105,7 @@ ar5210SetInterrupts(struct ath_hal *ah, HAL_INT ints) OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE); } - mask = ints & HAL_INT_COMMON; + mask = ints & (HAL_INT_COMMON - HAL_INT_BNR); if (ints & HAL_INT_RX) mask |= AR_IMR_RXOK_INT | AR_IMR_RXERR_INT; if (ints & HAL_INT_TX) { diff --git a/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c b/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c index be467def34ad..4c20ca1b5a24 100644 --- a/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5211/ar5211_interrupts.c @@ -64,8 +64,6 @@ ar5211GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) *masked |= HAL_INT_RX; if (isr & (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR | AR_ISR_TXEOL)) *masked |= HAL_INT_TX; - if (isr & AR_ISR_BNR) - *masked |= HAL_INT_BNR; /* * Receive overrun is usually non-fatal on Oahu/Spirit. * BUT on some parts rx could fail and the chip must be reset. @@ -139,8 +137,6 @@ ar5211SetInterrupts(struct ath_hal *ah, HAL_INT ints) } if (ints & HAL_INT_RX) mask |= AR_IMR_RXOK | AR_IMR_RXERR | AR_IMR_RXDESC; - if (ints & AR_ISR_BNR) - mask |= HAL_INT_BNR; if (ints & HAL_INT_FATAL) { /* * NB: ar5212Reset sets MCABT+SSERR+DPERR in AR_IMR_S2 diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c index d8f25d72b713..d6614276c2e8 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c @@ -92,8 +92,6 @@ ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXERR); ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL); } - if (isr & AR_ISR_BNR) - *masked |= HAL_INT_BNR; /* * Receive overrun is usually non-fatal on Oahu/Spirit. @@ -175,8 +173,6 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) if (ints & HAL_INT_CABEND) mask2 |= (AR_IMR_S2_CABEND ); } - if (ints & HAL_INT_BNR) - mask |= AR_IMR_BNR; if (ints & HAL_INT_FATAL) { /* * NB: ar5212Reset sets MCABT+SSERR+DPERR in AR_IMR_S2 diff --git a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c index 7aa538d6c540..7b6f951175f0 100644 --- a/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5416/ar5416_interrupts.c @@ -119,8 +119,6 @@ ar5416GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXERR); ahp->ah_intrTxqs |= MS(isr1, AR_ISR_S1_QCU_TXEOL); } - if (isr & AR_ISR_BNR) - *masked |= HAL_INT_BNR; /* Interrupt Mitigation on AR5416 */ #ifdef AR5416_INT_MITIGATION @@ -229,8 +227,6 @@ ar5416SetInterrupts(struct ath_hal *ah, HAL_INT ints) if (ints & HAL_INT_TSFOOR) mask2 |= AR_IMR_S2_TSFOOR; } - if (ints & HAL_INT_BNR) - mask |= AR_IMR_BNR; /* Write the new IMR and store off our SW copy. */ HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask); From 9a3009b8009f43f5d6d763c9e1e37ac9c5f8b358 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Tue, 19 May 2009 17:40:22 +0000 Subject: [PATCH 305/544] Add a new program, perror, which takes an errno as a command line argument and outputs the associated textual message in the same way that perror(3) would if called within a program. --- usr.bin/Makefile | 1 + usr.bin/perror/Makefile | 6 ++++ usr.bin/perror/perror.1 | 50 +++++++++++++++++++++++++++ usr.bin/perror/perror.c | 76 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+) create mode 100644 usr.bin/perror/Makefile create mode 100644 usr.bin/perror/perror.1 create mode 100644 usr.bin/perror/perror.c diff --git a/usr.bin/Makefile b/usr.bin/Makefile index cdfaf1294313..f67bfc25e095 100644 --- a/usr.bin/Makefile +++ b/usr.bin/Makefile @@ -149,6 +149,7 @@ SUBDIR= alias \ passwd \ paste \ pathchk \ + perror \ pr \ printenv \ printf \ diff --git a/usr.bin/perror/Makefile b/usr.bin/perror/Makefile new file mode 100644 index 000000000000..39e5dfffab27 --- /dev/null +++ b/usr.bin/perror/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= perror +SRCS= perror.c + +.include diff --git a/usr.bin/perror/perror.1 b/usr.bin/perror/perror.1 new file mode 100644 index 000000000000..7faf77f10d95 --- /dev/null +++ b/usr.bin/perror/perror.1 @@ -0,0 +1,50 @@ +.\" +.\" Copyright (c) 2009 Advanced Computing Technologies LLC +.\" Written by: George V. Neville-Neil +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd May 12, 2009 +.Dt PERROR 1 +.Os +.Sh NAME +.Nm perror +.Nd "print an error number as a string" +.Sh SYNOPSIS +.Nm +.Op Ar number +.Sh DESCRIPTION +The +.Nm +program takes a raw errno value and prints it as a string. +.Sh SEE ALSO +.Xr perror 3 +.Sh HISTORY +The +.Nm +program first appeared in +.Fx 8.0 . +.Sh AUTHORS +.An George V. Neville-Neil diff --git a/usr.bin/perror/perror.c b/usr.bin/perror/perror.c new file mode 100644 index 000000000000..749d3ea7d6c3 --- /dev/null +++ b/usr.bin/perror/perror.c @@ -0,0 +1,76 @@ +/*- + * Copyright (c) 2009 Advanced Computing Technologies LLC + * Written by: George V. Neville-Neil + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#define MAX_ERR 256 + +void usage() +{ + + printf("usage: perror number\n"); + printf("number must be between 1 and %d\n", ELAST); + exit(1); +} + +int main(int argc, char **argv) +{ + + char errstr[MAX_ERR]; + char *cp; + int errnum; + + if (argc != 2) + usage(); + + errnum = strtol(argv[1], &cp, 0); + + if (((errnum == 0) && (errno == EINVAL)) || (*cp != '\0')) { + printf("Argument %s not a number.\n", argv[1]); + usage(); + } + + if ((errnum <=0) || (errnum > ELAST)) { + printf("Number %d out of range.\n", errnum); + usage(); + } + + if (strerror_r(errnum, errstr, sizeof(errstr)) < 0) { + printf("Could not find error number %d.\n", errnum); + usage(); + } + + printf("Error %d is \"%s\"\n", errnum, errstr); + + exit(0); +} From 00e602a997988769585a1ae0e48ed7b87e8f4521 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 17:43:31 +0000 Subject: [PATCH 306/544] minor cleanup --- .../ath/ath_hal/ar5212/ar5212_interrupts.c | 25 ++++++------------- sys/dev/ath/ath_hal/ar5212/ar5212reg.h | 7 +++++- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c index d6614276c2e8..112bbeb00162 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c @@ -55,20 +55,20 @@ HAL_BOOL ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) { uint32_t isr, isr0, isr1; - uint32_t mask2=0; + uint32_t mask2; struct ath_hal_5212 *ahp = AH5212(ah); isr = OS_REG_READ(ah, AR_ISR); + mask2 = 0; if (isr & AR_ISR_BCNMISC) { - uint32_t isr2; - isr2 = OS_REG_READ(ah, AR_ISR_S2); + uint32_t isr2 = OS_REG_READ(ah, AR_ISR_S2); if (isr2 & AR_ISR_S2_TIM) mask2 |= HAL_INT_TIM; if (isr2 & AR_ISR_S2_DTIM) mask2 |= HAL_INT_DTIM; if (isr2 & AR_ISR_S2_DTIMSYNC) mask2 |= HAL_INT_DTIMSYNC; - if (isr2 & (AR_ISR_S2_CABEND )) + if (isr2 & AR_ISR_S2_CABEND) mask2 |= HAL_INT_CABEND; } isr = OS_REG_READ(ah, AR_ISR_RAC); @@ -137,7 +137,7 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) { struct ath_hal_5212 *ahp = AH5212(ah); uint32_t omask = ahp->ah_maskReg; - uint32_t mask,mask2; + uint32_t mask, mask2; HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__, omask, ints); @@ -171,7 +171,7 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) if (ints & HAL_INT_DTIMSYNC) mask2 |= AR_IMR_S2_DTIMSYNC; if (ints & HAL_INT_CABEND) - mask2 |= (AR_IMR_S2_CABEND ); + mask2 |= AR_IMR_S2_CABEND; } if (ints & HAL_INT_FATAL) { /* @@ -184,15 +184,8 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) /* Write the new IMR and store off our SW copy. */ HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask); OS_REG_WRITE(ah, AR_IMR, mask); - OS_REG_WRITE(ah, AR_IMR_S2, - (OS_REG_READ(ah, AR_IMR_S2) & - ~(AR_IMR_S2_TIM | - AR_IMR_S2_DTIM | - AR_IMR_S2_DTIMSYNC | - AR_IMR_S2_CABEND | - AR_IMR_S2_CABTO | - AR_IMR_S2_TSFOOR ) ) - | mask2); + OS_REG_WRITE(ah, AR_IMR_S2, + (OS_REG_READ(ah, AR_IMR_S2) &~ AR_IMR_SR2_BCNMISC) | mask2); ahp->ah_maskReg = ints; /* Re-enable interrupts if they were enabled before. */ @@ -200,7 +193,5 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__); OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE); } - - return omask; } diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h index 681c6e33bbbe..f4e255fb5ee9 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h +++ b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h @@ -14,7 +14,7 @@ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * - * $Id: ar5212reg.h,v 1.5 2008/11/16 06:45:43 sam Exp $ + * $FreeBSD$ */ #ifndef _DEV_ATH_AR5212REG_H_ #define _DEV_ATH_AR5212REG_H_ @@ -534,6 +534,11 @@ #define AR_IMR_S2_TSFOOR 0x80000000 /* TSF OOR */ #define AR_IMR_S2_RESV0 0xE0F8FC00 /* Reserved */ +/* AR_IMR_SR2 bits that correspond to AR_IMR_BCNMISC */ +#define AR_IMR_SR2_BCNMISC \ + (AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | \ + AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | AR_IMR_S2_TSFOOR) + #define AR_IMR_S3_QCU_QCBROVF 0x000003FF /* Mask for QCBROVF (QCU 0-9) */ #define AR_IMR_S3_QCU_QCBRURN 0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */ #define AR_IMR_S3_QCU_QCBRURN_S 16 /* Shift for QCBRURN (QCU 0-9) */ From 210411e0f1c6f40ecf812f3480d04b743a79a256 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 17:53:53 +0000 Subject: [PATCH 307/544] add TBTT interrupt support; this was added in Griffin so consumers should check HAL_CAP_INTRMASK before using it NB: didn't test 11n parts yet so supported only for 5212-class parts --- sys/dev/ath/ath_hal/ah.h | 4 +++- sys/dev/ath/ath_hal/ar5212/ar5212_attach.c | 2 ++ sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c | 4 ++++ sys/dev/ath/ath_hal/ar5212/ar5212reg.h | 10 ++++++---- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index faeec97b2df4..e91ad93cfdae 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -335,6 +335,7 @@ typedef enum { HAL_INT_GPIO = 0x01000000, HAL_INT_CABEND = 0x02000000, /* Non-common mapping */ HAL_INT_TSFOOR = 0x04000000, /* Non-common mapping */ + HAL_INT_TBTT = 0x08000000, /* Non-common mapping */ HAL_INT_CST = 0x10000000, /* Non-common mapping */ HAL_INT_GTT = 0x20000000, /* Non-common mapping */ HAL_INT_FATAL = 0x40000000, /* Non-common mapping */ @@ -342,7 +343,8 @@ typedef enum { HAL_INT_BMISC = HAL_INT_TIM | HAL_INT_DTIM | HAL_INT_DTIMSYNC - | HAL_INT_CABEND, + | HAL_INT_CABEND + | HAL_INT_TBTT, /* Interrupt bits that map directly to ISR/IMR bits */ HAL_INT_COMMON = HAL_INT_RXNOFRM diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c index 63856a4f4f7e..60e15218b507 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_attach.c @@ -847,6 +847,8 @@ ar5212FillCapabilityInfo(struct ath_hal *ah) | HAL_INT_BNR | HAL_INT_BMISC ; + if (AH_PRIVATE(ah)->ah_macVersion < AR_SREV_VERSION_GRIFFIN) + pCap->halIntrMask &= ~HAL_INT_TBTT; return AH_TRUE; #undef IS_COBRA diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c index 112bbeb00162..b9cee9ab23be 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c +++ b/sys/dev/ath/ath_hal/ar5212/ar5212_interrupts.c @@ -70,6 +70,8 @@ ar5212GetPendingInterrupts(struct ath_hal *ah, HAL_INT *masked) mask2 |= HAL_INT_DTIMSYNC; if (isr2 & AR_ISR_S2_CABEND) mask2 |= HAL_INT_CABEND; + if (isr2 & AR_ISR_S2_TBTT) + mask2 |= HAL_INT_TBTT; } isr = OS_REG_READ(ah, AR_ISR_RAC); if (isr == 0xffffffff) { @@ -172,6 +174,8 @@ ar5212SetInterrupts(struct ath_hal *ah, HAL_INT ints) mask2 |= AR_IMR_S2_DTIMSYNC; if (ints & HAL_INT_CABEND) mask2 |= AR_IMR_S2_CABEND; + if (ints & HAL_INT_TBTT) + mask2 |= AR_IMR_S2_TBTT; } if (ints & HAL_INT_FATAL) { /* diff --git a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h index f4e255fb5ee9..ef6d600fd35b 100644 --- a/sys/dev/ath/ath_hal/ar5212/ar5212reg.h +++ b/sys/dev/ath/ath_hal/ar5212/ar5212reg.h @@ -463,7 +463,8 @@ #define AR_ISR_S2_BCNTO 0x08000000 /* BCNTO */ #define AR_ISR_S2_CABTO 0x10000000 /* CABTO */ #define AR_ISR_S2_DTIM 0x20000000 /* DTIM */ -#define AR_ISR_S2_RESV0 0xE0F8FC00 /* Reserved */ +#define AR_ISR_S2_TSFOOR 0x40000000 /* TSF OOR */ +#define AR_ISR_S2_TBTT 0x80000000 /* TBTT timer */ #define AR_ISR_S3_QCU_QCBROVF 0x000003FF /* Mask for QCBROVF (QCU 0-9) */ #define AR_ISR_S3_QCU_QCBRURN 0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */ @@ -531,13 +532,14 @@ #define AR_IMR_S2_BCNTO 0x08000000 /* BCNTO */ #define AR_IMR_S2_CABTO 0x10000000 /* CABTO */ #define AR_IMR_S2_DTIM 0x20000000 /* DTIM */ -#define AR_IMR_S2_TSFOOR 0x80000000 /* TSF OOR */ -#define AR_IMR_S2_RESV0 0xE0F8FC00 /* Reserved */ +#define AR_IMR_S2_TSFOOR 0x40000000 /* TSF OOR */ +#define AR_IMR_S2_TBTT 0x80000000 /* TBTT timer */ /* AR_IMR_SR2 bits that correspond to AR_IMR_BCNMISC */ #define AR_IMR_SR2_BCNMISC \ (AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC | \ - AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | AR_IMR_S2_TSFOOR) + AR_IMR_S2_CABEND | AR_IMR_S2_CABTO | AR_IMR_S2_TSFOOR | \ + AR_IMR_S2_TBTT) #define AR_IMR_S3_QCU_QCBROVF 0x000003FF /* Mask for QCBROVF (QCU 0-9) */ #define AR_IMR_S3_QCU_QCBRURN 0x03FF0000 /* Mask for QCBRURN (QCU 0-9) */ From 3f51a182296b28d484ce0aefbc168e45e7d55912 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Tue, 19 May 2009 17:54:32 +0000 Subject: [PATCH 308/544] correct HAL_INT_BNR comment, this bit is mapped directly the h/w now --- sys/dev/ath/ath_hal/ah.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ath/ath_hal/ah.h b/sys/dev/ath/ath_hal/ah.h index e91ad93cfdae..ba55a2d7a3bd 100644 --- a/sys/dev/ath/ath_hal/ah.h +++ b/sys/dev/ath/ath_hal/ah.h @@ -328,7 +328,7 @@ typedef enum { HAL_INT_RXKCM = 0x00008000, HAL_INT_SWBA = 0x00010000, HAL_INT_BMISS = 0x00040000, - HAL_INT_BNR = 0x00100000, /* Non-common mapping */ + HAL_INT_BNR = 0x00100000, HAL_INT_TIM = 0x00200000, /* Non-common mapping */ HAL_INT_DTIM = 0x00400000, /* Non-common mapping */ HAL_INT_DTIMSYNC= 0x00800000, /* Non-common mapping */ From 56a3c6d4a7dfb67517b805ed1279b2e1f5fc1dd7 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Tue, 19 May 2009 19:21:25 +0000 Subject: [PATCH 309/544] With SMPng, DEVICE_POLLING uses its own idle threads, rather than the system idle loop, to run ether_poll(), so make ether_poll() static. MFC after: 1 week --- sys/kern/kern_poll.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/kern/kern_poll.c b/sys/kern/kern_poll.c index 8ca6b93fac92..2952a88995a6 100644 --- a/sys/kern/kern_poll.c +++ b/sys/kern/kern_poll.c @@ -53,7 +53,6 @@ static void netisr_pollmore(void); static int poll_switch(SYSCTL_HANDLER_ARGS); void hardclock_device_poll(void); /* hook from hardclock */ -void ether_poll(int); /* polling in idle loop */ static struct mtx poll_mtx; @@ -325,7 +324,7 @@ hardclock_device_poll(void) /* * ether_poll is called from the idle loop. */ -void +static void ether_poll(int count) { int i; From 99000ae1946d946fda8a47db7bae9708b46f5830 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Tue, 19 May 2009 20:16:18 +0000 Subject: [PATCH 310/544] Fix a few style(9) nits. Submitted by: danfe --- usr.bin/perror/perror.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/usr.bin/perror/perror.c b/usr.bin/perror/perror.c index 749d3ea7d6c3..4ef79cbd9959 100644 --- a/usr.bin/perror/perror.c +++ b/usr.bin/perror/perror.c @@ -35,15 +35,17 @@ __FBSDID("$FreeBSD$"); #define MAX_ERR 256 -void usage() +static void +usage() { - printf("usage: perror number\n"); - printf("number must be between 1 and %d\n", ELAST); + fprintf(stderr, "usage: perror number\n"); + fprintf(stderr, "number must be between 1 and %d\n", ELAST); exit(1); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { char errstr[MAX_ERR]; @@ -56,17 +58,17 @@ int main(int argc, char **argv) errnum = strtol(argv[1], &cp, 0); if (((errnum == 0) && (errno == EINVAL)) || (*cp != '\0')) { - printf("Argument %s not a number.\n", argv[1]); + fprintf(stderr, "Argument %s not a number.\n", argv[1]); usage(); } if ((errnum <=0) || (errnum > ELAST)) { - printf("Number %d out of range.\n", errnum); + fprintf(stderr, "Number %d out of range.\n", errnum); usage(); } if (strerror_r(errnum, errstr, sizeof(errstr)) < 0) { - printf("Could not find error number %d.\n", errnum); + fprintf(stderr, "Could not find error number %d.\n", errnum); usage(); } From a9ffff74c592f58f8d6eb837ba78acd7dbc42850 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Tue, 19 May 2009 22:28:33 +0000 Subject: [PATCH 311/544] Since audit(4) isn't based on posix1e, remove the commented out audit.h header, xref libbsm(3). Submitted by: rwatson MFC after: 3 days --- lib/libc/posix1e/posix1e.3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/libc/posix1e/posix1e.3 b/lib/libc/posix1e/posix1e.3 index 6333b08b8ab7..2065523bad98 100644 --- a/lib/libc/posix1e/posix1e.3 +++ b/lib/libc/posix1e/posix1e.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 17, 2000 +.Dd May 20, 2009 .Dt POSIX1E 3 .Os .Sh NAME @@ -36,7 +36,6 @@ .Sh SYNOPSIS .In sys/types.h .In sys/acl.h -.\" .In sys/audit.h .\" .In sys/capability.h .In sys/mac.h .Sh DESCRIPTION @@ -104,6 +103,7 @@ structure. .Sh SEE ALSO .Xr extattr 2 , .Xr acl 3 , +.Xr libbsm 3 , .Xr mac 3 , .Xr acl 9 , .Xr extattr 9 , From 126f8425c3dddba964f2ea0f51b9f3e5ed2e4f91 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Wed, 20 May 2009 02:51:48 +0000 Subject: [PATCH 312/544] Add minimal ZFS lock hierarchy --- sys/kern/subr_witness.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sys/kern/subr_witness.c b/sys/kern/subr_witness.c index 6d54be2f01e5..799dbccfea57 100644 --- a/sys/kern/subr_witness.c +++ b/sys/kern/subr_witness.c @@ -609,6 +609,13 @@ static struct witness_order_list_entry order_lists[] = { { "struct mount mtx", &lock_class_mtx_sleep }, { "vnode interlock", &lock_class_mtx_sleep }, { NULL, NULL }, + /* + * ZFS locking + */ + { "dn->dn_mtx", &lock_class_sx }, + { "dr->dt.di.dr_mtx", &lock_class_sx }, + { "db->db_mtx", &lock_class_sx }, + { NULL, NULL }, /* * spin locks */ From e32035ce1e794b9cff2908b8e192893b7c815b71 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Wed, 20 May 2009 03:33:27 +0000 Subject: [PATCH 313/544] pci(4) handles PCIM_CMD_INTxDIS so there is no need to poke this bit in driver. --- sys/dev/age/if_age.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/sys/dev/age/if_age.c b/sys/dev/age/if_age.c index 74afa2e44c7e..d60c2850c9cb 100644 --- a/sys/dev/age/if_age.c +++ b/sys/dev/age/if_age.c @@ -1477,23 +1477,11 @@ age_resume(device_t dev) { struct age_softc *sc; struct ifnet *ifp; - uint16_t cmd; sc = device_get_softc(dev); AGE_LOCK(sc); - /* - * Clear INTx emulation disable for hardwares that - * is set in resume event. From Linux. - */ - cmd = pci_read_config(sc->age_dev, PCIR_COMMAND, 2); - if ((cmd & 0x0400) != 0) { - cmd &= ~0x0400; - pci_write_config(sc->age_dev, PCIR_COMMAND, cmd, 2); - } - AGE_UNLOCK(sc); age_phy_reset(sc); - AGE_LOCK(sc); ifp = sc->age_ifp; if ((ifp->if_flags & IFF_UP) != 0) age_init_locked(sc); From e557e680881d7ae8ffc29fc201b81fc82a57d1eb Mon Sep 17 00:00:00 2001 From: Weongyo Jeong Date: Wed, 20 May 2009 03:49:16 +0000 Subject: [PATCH 314/544] try to unsetup USB xfers before calling ieee80211_ifdetach() to fix a bug referencing a destroyed lock within TX callbacks during device detach. Submitted by: hps (original version) Tested by: Lucius Windschuh --- sys/dev/usb/wlan/if_uath.c | 2 +- sys/dev/usb/wlan/if_upgt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 98c494355bc6..f647daec99f4 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -517,12 +517,12 @@ uath_detach(device_t dev) sc->sc_flags |= UATH_FLAG_INVALID; uath_stop(ifp); - ieee80211_ifdetach(ic); callout_drain(&sc->stat_ch); callout_drain(&sc->watchdog_ch); usb2_transfer_unsetup(sc->sc_xfer, UATH_N_XFERS); + ieee80211_ifdetach(ic); /* free buffers */ UATH_LOCK(sc); diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index 3bef0b43359d..d99c74008630 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -2002,12 +2002,12 @@ upgt_detach(device_t dev) return 0; upgt_stop(sc); - ieee80211_ifdetach(ic); callout_drain(&sc->sc_led_ch); callout_drain(&sc->sc_watchdog_ch); usb2_transfer_unsetup(sc->sc_xfer, UPGT_N_XFERS); + ieee80211_ifdetach(ic); upgt_free_rx(sc); upgt_free_tx(sc); From 2785354e6806ad4c985de04078999cfbc5d6854c Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Wed, 20 May 2009 05:49:06 +0000 Subject: [PATCH 315/544] o style.Makefile(5): remove SRCS. --- usr.bin/perror/Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/usr.bin/perror/Makefile b/usr.bin/perror/Makefile index 39e5dfffab27..e76d593dc433 100644 --- a/usr.bin/perror/Makefile +++ b/usr.bin/perror/Makefile @@ -1,6 +1,5 @@ # $FreeBSD$ PROG= perror -SRCS= perror.c .include From 866772cfa746cd2518075ae7165998d58d07659f Mon Sep 17 00:00:00 2001 From: Marcel Moolenaar Date: Wed, 20 May 2009 06:01:20 +0000 Subject: [PATCH 316/544] Simplify now that we have gpart. --- lib/libdisk/open_ia64_disk.c | 117 ++++++++++------------------------- 1 file changed, 33 insertions(+), 84 deletions(-) diff --git a/lib/libdisk/open_ia64_disk.c b/lib/libdisk/open_ia64_disk.c index aeac7c88f0ce..287757d8226d 100644 --- a/lib/libdisk/open_ia64_disk.c +++ b/lib/libdisk/open_ia64_disk.c @@ -40,16 +40,9 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include #include "libdisk.h" -static uuid_t _efi = GPT_ENT_TYPE_EFI; -static uuid_t _mbr = GPT_ENT_TYPE_MBR; -static uuid_t _fbsd = GPT_ENT_TYPE_FREEBSD; -static uuid_t _swap = GPT_ENT_TYPE_FREEBSD_SWAP; -static uuid_t _ufs = GPT_ENT_TYPE_FREEBSD_UFS; - static struct disk * parse_disk(char *conftxt, const char *name) { @@ -147,11 +140,9 @@ struct disk * Int_Open_Disk(const char *name, char *conftxt) { struct chunk chunk; - uuid_t uuid; struct disk *disk; - char *p, *q, *r, *s, *sd, *type; + char *p, *q, *r, *s, *sd; u_long i; - uint32_t status; p = conftxt; while (p != NULL && *p != 0) { @@ -186,17 +177,27 @@ Int_Open_Disk(const char *name, char *conftxt) if (conftxt != NULL) *conftxt++ = '\0'; + /* + * 1 PART da0p4 34359738368 512 + * i 4 o 52063912960 ty freebsd-ufs + * xs GPT xt 516e7cb6-6ecf-11d6-8ff8-00022d09712b + */ sd = strsep(&p, " "); /* depth */ if (strcmp(sd, "0") == 0) break; - type = strsep(&p, " "); /* type */ + q = strsep(&p, " "); /* type */ + if (strcmp(q, "PART") != 0) + continue; + chunk.name = strsep(&p, " "); /* name */ + q = strsep(&p, " "); /* length */ i = strtoimax(q, &r, 0); if (*r) abort(); chunk.end = i / disk->sector_size; + q = strsep(&p, " "); /* sector size */ for (;;) { @@ -205,82 +206,30 @@ Int_Open_Disk(const char *name, char *conftxt) break; r = strsep(&p, " "); i = strtoimax(r, &s, 0); - if (*s) { - status = uuid_s_ok; + if (strcmp(q, "ty") == 0 && *s != '\0') { if (!strcmp(r, "efi")) - uuid = _efi; - else if (!strcmp(r, "mbr")) - uuid = _mbr; - else if (!strcmp(r, "freebsd")) - uuid = _fbsd; - else if (!strcmp(r, "freebsd-swap")) - uuid = _swap; - else if (!strcmp(r, "freebsd-ufs")) - uuid = _ufs; - else { - if (!strcmp(type, "PART")) - uuid_from_string(r + 1, &uuid, - &status); - else - uuid_from_string(r, &uuid, - &status); + chunk.type = efi; + else if (!strcmp(r, "freebsd")) { + chunk.type = freebsd; + chunk.subtype = 0xa5; + } else if (!strcmp(r, "freebsd-swap")) { + chunk.type = part; + chunk.subtype = FS_SWAP; + } else if (!strcmp(r, "freebsd-ufs")) { + chunk.type = part; + chunk.subtype = FS_BSDFFS; + } else { + chunk.type = part; + chunk.subtype = FS_OTHER; } - } else - status = uuid_s_invalid_string_uuid; - if (!strcmp(q, "o")) - chunk.offset = i / disk->sector_size; - else if (!strcmp(q, "i")) - chunk.flags = CHUNK_ITOF(i) | CHUNK_HAS_INDEX; - else if (!strcmp(q, "ty")) - chunk.subtype = i; - } - - if (strncmp(type, "MBR", 3) == 0) { - switch (chunk.subtype) { - case 0xa5: - chunk.type = freebsd; - break; - case 0x01: - case 0x04: - case 0x06: - case 0x0b: - case 0x0c: - case 0x0e: - chunk.type = fat; - break; - case 0xef: /* EFI */ - chunk.type = efi; - break; - default: - chunk.type = mbr; - break; + } else { + if (!strcmp(q, "o")) + chunk.offset = i / disk->sector_size; + else if (!strcmp(q, "i")) + chunk.flags = CHUNK_ITOF(i) | + CHUNK_HAS_INDEX; } - } else if (strcmp(type, "BSD") == 0) { - chunk.type = part; - } else if (strcmp(type, "GPT") == 0 || - strcmp(type, "PART") == 0) { - chunk.subtype = 0; - if (status != uuid_s_ok) - abort(); - if (uuid_is_nil(&uuid, NULL)) - chunk.type = unused; - else if (uuid_equal(&uuid, &_efi, NULL)) - chunk.type = efi; - else if (uuid_equal(&uuid, &_mbr, NULL)) - chunk.type = mbr; - else if (uuid_equal(&uuid, &_fbsd, NULL)) { - chunk.type = freebsd; - chunk.subtype = 0xa5; - } else if (uuid_equal(&uuid, &_swap, NULL)) { - chunk.type = part; - chunk.subtype = FS_SWAP; - } else if (uuid_equal(&uuid, &_ufs, NULL)) { - chunk.type = part; - chunk.subtype = FS_BSDFFS; - } else - chunk.type = part; - } else - abort(); + } Add_Chunk(disk, chunk.offset, chunk.end, chunk.name, chunk.type, chunk.subtype, chunk.flags, 0); From 15344a56903b4a79b565e45c3d8b40ee7ca37b9d Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Wed, 20 May 2009 08:32:25 +0000 Subject: [PATCH 317/544] Verify that the username length is smaller than MAXLOGNAME when asked to verify a passwd file (pwd_mkdb -C). Entries with oversized usernames are still permitted when building the passwd database. When entries are >= MAXLOGNAME in length, they are correctly stored in passwd, pwd.db and spwd.db but are only correctly retrieved by getpwent*() and getpwuid*(). getpwnam*() truncates to MAXLOGNAME - 1 when reading from a file (breaking at least sh, tcsh and bash) and utilities such as su(1) check, complain and fail if the passed name is >= MAXLOGNAME in length. MFC after: 3 weeks --- usr.sbin/pwd_mkdb/pwd_mkdb.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/usr.sbin/pwd_mkdb/pwd_mkdb.c b/usr.sbin/pwd_mkdb/pwd_mkdb.c index 3c8ca252a0c8..2abbcdf34c99 100644 --- a/usr.sbin/pwd_mkdb/pwd_mkdb.c +++ b/usr.sbin/pwd_mkdb/pwd_mkdb.c @@ -204,7 +204,11 @@ main(int argc, char *argv[]) /* check only if password database is valid */ if (Cflag) { - for (cnt = 1; scan(fp, &pwd); ++cnt); + while (scan(fp, &pwd)) + if (!is_comment && strlen(pwd.pw_name) >= MAXLOGNAME) { + warnx("%s: username too long", pwd.pw_name); + exit(1); + } exit(0); } From 74150c398ab0f07201b8c5b9c503f26799de70da Mon Sep 17 00:00:00 2001 From: Alexander Motin Date: Wed, 20 May 2009 09:44:32 +0000 Subject: [PATCH 318/544] Fix NULL dereference on Promise SX4 controllers, while executing commands that do not require data transfer (FLUSHCACHE). Tested by: Magnus Kling MFC after: 1 week --- sys/dev/ata/chipsets/ata-promise.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 4577ee642a9a..f0632071b2c1 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -1054,7 +1054,7 @@ ata_promise_sx4_command(struct ata_request *request) device_t gparent = GRANDPARENT(request->dev); struct ata_pci_controller *ctlr = device_get_softc(gparent); struct ata_channel *ch = device_get_softc(request->parent); - struct ata_dma_prdentry *prd = request->dma->sg; + struct ata_dma_prdentry *prd; caddr_t window = rman_get_virtual(ctlr->r_res1); u_int32_t *wordp; int i, idx, length = 0; @@ -1098,6 +1098,7 @@ ata_promise_sx4_command(struct ata_request *request) case ATA_READ_DMA48: case ATA_WRITE_DMA: case ATA_WRITE_DMA48: + prd = request->dma->sg; wordp = (u_int32_t *) (window + (ch->unit * ATA_PDC_CHN_OFFSET) + ATA_PDC_HSG_OFFSET); i = idx = 0; From 515c5b1ede5a730b7138d1324401ddb8ef7d97cc Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 16:11:22 +0000 Subject: [PATCH 319/544] Don't bother reading the initial value of the machine check banks during startup on Pentium 4 CPUs. This wasn't safe to do on APs during AP startup, was of limited value, and won't be used for future processors. --- sys/amd64/amd64/mca.c | 4 ---- sys/i386/i386/mca.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/sys/amd64/amd64/mca.c b/sys/amd64/amd64/mca.c index 8669c2bd74b7..d291d009ee23 100644 --- a/sys/amd64/amd64/mca.c +++ b/sys/amd64/amd64/mca.c @@ -491,10 +491,6 @@ mca_init(void) if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); - /* XXX: Better CPU test needed here. */ - if ((cpu_id & 0xf00) == 0xf00) - mca_record_entry(i); - /* Clear all errors. */ wrmsr(MSR_MC_STATUS(i), 0); } diff --git a/sys/i386/i386/mca.c b/sys/i386/i386/mca.c index 5ad8c526d18a..5e7e4ffea260 100644 --- a/sys/i386/i386/mca.c +++ b/sys/i386/i386/mca.c @@ -491,10 +491,6 @@ mca_init(void) if (!(i == 0 && (cpu_id & 0xf00) == 0x600)) wrmsr(MSR_MC_CTL(i), 0xffffffffffffffffUL); - /* XXX: Better CPU test needed here. */ - if ((cpu_id & 0xf00) == 0xf00) - mca_record_entry(i); - /* Clear all errors. */ wrmsr(MSR_MC_STATUS(i), 0); } From 09605c1806f9a74334c8375c64621a381e8c54da Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 16:29:22 +0000 Subject: [PATCH 320/544] Some minor style changes: o Convert K&R function definitions to ANSI o Eliminate spaces/tabs that should have been deleted as part of the de__P efforts o Use struct thread * in preference to d_thread_t *. --- sys/i386/bios/smapi.c | 36 ++++++++++++++---------------------- 1 file changed, 14 insertions(+), 22 deletions(-) diff --git a/sys/i386/bios/smapi.c b/sys/i386/bios/smapi.c index bb0b2bf3a6af..e572664e2aca 100644 --- a/sys/i386/bios/smapi.c +++ b/sys/i386/bios/smapi.c @@ -58,7 +58,7 @@ __FBSDID("$FreeBSD$"); #define ADDR2HDR(addr) ((struct smapi_bios_header *)BIOS_PADDRTOVADDR(addr)) struct smapi_softc { - struct cdev *cdev; + struct cdev * cdev; device_t dev; struct resource * res; int rid; @@ -82,27 +82,22 @@ static struct cdevsw smapi_cdevsw = { .d_flags = D_MEM | D_NEEDGIANT, }; -static void smapi_identify (driver_t *, device_t); -static int smapi_probe (device_t); -static int smapi_attach (device_t); -static int smapi_detach (device_t); -static int smapi_modevent (module_t, int, void *); +static void smapi_identify(driver_t *, device_t); +static int smapi_probe(device_t); +static int smapi_attach(device_t); +static int smapi_detach(device_t); +static int smapi_modevent(module_t, int, void *); -static int smapi_header_cksum (struct smapi_bios_header *); +static int smapi_header_cksum(struct smapi_bios_header *); -extern int smapi32 (struct smapi_bios_parameter *, - struct smapi_bios_parameter *); -extern int smapi32_new (u_long, u_short, - struct smapi_bios_parameter *, - struct smapi_bios_parameter *); +extern int smapi32(struct smapi_bios_parameter *, + struct smapi_bios_parameter *); +extern int smapi32_new(u_long, u_short, + struct smapi_bios_parameter *, + struct smapi_bios_parameter *); static int -smapi_ioctl (dev, cmd, data, fflag, td) - struct cdev *dev; - u_long cmd; - caddr_t data; - int fflag; - d_thread_t * td; +smapi_ioctl (struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { struct smapi_softc *sc; int error; @@ -283,10 +278,7 @@ smapi_detach (device_t dev) } static int -smapi_modevent (mod, what, arg) - module_t mod; - int what; - void * arg; +smapi_modevent (module_t mod, int what, void *arg) { device_t * devs; int count; From 1de9b53249baaa4088cbf9edd5ae6959fd2d8e21 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 16:47:40 +0000 Subject: [PATCH 321/544] We don't need d_thread_t for cross-branch portability here anymore. Move do struct thread * instead. --- sys/i386/acpica/acpi_machdep.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/i386/acpica/acpi_machdep.c b/sys/i386/acpica/acpi_machdep.c index 8d130fbe668e..4d31b44ab736 100644 --- a/sys/i386/acpica/acpi_machdep.c +++ b/sys/i386/acpica/acpi_machdep.c @@ -277,7 +277,7 @@ apm_create_clone(struct cdev *dev, struct acpi_softc *acpi_sc) } static int -apmopen(struct cdev *dev, int flag, int fmt, d_thread_t *td) +apmopen(struct cdev *dev, int flag, int fmt, struct thread *td) { struct acpi_softc *acpi_sc; struct apm_clone_data *clone; @@ -294,7 +294,7 @@ apmopen(struct cdev *dev, int flag, int fmt, d_thread_t *td) } static int -apmclose(struct cdev *dev, int flag, int fmt, d_thread_t *td) +apmclose(struct cdev *dev, int flag, int fmt, struct thread *td) { struct apm_clone_data *clone; struct acpi_softc *acpi_sc; @@ -318,7 +318,7 @@ apmclose(struct cdev *dev, int flag, int fmt, d_thread_t *td) } static int -apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td) +apmioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { int error; struct apm_clone_data *clone; @@ -436,7 +436,7 @@ apmwrite(struct cdev *dev, struct uio *uio, int ioflag) } static int -apmpoll(struct cdev *dev, int events, d_thread_t *td) +apmpoll(struct cdev *dev, int events, struct thread *td) { struct apm_clone_data *clone; int revents; From 248343f9d12d2b8f889be124ed7030ff463de7d9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 16:58:16 +0000 Subject: [PATCH 322/544] We no longer need to use d_thread_t for portability here, switch to struct thread *. --- sys/kern/subr_bus.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 92a403841265..90d800f4e6d4 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -403,7 +403,7 @@ devinit(void) } static int -devopen(struct cdev *dev, int oflags, int devtype, d_thread_t *td) +devopen(struct cdev *dev, int oflags, int devtype, struct thread *td) { if (devsoftc.inuse) return (EBUSY); @@ -415,7 +415,7 @@ devopen(struct cdev *dev, int oflags, int devtype, d_thread_t *td) } static int -devclose(struct cdev *dev, int fflag, int devtype, d_thread_t *td) +devclose(struct cdev *dev, int fflag, int devtype, struct thread *td) { devsoftc.inuse = 0; mtx_lock(&devsoftc.mtx); @@ -464,7 +464,7 @@ devread(struct cdev *dev, struct uio *uio, int ioflag) } static int -devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td) +devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) { switch (cmd) { @@ -494,7 +494,7 @@ devioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td) } static int -devpoll(struct cdev *dev, int events, d_thread_t *td) +devpoll(struct cdev *dev, int events, struct thread *td) { int revents = 0; From b28838a8612296578567bcba4a787b145f96cee8 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 20 May 2009 16:58:53 +0000 Subject: [PATCH 323/544] The register shift is not needed on this controller. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/uss820dci_atmelarm.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/dev/usb/controller/uss820dci_atmelarm.c b/sys/dev/usb/controller/uss820dci_atmelarm.c index c01c2c57628a..18b0eb380da8 100644 --- a/sys/dev/usb/controller/uss820dci_atmelarm.c +++ b/sys/dev/usb/controller/uss820dci_atmelarm.c @@ -152,9 +152,6 @@ uss820_atmelarm_attach(device_t dev) sc->sc_io_hdl = rman_get_bushandle(sc->sc_io_res); sc->sc_io_size = rman_get_size(sc->sc_io_res); - /* multiply all addresses by 4 */ - sc->sc_reg_shift = 2; - rid = 0; sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, RF_SHAREABLE | RF_ACTIVE); From 78bf597bb3e7db0b6bf7934ee6ac06b98300cc0d Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 17:00:16 +0000 Subject: [PATCH 324/544] Replace d_thread_t * with struct thread *. --- sys/netnatm/natm.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/sys/netnatm/natm.c b/sys/netnatm/natm.c index baa596e28930..cfcbaa786c73 100644 --- a/sys/netnatm/natm.c +++ b/sys/netnatm/natm.c @@ -100,24 +100,24 @@ struct mtx natm_mtx; /* * User socket requests. */ -static int natm_usr_attach(struct socket *, int, d_thread_t *); +static int natm_usr_attach(struct socket *, int, struct thread *); static void natm_usr_detach(struct socket *); static int natm_usr_connect(struct socket *, struct sockaddr *, - d_thread_t *); + struct thread *); static int natm_usr_disconnect(struct socket *); static int natm_usr_shutdown(struct socket *); static int natm_usr_send(struct socket *, int, struct mbuf *, - struct sockaddr *, struct mbuf *, d_thread_t *); + struct sockaddr *, struct mbuf *, struct thread *); static int natm_usr_peeraddr(struct socket *, struct sockaddr **); static int natm_usr_control(struct socket *, u_long, caddr_t, - struct ifnet *, d_thread_t *); + struct ifnet *, struct thread *); static void natm_usr_abort(struct socket *); static int natm_usr_bind(struct socket *, struct sockaddr *, - d_thread_t *); + struct thread *); static int natm_usr_sockaddr(struct socket *, struct sockaddr **); static int -natm_usr_attach(struct socket *so, int proto, d_thread_t *p) +natm_usr_attach(struct socket *so, int proto, struct thread *p) { struct natmpcb *npcb; int error = 0; @@ -155,7 +155,7 @@ natm_usr_detach(struct socket *so) } static int -natm_usr_connect(struct socket *so, struct sockaddr *nam, d_thread_t *p) +natm_usr_connect(struct socket *so, struct sockaddr *nam, struct thread *p) { struct natmpcb *npcb; struct sockaddr_natm *snatm; @@ -271,7 +271,7 @@ natm_usr_shutdown(struct socket *so) static int natm_usr_send(struct socket *so, int flags, struct mbuf *m, - struct sockaddr *nam, struct mbuf *control, d_thread_t *p) + struct sockaddr *nam, struct mbuf *control, struct thread *p) { struct natmpcb *npcb; struct atm_pseudohdr *aph; @@ -332,7 +332,7 @@ natm_usr_peeraddr(struct socket *so, struct sockaddr **nam) static int natm_usr_control(struct socket *so, u_long cmd, caddr_t arg, - struct ifnet *ifp, d_thread_t *p) + struct ifnet *ifp, struct thread *p) { struct natmpcb *npcb; @@ -357,7 +357,7 @@ natm_usr_close(struct socket *so) } static int -natm_usr_bind(struct socket *so, struct sockaddr *nam, d_thread_t *p) +natm_usr_bind(struct socket *so, struct sockaddr *nam, struct thread *p) { return (EOPNOTSUPP); From 7eaa41aed85939e4f5746bbdd04b0543f11f7496 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 20 May 2009 17:00:55 +0000 Subject: [PATCH 325/544] - Add new register definitions - Enable the controller and wait for the PLL to start Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/atmegadci.c | 39 ++++++++++++++++++++++-------- sys/dev/usb/controller/atmegadci.h | 16 ++++++++++++ 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index dc9372a69109..f296e30142a4 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -672,7 +672,7 @@ atmegadci_interrupt(struct atmegadci_softc *sc) * that like RESUME. Resume is set when there is at least 3 * milliseconds of inactivity on the USB BUS. */ - if (status & ATMEGA_UDINT_EORSMI) { + if (status & ATMEGA_UDINT_WAKEUPI) { DPRINTFN(5, "resume interrupt\n"); @@ -700,7 +700,7 @@ atmegadci_interrupt(struct atmegadci_softc *sc) /* disable suspend interrupt */ ATMEGA_WRITE_1(sc, ATMEGA_UDIEN, - ATMEGA_UDINT_EORSMI | + ATMEGA_UDINT_WAKEUPE | ATMEGA_UDINT_EORSTE); /* complete root HUB interrupt endpoint */ @@ -1152,13 +1152,12 @@ atmegadci_clear_stall_sub(struct atmegadci_softc *sc, uint8_t ep_no, ATMEGA_UECONX_STALLRQC); do { - temp = 0; if (ep_type == UE_BULK) { - temp |= ATMEGA_UECFG0X_EPTYPE2; + temp = ATMEGA_UECFG0X_EPTYPE2; } else if (ep_type == UE_INTERRUPT) { - temp |= ATMEGA_UECFG0X_EPTYPE3; + temp = ATMEGA_UECFG0X_EPTYPE3; } else { - temp |= ATMEGA_UECFG0X_EPTYPE1; + temp = ATMEGA_UECFG0X_EPTYPE1; } if (ep_dir & UE_DIR_IN) { temp |= ATMEGA_UECFG0X_EPDIR; @@ -1217,13 +1216,28 @@ atmegadci_init(struct atmegadci_softc *sc) sc->sc_bus.methods = &atmegadci_bus_methods; USB_BUS_LOCK(&sc->sc_bus); -#if 0 - /* XXX TODO - currently done by boot strap */ + + /* make sure USB is enabled */ + ATMEGA_WRITE_1(sc, ATMEGA_USBCON, + ATMEGA_USBCON_USBE | + ATMEGA_USBCON_FRZCLK); /* enable USB PAD regulator */ ATMEGA_WRITE_1(sc, ATMEGA_UHWCON, - ATMEGA_UHWCON_UVREGE | ATMEGA_UHWCON_UIMOD); -#endif + ATMEGA_UHWCON_UVREGE | + ATMEGA_UHWCON_UIMOD); + + /* the following register sets up the USB PLL, assuming 16MHz X-tal */ + ATMEGA_WRITE_1(sc, 0x49 /* PLLCSR */, 0x14 | 0x02); + + /* wait for PLL to lock */ + for (n = 0; n != 20; n++) { + if (ATMEGA_READ_1(sc, 0x49) & 0x01) + break; + /* wait a little bit for PLL to start */ + usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 100); + } + /* make sure USB is enabled */ ATMEGA_WRITE_1(sc, ATMEGA_USBCON, ATMEGA_USBCON_USBE | @@ -1847,6 +1861,11 @@ atmegadci_roothub_exec(struct usb2_device *udev, /* clear connect change flag */ sc->sc_flags.change_connect = 0; + if (!sc->sc_flags.status_bus_reset) { + /* we are not connected */ + break; + } + /* configure the control endpoint */ /* select endpoint number */ diff --git a/sys/dev/usb/controller/atmegadci.h b/sys/dev/usb/controller/atmegadci.h index 69939544a781..cd4b4f13a4e7 100644 --- a/sys/dev/usb/controller/atmegadci.h +++ b/sys/dev/usb/controller/atmegadci.h @@ -34,6 +34,10 @@ #define ATMEGA_MAX_DEVICES (USB_MIN_DEVICES + 1) +#define ATMEGA_OTGTCON 0xF9 +#define ATMEGA_OTGTCON_VALUE(x) ((x) << 0) +#define ATMEGA_OTGTCON_PAGE(x) ((x) << 5) + #define ATMEGA_UEINT 0xF4 #define ATMEGA_UEINT_MASK(n) (1 << (n)) /* endpoint interrupt mask */ @@ -136,8 +140,19 @@ #define ATMEGA_UDCON_LSM (1 << 2) #define ATMEGA_UDCON_RSTCPU (1 << 3) +#define ATMEGA_OTGINT 0xDF + +#define ATMEGA_OTGCON 0xDD +#define ATMEGA_OTGCON_VBUSRQC (1 << 0) +#define ATMEGA_OTGCON_VBUSREQ (1 << 1) +#define ATMEGA_OTGCON_VBUSHWC (1 << 2) +#define ATMEGA_OTGCON_SRPSEL (1 << 3) +#define ATMEGA_OTGCON_SRPREQ (1 << 4) +#define ATMEGA_OTGCON_HNPREQ (1 << 5) + #define ATMEGA_USBINT 0xDA #define ATMEGA_USBINT_VBUSTI (1 << 0) /* USB VBUS interrupt */ +#define ATMEGA_USBINT_IDI (1 << 1) /* USB ID interrupt */ #define ATMEGA_USBSTA 0xD9 #define ATMEGA_USBSTA_VBUS (1 << 0) @@ -145,6 +160,7 @@ #define ATMEGA_USBCON 0xD8 #define ATMEGA_USBCON_VBUSTE (1 << 0) +#define ATMEGA_USBCON_IDE (1 << 1) #define ATMEGA_USBCON_OTGPADE (1 << 4) #define ATMEGA_USBCON_FRZCLK (1 << 5) #define ATMEGA_USBCON_USBE (1 << 7) From 8060a8933ebf232b895d01d8f35679994170dfb9 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 17:01:40 +0000 Subject: [PATCH 326/544] Use struct thread instead of d_thread_t. --- sys/nfs4client/nfs4_dev.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/nfs4client/nfs4_dev.c b/sys/nfs4client/nfs4_dev.c index d8186e6d04f9..fc1e4875d841 100644 --- a/sys/nfs4client/nfs4_dev.c +++ b/sys/nfs4client/nfs4_dev.c @@ -255,7 +255,7 @@ nfs4dev_uninit(void) /* device interface functions */ static int -nfs4dev_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +nfs4dev_open(struct cdev *dev, int flags, int fmt, struct thread *td) { if (dev != nfs4device) return ENODEV; @@ -274,7 +274,7 @@ nfs4dev_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) } static int -nfs4dev_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +nfs4dev_close(struct cdev *dev, int flags, int fmt, struct thread *td) { struct nfs4dev_upcall * u; From 6f6932dc0b85572e3bbe2558e96d7be4e6c41e52 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Wed, 20 May 2009 17:03:12 +0000 Subject: [PATCH 327/544] Use defines for register offsets that do not change. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/uss820dci.c | 68 ++++++++++++------------------ sys/dev/usb/controller/uss820dci.h | 24 +---------- 2 files changed, 29 insertions(+), 63 deletions(-) diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index e31942545ade..371304ef6178 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -230,11 +230,11 @@ uss820dci_setup_rx(struct uss820dci_td *td) /* select the correct endpoint */ bus_space_write_1(td->io_tag, td->io_hdl, - td->ep_reg, td->ep_index); + USS820_EPINDEX, td->ep_index); /* read out FIFO status */ rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_stat_reg); + USS820_RXSTAT); /* get pointer to softc */ sc = USS820_DCI_PC2SC(td->pc); @@ -260,9 +260,9 @@ uss820dci_setup_rx(struct uss820dci_td *td) /* get the packet byte count */ count = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_count_low_reg); + USS820_RXCNTL); count |= (bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_count_high_reg) << 8); + USS820_RXCNTH) << 8); count &= 0x3FF; /* verify data length */ @@ -278,11 +278,11 @@ uss820dci_setup_rx(struct uss820dci_td *td) } /* receive data */ bus_space_read_multi_1(td->io_tag, td->io_hdl, - td->rx_fifo_reg, (void *)&req, sizeof(req)); + USS820_RXDAT, (void *)&req, sizeof(req)); /* read out FIFO status */ rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_stat_reg); + USS820_RXSTAT); if (rx_stat & (USS820_RXSTAT_EDOVW | USS820_RXSTAT_STOVW)) { @@ -297,10 +297,10 @@ uss820dci_setup_rx(struct uss820dci_td *td) /* set RXFFRC bit */ temp = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg); + USS820_RXCON); temp |= USS820_RXCON_RXFFRC; bus_space_write_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg, temp); + USS820_RXCON, temp); /* copy data into real buffer */ usb2_copy_in(td->pc, 0, &req, sizeof(req)); @@ -321,10 +321,10 @@ uss820dci_setup_rx(struct uss820dci_td *td) /* set RXFFRC bit */ temp = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg); + USS820_RXCON); temp |= USS820_RXCON_RXFFRC; bus_space_write_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg, temp); + USS820_RXCON, temp); /* FALLTHROUGH */ @@ -365,16 +365,16 @@ uss820dci_data_rx(struct uss820dci_td *td) got_short = 0; /* select the correct endpoint */ - bus_space_write_1(td->io_tag, td->io_hdl, td->ep_reg, td->ep_index); + bus_space_write_1(td->io_tag, td->io_hdl, USS820_EPINDEX, td->ep_index); /* check if any of the FIFO banks have data */ repeat: /* read out FIFO flag */ rx_flag = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_flag_reg); + USS820_RXFLG); /* read out FIFO status */ rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_stat_reg); + USS820_RXSTAT); DPRINTFN(5, "rx_stat=0x%02x rx_flag=0x%02x rem=%u\n", rx_stat, rx_flag, td->remainder); @@ -419,10 +419,10 @@ uss820dci_data_rx(struct uss820dci_td *td) } /* get the packet byte count */ count = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_count_low_reg); + USS820_RXCNTL); count |= (bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_count_high_reg) << 8); + USS820_RXCNTH) << 8); count &= 0x3FF; DPRINTFN(5, "count=0x%04x\n", count); @@ -454,7 +454,7 @@ uss820dci_data_rx(struct uss820dci_td *td) } /* receive data */ bus_space_read_multi_1(td->io_tag, td->io_hdl, - td->rx_fifo_reg, buf_res.buffer, buf_res.length); + USS820_RXDAT, buf_res.buffer, buf_res.length); /* update counters */ count -= buf_res.length; @@ -464,10 +464,10 @@ uss820dci_data_rx(struct uss820dci_td *td) /* set RXFFRC bit */ rx_cntl = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg); + USS820_RXCON); rx_cntl |= USS820_RXCON_RXFFRC; bus_space_write_1(td->io_tag, td->io_hdl, - td->rx_cntl_reg, rx_cntl); + USS820_RXCON, rx_cntl); /* check if we are complete */ if ((td->remainder == 0) || got_short) { @@ -495,18 +495,18 @@ uss820dci_data_tx(struct uss820dci_td *td) /* select the correct endpoint */ bus_space_write_1(td->io_tag, td->io_hdl, - td->ep_reg, td->ep_index); + USS820_EPINDEX, td->ep_index); to = 2; /* don't loop forever! */ repeat: /* read out TX FIFO flags */ tx_flag = bus_space_read_1(td->io_tag, td->io_hdl, - td->tx_flag_reg); + USS820_TXFLG); /* read out RX FIFO status last */ rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_stat_reg); + USS820_RXSTAT); DPRINTFN(5, "rx_stat=0x%02x tx_flag=0x%02x rem=%u\n", rx_stat, tx_flag, td->remainder); @@ -553,7 +553,7 @@ uss820dci_data_tx(struct uss820dci_td *td) } /* transmit data */ bus_space_write_multi_1(td->io_tag, td->io_hdl, - td->tx_fifo_reg, buf_res.buffer, buf_res.length); + USS820_TXDAT, buf_res.buffer, buf_res.length); /* update counters */ count -= buf_res.length; @@ -563,11 +563,11 @@ uss820dci_data_tx(struct uss820dci_td *td) /* post-write high packet byte count first */ bus_space_write_1(td->io_tag, td->io_hdl, - td->tx_count_high_reg, count_copy >> 8); + USS820_TXCNTH, count_copy >> 8); /* post-write low packet byte count last */ bus_space_write_1(td->io_tag, td->io_hdl, - td->tx_count_low_reg, count_copy); + USS820_TXCNTL, count_copy); /* * Enable TX output, which must happen after that we have written @@ -600,15 +600,15 @@ uss820dci_data_tx_sync(struct uss820dci_td *td) /* select the correct endpoint */ bus_space_write_1(td->io_tag, td->io_hdl, - td->ep_reg, td->ep_index); + USS820_EPINDEX, td->ep_index); /* read out TX FIFO flag */ tx_flag = bus_space_read_1(td->io_tag, td->io_hdl, - td->tx_flag_reg); + USS820_TXFLG); /* read out RX FIFO status last */ rx_stat = bus_space_read_1(td->io_tag, td->io_hdl, - td->rx_stat_reg); + USS820_RXSTAT); DPRINTFN(5, "rx_stat=0x%02x rem=%u\n", rx_stat, td->remainder); @@ -2269,20 +2269,6 @@ uss820dci_xfer_setup(struct usb2_setup_params *parm) td->io_tag = sc->sc_io_tag; td->io_hdl = sc->sc_io_hdl; td->max_packet_size = xfer->max_packet_size; - td->rx_stat_reg = USS820_GET_REG(sc, USS820_RXSTAT); - td->tx_stat_reg = USS820_GET_REG(sc, USS820_TXSTAT); - td->rx_flag_reg = USS820_GET_REG(sc, USS820_RXFLG); - td->tx_flag_reg = USS820_GET_REG(sc, USS820_TXFLG); - td->rx_fifo_reg = USS820_GET_REG(sc, USS820_RXDAT); - td->tx_fifo_reg = USS820_GET_REG(sc, USS820_TXDAT); - td->rx_count_low_reg = USS820_GET_REG(sc, USS820_RXCNTL); - td->rx_count_high_reg = USS820_GET_REG(sc, USS820_RXCNTH); - td->tx_count_low_reg = USS820_GET_REG(sc, USS820_TXCNTL); - td->tx_count_high_reg = USS820_GET_REG(sc, USS820_TXCNTH); - td->rx_cntl_reg = USS820_GET_REG(sc, USS820_RXCON); - td->tx_cntl_reg = USS820_GET_REG(sc, USS820_TXCON); - td->pend_reg = USS820_GET_REG(sc, USS820_PEND); - td->ep_reg = USS820_GET_REG(sc, USS820_EPINDEX); td->ep_index = ep_no; if (pf->support_multi_buffer && (parm->methods != &uss820dci_device_ctrl_methods)) { diff --git a/sys/dev/usb/controller/uss820dci.h b/sys/dev/usb/controller/uss820dci.h index deba99002004..24e3ce20a061 100644 --- a/sys/dev/usb/controller/uss820dci.h +++ b/sys/dev/usb/controller/uss820dci.h @@ -255,16 +255,11 @@ #define USS820_UNK1 0x1f /* Unknown */ #define USS820_UNK1_UNKNOWN 0xFF -#define USS820_GET_REG(sc,reg) \ - ((reg) << (sc)->sc_reg_shift) - #define USS820_READ_1(sc, reg) \ - bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \ - USS820_GET_REG(sc,reg)) + bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) #define USS820_WRITE_1(sc, reg, data) \ - bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, \ - USS820_GET_REG(sc,reg), data) + bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data) struct uss820dci_td; @@ -279,20 +274,6 @@ struct uss820dci_td { uint32_t offset; uint32_t remainder; uint16_t max_packet_size; - uint8_t rx_stat_reg; - uint8_t tx_stat_reg; - uint8_t rx_flag_reg; - uint8_t tx_flag_reg; - uint8_t rx_fifo_reg; - uint8_t tx_fifo_reg; - uint8_t rx_count_low_reg; - uint8_t rx_count_high_reg; - uint8_t tx_count_low_reg; - uint8_t tx_count_high_reg; - uint8_t rx_cntl_reg; - uint8_t tx_cntl_reg; - uint8_t ep_reg; - uint8_t pend_reg; uint8_t ep_index; uint8_t error:1; uint8_t alt_next:1; @@ -356,7 +337,6 @@ struct uss820dci_softc { uint8_t sc_rt_addr; /* root HUB address */ uint8_t sc_dv_addr; /* device address */ uint8_t sc_conf; /* root HUB config */ - uint8_t sc_reg_shift; uint8_t sc_hub_idata[1]; From 4ab9c8af927629d232120e67a0e73e5f70cbf1b9 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 17:19:30 +0000 Subject: [PATCH 328/544] Fix a typo. --- sys/kern/subr_bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/subr_bus.c b/sys/kern/subr_bus.c index 90d800f4e6d4..39ec6d4e7bf0 100644 --- a/sys/kern/subr_bus.c +++ b/sys/kern/subr_bus.c @@ -712,7 +712,7 @@ devremoved(device_t dev) /* * Called when there's no match for this device. This is only called - * the first time that no match happens, so we don't keep getitng this + * the first time that no match happens, so we don't keep getting this * message. Should that prove to be undesirable, we can change it. * This is called when all drivers that can attach to a given bus * decline to accept this device. Other errrors may not be detected. From 00b4e54ae7b69db140f2168049138a443fd3190f Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 17:29:21 +0000 Subject: [PATCH 329/544] We no longer need to use d_thread_t, migrate to struct thread *. --- sys/dev/aac/aac.c | 8 ++-- sys/dev/acpica/acpi.c | 6 +-- sys/dev/amr/amr.c | 10 ++--- sys/dev/amr/amr_linux.c | 2 +- sys/dev/arcmsr/arcmsr.c | 6 +-- sys/dev/ata/ata-all.c | 2 +- sys/dev/ciss/ciss.c | 6 +-- sys/dev/cxgb/cxgb_main.c | 4 +- sys/dev/iir/iir_ctrl.c | 6 +-- sys/dev/mfi/mfi.c | 10 ++--- sys/dev/mfi/mfi_linux.c | 2 +- sys/dev/mpt/mpt_user.c | 6 +-- sys/dev/pci/pci.c | 87 ++++++++++++++++++++++++++++++++++++ sys/dev/pci/pci_pci.c | 15 +++++++ sys/dev/pci/pcib_if.m | 14 ++++++ sys/dev/twa/tw_osl_freebsd.c | 6 +-- sys/dev/twe/twe_freebsd.c | 6 +-- sys/dev/wi/if_wavelan_ieee.h | 3 -- sys/dev/wi/if_wi.c | 5 ++- sys/dev/wi/if_wivar.h | 3 ++ 20 files changed, 162 insertions(+), 45 deletions(-) diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c index 1cee9f4f1649..f3d931aaf06b 100644 --- a/sys/dev/aac/aac.c +++ b/sys/dev/aac/aac.c @@ -2905,7 +2905,7 @@ aac_describe_code(struct aac_code_lookup *table, u_int32_t code) */ static int -aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +aac_open(struct cdev *dev, int flags, int fmt, struct thread *td) { struct aac_softc *sc; @@ -2918,7 +2918,7 @@ aac_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) } static int -aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +aac_close(struct cdev *dev, int flags, int fmt, struct thread *td) { struct aac_softc *sc; @@ -2933,7 +2933,7 @@ aac_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) } static int -aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) +aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { union aac_statrequest *as; struct aac_softc *sc; @@ -3038,7 +3038,7 @@ aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) } static int -aac_poll(struct cdev *dev, int poll_events, d_thread_t *td) +aac_poll(struct cdev *dev, int poll_events, struct thread *td) { struct aac_softc *sc; struct aac_fib_context *ctx; diff --git a/sys/dev/acpica/acpi.c b/sys/dev/acpica/acpi.c index d79b4133f0a9..4bc059b3c5df 100644 --- a/sys/dev/acpica/acpi.c +++ b/sys/dev/acpica/acpi.c @@ -3186,19 +3186,19 @@ acpi_deregister_ioctl(u_long cmd, acpi_ioctl_fn fn) } static int -acpiopen(struct cdev *dev, int flag, int fmt, d_thread_t *td) +acpiopen(struct cdev *dev, int flag, int fmt, struct thread *td) { return (0); } static int -acpiclose(struct cdev *dev, int flag, int fmt, d_thread_t *td) +acpiclose(struct cdev *dev, int flag, int fmt, struct thread *td) { return (0); } static int -acpiioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, d_thread_t *td) +acpiioctl(struct cdev *dev, u_long cmd, caddr_t addr, int flag, struct thread *td) { struct acpi_softc *sc; struct acpi_ioctl_hook *hp; diff --git a/sys/dev/amr/amr.c b/sys/dev/amr/amr.c index 6b75ebbdbd61..2061fcc801f9 100644 --- a/sys/dev/amr/amr.c +++ b/sys/dev/amr/amr.c @@ -173,7 +173,7 @@ static void amr_printcommand(struct amr_command *ac); static void amr_init_sysctl(struct amr_softc *sc); static int amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, - int32_t flag, d_thread_t *td); + int32_t flag, struct thread *td); MALLOC_DEFINE(M_AMR, "amr", "AMR memory"); @@ -431,7 +431,7 @@ amr_submit_bio(struct amr_softc *sc, struct bio *bio) * Accept an open operation on the control device. */ static int -amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +amr_open(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); @@ -487,7 +487,7 @@ amr_prepare_ld_delete(struct amr_softc *sc) * Accept the last close on the control device. */ static int -amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +amr_close(struct cdev *dev, int flags, int fmt, struct thread *td) { int unit = dev2unit(dev); struct amr_softc *sc = devclass_get_softc(devclass_find("amr"), unit); @@ -537,7 +537,7 @@ amr_rescan_drives(struct cdev *dev) int amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, - d_thread_t *td) + struct thread *td) { struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; struct amr_command *ac; @@ -736,7 +736,7 @@ amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, } static int -amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) +amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) { struct amr_softc *sc = (struct amr_softc *)dev->si_drv1; union { diff --git a/sys/dev/amr/amr_linux.c b/sys/dev/amr/amr_linux.c index 0fe89d7f045e..cb8c4573ef6b 100644 --- a/sys/dev/amr/amr_linux.c +++ b/sys/dev/amr/amr_linux.c @@ -69,7 +69,7 @@ DEV_MODULE(amr_linux, amr_linux_modevent, NULL); MODULE_DEPEND(amr, linux, 1, 1, 1); static int -amr_linux_ioctl(d_thread_t *p, struct linux_ioctl_args *args) +amr_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { struct file *fp; int error; diff --git a/sys/dev/arcmsr/arcmsr.c b/sys/dev/arcmsr/arcmsr.c index 3d19a53ef7a0..09bce1b9455f 100644 --- a/sys/dev/arcmsr/arcmsr.c +++ b/sys/dev/arcmsr/arcmsr.c @@ -249,7 +249,7 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1); #if __FreeBSD_version < 503000 static int arcmsr_open(dev_t dev, int flags, int fmt, struct thread *proc) #else - static int arcmsr_open(struct cdev *dev, int flags, int fmt, d_thread_t *proc) + static int arcmsr_open(struct cdev *dev, int flags, int fmt, struct thread *proc) #endif #endif { @@ -274,7 +274,7 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1); #if __FreeBSD_version < 503000 static int arcmsr_close(dev_t dev, int flags, int fmt, struct thread *proc) #else - static int arcmsr_close(struct cdev *dev, int flags, int fmt, d_thread_t *proc) + static int arcmsr_close(struct cdev *dev, int flags, int fmt, struct thread *proc) #endif #endif { @@ -299,7 +299,7 @@ MODULE_DEPEND(arcmsr, cam, 1, 1, 1); #if __FreeBSD_version < 503000 static int arcmsr_ioctl(dev_t dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc) #else - static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, d_thread_t *proc) + static int arcmsr_ioctl(struct cdev *dev, u_long ioctl_cmd, caddr_t arg, int flags, struct thread *proc) #endif #endif { diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 4530767f3aaa..1131ee1fae28 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -663,7 +663,7 @@ ata_getparam(struct ata_device *atadev, int init) btrim(atacap->serial, sizeof(atacap->serial)); bpack(atacap->serial, atacap->serial, sizeof(atacap->serial)); - if (bootverbose) + if (bootverbose || 1) printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n", device_get_unit(ch->dev), ata_unit2str(atadev), diff --git a/sys/dev/ciss/ciss.c b/sys/dev/ciss/ciss.c index f2b89f80965d..93aea725299c 100644 --- a/sys/dev/ciss/ciss.c +++ b/sys/dev/ciss/ciss.c @@ -4442,7 +4442,7 @@ ciss_name_command_status(int status) * Handle an open on the control device. */ static int -ciss_open(struct cdev *dev, int flags, int fmt, d_thread_t *p) +ciss_open(struct cdev *dev, int flags, int fmt, struct thread *p) { struct ciss_softc *sc; @@ -4462,7 +4462,7 @@ ciss_open(struct cdev *dev, int flags, int fmt, d_thread_t *p) * Handle the last close on the control device. */ static int -ciss_close(struct cdev *dev, int flags, int fmt, d_thread_t *p) +ciss_close(struct cdev *dev, int flags, int fmt, struct thread *p) { struct ciss_softc *sc; @@ -4483,7 +4483,7 @@ ciss_close(struct cdev *dev, int flags, int fmt, d_thread_t *p) * simplify the porting of Compaq's userland tools. */ static int -ciss_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *p) +ciss_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *p) { struct ciss_softc *sc; IOCTL_Command_struct *ioc = (IOCTL_Command_struct *)addr; diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index cc09aa0438f5..3108688c823e 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -2528,13 +2528,13 @@ in_range(int val, int lo, int hi) } static int -cxgb_extension_open(struct cdev *dev, int flags, int fmp, d_thread_t *td) +cxgb_extension_open(struct cdev *dev, int flags, int fmp, struct thread *td) { return (0); } static int -cxgb_extension_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +cxgb_extension_close(struct cdev *dev, int flags, int fmt, struct thread *td) { return (0); } diff --git a/sys/dev/iir/iir_ctrl.c b/sys/dev/iir/iir_ctrl.c index e5fbac94df5d..6546f07160d4 100644 --- a/sys/dev/iir/iir_ctrl.c +++ b/sys/dev/iir/iir_ctrl.c @@ -144,7 +144,7 @@ gdt_minor2softc(int minor_no) } static int -iir_open(struct cdev *dev, int flags, int fmt, d_thread_t * p) +iir_open(struct cdev *dev, int flags, int fmt, struct thread * p) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_open()\n")); @@ -162,7 +162,7 @@ iir_open(struct cdev *dev, int flags, int fmt, d_thread_t * p) } static int -iir_close(struct cdev *dev, int flags, int fmt, d_thread_t * p) +iir_close(struct cdev *dev, int flags, int fmt, struct thread * p) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_close()\n")); @@ -222,7 +222,7 @@ iir_read(struct cdev *dev, struct uio * uio, int ioflag) */ static int -iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, d_thread_t * p) +iir_ioctl(struct cdev *dev, u_long cmd, caddr_t cmdarg, int flags, struct thread * p) { GDT_DPRINTF(GDT_D_DEBUG, ("iir_ioctl() cmd 0x%lx\n",cmd)); diff --git a/sys/dev/mfi/mfi.c b/sys/dev/mfi/mfi.c index 7cdb304b6ba6..cfd8f1d21b4b 100644 --- a/sys/dev/mfi/mfi.c +++ b/sys/dev/mfi/mfi.c @@ -104,7 +104,7 @@ static int mfi_mapcmd(struct mfi_softc *, struct mfi_command *); static int mfi_send_frame(struct mfi_softc *, struct mfi_command *); static void mfi_complete(struct mfi_softc *, struct mfi_command *); static int mfi_abort(struct mfi_softc *, struct mfi_command *); -static int mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, d_thread_t *); +static int mfi_linux_ioctl_int(struct cdev *, u_long, caddr_t, int, struct thread *); static void mfi_timeout(void *); static int mfi_user_command(struct mfi_softc *, struct mfi_ioc_passthru *); @@ -1686,7 +1686,7 @@ mfi_dump_blocks(struct mfi_softc *sc, int id, uint64_t lba, void *virt, int len) } static int -mfi_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +mfi_open(struct cdev *dev, int flags, int fmt, struct thread *td) { struct mfi_softc *sc; int error; @@ -1706,7 +1706,7 @@ mfi_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) } static int -mfi_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +mfi_close(struct cdev *dev, int flags, int fmt, struct thread *td) { struct mfi_softc *sc; struct mfi_aen *mfi_aen_entry, *tmp; @@ -1910,7 +1910,7 @@ mfi_user_command(struct mfi_softc *sc, struct mfi_ioc_passthru *ioc) #endif static int -mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) +mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { struct mfi_softc *sc; union mfi_statrequest *ms; @@ -2234,7 +2234,7 @@ mfi_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) } static int -mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) +mfi_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { struct mfi_softc *sc; struct mfi_linux_ioc_packet l_ioc; diff --git a/sys/dev/mfi/mfi_linux.c b/sys/dev/mfi/mfi_linux.c index 911c02c9059c..44edf49109db 100644 --- a/sys/dev/mfi/mfi_linux.c +++ b/sys/dev/mfi/mfi_linux.c @@ -80,7 +80,7 @@ DEV_MODULE(mfi_linux, mfi_linux_modevent, NULL); MODULE_DEPEND(mfi, linux, 1, 1, 1); static int -mfi_linux_ioctl(d_thread_t *p, struct linux_ioctl_args *args) +mfi_linux_ioctl(struct thread *p, struct linux_ioctl_args *args) { struct file *fp; int error; diff --git a/sys/dev/mpt/mpt_user.c b/sys/dev/mpt/mpt_user.c index 971c26232414..6e3b32f2a7fd 100644 --- a/sys/dev/mpt/mpt_user.c +++ b/sys/dev/mpt/mpt_user.c @@ -173,14 +173,14 @@ mpt_user_detach(struct mpt_softc *mpt) } static int -mpt_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +mpt_open(struct cdev *dev, int flags, int fmt, struct thread *td) { return (0); } static int -mpt_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +mpt_close(struct cdev *dev, int flags, int fmt, struct thread *td) { return (0); @@ -585,7 +585,7 @@ mpt_user_raid_action(struct mpt_softc *mpt, struct mpt_raid_action *raid_act, #endif static int -mpt_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td) +mpt_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { struct mpt_softc *mpt; struct mpt_cfg_page_req *page_req; diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 3b330c7b8301..af1691b1855a 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -418,6 +418,38 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) #undef REG } +/* + * This is a lame example: we should have some way of managing this table + * from userland. The user should be able to tell us from the boot loader + * or at runtime what mapping to do. + */ +static struct pci_remap_entry +{ + uint16_t vendor; + uint16_t device; + uint16_t mapped_vendor; + uint16_t mapped_device; +} pci_remap[] = +{ + { 0x1039, 0x0901, 0x1039, 0x0900 } /* Map sis 901 to sis 900 */ +}; +static int pci_remap_entries = 1; + +static void +pci_apply_remap_table(pcicfgregs *cfg) +{ + int i; + + for (i = 0; i < pci_remap_entries; i++) { + if (cfg->vendor == pci_remap[i].vendor && + cfg->device == pci_remap[i].device) { + cfg->vendor = pci_remap[i].mapped_vendor; + cfg->device = pci_remap[i].mapped_device; + return; + } + } +} + /* read configuration header into pcicfgregs structure */ struct pci_devinfo * pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size) @@ -464,6 +496,7 @@ pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size) pci_fixancient(cfg); pci_hdrtypedata(pcib, b, s, f, cfg); + pci_apply_remap_table(cfg); if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) pci_read_extcap(pcib, cfg); @@ -2619,6 +2652,59 @@ pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask) } } +/* + * After we've added the children to the pci bus device, we need to fixup + * the children in various ways. This function fixes things that require + * multiple passes to get right, such as bus number and some resource + * things (although the latter hasn't been implemented yet). This must be + * done before the children are probe/attached, sicne by that point these + * things must be fixed. + */ +static void +pci_fix_bridges(device_t dev) +{ + int i, numdevs, error, secbus, subbus; + device_t child, *devlist; + + if ((error = device_get_children(dev, &devlist, &numdevs))) + return; + /* + * First pass, get the bus numbers that are in use + */ + for (i = 0; i < numdevs; i++) { + child = devlist[i]; + switch (pci_read_config(child, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) { + default: + continue; + case 1: /* PCI-PCI bridge */ + case 2: /* CardBus bridge -- offsets are the same */ + secbus = pci_read_config(child, PCIR_SECBUS_1, 1); + subbus = pci_read_config(child, PCIR_SUBBUS_1, 1); + break; + } + printf("%d:%d:%d:%d sec %d sub %d\n", pcib_get_domain(dev), + pci_get_bus(child), pci_get_slot(child), + pci_get_function(child), secbus, subbus); + } +#if 0 + /* + * Second pass, Fix the bus numbers, as needed + */ + for (i = 0; i < numdevs; i++) { + child = devlist[i]; + switch (pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) { + case 1: /* PCI-PCI bridge */ + break; + case 2: /* CardBus bridge */ + break; + default: + continue; + } + } +#endif + free(devlist, M_TEMP); +} + void pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size) { @@ -2650,6 +2736,7 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size) } } #undef REG + pci_fix_bridges(dev); } void diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index 15cad92484d7..8bb2eff39156 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -52,6 +52,13 @@ __FBSDID("$FreeBSD$"); #include "pcib_if.h" +// #define KLUDGE_O_MATIC +#ifdef KLUDGE_O_MATIC +int hack_unit = 1; +u_long mem_base = 0xc0400000ul; +u_long mem_limit = 0x00100000ul; +#endif + static int pcib_probe(device_t dev); static device_method_t pcib_methods[] = { @@ -324,6 +331,14 @@ pcib_attach(device_t dev) struct pcib_softc *sc; device_t child; +#ifdef KLUDGE_O_MATIC + if (device_get_unit(dev) == hack_unit) { + pci_write_config(dev, PCIR_COMMAND, + PCIM_CMD_MEMEN | pci_read_config(dev, PCIR_COMMAND, 1), 1); + pci_write_config(dev, PCIR_MEMBASE_1, mem_base >> 16, 2); + pci_write_config(dev, PCIR_MEMLIMIT_1, mem_limit >> 16, 2); + } +#endif pcib_attach_common(dev); sc = device_get_softc(dev); if (sc->secbus != 0) { diff --git a/sys/dev/pci/pcib_if.m b/sys/dev/pci/pcib_if.m index 0b7e8bc62c9b..765e6449a312 100644 --- a/sys/dev/pci/pcib_if.m +++ b/sys/dev/pci/pcib_if.m @@ -144,3 +144,17 @@ METHOD int map_msi { uint64_t *addr; uint32_t *data; }; + +# +# Return the range of busses passed through this bridge. For normal +# pci-pci bridges (and compatible things like pci-x and pcie), this will +# just be the secbus and subbus configuration registers. For non-standard +# bridges, or for host bridges which have no standard, this will be the +# same data read from either device specific registers of from "perfect +# knowledge" of what they must be. +# +METHOD int bus_range { + device_t pcib; + u_int *secbus; + u_int *subbus; +}; diff --git a/sys/dev/twa/tw_osl_freebsd.c b/sys/dev/twa/tw_osl_freebsd.c index f435c2c3d969..d3f82f3831d2 100644 --- a/sys/dev/twa/tw_osl_freebsd.c +++ b/sys/dev/twa/tw_osl_freebsd.c @@ -86,7 +86,7 @@ static devclass_t twa_devclass; * non-zero-- failure */ static TW_INT32 -twa_open(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc) +twa_open(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, struct thread *proc) { struct twa_softc *sc = (struct twa_softc *)(dev->si_drv1); @@ -111,7 +111,7 @@ twa_open(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc) * non-zero-- failure */ static TW_INT32 -twa_close(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc) +twa_close(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, struct thread *proc) { struct twa_softc *sc = (struct twa_softc *)(dev->si_drv1); @@ -140,7 +140,7 @@ twa_close(struct cdev *dev, TW_INT32 flags, TW_INT32 fmt, d_thread_t *proc) * non-zero-- failure */ static TW_INT32 -twa_ioctl(struct cdev *dev, u_long cmd, caddr_t buf, TW_INT32 flags, d_thread_t *proc) +twa_ioctl(struct cdev *dev, u_long cmd, caddr_t buf, TW_INT32 flags, struct thread *proc) { struct twa_softc *sc = (struct twa_softc *)(dev->si_drv1); TW_INT32 error; diff --git a/sys/dev/twe/twe_freebsd.c b/sys/dev/twe/twe_freebsd.c index 6a99864456e0..9ad65c94d9e2 100644 --- a/sys/dev/twe/twe_freebsd.c +++ b/sys/dev/twe/twe_freebsd.c @@ -79,7 +79,7 @@ static struct cdevsw twe_cdevsw = { * Accept an open operation on the control device. */ static int -twe_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) +twe_open(struct cdev *dev, int flags, int fmt, struct thread *td) { struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; @@ -91,7 +91,7 @@ twe_open(struct cdev *dev, int flags, int fmt, d_thread_t *td) * Accept the last close on the control device. */ static int -twe_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) +twe_close(struct cdev *dev, int flags, int fmt, struct thread *td) { struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; @@ -103,7 +103,7 @@ twe_close(struct cdev *dev, int flags, int fmt, d_thread_t *td) * Handle controller-specific control operations. */ static int -twe_ioctl_wrapper(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td) +twe_ioctl_wrapper(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) { struct twe_softc *sc = (struct twe_softc *)dev->si_drv1; diff --git a/sys/dev/wi/if_wavelan_ieee.h b/sys/dev/wi/if_wavelan_ieee.h index 0061e638bd0d..82bc9e509c2c 100644 --- a/sys/dev/wi/if_wavelan_ieee.h +++ b/sys/dev/wi/if_wavelan_ieee.h @@ -58,14 +58,11 @@ * value. */ #define WI_MAX_DATALEN 512 - -#if 0 struct wi_req { u_int16_t wi_len; u_int16_t wi_type; u_int16_t wi_val[WI_MAX_DATALEN]; }; -#endif /* * Private LTV records (interpreted only by the driver). This is diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 3dce8471b632..3dc329b7088e 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -143,7 +143,6 @@ static int wi_alloc_fid(struct wi_softc *, int, int *); static void wi_read_nicid(struct wi_softc *); static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); -static int wi_cmd(struct wi_softc *, int, int, int, int); static int wi_seek_bap(struct wi_softc *, int, int); static int wi_read_bap(struct wi_softc *, int, int, void *, int); static int wi_write_bap(struct wi_softc *, int, int, void *, int); @@ -1801,7 +1800,7 @@ wi_write_wep(struct wi_softc *sc, struct ieee80211vap *vap) return error; } -static int +int wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) { int i, s = 0; @@ -2120,3 +2119,5 @@ wi_free(device_t dev) sc->mem = NULL; } } + +MODULE_VERSION(wi, 1); diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index fdcedd893c4d..3739a8e5a463 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -186,3 +186,6 @@ void wi_init(void *); void wi_intr(void *); int wi_mgmt_xmit(struct wi_softc *, caddr_t, int); void wi_stop(struct wi_softc *, int); + +/* KLUDGE */ +int wi_cmd(struct wi_softc *, int, int, int, int); From e57c620d84fb00fedba19b6faf727bdf3cbbc046 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 17:59:49 +0000 Subject: [PATCH 330/544] Tweak some comments. --- sys/sys/interrupt.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/sys/interrupt.h b/sys/sys/interrupt.h index fed9020d0f8a..92c0f03bfcd9 100644 --- a/sys/sys/interrupt.h +++ b/sys/sys/interrupt.h @@ -43,9 +43,9 @@ struct trapframe; * together. */ struct intr_handler { - driver_filter_t *ih_filter; /* Filter function. */ - driver_intr_t *ih_handler; /* Handler function. */ - void *ih_argument; /* Argument to pass to handler. */ + driver_filter_t *ih_filter; /* Filter handler function. */ + driver_intr_t *ih_handler; /* Threaded handler function. */ + void *ih_argument; /* Argument to pass to handlers. */ int ih_flags; const char *ih_name; /* Name of handler. */ struct intr_event *ih_event; /* Event we are connected to. */ From ba55ca9732ae61b717403854111fb98bd18a457b Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Wed, 20 May 2009 18:04:56 +0000 Subject: [PATCH 331/544] Remove license clauses 3 and 4 as per rev. 1.12 of cs4231reg.h in NetBSD. --- sys/dev/sound/sbus/cs4231.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/sound/sbus/cs4231.h b/sys/dev/sound/sbus/cs4231.h index 26ca399a0fe0..d1e9185d31c6 100644 --- a/sys/dev/sound/sbus/cs4231.h +++ b/sys/dev/sound/sbus/cs4231.h @@ -14,13 +14,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED From 1d631ee69a7ce7e227bd6dd0548e6520de23e3ea Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Wed, 20 May 2009 18:15:13 +0000 Subject: [PATCH 332/544] Remove license clauses 3 and 4 as per rev. 1.112 of uaudio.c and rev. 1.15 of uaudioreg.h in NetBSD. --- sys/dev/sound/usb/uaudio.c | 7 ------- sys/dev/sound/usb/uaudioreg.h | 7 ------- 2 files changed, 14 deletions(-) diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 50866dabec9b..9cd51042b44c 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -17,13 +17,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED diff --git a/sys/dev/sound/usb/uaudioreg.h b/sys/dev/sound/usb/uaudioreg.h index 2bf68a17c609..6b814d0cff67 100644 --- a/sys/dev/sound/usb/uaudioreg.h +++ b/sys/dev/sound/usb/uaudioreg.h @@ -17,13 +17,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED From 63ba66086a9f6ec5e3d1e7660c54231f217ea138 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 18:25:16 +0000 Subject: [PATCH 333/544] Put the vnode returned from namei() immediately after namei() returns in svr4_sys_resolvepath(). --- sys/compat/svr4/svr4_misc.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index ad56a119e70d..dd93c36f7d83 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1611,14 +1611,14 @@ svr4_sys_resolvepath(td, uap) struct nameidata nd; int error, *retval = td->td_retval; unsigned int ncopy; - int vfslocked; NDINIT(&nd, LOOKUP, NOFOLLOW | SAVENAME | MPSAFE, UIO_USERSPACE, uap->path, td); if ((error = namei(&nd)) != 0) - return error; - vfslocked = NDHASGIANT(&nd); + return (error); + NDFREE(&nd, NDF_NO_FREE_PNBUF); + VFS_UNLOCK_GIANT(NDHASGIANT(&nd)); ncopy = min(uap->bufsiz, strlen(nd.ni_cnd.cn_pnbuf) + 1); if ((error = copyout(nd.ni_cnd.cn_pnbuf, uap->buf, ncopy)) != 0) @@ -1627,7 +1627,5 @@ svr4_sys_resolvepath(td, uap) *retval = ncopy; bad: NDFREE(&nd, NDF_ONLY_PNBUF); - vput(nd.ni_vp); - VFS_UNLOCK_GIANT(vfslocked); return error; } From 583220dc4c75c6bcc5eef66be88e7c393a795816 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 18:29:14 +0000 Subject: [PATCH 334/544] Remove an obsolete assertion. We always wake up all waiters when unlocking a mutex and never set the lock cookie == MTX_CONTESTED. --- sys/kern/kern_mutex.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sys/kern/kern_mutex.c b/sys/kern/kern_mutex.c index c56e124dedc6..ea85268e4555 100644 --- a/sys/kern/kern_mutex.c +++ b/sys/kern/kern_mutex.c @@ -364,8 +364,6 @@ _mtx_lock_sleep(struct mtx *m, uintptr_t tid, int opts, const char *file, continue; } - MPASS(v != MTX_CONTESTED); - #ifdef ADAPTIVE_MUTEXES /* * If the current owner of the lock is executing on another From 4367b59545e21f7290ae2a66c7d9f12dc42c3bc5 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Wed, 20 May 2009 18:31:11 +0000 Subject: [PATCH 335/544] Remove license clauses 3 and 4 as per rev. 1.65 of auvia.c in NetBSD. --- sys/dev/sound/pci/via82c686.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/sound/pci/via82c686.h b/sys/dev/sound/pci/via82c686.h index ac6750e71b08..43dcb4131305 100644 --- a/sys/dev/sound/pci/via82c686.h +++ b/sys/dev/sound/pci/via82c686.h @@ -13,13 +13,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED From e05a128eb7ca0fc9c5ab04fc84ac9716bb0ad21b Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Wed, 20 May 2009 18:34:26 +0000 Subject: [PATCH 336/544] Remove license clauses 3 and 4 as per rev. 1.65 of midi.c in NetBSD. Approved by: matk --- sys/dev/sound/midi/midi.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/sound/midi/midi.c b/sys/dev/sound/midi/midi.c index 364c6ba41163..b6ac879a118d 100644 --- a/sys/dev/sound/midi/midi.c +++ b/sys/dev/sound/midi/midi.c @@ -14,13 +14,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED From 31bd8c7dcfaaa42d7448ec4cbad109e644a54531 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 18:36:17 +0000 Subject: [PATCH 337/544] Comment nits. --- sys/compat/svr4/svr4_misc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/compat/svr4/svr4_misc.c b/sys/compat/svr4/svr4_misc.c index dd93c36f7d83..3fe090913ba5 100644 --- a/sys/compat/svr4/svr4_misc.c +++ b/sys/compat/svr4/svr4_misc.c @@ -1199,12 +1199,12 @@ svr4_sys_waitsys(td, uap) /* * Ok, handle the weird cases. Either WNOWAIT is set (meaning we - * just want to see if there is a process to harvest, we dont' + * just want to see if there is a process to harvest, we don't * want to actually harvest it), or WEXIT and WTRAPPED are clear * meaning we want to ignore zombies. Either way, we don't have * to handle harvesting zombies here. We do have to duplicate the - * other portions of kern_wait() though, especially for the - * WCONTINUED and WSTOPPED. + * other portions of kern_wait() though, especially for WCONTINUED + * and WSTOPPED. */ loop: nfound = 0; From 498a9afee2c79acbf1e84ac86948ce6c3683c2c1 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Wed, 20 May 2009 18:38:43 +0000 Subject: [PATCH 338/544] Slightly adjust copyright text. Approved by: matk --- sys/dev/sound/pci/emu10kx-midi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/sound/pci/emu10kx-midi.c b/sys/dev/sound/pci/emu10kx-midi.c index 736e7c25c377..012796d51178 100644 --- a/sys/dev/sound/pci/emu10kx-midi.c +++ b/sys/dev/sound/pci/emu10kx-midi.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 1999 Seigo Tanimura - * (c) 2003 Mathew Kanner + * Copyright (c) 2003 Mathew Kanner * Copyright (c) 2003-2006 Yuriy Tsibizov * All rights reserved * From 6ca33ea3457f582353a6fe4ef7f7d5831fd5c888 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 18:42:04 +0000 Subject: [PATCH 339/544] Set the umask in a new file descriptor table earlier in fdcopy() to remove two lock operations. --- sys/kern/kern_descrip.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c index e0008e666421..4553bb40e469 100644 --- a/sys/kern/kern_descrip.c +++ b/sys/kern/kern_descrip.c @@ -1626,17 +1626,15 @@ fdcopy(struct filedesc *fdp) newfdp->fd_freefile = i; } } + newfdp->fd_cmask = fdp->fd_cmask; FILEDESC_SUNLOCK(fdp); FILEDESC_XLOCK(newfdp); for (i = 0; i <= newfdp->fd_lastfile; ++i) if (newfdp->fd_ofiles[i] != NULL) fdused(newfdp, i); - FILEDESC_XUNLOCK(newfdp); - FILEDESC_SLOCK(fdp); if (newfdp->fd_freefile == -1) newfdp->fd_freefile = i; - newfdp->fd_cmask = fdp->fd_cmask; - FILEDESC_SUNLOCK(fdp); + FILEDESC_XUNLOCK(newfdp); return (newfdp); } From 85de716af38b01c5db2227027f65d62fb6cbfc8a Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Wed, 20 May 2009 18:45:49 +0000 Subject: [PATCH 340/544] Add a new locking note for p_aioinfo as it is not a normal PROC_LOCK field. --- sys/sys/proc.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/sys/proc.h b/sys/sys/proc.h index dd3e0b2e8257..96f811dda876 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -148,6 +148,8 @@ struct pargs { * r - p_peers lock * t - thread lock * x - created at fork, only changes during single threading in exec + * y - created at first aio, doesn't change until exit or exec at which + * point we are single-threaded and only curthread changes it * z - zombie threads lock * * If the locking key specifies two identifiers (for example, p_pptr) then @@ -503,7 +505,7 @@ struct proc { char p_step; /* (c) Process is stopped. */ u_char p_pfsflags; /* (c) Procfs flags. */ struct nlminfo *p_nlminfo; /* (?) Only used by/for lockd. */ - struct kaioinfo *p_aioinfo; /* (c) ASYNC I/O info. */ + struct kaioinfo *p_aioinfo; /* (y) ASYNC I/O info. */ struct thread *p_singlethread;/* (c + j) If single threading this is it */ int p_suspcount; /* (j) Num threads in suspended mode. */ struct thread *p_xthread; /* (c) Trap thread */ From 29e890f126611d30e63a6aa1c515693bb63f43d3 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Wed, 20 May 2009 18:58:07 +0000 Subject: [PATCH 341/544] Although it should never happen, all the nfsv4 server can do when it runs out of clientids is reboot. I had replaced cpu_reboot() with printf(), since cpu_reboot() doesn't exist for sparc64. This change replaces the printf() with panic(), so the reboot would occur for this highly unlikely occurrence. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index f33c59a000ef..aa0e72543da0 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3709,7 +3709,7 @@ nfsrv_nextclientindex(void) * In practice, we'll never get here, but the reboot is here, * just for fun. (client_index will not wrap around on any real server) */ - printf("you must reboot now\n"); + panic("nfsv4 server out of clientids"); return (0); /* Just to shut the compiler up */ } From 5463c4a485ef2a317cc554b7699984484ec0983d Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 20 May 2009 20:00:40 +0000 Subject: [PATCH 342/544] Overhaul monitor mode handling: o replace DLT_IEEE802_11 support in net80211 with DLT_IEEE802_11_RADIO and remove explicit bpf support from wireless drivers; drivers now use ieee80211_radiotap_attach to setup shared data structures that hold the radiotap header for each packet tx/rx o remove rx timestamp from the rx path; it was used only by the tdma support for debugging and was mostly useless due to it being 32-bits and mostly unavailable o track DLT_IEEE80211_RADIO bpf attachments and maintain per-vap and per-com state when there are active taps o track the number of monitor mode vaps o use bpf tap and monitor mode vap state to decide when to collect radiotap state and dispatch frames; drivers no longer explicitly directly check bpf state or use bpf calls to tap frames o handle radiotap state updates on channel change in net80211; drivers should not do this (unless they bypass net80211 which is almost always a mistake) o update various drivers to be more consistent/correct in handling radiotap o update ral to include TSF in radiotap'd frames o add promisc mode callback to wi Reviewed by: cbzimmer, rpaulo, thompsa --- sys/conf/files | 1 + sys/dev/ath/if_ath.c | 132 +++++------- sys/dev/ath/if_athvar.h | 15 +- sys/dev/bwi/if_bwi.c | 43 ++-- sys/dev/bwi/if_bwivar.h | 2 - sys/dev/ipw/if_ipw.c | 44 ++-- sys/dev/ipw/if_ipwvar.h | 9 +- sys/dev/iwi/if_iwi.c | 40 ++-- sys/dev/iwi/if_iwivar.h | 7 +- sys/dev/iwn/if_iwn.c | 53 ++--- sys/dev/iwn/if_iwnvar.h | 2 - sys/dev/malo/if_malo.c | 49 +---- sys/dev/malo/if_malo.h | 3 - sys/dev/ral/rt2560.c | 77 +++---- sys/dev/ral/rt2560var.h | 6 +- sys/dev/ral/rt2661.c | 66 +++--- sys/dev/ral/rt2661var.h | 6 +- sys/dev/usb/wlan/if_rum.c | 55 ++--- sys/dev/usb/wlan/if_rumvar.h | 7 +- sys/dev/usb/wlan/if_uath.c | 71 +++---- sys/dev/usb/wlan/if_uathvar.h | 31 ++- sys/dev/usb/wlan/if_upgt.c | 32 +-- sys/dev/usb/wlan/if_ural.c | 61 +++--- sys/dev/usb/wlan/if_uralvar.h | 6 +- sys/dev/usb/wlan/if_zyd.c | 38 ++-- sys/dev/wi/if_wi.c | 99 ++++----- sys/dev/wi/if_wireg.h | 4 +- sys/dev/wi/if_wivar.h | 6 +- sys/dev/wpi/if_wpi.c | 30 +-- sys/dev/wpi/if_wpivar.h | 2 - sys/net80211/ieee80211.c | 11 +- sys/net80211/ieee80211_adhoc.c | 35 ++-- sys/net80211/ieee80211_ddb.c | 6 +- sys/net80211/ieee80211_freebsd.c | 29 +++ sys/net80211/ieee80211_hostap.c | 42 ++-- sys/net80211/ieee80211_ht.c | 4 +- sys/net80211/ieee80211_input.c | 5 +- sys/net80211/ieee80211_monitor.c | 8 +- sys/net80211/ieee80211_node.c | 6 +- sys/net80211/ieee80211_node.h | 1 - sys/net80211/ieee80211_output.c | 7 - sys/net80211/ieee80211_proto.c | 1 + sys/net80211/ieee80211_proto.h | 7 +- sys/net80211/ieee80211_radiotap.c | 325 ++++++++++++++++++++++++++++++ sys/net80211/ieee80211_scan.c | 6 +- sys/net80211/ieee80211_scan.h | 5 +- sys/net80211/ieee80211_scan_sta.c | 3 +- sys/net80211/ieee80211_sta.c | 39 ++-- sys/net80211/ieee80211_superg.c | 4 +- sys/net80211/ieee80211_tdma.c | 19 +- sys/net80211/ieee80211_tdma.h | 2 +- sys/net80211/ieee80211_var.h | 41 +++- sys/net80211/ieee80211_wds.c | 39 ++-- 53 files changed, 929 insertions(+), 713 deletions(-) create mode 100644 sys/net80211/ieee80211_radiotap.c diff --git a/sys/conf/files b/sys/conf/files index 0d3339e53896..33b4c6fd5da9 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2218,6 +2218,7 @@ net80211/ieee80211_output.c optional wlan net80211/ieee80211_phy.c optional wlan net80211/ieee80211_power.c optional wlan net80211/ieee80211_proto.c optional wlan +net80211/ieee80211_radiotap.c optional wlan net80211/ieee80211_regdomain.c optional wlan net80211/ieee80211_rssadapt.c optional wlan wlan_rssadapt net80211/ieee80211_scan.c optional wlan diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index aa52a3ed989b..05930e3ba8b3 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -172,7 +172,7 @@ static void ath_node_getsignal(const struct ieee80211_node *, int8_t *, int8_t *); static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *); static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, - int subtype, int rssi, int noise, u_int32_t rstamp); + int subtype, int rssi, int nf); static void ath_setdefantenna(struct ath_softc *, u_int); static void ath_rx_proc(void *, int); static void ath_txq_init(struct ath_softc *sc, struct ath_txq *, int); @@ -214,7 +214,6 @@ static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode); static void ath_sysctlattach(struct ath_softc *); static int ath_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void ath_bpfattach(struct ath_softc *); static void ath_announce(struct ath_softc *); #ifdef IEEE80211_SUPPORT_TDMA @@ -715,7 +714,12 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) ic->ic_scan_end = ath_scan_end; ic->ic_set_channel = ath_set_channel; - ath_bpfattach(sc); + ieee80211_radiotap_attach(ic, + &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), + ATH_TX_RADIOTAP_PRESENT, + &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), + ATH_RX_RADIOTAP_PRESENT); + /* * Setup dynamic sysctl's now that country code and * regdomain are available from the hal. @@ -753,8 +757,6 @@ ath_detach(struct ath_softc *sc) * insure callbacks into the driver to delete global * key cache entries can be handled * o free the taskqueue which drains any pending tasks - * o reclaim the bpf tap now that we know nothing will use - * it (e.g. rx processing from the task q thread) * o reclaim the tx queue data structures after calling * the 802.11 layer as we'll get called back to reclaim * node state and potentially want to use them @@ -765,7 +767,6 @@ ath_detach(struct ath_softc *sc) ath_stop(ifp); ieee80211_ifdetach(ifp->if_l2com); taskqueue_free(sc->sc_tq); - bpfdetach(ifp); #ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) sc->sc_tx99->detach(sc->sc_tx99); @@ -2353,6 +2354,7 @@ ath_calcrxfilter(struct ath_softc *sc) rfilt |= HAL_RX_FILTER_PHYERR; if (ic->ic_opmode != IEEE80211_M_STA) rfilt |= HAL_RX_FILTER_PROBEREQ; + /* XXX ic->ic_monvaps != 0? */ if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC)) rfilt |= HAL_RX_FILTER_PROM; if (ic->ic_opmode == IEEE80211_M_STA || @@ -3573,7 +3575,7 @@ ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf) */ static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, - int subtype, int rssi, int noise, u_int32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; @@ -3582,7 +3584,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, * Call up first so subsequent work can use information * potentially stored in the node (e.g. for ibss merge). */ - ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, nf); switch (subtype) { case IEEE80211_FC0_SUBTYPE_BEACON: /* update rssi statistics for use by the hal */ @@ -3599,6 +3601,7 @@ ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, case IEEE80211_FC0_SUBTYPE_PROBE_RESP: if (vap->iv_opmode == IEEE80211_M_IBSS && vap->iv_state == IEEE80211_S_RUN) { + uint32_t rstamp = sc->sc_lastrs->rs_tstamp; u_int64_t tsf = ath_extend_tsf(rstamp, ath_hal_gettsf64(sc->sc_ah)); /* @@ -3639,7 +3642,7 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna) sc->sc_rxotherant = 0; } -static int +static void ath_rx_tap(struct ifnet *ifp, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { @@ -3651,15 +3654,6 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m, const HAL_RATE_TABLE *rt; uint8_t rix; - /* - * Discard anything shorter than an ack or cts. - */ - if (m->m_pkthdr.len < IEEE80211_ACK_LEN) { - DPRINTF(sc, ATH_DEBUG_RECV, "%s: runt packet %d\n", - __func__, m->m_pkthdr.len); - sc->sc_stats.ast_rx_tooshort++; - return 0; - } rt = sc->sc_currates; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); rix = rt->rateCodeToIndex[rs->rs_rate]; @@ -3684,13 +3678,9 @@ ath_rx_tap(struct ifnet *ifp, struct mbuf *m, if (rs->rs_status & HAL_RXERR_CRC) sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; /* XXX propagate other error flags from descriptor */ - sc->sc_rx_th.wr_antsignal = rs->rs_rssi + nf; sc->sc_rx_th.wr_antnoise = nf; + sc->sc_rx_th.wr_antsignal = nf + rs->rs_rssi; sc->sc_rx_th.wr_antenna = rs->rs_antenna; - - bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); - - return 1; #undef CHAN_HT #undef CHAN_HT20 #undef CHAN_HT40U @@ -3812,7 +3802,7 @@ ath_rx_proc(void *arg, int npending) sc->sc_stats.ast_rx_badmic++; /* * Do minimal work required to hand off - * the 802.11 header for notifcation. + * the 802.11 header for notification. */ /* XXX frag's and qos frames */ len = rs->rs_datalen; @@ -3841,14 +3831,15 @@ ath_rx_proc(void *arg, int npending) * pass decrypt+mic errors but others may be * interesting (e.g. crc). */ - if (bpf_peers_present(ifp->if_bpf) && + if (ieee80211_radiotap_active(ic) && (rs->rs_status & sc->sc_monpass)) { bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); /* NB: bpf needs the mbuf length setup */ len = rs->rs_datalen; m->m_pkthdr.len = m->m_len = len; - (void) ath_rx_tap(ifp, m, rs, tsf, nf); + ath_rx_tap(ifp, m, rs, tsf, nf); + ieee80211_radiotap_rx_all(ic, m); } /* XXX pass MIC errors up for s/w reclaculation */ goto rx_next; @@ -3906,20 +3897,29 @@ ath_rx_proc(void *arg, int npending) ifp->if_ipackets++; sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; - if (bpf_peers_present(ifp->if_bpf) && - !ath_rx_tap(ifp, m, rs, tsf, nf)) { - m_freem(m); /* XXX reclaim */ - goto rx_next; - } + /* + * Populate the rx status block. When there are bpf + * listeners we do the additional work to provide + * complete status. Otherwise we fill in only the + * material required by ieee80211_input. Note that + * noise setting is filled in above. + */ + if (ieee80211_radiotap_active(ic)) + ath_rx_tap(ifp, m, rs, tsf, nf); /* * From this point on we assume the frame is at least * as large as ieee80211_frame_min; verify that. */ if (len < IEEE80211_MIN_LEN) { - DPRINTF(sc, ATH_DEBUG_RECV, "%s: short packet %d\n", - __func__, len); - sc->sc_stats.ast_rx_tooshort++; + if (!ieee80211_radiotap_active(ic)) { + DPRINTF(sc, ATH_DEBUG_RECV, + "%s: short packet %d\n", __func__, len); + sc->sc_stats.ast_rx_tooshort++; + } else { + /* NB: in particular this captures ack's */ + ieee80211_radiotap_rx_all(ic, m); + } m_freem(m); goto rx_next; } @@ -3947,11 +3947,8 @@ ath_rx_proc(void *arg, int npending) /* * Sending station is known, dispatch directly. */ -#ifdef IEEE80211_SUPPORT_TDMA - sc->sc_tdmars = rs; -#endif - type = ieee80211_input(ni, m, - rs->rs_rssi, nf, rs->rs_tstamp); + sc->sc_lastrs = rs; + type = ieee80211_input(ni, m, rs->rs_rssi, nf); ieee80211_free_node(ni); /* * Arrange to update the last rx timestamp only for @@ -3963,8 +3960,7 @@ ath_rx_proc(void *arg, int npending) rs->rs_keyix != HAL_RXKEYIX_INVALID) ngood++; } else { - type = ieee80211_input_all(ic, m, - rs->rs_rssi, nf, rs->rs_tstamp); + type = ieee80211_input_all(ic, m, rs->rs_rssi, nf); } /* * Track rx rssi and do any rx antenna management. @@ -4781,7 +4777,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf ieee80211_dump_pkt(ic, mtod(m0, const uint8_t *), m0->m_len, sc->sc_hwmap[rix].ieeerate, -1); - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { u_int64_t tsf = ath_hal_gettsf64(ah); sc->sc_tx_th.wt_tsf = htole64(tsf); @@ -4794,7 +4790,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf sc->sc_tx_th.wt_txpower = ni->ni_txpower; sc->sc_tx_th.wt_antenna = sc->sc_txantenna; - bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); + ieee80211_radiotap_tx(vap, m0); } /* @@ -5289,15 +5285,6 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan) if (mode != sc->sc_curmode) ath_setcurmode(sc, mode); sc->sc_curchan = chan; - - sc->sc_rx_th.wr_chan_flags = htole32(chan->ic_flags); - sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags; - sc->sc_rx_th.wr_chan_freq = htole16(chan->ic_freq); - sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq; - sc->sc_rx_th.wr_chan_ieee = chan->ic_ieee; - sc->sc_tx_th.wt_chan_ieee = sc->sc_rx_th.wr_chan_ieee; - sc->sc_rx_th.wr_chan_maxpow = chan->ic_maxregpower; - sc->sc_tx_th.wt_chan_maxpow = sc->sc_rx_th.wr_chan_maxpow; } /* @@ -5988,10 +5975,7 @@ ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode) if (rt->info[i].shortPreamble || rt->info[i].phy == IEEE80211_T_OFDM) sc->sc_hwmap[i].txflags |= IEEE80211_RADIOTAP_F_SHORTPRE; - /* NB: receive frames include FCS */ - sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags | - IEEE80211_RADIOTAP_F_FCS; - /* setup blink rate table to avoid per-packet lookup */ + sc->sc_hwmap[i].rxflags = sc->sc_hwmap[i].txflags; for (j = 0; j < N(blinkrates)-1; j++) if (blinkrates[j].rate == sc->sc_hwmap[i].ieeerate) break; @@ -6627,31 +6611,6 @@ ath_sysctlattach(struct ath_softc *sc) #endif } -static void -ath_bpfattach(struct ath_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); - /* - * Initialize constant fields. - * XXX make header lengths a multiple of 32-bits so subsequent - * headers are properly aligned; this is a kludge to keep - * certain applications happy. - * - * NB: the channel is setup each time we transition to the - * RUN state to avoid filling it in for each frame. - */ - sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t)); - sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); - sc->sc_tx_th.wt_ihdr.it_present = htole32(ATH_TX_RADIOTAP_PRESENT); - - sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t)); - sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); - sc->sc_rx_th.wr_ihdr.it_present = htole32(ATH_RX_RADIOTAP_PRESENT); -} - static int ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0, @@ -6660,6 +6619,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ifnet *ifp = sc->sc_ifp; struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; + struct ieee80211vap *vap = ni->ni_vap; int error, ismcast, ismrr; int keyix, hdrlen, pktlen, try0, txantenna; u_int8_t rix, cix, txrate, ctsrate, rate1, rate2, rate3; @@ -6791,18 +6751,20 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len, sc->sc_hwmap[rix].ieeerate, -1); - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { u_int64_t tsf = ath_hal_gettsf64(ah); sc->sc_tx_th.wt_tsf = htole64(tsf); sc->sc_tx_th.wt_flags = sc->sc_hwmap[rix].txflags; if (wh->i_fc[1] & IEEE80211_FC1_WEP) sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; + if (m0->m_flags & M_FRAG) + sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_FRAG; sc->sc_tx_th.wt_rate = sc->sc_hwmap[rix].ieeerate; sc->sc_tx_th.wt_txpower = ni->ni_txpower; sc->sc_tx_th.wt_antenna = sc->sc_txantenna; - bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); + ieee80211_radiotap_tx(vap, m0); } /* @@ -7141,8 +7103,9 @@ ath_tdma_update(struct ieee80211_node *ni, } /* extend rx timestamp to 64 bits */ + rs = sc->sc_lastrs; tsf = ath_hal_gettsf64(ah); - rstamp = ath_extend_tsf(ni->ni_rstamp, tsf); + rstamp = ath_extend_tsf(rs->rs_tstamp, tsf); /* * The rx timestamp is set by the hardware on completing * reception (at the point where the rx descriptor is DMA'd @@ -7150,7 +7113,6 @@ ath_tdma_update(struct ieee80211_node *ni, * must adjust this time by the time required to send * the packet just received. */ - rs = sc->sc_tdmars; rix = rt->rateCodeToIndex[rs->rs_rate]; txtime = ath_hal_computetxtime(ah, rt, rs->rs_datalen, rix, rt->info[rix].shortPreamble); diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index 8f88b59de5b1..9d9e459e6078 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -187,7 +187,7 @@ struct ath_vap { struct ath_txq av_mcastq; /* buffered mcast s/w queue */ void (*av_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, u_int32_t); + struct mbuf *, int, int, int); int (*av_newstate)(struct ieee80211vap *, enum ieee80211_state, int); void (*av_bmiss)(struct ieee80211vap *); @@ -284,12 +284,6 @@ struct ath_softc { u_int sc_rfsilentpin; /* GPIO pin for rfkill int */ u_int sc_rfsilentpol; /* pin setting for rfkill on */ - struct ath_tx_radiotap_header sc_tx_th; - int sc_tx_th_len; - struct ath_rx_radiotap_header sc_rx_th; - int sc_rx_th_len; - u_int sc_monpass; /* frames to pass in mon.mode */ - struct ath_descdma sc_rxdma; /* RX descriptors */ ath_bufhead sc_rxbuf; /* receive buffer */ struct mbuf *sc_rxpending; /* pending receive data */ @@ -298,6 +292,10 @@ struct ath_softc { u_int8_t sc_defant; /* current default antenna */ u_int8_t sc_rxotherant; /* rx's on non-default antenna*/ u_int64_t sc_lastrx; /* tsf at last rx'd frame */ + struct ath_rx_status *sc_lastrs; /* h/w status of last rx */ + struct ath_rx_radiotap_header sc_rx_th; + int sc_rx_th_len; + u_int sc_monpass; /* frames to pass in mon.mode */ struct ath_descdma sc_txdma; /* TX descriptors */ ath_bufhead sc_txbuf; /* transmit buffer */ @@ -310,6 +308,8 @@ struct ath_softc { struct task sc_txtask; /* tx int processing */ int sc_wd_timer; /* count down for wd timer */ struct callout sc_wd_ch; /* tx watchdog timer */ + struct ath_tx_radiotap_header sc_tx_th; + int sc_tx_th_len; struct ath_descdma sc_bdma; /* beacon descriptors */ ath_bufhead sc_bbuf; /* beacon buffers */ @@ -338,7 +338,6 @@ struct ath_softc { u_int32_t sc_tdmabintval; /* TDMA beacon interval (TU) */ u_int32_t sc_tdmaguard; /* TDMA guard time (usec) */ u_int sc_tdmaslotlen; /* TDMA slot length (usec) */ - struct ath_rx_status *sc_tdmars; /* TDMA status of last rx */ u_int32_t sc_avgtsfdeltap;/* TDMA slot adjust (+) */ u_int32_t sc_avgtsfdeltam;/* TDMA slot adjust (-) */ }; diff --git a/sys/dev/bwi/if_bwi.c b/sys/dev/bwi/if_bwi.c index 1cb8c0bda228..48580a52a7bf 100644 --- a/sys/dev/bwi/if_bwi.c +++ b/sys/dev/bwi/if_bwi.c @@ -123,7 +123,7 @@ static int bwi_calc_rssi(struct bwi_softc *, const struct bwi_rxbuf_hdr *); static int bwi_calc_noise(struct bwi_softc *); static __inline uint8_t bwi_ofdm_plcp2rate(const uint32_t *); static __inline uint8_t bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *); -static void bwi_rx_radiotap(struct ifnet *, struct mbuf *, +static void bwi_rx_radiotap(struct bwi_softc *, struct mbuf *, struct bwi_rxbuf_hdr *, const void *, int, int, int); static void bwi_restart(void *, int); @@ -532,19 +532,11 @@ bwi_attach(struct bwi_softc *sc) sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - /* - * Attach bpf. - */ - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); - - sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(uint32_t)); - sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); - sc->sc_tx_th.wt_ihdr.it_present = htole32(BWI_TX_RADIOTAP_PRESENT); - - sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(uint32_t)); - sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); - sc->sc_rx_th.wr_ihdr.it_present = htole32(BWI_RX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), + BWI_TX_RADIOTAP_PRESENT, + &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), + BWI_RX_RADIOTAP_PRESENT); /* * Add sysctl nodes @@ -2675,8 +2667,8 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) rate = bwi_ds_plcp2rate(plcp); /* RX radio tap */ - if (bpf_peers_present(ifp->if_bpf)) - bwi_rx_radiotap(ifp, m, hdr, plcp, rate, rssi, noise); + if (ieee80211_radiotap_active(ic)) + bwi_rx_radiotap(sc, m, hdr, plcp, rate, rssi, noise); m_adj(m, -IEEE80211_CRC_LEN); @@ -2685,11 +2677,10 @@ bwi_rxeof(struct bwi_softc *sc, int end_idx) wh = mtod(m, struct ieee80211_frame_min *); ni = ieee80211_find_rxnode(ic, wh); if (ni != NULL) { - type = ieee80211_input(ni, m, rssi - noise, noise, 0); + type = ieee80211_input(ni, m, rssi - noise, noise); ieee80211_free_node(ni); } else - type = ieee80211_input_all(ic, m, rssi - noise, - noise, 0); + type = ieee80211_input_all(ic, m, rssi - noise, noise); if (type == IEEE80211_FC0_TYPE_DATA) { rx_data = 1; sc->sc_rx_rate = rate; @@ -3001,7 +2992,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, /* * TX radio tap */ - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { sc->sc_tx_th.wt_flags = 0; if (wh->i_fc[1] & IEEE80211_FC1_WEP) sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; @@ -3012,7 +3003,7 @@ bwi_encap(struct bwi_softc *sc, int idx, struct mbuf *m, } sc->sc_tx_th.wt_rate = rate; - bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m); + ieee80211_radiotap_tx(vap, m); } /* @@ -3134,6 +3125,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { struct ifnet *ifp = sc->sc_ifp; + struct ieee80211vap *vap = ni->ni_vap; struct bwi_ring_data *rd = &sc->sc_tx_rdata[BWI_TX_DATA_RING]; struct bwi_txbuf_data *tbd = &sc->sc_tx_bdata[BWI_TX_DATA_RING]; struct bwi_txbuf *tb = &tbd->tbd_buf[idx]; @@ -3169,7 +3161,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, /* * TX radio tap */ - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { sc->sc_tx_th.wt_flags = 0; /* XXX IEEE80211_BPF_CRYPTO */ if (wh->i_fc[1] & IEEE80211_FC1_WEP) @@ -3178,7 +3170,7 @@ bwi_encap_raw(struct bwi_softc *sc, int idx, struct mbuf *m, sc->sc_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; sc->sc_tx_th.wt_rate = rate; - bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m); + ieee80211_radiotap_tx(vap, m); } /* @@ -3806,10 +3798,9 @@ bwi_ds_plcp2rate(const struct ieee80211_ds_plcp_hdr *hdr) } static void -bwi_rx_radiotap(struct ifnet *ifp, struct mbuf *m, +bwi_rx_radiotap(struct bwi_softc *sc, struct mbuf *m, struct bwi_rxbuf_hdr *hdr, const void *plcp, int rate, int rssi, int noise) { - struct bwi_softc *sc = ifp->if_softc; const struct ieee80211_frame_min *wh; sc->sc_rx_th.wr_flags = IEEE80211_RADIOTAP_F_FCS; @@ -3824,8 +3815,6 @@ bwi_rx_radiotap(struct ifnet *ifp, struct mbuf *m, sc->sc_rx_th.wr_rate = rate; sc->sc_rx_th.wr_antsignal = rssi; sc->sc_rx_th.wr_antnoise = noise; - - bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); } static void diff --git a/sys/dev/bwi/if_bwivar.h b/sys/dev/bwi/if_bwivar.h index 311e38f847a3..af4b0ea5cc12 100644 --- a/sys/dev/bwi/if_bwivar.h +++ b/sys/dev/bwi/if_bwivar.h @@ -615,9 +615,7 @@ struct bwi_softc { const struct ieee80211_rate_table *sc_rates; struct bwi_tx_radiotap_hdr sc_tx_th; - int sc_tx_th_len; struct bwi_rx_radiotap_hdr sc_rx_th; - int sc_rx_th_len; struct taskqueue *sc_tq; struct task sc_restart_task; diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index c69ab6d8d975..1c4e492f7586 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -346,16 +346,11 @@ ipw_attach(device_t dev) ic->ic_vap_create = ipw_vap_create; ic->ic_vap_delete = ipw_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(IPW_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(IPW_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + IPW_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + IPW_RX_RADIOTAP_PRESENT); /* * Add a few sysctl knobs. @@ -407,7 +402,6 @@ ipw_detach(device_t dev) ieee80211_draintask(ic, &sc->sc_init_task); ipw_stop(sc); - bpfdetach(ifp); ieee80211_ifdetach(ic); callout_drain(&sc->sc_wdtimer); @@ -1107,10 +1101,7 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) struct ieee80211com *ic = ifp->if_l2com; ic->ic_curchan = chan; - sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = - htole16(ic->ic_curchan->ic_freq); - sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = - htole16(ic->ic_curchan->ic_flags); + ieee80211_radiotap_chan_change(ic); } /* @@ -1172,6 +1163,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, struct ieee80211_node *ni; bus_addr_t physaddr; int error; + int8_t rssi, nf; IPW_LOCK_DECL; DPRINTFN(5, ("received frame len=%u, rssi=%u\n", le32toh(status->len), @@ -1226,15 +1218,14 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = le32toh(status->len); - if (bpf_peers_present(ifp->if_bpf)) { + rssi = status->rssi + IPW_RSSI_TO_DBM; + nf = -95; + if (ieee80211_radiotap_active(ic)) { struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; - tap->wr_antsignal = status->rssi + IPW_RSSI_TO_DBM; - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + tap->wr_antsignal = rssi; + tap->wr_antnoise = nf; } if (sc->flags & IPW_FLAG_SCANNING) @@ -1243,10 +1234,10 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, IPW_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, status->rssi, -95, 0); + (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, status->rssi, -95, 0); + (void) ieee80211_input_all(ic, m, rssi, nf); IPW_LOCK(sc); bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE); @@ -1570,6 +1561,7 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) { struct ipw_softc *sc = ifp->if_softc; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_frame *wh; struct ipw_soft_bd *sbd; struct ipw_soft_hdr *shdr; @@ -1592,14 +1584,12 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct ipw_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } shdr = SLIST_FIRST(&sc->free_shdr); diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h index 24fb8e85d26c..8d9e049ccfb3 100644 --- a/sys/dev/ipw/if_ipwvar.h +++ b/sys/dev/ipw/if_ipwvar.h @@ -57,13 +57,15 @@ struct ipw_rx_radiotap_header { uint8_t wr_flags; uint16_t wr_chan_freq; uint16_t wr_chan_flags; - uint8_t wr_antsignal; + int8_t wr_antsignal; + int8_t wr_antnoise; }; #define IPW_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTNOISE)) struct ipw_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; @@ -155,10 +157,7 @@ struct ipw_softc { int txfree; struct ipw_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - struct ipw_tx_radiotap_header sc_txtap; - int sc_txtap_len; }; /* diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index f7d891e3d6fe..dcfde7e14d02 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -419,16 +419,11 @@ iwi_attach(device_t dev) ic->ic_vap_create = iwi_vap_create; ic->ic_vap_delete = iwi_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(IWI_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(IWI_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + IWI_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + IWI_RX_RADIOTAP_PRESENT); iwi_sysctlattach(sc); iwi_ledattach(sc); @@ -468,7 +463,6 @@ iwi_detach(device_t dev) iwi_stop(sc); - bpfdetach(ifp); ieee80211_ifdetach(ic); iwi_put_firmware(sc); @@ -1196,11 +1190,7 @@ iwi_setcurchan(struct iwi_softc *sc, int chan) struct ieee80211com *ic = ifp->if_l2com; sc->curchan = chan; - - sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = - htole16(ic->ic_curchan->ic_freq); - sc->sc_rxtap.wr_chan_flags = sc->sc_txtap.wt_chan_flags = - htole16(ic->ic_curchan->ic_flags); + ieee80211_radiotap_chan_change(ic); } static void @@ -1212,6 +1202,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, struct mbuf *mnew, *m; struct ieee80211_node *ni; int type, error, framelen; + int8_t rssi, nf; IWI_LOCK_DECL; framelen = le16toh(frame->len); @@ -1283,24 +1274,25 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame)); - if (bpf_peers_present(ifp->if_bpf)) { + rssi = frame->signal; + nf = -95; + if (ieee80211_radiotap_active(ic)) { struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; + tap->wr_antsignal = rssi; + tap->wr_antnoise = nf; tap->wr_rate = iwi_cvtrate(frame->rate); - tap->wr_antsignal = frame->signal; tap->wr_antenna = frame->antenna; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } IWI_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - type = ieee80211_input(ni, m, frame->rssi_dbm, 0, 0); + type = ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - type = ieee80211_input_all(ic, m, frame->rssi_dbm, 0, 0); + type = ieee80211_input_all(ic, m, rssi, nf); IWI_LOCK(sc); if (sc->sc_softled) { @@ -1852,12 +1844,12 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct iwi_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data = &txq->data[txq->cur]; diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index b31af36c05ad..1acb6c3e69a6 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -33,7 +33,8 @@ struct iwi_rx_radiotap_header { uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; - uint8_t wr_antsignal; + int8_t wr_antsignal; + int8_t wr_antnoise; uint8_t wr_antenna; }; @@ -42,6 +43,7 @@ struct iwi_rx_radiotap_header { (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \ (1 << IEEE80211_RADIOTAP_ANTENNA)) struct iwi_tx_radiotap_header { @@ -213,10 +215,7 @@ struct iwi_softc { int sc_busy_timer; /* firmware cmd timer */ struct iwi_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; - struct iwi_tx_radiotap_header sc_txtap; - int sc_txtap_len; }; #define IWI_STATE_BEGIN(_sc, _state) do { \ diff --git a/sys/dev/iwn/if_iwn.c b/sys/dev/iwn/if_iwn.c index 9913d90ce68b..cc12828e3ed9 100644 --- a/sys/dev/iwn/if_iwn.c +++ b/sys/dev/iwn/if_iwn.c @@ -185,7 +185,6 @@ static void iwn_scan_mindwell(struct ieee80211_scan_state *); static void iwn_hwreset(void *, int); static void iwn_radioon(void *, int); static void iwn_radiooff(void *, int); -static void iwn_bpfattach(struct iwn_softc *); static void iwn_sysctlattach(struct iwn_softc *); #define IWN_DEBUG @@ -426,7 +425,12 @@ iwn_attach(device_t dev) ic->ic_scan_curchan = iwn_scan_curchan; ic->ic_scan_mindwell = iwn_scan_mindwell; - iwn_bpfattach(sc); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + IWN_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + IWN_RX_RADIOTAP_PRESENT); + iwn_sysctlattach(sc); /* @@ -471,7 +475,6 @@ iwn_cleanup(device_t dev) if (ifp != NULL) { iwn_stop(sc); callout_drain(&sc->sc_timer_to); - bpfdetach(ifp); ieee80211_ifdetach(ic); } @@ -1472,29 +1475,26 @@ iwn_rx_intr(struct iwn_softc *sc, struct iwn_rx_desc *desc, nf = (ni != NULL && ni->ni_vap->iv_state == IEEE80211_S_RUN && (ic->ic_flags & IEEE80211_F_SCAN) == 0) ? sc->noise : -95; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct iwn_rx_radiotap_header *tap = &sc->sc_rxtap; - tap->wr_flags = 0; - tap->wr_dbm_antsignal = rssi; - tap->wr_dbm_antnoise = nf; - tap->wr_rate = maprate(stat->rate); tap->wr_tsft = htole64(stat->tstamp); - + tap->wr_flags = 0; if (stat->flags & htole16(IWN_CONFIG_SHPREAMBLE)) tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + tap->wr_rate = maprate(stat->rate); + tap->wr_dbm_antsignal = rssi; + tap->wr_dbm_antnoise = nf; } IWN_UNLOCK(sc); /* send the frame to the 802.11 layer */ if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi - nf, nf, 0); + (void) ieee80211_input(ni, m, rssi - nf, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi - nf, nf, 0); + (void) ieee80211_input_all(ic, m, rssi - nf, nf); IWN_LOCK(sc); } @@ -1931,7 +1931,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, } else k = NULL; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct iwn_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1939,7 +1939,7 @@ iwn_tx_data(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, if (k != NULL) tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } flags = IWN_TX_AUTO_SEQ; @@ -2226,7 +2226,7 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, struct iwn_tx_ring *ring, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; + struct ieee80211vap *vap = ni->ni_vap; struct iwn_tx_cmd *cmd; struct iwn_cmd_data *tx; struct ieee80211_frame *wh; @@ -2264,13 +2264,13 @@ iwn_tx_data_raw(struct iwn_softc *sc, struct mbuf *m0, /* pick a tx rate */ rate = params->ibp_rate0; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct iwn_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } cmd = &ring->cmd[ring->cur]; @@ -4411,23 +4411,6 @@ iwn_radiooff(void *arg0, int pending) IWN_UNLOCK(sc); } -static void -iwn_bpfattach(struct iwn_softc *sc) -{ - struct ifnet *ifp = sc->sc_ifp; - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(IWN_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(IWN_TX_RADIOTAP_PRESENT); -} - static void iwn_sysctlattach(struct iwn_softc *sc) { diff --git a/sys/dev/iwn/if_iwnvar.h b/sys/dev/iwn/if_iwnvar.h index d956525d30a2..19cc0250b94c 100644 --- a/sys/dev/iwn/if_iwnvar.h +++ b/sys/dev/iwn/if_iwnvar.h @@ -144,9 +144,7 @@ struct iwn_softc { const struct ieee80211_channel *sc_curchan; struct iwn_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; struct iwn_tx_radiotap_header sc_txtap; - int sc_txtap_len; /* locks */ struct mtx sc_mtx; diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c index c17e98cd4a19..e9c6716ef3df 100644 --- a/sys/dev/malo/if_malo.c +++ b/sys/dev/malo/if_malo.c @@ -144,7 +144,6 @@ static void malo_scan_end(struct ieee80211com *); static void malo_set_channel(struct ieee80211com *); static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static void malo_bpfattach(struct malo_softc *); static void malo_sysctlattach(struct malo_softc *); static void malo_announce(struct malo_softc *); static void malo_dma_cleanup(struct malo_softc *); @@ -317,7 +316,11 @@ malo_attach(uint16_t devid, struct malo_softc *sc) sc->malo_invalid = 0; /* ready to go, enable int handling */ - malo_bpfattach(sc); + ieee80211_radiotap_attach(ic, + &sc->malo_tx_th.wt_ihdr, sizeof(sc->malo_tx_th), + MALO_TX_RADIOTAP_PRESENT, + &sc->malo_rx_th.wr_ihdr, sizeof(sc->malo_rx_th), + MALO_RX_RADIOTAP_PRESENT); /* * Setup dynamic sysctl's. @@ -1091,6 +1094,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, struct ieee80211_frame *wh; struct ifnet *ifp = sc->malo_ifp; struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; struct malo_txdesc *ds; struct malo_txrec *tr; struct malo_txq *txq; @@ -1148,14 +1152,14 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { sc->malo_tx_th.wt_flags = 0; /* XXX */ if (iswep) sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; sc->malo_tx_th.wt_txpower = ni->ni_txpower; sc->malo_tx_th.wt_antenna = sc->malo_txantenna; - bpf_mtap2(ifp->if_bpf, &sc->malo_tx_th, sc->malo_tx_th_len, m0); + ieee80211_radiotap_tx(vap, m0); } /* @@ -1899,32 +1903,6 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -static void -malo_bpfattach(struct malo_softc *sc) -{ - struct ifnet *ifp = sc->malo_ifp; - - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->malo_tx_th)); - - /* - * Initialize constant fields. - * XXX make header lengths a multiple of 32-bits so subsequent - * headers are properly aligned; this is a kludge to keep - * certain applications happy. - * - * NB: the channel is setup each time we transition to the - * RUN state to avoid filling it in for each frame. - */ - sc->malo_tx_th_len = roundup(sizeof(sc->malo_tx_th), sizeof(uint32_t)); - sc->malo_tx_th.wt_ihdr.it_len = htole16(sc->malo_tx_th_len); - sc->malo_tx_th.wt_ihdr.it_present = htole32(MALO_TX_RADIOTAP_PRESENT); - - sc->malo_rx_th_len = roundup(sizeof(sc->malo_rx_th), sizeof(uint32_t)); - sc->malo_rx_th.wr_ihdr.it_len = htole16(sc->malo_rx_th_len); - sc->malo_rx_th.wr_ihdr.it_present = htole32(MALO_RX_RADIOTAP_PRESENT); -} - static void malo_sysctlattach(struct malo_softc *sc) { @@ -2173,14 +2151,11 @@ malo_rx_proc(void *arg, int npending) *(uint16_t *)wh->i_qos = ds->qosctrl; } } - if (sc->malo_drvbpf != NULL) { + if (ieee80211_radiotap_active(ic)) { sc->malo_rx_th.wr_flags = 0; sc->malo_rx_th.wr_rate = ds->rate; sc->malo_rx_th.wr_antsignal = rssi; sc->malo_rx_th.wr_antnoise = ds->nf; - - bpf_mtap2(ifp->if_bpf, &sc->malo_rx_th, - sc->malo_rx_th_len, m); } #ifdef MALO_DEBUG if (IFF_DUMPPKTS_RECV(sc, wh)) { @@ -2194,10 +2169,10 @@ malo_rx_proc(void *arg, int npending) ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, ds->nf, 0); + (void) ieee80211_input(ni, m, rssi, ds->nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, ds->nf, 0); + (void) ieee80211_input_all(ic, m, rssi, ds->nf); rx_next: /* NB: ignore ENOMEM so we process more descriptors */ (void) malo_rxbuf_init(sc, bf); @@ -2253,8 +2228,6 @@ malo_detach(struct malo_softc *sc) sc->malo_tq = NULL; } - bpfdetach(ifp); - /* * NB: the order of these is important: * o call the 802.11 layer before detaching the hal to diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h index 070649acefa3..7e3a7e89e486 100644 --- a/sys/dev/malo/if_malo.h +++ b/sys/dev/malo/if_malo.h @@ -551,11 +551,8 @@ struct malo_softc { struct malo_txq malo_txq[MALO_NUM_TX_QUEUES]; struct task malo_txtask; /* tx int processing */ - struct bpf_if *malo_drvbpf; struct malo_tx_radiotap_header malo_tx_th; - int malo_tx_th_len; struct malo_rx_radiotap_header malo_rx_th; - int malo_rx_th_len; struct malo_stats malo_stats; /* interface statistics */ int malo_debug; diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index 936fe8ea7e03..95c5ebd2566b 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -144,6 +144,7 @@ static void rt2560_set_chan(struct rt2560_softc *, static void rt2560_disable_rf_tune(struct rt2560_softc *); #endif static void rt2560_enable_tsf_sync(struct rt2560_softc *); +static void rt2560_enable_tsf(struct rt2560_softc *); static void rt2560_update_plcp(struct rt2560_softc *); static void rt2560_update_slot(struct ifnet *); static void rt2560_set_basicrates(struct rt2560_softc *); @@ -313,16 +314,11 @@ rt2560_attach(device_t dev, int id) ic->ic_vap_create = rt2560_vap_create; ic->ic_vap_delete = rt2560_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2560_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RT2560_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + RT2560_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + RT2560_RX_RADIOTAP_PRESENT); /* * Add a few sysctl knobs. @@ -364,7 +360,6 @@ rt2560_detach(void *xsc) rt2560_stop(sc); - bpfdetach(ifp); ieee80211_ifdetach(ic); rt2560_free_tx_ring(sc, &sc->txq); @@ -833,6 +828,8 @@ rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode != IEEE80211_M_MONITOR) rt2560_enable_tsf_sync(sc); + else + rt2560_enable_tsf(sc); } return error; } @@ -1146,6 +1143,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) struct ieee80211_node *ni; struct mbuf *mnew, *m; int hw, error; + int8_t rssi, nf; /* retrieve last decriptor index processed by cipher engine */ hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr; @@ -1222,7 +1220,9 @@ rt2560_decryption_intr(struct rt2560_softc *sc) m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; - if (bpf_peers_present(ifp->if_bpf)) { + rssi = RT2560_RSSI(sc, desc->rssi); + nf = RT2560_NOISE_FLOOR; + if (ieee80211_radiotap_active(ic)) { struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap; uint32_t tsf_lo, tsf_hi; @@ -1237,9 +1237,8 @@ rt2560_decryption_intr(struct rt2560_softc *sc) (desc->flags & htole32(RT2560_RX_OFDM)) ? IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_antenna = sc->rx_ant; - tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + tap->wr_antsignal = nf + rssi; + tap->wr_antnoise = nf; } sc->sc_flags |= RT2560_F_INPUT_RUNNING; @@ -1248,12 +1247,10 @@ rt2560_decryption_intr(struct rt2560_softc *sc) ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); if (ni != NULL) { - (void) ieee80211_input(ni, m, - RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0); + (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, - RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0); + (void) ieee80211_input_all(ic, m, rssi, nf); RAL_LOCK(sc); sc->sc_flags &= ~RT2560_F_INPUT_RUNNING; @@ -1507,8 +1504,6 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; @@ -1529,16 +1524,14 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data->m = m0; @@ -1565,7 +1558,6 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_frame *wh; @@ -1599,16 +1591,14 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data->m = m0; @@ -1724,8 +1714,7 @@ static int rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = ni->ni_vap; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; @@ -1767,16 +1756,14 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(ni->ni_vap, m0); } data->m = m0; @@ -1808,7 +1795,6 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_frame *wh; @@ -1897,14 +1883,14 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data->m = m0; @@ -2234,11 +2220,6 @@ rt2560_set_channel(struct ieee80211com *ic) RAL_LOCK(sc); rt2560_set_chan(sc, ic->ic_curchan); - - sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags); RAL_UNLOCK(sc); } @@ -2302,6 +2283,14 @@ rt2560_enable_tsf_sync(struct rt2560_softc *sc) DPRINTF(sc, "%s", "enabling TSF synchronization\n"); } +static void +rt2560_enable_tsf(struct rt2560_softc *sc) +{ + RAL_WRITE(sc, RT2560_CSR14, 0); + RAL_WRITE(sc, RT2560_CSR14, + RT2560_ENABLE_TSF_SYNC(2) | RT2560_ENABLE_TSF); +} + static void rt2560_update_plcp(struct rt2560_softc *sc) { diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h index d53c0d16afd8..288577b62667 100644 --- a/sys/dev/ral/rt2560var.h +++ b/sys/dev/ral/rt2560var.h @@ -24,8 +24,9 @@ struct rt2560_rx_radiotap_header { uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; uint8_t wr_antenna; - uint8_t wr_antsignal; }; #define RT2560_RX_RADIOTAP_PRESENT \ @@ -34,7 +35,8 @@ struct rt2560_rx_radiotap_header { (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) struct rt2560_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index a3b19863869b..8b30c9b34bbc 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -169,6 +169,7 @@ static int rt2661_radar_stop(struct rt2661_softc *); static int rt2661_prepare_beacon(struct rt2661_softc *, struct ieee80211vap *); static void rt2661_enable_tsf_sync(struct rt2661_softc *); +static void rt2661_enable_tsf(struct rt2661_softc *); static int rt2661_get_rssi(struct rt2661_softc *, uint8_t); static const struct { @@ -319,16 +320,11 @@ rt2661_attach(device_t dev, int id) ic->ic_vap_create = rt2661_vap_create; ic->ic_vap_delete = rt2661_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2661_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + RT2661_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + RT2661_RX_RADIOTAP_PRESENT); #ifdef RAL_DEBUG SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), @@ -359,7 +355,6 @@ rt2661_detach(void *xsc) rt2661_stop_locked(sc); RAL_UNLOCK(sc); - bpfdetach(ifp); ieee80211_ifdetach(ic); rt2661_free_tx_ring(sc, &sc->txq[0]); @@ -830,6 +825,8 @@ rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) } if (vap->iv_opmode != IEEE80211_M_MONITOR) rt2661_enable_tsf_sync(sc); + else + rt2661_enable_tsf(sc); } return error; } @@ -1025,7 +1022,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) BUS_DMASYNC_POSTREAD); for (;;) { - int rssi; + int8_t rssi, nf; desc = &sc->rxq.desc[sc->rxq.cur]; data = &sc->rxq.data[sc->rxq.cur]; @@ -1100,8 +1097,12 @@ rt2661_rx_intr(struct rt2661_softc *sc) (le32toh(desc->flags) >> 16) & 0xfff; rssi = rt2661_get_rssi(sc, desc->rssi); + /* Error happened during RSSI conversion. */ + if (rssi < 0) + rssi = -30; /* XXX ignored by net80211 */ + nf = RT2661_NOISE_FLOOR; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap; uint32_t tsf_lo, tsf_hi; @@ -1115,9 +1116,8 @@ rt2661_rx_intr(struct rt2661_softc *sc) tap->wr_rate = ieee80211_plcp2rate(desc->rate, (desc->flags & htole32(RT2661_RX_OFDM)) ? IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_antsignal = rssi < 0 ? 0 : rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + tap->wr_antsignal = nf + rssi; + tap->wr_antnoise = nf; } sc->sc_flags |= RAL_INPUT_RUNNING; RAL_UNLOCK(sc); @@ -1127,16 +1127,10 @@ rt2661_rx_intr(struct rt2661_softc *sc) ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); if (ni != NULL) { - /* Error happened during RSSI conversion. */ - if (rssi < 0) - rssi = -30; /* XXX ignored by net80211 */ - - (void) ieee80211_input(ni, m, rssi, - RT2661_NOISE_FLOOR, 0); + (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, - RT2661_NOISE_FLOOR, 0); + (void) ieee80211_input_all(ic, m, rssi, nf); RAL_LOCK(sc); sc->sc_flags &= ~RAL_INPUT_RUNNING; @@ -1332,7 +1326,6 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; struct ieee80211_frame *wh; @@ -1366,13 +1359,13 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data->m = m0; @@ -1587,15 +1580,13 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } data->m = m0; @@ -2789,6 +2780,14 @@ rt2661_enable_tsf_sync(struct rt2661_softc *sc) RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp); } +static void +rt2661_enable_tsf(struct rt2661_softc *sc) +{ + RAL_WRITE(sc, RT2661_TXRX_CSR9, + (RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000) + | RT2661_TSF_TICKING | RT2661_TSF_MODE(2)); +} + /* * Retrieve the "Received Signal Strength Indicator" from the raw values * contained in Rx descriptors. The computation depends on which band the @@ -2869,11 +2868,6 @@ rt2661_set_channel(struct ieee80211com *ic) RAL_LOCK(sc); rt2661_set_chan(sc, ic->ic_curchan); - - sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags); RAL_UNLOCK(sc); } diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h index 6fc958ad4f9b..db1d4de56f80 100644 --- a/sys/dev/ral/rt2661var.h +++ b/sys/dev/ral/rt2661var.h @@ -24,7 +24,8 @@ struct rt2661_rx_radiotap_header { uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; - uint8_t wr_antsignal; + int8_t wr_antsignal; + int8_t wr_antnoise; } __packed; #define RT2661_RX_RADIOTAP_PRESENT \ @@ -32,7 +33,8 @@ struct rt2661_rx_radiotap_header { (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) struct rt2661_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 0c3012e89d45..9d8e575ffabb 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -196,6 +196,7 @@ static void rum_select_band(struct rum_softc *, static void rum_set_chan(struct rum_softc *, struct ieee80211_channel *); static void rum_enable_tsf_sync(struct rum_softc *); +static void rum_enable_tsf(struct rum_softc *); static void rum_update_slot(struct ifnet *); static void rum_set_bssid(struct rum_softc *, const uint8_t *); static void rum_set_macaddr(struct rum_softc *, const uint8_t *); @@ -522,16 +523,11 @@ rum_attach(device_t self) ic->ic_vap_create = rum_vap_create; ic->ic_vap_delete = rum_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + RT2573_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + RT2573_RX_RADIOTAP_PRESENT); if (bootverbose) ieee80211_announce(ic); @@ -560,7 +556,6 @@ rum_detach(device_t self) if (ifp) { ic = ifp->if_l2com; - bpfdetach(ifp); ieee80211_ifdetach(ic); if_free(ifp); } @@ -752,9 +747,11 @@ rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode != IEEE80211_M_MONITOR) rum_enable_tsf_sync(sc); + else + rum_enable_tsf(sc); /* enable automatic rate adaptation */ - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) rum_amrr_start(sc, ni); break; @@ -771,8 +768,7 @@ rum_bulk_write_callback(struct usb2_xfer *xfer) { struct rum_softc *sc = xfer->priv_sc; struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211_channel *c = ic->ic_curchan; + struct ieee80211vap *vap; struct rum_tx_data *data; struct mbuf *m; unsigned int len; @@ -807,16 +803,15 @@ rum_bulk_write_callback(struct usb2_xfer *xfer) usb2_m_copy_in(xfer->frbuffers, RT2573_TX_DESC_SIZE, m, 0, m->m_pkthdr.len); - if (bpf_peers_present(ifp->if_bpf)) { + vap = data->ni->ni_vap; + if (ieee80211_radiotap_active_vap(vap)) { struct rum_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = data->rate; - tap->wt_chan_freq = htole16(c->ic_freq); - tap->wt_chan_flags = htole16(c->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); + ieee80211_radiotap_tx(vap, m); } /* align end on a 4-bytes boundary */ @@ -911,19 +906,17 @@ rum_bulk_read_callback(struct usb2_xfer *xfer) m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; - tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; + /* XXX read tsf */ + tap->wr_flags = 0; tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate, (flags & RT2573_RX_OFDM) ? IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wr_antsignal = RT2573_NOISE_FLOOR + rssi; + tap->wr_antnoise = RT2573_NOISE_FLOOR; tap->wr_antenna = sc->rx_ant; - tap->wr_antsignal = rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } /* FALLTHROUGH */ case USB_ST_SETUP: @@ -942,11 +935,11 @@ rum_bulk_read_callback(struct usb2_xfer *xfer) mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { (void) ieee80211_input(ni, m, rssi, - RT2573_NOISE_FLOOR, 0); + RT2573_NOISE_FLOOR); ieee80211_free_node(ni); } else (void) ieee80211_input_all(ic, m, rssi, - RT2573_NOISE_FLOOR, 0); + RT2573_NOISE_FLOOR); RUM_LOCK(sc); } return; @@ -1736,6 +1729,14 @@ rum_enable_tsf_sync(struct rum_softc *sc) rum_write(sc, RT2573_TXRX_CSR9, tmp); } +static void +rum_enable_tsf(struct rum_softc *sc) +{ + rum_write(sc, RT2573_TXRX_CSR9, + (rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000) | + RT2573_TSF_TICKING | RT2573_TSF_MODE(2)); +} + static void rum_update_slot(struct ifnet *ifp) { diff --git a/sys/dev/usb/wlan/if_rumvar.h b/sys/dev/usb/wlan/if_rumvar.h index 2ba40075c24f..13b84f7ee1aa 100644 --- a/sys/dev/usb/wlan/if_rumvar.h +++ b/sys/dev/usb/wlan/if_rumvar.h @@ -26,16 +26,19 @@ struct rum_rx_radiotap_header { uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; uint8_t wr_antenna; - uint8_t wr_antsignal; }; #define RT2573_RX_RADIOTAP_PRESENT \ ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + 0) struct rum_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index f647daec99f4..f5f1b1a24afc 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -481,16 +481,11 @@ uath_attach(device_t dev) ic->ic_update_mcast = uath_update_mcast; ic->ic_update_promisc = uath_update_promisc; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(UATH_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(UATH_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + UATH_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + UATH_RX_RADIOTAP_PRESENT); if (bootverbose) ieee80211_announce(ic); @@ -531,7 +526,6 @@ uath_detach(device_t dev) uath_free_cmd_list(sc, sc->sc_cmd, UATH_CMD_LIST_COUNT); UATH_UNLOCK(sc); - bpfdetach(ifp); if_free(ifp); mtx_destroy(&sc->sc_mtx); return (0); @@ -1601,8 +1595,6 @@ static int uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, struct uath_data *data) { - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; struct ieee80211vap *vap = ni->ni_vap; struct uath_chunk *chunk; struct uath_tx_desc *desc; @@ -1617,16 +1609,14 @@ uath_tx_start(struct uath_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, chunk = (struct uath_chunk *)data->buf; desc = (struct uath_tx_desc *)(chunk + 1); - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct uath_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; if (m0->m_flags & M_FRAG) tap->wt_flags |= IEEE80211_RADIOTAP_F_FRAG; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } wh = mtod(m0, struct ieee80211_frame *); @@ -1921,7 +1911,7 @@ uath_set_channel(struct ieee80211com *ic) static int uath_set_rxmulti_filter(struct uath_softc *sc) { - + /* XXX broken */ return (0); } static void @@ -1929,13 +1919,14 @@ uath_update_mcast(struct ifnet *ifp) { struct uath_softc *sc = ifp->if_softc; + UATH_LOCK(sc); /* * this is for avoiding the race condition when we're try to * connect to the AP with WPA. */ - if (!(sc->sc_flags & UATH_FLAG_INITDONE)) - return; - (void)uath_set_rxmulti_filter(sc); + if (sc->sc_flags & UATH_FLAG_INITDONE) + (void)uath_set_rxmulti_filter(sc); + UATH_UNLOCK(sc); } static void @@ -1943,12 +1934,14 @@ uath_update_promisc(struct ifnet *ifp) { struct uath_softc *sc = ifp->if_softc; - if (!(sc->sc_flags & UATH_FLAG_INITDONE)) - return; - uath_set_rxfilter(sc, - UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | - UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON | - UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET); + UATH_LOCK(sc); + if (sc->sc_flags & UATH_FLAG_INITDONE) { + uath_set_rxfilter(sc, + UATH_FILTER_RX_UCAST | UATH_FILTER_RX_MCAST | + UATH_FILTER_RX_BCAST | UATH_FILTER_RX_BEACON | + UATH_FILTER_RX_PROM, UATH_FILTER_OP_SET); + } + UATH_UNLOCK(sc); } static int @@ -2653,14 +2646,22 @@ uath_data_rxeof(struct usb2_xfer *xfer, struct uath_data *data, } /* there are a lot more fields in the RX descriptor */ - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct uath_rx_radiotap_header *tap = &sc->sc_rxtap; + uint32_t tsf_hi = be32toh(desc->tstamp_high); + uint32_t tsf_lo = be32toh(desc->tstamp_low); - tap->wr_chan_freq = htole16(be32toh(desc->channel)); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - tap->wr_dbm_antsignal = (int8_t)be32toh(desc->rssi); - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + /* XXX only get low order 24bits of tsf from h/w */ + tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo); + tap->wr_flags = 0; + if (be32toh(desc->status) == UATH_STATUS_CRC_ERR) + tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; + /* XXX map other status to BADFCS? */ + /* XXX ath h/w rate code, need to map */ + tap->wr_rate = be32toh(desc->rate); + tap->wr_antenna = be32toh(desc->antenna); + tap->wr_antsignal = -95 + be32toh(desc->rssi); + tap->wr_antnoise = -95; } ifp->if_ipackets++; @@ -2721,12 +2722,12 @@ uath_bulk_rx_callback(struct usb2_xfer *xfer) nf = -95; /* XXX */ if (ni != NULL) { (void) ieee80211_input(ni, m, - (int)be32toh(desc->rssi), nf, 0); + (int)be32toh(desc->rssi), nf); /* node is no longer needed */ ieee80211_free_node(ni); } else (void) ieee80211_input_all(ic, m, - (int)be32toh(desc->rssi), nf, 0); + (int)be32toh(desc->rssi), nf); m = NULL; desc = NULL; } diff --git a/sys/dev/usb/wlan/if_uathvar.h b/sys/dev/usb/wlan/if_uathvar.h index 2757ad459c94..9b0a12694e55 100644 --- a/sys/dev/usb/wlan/if_uathvar.h +++ b/sys/dev/usb/wlan/if_uathvar.h @@ -44,22 +44,31 @@ enum { struct uath_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; - uint8_t wr_flags; - uint16_t wr_chan_freq; - uint16_t wr_chan_flags; - int8_t wr_dbm_antsignal; + u_int64_t wr_tsf; + u_int8_t wr_flags; + u_int8_t wr_rate; + uint16_t wr_chan_freq; + uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; + u_int8_t wr_antenna; } __packed; -#define UATH_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ - (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL)) +#define UATH_RX_RADIOTAP_PRESENT ( \ + (1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ + (1 << IEEE80211_RADIOTAP_RATE) | \ + (1 << IEEE80211_RADIOTAP_ANTENNA) | \ + (1 << IEEE80211_RADIOTAP_CHANNEL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ + 0) struct uath_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; - uint8_t wt_flags; - uint16_t wt_chan_freq; - uint16_t wt_chan_flags; + uint8_t wt_flags; + uint16_t wt_chan_freq; + uint16_t wt_chan_flags; } __packed; #define UATH_TX_RADIOTAP_PRESENT \ diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index d99c74008630..c10e8ec61544 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -367,14 +367,11 @@ upgt_attach(device_t dev) ic->ic_vap_delete = upgt_vap_delete; ic->ic_update_mcast = upgt_update_mcast; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof(sc->sc_rxtap); - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(UPGT_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof(sc->sc_txtap); - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(UPGT_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + UPGT_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + UPGT_RX_RADIOTAP_PRESENT); upgt_sysctl_node(sc); @@ -1507,16 +1504,12 @@ upgt_rx(struct upgt_softc *sc, uint8_t *data, int pkglen, int *rssi) m->m_len = m->m_pkthdr.len = pkglen - IEEE80211_CRC_LEN; m->m_pkthdr.rcvif = ifp; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct upgt_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; tap->wr_rate = upgt_rx_rate(sc, rxdesc->rate); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antsignal = rxdesc->rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } ifp->if_ipackets++; @@ -2011,7 +2004,6 @@ upgt_detach(device_t dev) upgt_free_rx(sc); upgt_free_tx(sc); - bpfdetach(ifp); if_free(ifp); mtx_destroy(&sc->sc_mtx); @@ -2157,11 +2149,11 @@ static int upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni, struct upgt_data *data) { + struct ieee80211vap *vap = ni->ni_vap; int error = 0, len; struct ieee80211_frame *wh; struct ieee80211_key *k; struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; struct upgt_lmac_mem *mem; struct upgt_lmac_tx_desc *txdesc; @@ -2211,15 +2203,13 @@ upgt_tx_start(struct upgt_softc *sc, struct mbuf *m, struct ieee80211_node *ni, txdesc->type = htole32(UPGT_TX_DESC_TYPE_DATA); txdesc->pad3[0] = UPGT_TX_DESC_PAD3_SIZE; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct upgt_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = 0; /* XXX where to get from? */ - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); + ieee80211_radiotap_tx(vap, m); } /* copy frame below our TX descriptor header */ @@ -2299,11 +2289,11 @@ upgt_bulk_rx_callback(struct usb2_xfer *xfer) (struct ieee80211_frame_min *)wh); nf = -95; /* XXX */ if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, nf, 0); + (void) ieee80211_input(ni, m, rssi, nf); /* node is no longer needed */ ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, nf, 0); + (void) ieee80211_input_all(ic, m, rssi, nf); m = NULL; } UPGT_LOCK(sc); diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index 523cc61d40d7..732b52039c20 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -176,6 +176,7 @@ static void ural_set_chan(struct ural_softc *, struct ieee80211_channel *); static void ural_disable_rf_tune(struct ural_softc *); static void ural_enable_tsf_sync(struct ural_softc *); +static void ural_enable_tsf(struct ural_softc *); static void ural_update_slot(struct ifnet *); static void ural_set_txpreamble(struct ural_softc *); static void ural_set_basicrates(struct ural_softc *, @@ -513,16 +514,11 @@ ural_attach(device_t self) ic->ic_vap_create = ural_vap_create; ic->ic_vap_delete = ural_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + RAL_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + RAL_RX_RADIOTAP_PRESENT); if (bootverbose) ieee80211_announce(ic); @@ -551,7 +547,6 @@ ural_detach(device_t self) if (ifp) { ic = ifp->if_l2com; - bpfdetach(ifp); ieee80211_ifdetach(ic); if_free(ifp); } @@ -761,9 +756,12 @@ ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) if (vap->iv_opmode != IEEE80211_M_MONITOR) ural_enable_tsf_sync(sc); + else + ural_enable_tsf(sc); /* enable automatic rate adaptation */ - tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; + /* XXX should use ic_bsschan but not valid until after newstate call below */ + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) ural_amrr_start(sc, ni); @@ -783,8 +781,7 @@ ural_bulk_write_callback(struct usb2_xfer *xfer) { struct ural_softc *sc = xfer->priv_sc; struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211_channel *c = ic->ic_curchan; + struct ieee80211vap *vap; struct ural_tx_data *data; struct mbuf *m; unsigned int len; @@ -819,16 +816,15 @@ ural_bulk_write_callback(struct usb2_xfer *xfer) usb2_m_copy_in(xfer->frbuffers, RAL_TX_DESC_SIZE, m, 0, m->m_pkthdr.len); - if (bpf_peers_present(ifp->if_bpf)) { + vap = data->ni->ni_vap; + if (ieee80211_radiotap_active_vap(vap)) { struct ural_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = data->rate; - tap->wt_chan_freq = htole16(c->ic_freq); - tap->wt_chan_flags = htole16(c->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); + ieee80211_radiotap_tx(vap, m); } /* xfer length needs to be a multiple of two! */ @@ -877,7 +873,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer) struct ieee80211_node *ni; struct mbuf *m = NULL; uint32_t flags; - uint8_t rssi = 0; + int8_t rssi = 0, nf = 0; unsigned int len; switch (USB_GET_STATE(xfer)) { @@ -899,6 +895,7 @@ ural_bulk_read_callback(struct usb2_xfer *xfer) RAL_RX_DESC_SIZE); rssi = URAL_RSSI(sc->sc_rx_desc.rssi); + nf = RAL_NOISE_FLOOR; flags = le32toh(sc->sc_rx_desc.flags); if (flags & (RAL_RX_PHY_ERROR | RAL_RX_CRC_ERROR)) { /* @@ -923,19 +920,17 @@ ural_bulk_read_callback(struct usb2_xfer *xfer) m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (flags >> 16) & 0xfff; - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct ural_rx_radiotap_header *tap = &sc->sc_rxtap; - tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; + /* XXX set once */ + tap->wr_flags = 0; tap->wr_rate = ieee80211_plcp2rate(sc->sc_rx_desc.rate, (flags & RAL_RX_OFDM) ? IEEE80211_T_OFDM : IEEE80211_T_CCK); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antenna = sc->rx_ant; - tap->wr_antsignal = rssi; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); + tap->wr_antsignal = nf + rssi; + tap->wr_antnoise = nf; } /* Strip trailing 802.11 MAC FCS. */ m_adj(m, -IEEE80211_CRC_LEN); @@ -956,12 +951,10 @@ ural_bulk_read_callback(struct usb2_xfer *xfer) ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, - RAL_NOISE_FLOOR, 0); + (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, - RAL_NOISE_FLOOR, 0); + (void) ieee80211_input_all(ic, m, rssi, nf); RAL_LOCK(sc); } return; @@ -1799,6 +1792,14 @@ ural_enable_tsf_sync(struct ural_softc *sc) DPRINTF("enabling TSF synchronization\n"); } +static void +ural_enable_tsf(struct ural_softc *sc) +{ + /* first, disable TSF synchronization */ + ural_write(sc, RAL_TXRX_CSR19, 0); + ural_write(sc, RAL_TXRX_CSR19, RAL_ENABLE_TSF | RAL_ENABLE_TSF_SYNC(2)); +} + #define RAL_RXTX_TURNAROUND 5 /* us */ static void ural_update_slot(struct ifnet *ifp) diff --git a/sys/dev/usb/wlan/if_uralvar.h b/sys/dev/usb/wlan/if_uralvar.h index 5149f6b10d9a..663e0c178d6a 100644 --- a/sys/dev/usb/wlan/if_uralvar.h +++ b/sys/dev/usb/wlan/if_uralvar.h @@ -31,8 +31,9 @@ struct ural_rx_radiotap_header { uint8_t wr_rate; uint16_t wr_chan_freq; uint16_t wr_chan_flags; + int8_t wr_antsignal; + int8_t wr_antnoise; uint8_t wr_antenna; - uint8_t wr_antsignal; }; #define RAL_RX_RADIOTAP_PRESENT \ @@ -40,7 +41,8 @@ struct ural_rx_radiotap_header { (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_ANTENNA) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL)) + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE)) struct ural_tx_radiotap_header { struct ieee80211_radiotap_header wt_ihdr; diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index c386ea87fb29..ecf1e88c5848 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -421,14 +421,11 @@ zyd_attach(device_t dev) ic->ic_update_mcast = zyd_update_mcast; ic->ic_update_promisc = zyd_update_mcast; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof(sc->sc_rxtap); - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(ZYD_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof(sc->sc_txtap); - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(ZYD_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + ZYD_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + ZYD_RX_RADIOTAP_PRESENT); if (bootverbose) ieee80211_announce(ic); @@ -455,7 +452,6 @@ zyd_detach(device_t dev) if (ifp) { ic = ifp->if_l2com; - bpfdetach(ifp); ieee80211_ifdetach(ic); if_free(ifp); } @@ -2132,6 +2128,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len) { struct zyd_softc *sc = xfer->priv_sc; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct zyd_plcphdr plcp; struct zyd_rx_stat stat; struct mbuf *m; @@ -2180,7 +2177,7 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len) usb2_copy_out(xfer->frbuffers, offset + sizeof(plcp), mtod(m, uint8_t *), rlen); - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -2194,8 +2191,6 @@ zyd_rx_data(struct usb2_xfer *xfer, int offset, uint16_t len) IEEE80211_T_OFDM : IEEE80211_T_CCK); tap->wr_antsignal = stat.rssi + -95; tap->wr_antnoise = -95; /* XXX */ - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } rssi = (stat.rssi > 63) ? 127 : 2 * stat.rssi; @@ -2272,10 +2267,10 @@ zyd_bulk_read_callback(struct usb2_xfer *xfer) ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void)ieee80211_input(ni, m, rssi, nf, 0); + (void)ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void)ieee80211_input_all(ic, m, rssi, nf, 0); + (void)ieee80211_input_all(ic, m, rssi, nf); } ZYD_LOCK(sc); break; @@ -2331,7 +2326,6 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = sc->sc_ifp; struct zyd_tx_desc *desc; struct zyd_tx_data *data; struct ieee80211_frame *wh; @@ -2409,13 +2403,13 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->plcp_service |= ZYD_PLCP_LENGEXT; } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } DPRINTF(sc, ZYD_DEBUG_XMIT, @@ -2434,8 +2428,7 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer) { struct zyd_softc *sc = xfer->priv_sc; struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = ifp->if_l2com; - struct ieee80211_channel *c = ic->ic_curchan; + struct ieee80211vap *vap; struct zyd_tx_data *data; struct mbuf *m; @@ -2470,15 +2463,14 @@ zyd_bulk_write_callback(struct usb2_xfer *xfer) usb2_m_copy_in(xfer->frbuffers, ZYD_TX_DESC_SIZE, m, 0, m->m_pkthdr.len); - if (bpf_peers_present(ifp->if_bpf)) { + vap = data->ni->ni_vap; + if (ieee80211_radiotap_active_vap(vap)) { struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = data->rate; - tap->wt_chan_freq = htole16(c->ic_freq); - tap->wt_chan_flags = htole16(c->ic_flags); - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m); + ieee80211_radiotap_tx(vap, m); } xfer->frlengths[0] = ZYD_TX_DESC_SIZE + m->m_pkthdr.len; diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 3dc329b7088e..5cdec5f8506e 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -121,9 +121,10 @@ static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int); -static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, int); +static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, + int); static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, - int subtype, int rssi, int noise, u_int32_t rstamp); + int subtype, int rssi, int nf); static int wi_reset(struct wi_softc *); static void wi_watchdog(void *); static int wi_ioctl(struct ifnet *, u_long, caddr_t); @@ -139,6 +140,7 @@ static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *); static int wi_write_wep(struct wi_softc *, struct ieee80211vap *); static int wi_write_multi(struct wi_softc *); static void wi_update_mcast(struct ifnet *); +static void wi_update_promisc(struct ifnet *); static int wi_alloc_fid(struct wi_softc *, int, int *); static void wi_read_nicid(struct wi_softc *); static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); @@ -455,25 +457,13 @@ wi_attach(device_t dev) ic->ic_vap_create = wi_vap_create; ic->ic_vap_delete = wi_vap_delete; ic->ic_update_mcast = wi_update_mcast; + ic->ic_update_promisc = wi_update_promisc; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); - /* - * Initialize constant fields. - * XXX make header lengths a multiple of 32-bits so subsequent - * headers are properly aligned; this is a kludge to keep - * certain applications happy. - * - * NB: the channel is setup each time we transition to the - * RUN state to avoid filling it in for each frame. - */ - sc->sc_tx_th_len = roundup(sizeof(sc->sc_tx_th), sizeof(u_int32_t)); - sc->sc_tx_th.wt_ihdr.it_len = htole16(sc->sc_tx_th_len); - sc->sc_tx_th.wt_ihdr.it_present = htole32(WI_TX_RADIOTAP_PRESENT); - - sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t)); - sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); - sc->sc_rx_th.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_tx_th.wt_ihdr, sizeof(sc->sc_tx_th), + WI_TX_RADIOTAP_PRESENT, + &sc->sc_rx_th.wr_ihdr, sizeof(sc->sc_rx_th), + WI_RX_RADIOTAP_PRESENT); if (bootverbose) ieee80211_announce(ic); @@ -482,7 +472,6 @@ wi_attach(device_t dev) NULL, wi_intr, sc, &sc->wi_intrhand); if (error) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); - bpfdetach(ifp); ieee80211_ifdetach(ic); if_free(sc->sc_ifp); wi_free(dev); @@ -506,7 +495,6 @@ wi_detach(device_t dev) wi_stop_locked(sc, 0); WI_UNLOCK(sc); - bpfdetach(ifp); ieee80211_ifdetach(ic); bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); @@ -761,11 +749,6 @@ wi_set_channel(struct ieee80211com *ic) WI_LOCK(sc); wi_write_val(sc, WI_RID_OWN_CHNL, ieee80211_chan2ieee(ic, ic->ic_curchan)); - - sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = - htole16(ic->ic_curchan->ic_freq); - sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = - htole16(ic->ic_curchan->ic_flags); WI_UNLOCK(sc); } @@ -812,7 +795,7 @@ wi_scan_end(struct ieee80211com *ic) static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, - int subtype, int rssi, int noise, u_int32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; @@ -823,7 +806,7 @@ wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, /* NB: filter frames that trigger state changes */ return; } - WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, nf); } static int @@ -1025,10 +1008,9 @@ wi_start_locked(struct ifnet *ifp) frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(ni->ni_vap)) { sc->sc_tx_th.wt_rate = ni->ni_txrate; - bpf_mtap2(ifp->if_bpf, - &sc->sc_tx_th, sc->sc_tx_th_len, m0); + ieee80211_radiotap_tx(ni->ni_vap, m0); } m_copydata(m0, 0, sizeof(struct ieee80211_frame), @@ -1088,6 +1070,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, { struct ieee80211com *ic = ni->ni_ic; struct ifnet *ifp = ic->ic_ifp; + struct ieee80211vap *vap = ni->ni_vap; struct wi_softc *sc = ifp->if_softc; struct ieee80211_key *k; struct ieee80211_frame *wh; @@ -1127,9 +1110,9 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, } frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); } - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { sc->sc_tx_th.wt_rate = ni->ni_txrate; - bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); + ieee80211_radiotap_tx(vap, m0); } m_copydata(m0, 0, sizeof(struct ieee80211_frame), (caddr_t)&frmhdr.wi_whdr); @@ -1328,10 +1311,10 @@ wi_rx_intr(struct wi_softc *sc) struct mbuf *m; struct ieee80211_frame *wh; struct ieee80211_node *ni; - int fid, len, off, rssi; + int fid, len, off; u_int8_t dir; u_int16_t status; - u_int32_t rstamp; + int8_t rssi, nf; fid = CSR_READ_2(sc, WI_RX_FID); @@ -1353,9 +1336,6 @@ wi_rx_intr(struct wi_softc *sc) DPRINTF(("wi_rx_intr: fid %x error status %x\n", fid, status)); return; } - rssi = frmhdr.wi_rx_signal; - rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) | - le16toh(frmhdr.wi_rx_tstamp1); len = le16toh(frmhdr.wi_dat_len); off = ALIGN(sizeof(struct ieee80211_frame)); @@ -1393,17 +1373,24 @@ wi_rx_intr(struct wi_softc *sc) CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - if (bpf_peers_present(ifp->if_bpf)) { + rssi = frmhdr.wi_rx_signal; + nf = frmhdr.wi_rx_silence; + if (ieee80211_radiotap_active(ic)) { + struct wi_rx_radiotap_header *tap = &sc->sc_rx_th; + uint32_t rstamp; + + rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) | + le16toh(frmhdr.wi_rx_tstamp1); + tap->wr_tsf = htole64(rstamp); /* XXX replace divide by table */ - sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5; - sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal; - sc->sc_rx_th.wr_antnoise = frmhdr.wi_rx_silence; - sc->sc_rx_th.wr_flags = 0; + tap->wr_rate = frmhdr.wi_rx_rate / 5; + tap->wr_flags = 0; if (frmhdr.wi_status & WI_STAT_PCF) - sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP; + tap->wr_flags |= IEEE80211_RADIOTAP_F_CFP; if (m->m_flags & M_WEP) - sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; - bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); + tap->wr_flags |= IEEE80211_RADIOTAP_F_WEP; + tap->wr_antsignal = rssi; + tap->wr_antnoise = nf; } /* synchronize driver's BSSID with firmware's BSSID */ @@ -1416,10 +1403,10 @@ wi_rx_intr(struct wi_softc *sc) ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, rssi, -95/*XXX*/, rstamp); + (void) ieee80211_input(ni, m, rssi, nf); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, rssi, -95/*XXX*/, rstamp); + (void) ieee80211_input_all(ic, m, rssi, nf); WI_LOCK(sc); } @@ -1614,6 +1601,20 @@ wi_update_mcast(struct ifnet *ifp) wi_write_multi(ifp->if_softc); } +static void +wi_update_promisc(struct ifnet *ifp) +{ + struct wi_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; + + WI_LOCK(sc); + /* XXX handle WEP special case handling? */ + wi_write_val(sc, WI_RID_PROMISC, + (ic->ic_opmode == IEEE80211_M_MONITOR || + (ifp->if_flags & IFF_PROMISC))); + WI_UNLOCK(sc); +} + static void wi_read_nicid(struct wi_softc *sc) { diff --git a/sys/dev/wi/if_wireg.h b/sys/dev/wi/if_wireg.h index 176e4a0056ae..d99e597c042a 100644 --- a/sys/dev/wi/if_wireg.h +++ b/sys/dev/wi/if_wireg.h @@ -691,7 +691,8 @@ struct wi_frame { * Radio capture format for Prism. */ #define WI_RX_RADIOTAP_PRESENT \ - ((1 << IEEE80211_RADIOTAP_FLAGS) | \ + ((1 << IEEE80211_RADIOTAP_TSFT) | \ + (1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ @@ -699,6 +700,7 @@ struct wi_frame { struct wi_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; + u_int64_t wr_tsf; u_int8_t wr_flags; u_int8_t wr_rate; u_int16_t wr_chan_freq; diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index 3739a8e5a463..c5bc1391ad4e 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -60,8 +60,8 @@ struct wi_vap { struct ieee80211vap wv_vap; struct ieee80211_beacon_offsets wv_bo; - void (*wv_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, u_int32_t); + void (*wv_recv_mgmt)(struct ieee80211_node *, struct mbuf *, + int, int, int); int (*wv_newstate)(struct ieee80211vap *, enum ieee80211_state, int); }; @@ -141,9 +141,7 @@ struct wi_softc { u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2]; struct wi_tx_radiotap_header sc_tx_th; - int sc_tx_th_len; struct wi_rx_radiotap_header sc_rx_th; - int sc_rx_th_len; }; /* maximum consecutive false change-of-BSSID indications */ diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 9537dd4e0fa5..4378164ac4fe 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -681,16 +681,11 @@ wpi_attach(device_t dev) ic->ic_vap_create = wpi_vap_create; ic->ic_vap_delete = wpi_vap_delete; - bpfattach(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); - - sc->sc_rxtap_len = sizeof sc->sc_rxtap; - sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); - sc->sc_rxtap.wr_ihdr.it_present = htole32(WPI_RX_RADIOTAP_PRESENT); - - sc->sc_txtap_len = sizeof sc->sc_txtap; - sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); - sc->sc_txtap.wt_ihdr.it_present = htole32(WPI_TX_RADIOTAP_PRESENT); + ieee80211_radiotap_attach(ic, + &sc->sc_txtap.wt_ihdr, sizeof(sc->sc_txtap), + WPI_TX_RADIOTAP_PRESENT, + &sc->sc_rxtap.wr_ihdr, sizeof(sc->sc_rxtap), + WPI_RX_RADIOTAP_PRESENT); /* * Hook our interrupt after all initialization is complete. @@ -728,7 +723,6 @@ wpi_detach(device_t dev) wpi_stop(sc); callout_drain(&sc->watchdog_to); callout_drain(&sc->calib_to); - bpfdetach(ifp); ieee80211_ifdetach(ic); } @@ -1519,7 +1513,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, /* update Rx descriptor */ ring->desc[ring->cur] = htole32(paddr); - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active(ic)) { struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -1551,18 +1545,16 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, } if (le16toh(head->flags) & 0x4) tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; - - bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } WPI_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); if (ni != NULL) { - (void) ieee80211_input(ni, m, stat->rssi, 0, 0); + (void) ieee80211_input(ni, m, stat->rssi, 0); ieee80211_free_node(ni); } else - (void) ieee80211_input_all(ic, m, stat->rssi, 0, 0); + (void) ieee80211_input_all(ic, m, stat->rssi, 0); WPI_LOCK(sc); } @@ -1938,17 +1930,15 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, tx->data_ntries = 15; /* XXX way too high */ #endif - if (bpf_peers_present(ifp->if_bpf)) { + if (ieee80211_radiotap_active_vap(vap)) { struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); - tap->wt_chan_flags = htole16(ni->ni_chan->ic_flags); tap->wt_rate = rate; tap->wt_hwqueue = ac; if (wh->i_fc[1] & IEEE80211_FC1_WEP) tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; - bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); + ieee80211_radiotap_tx(vap, m0); } /* save and trim IEEE802.11 header */ diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h index 36da3b1f0070..811624b37ca7 100644 --- a/sys/dev/wpi/if_wpivar.h +++ b/sys/dev/wpi/if_wpivar.h @@ -182,9 +182,7 @@ struct wpi_softc { struct bpf_if *sc_drvbpf; struct wpi_rx_radiotap_header sc_rxtap; - int sc_rxtap_len; struct wpi_tx_radiotap_header sc_txtap; - int sc_txtap_len; /* firmware image */ const struct firmware *fw_fp; diff --git a/sys/net80211/ieee80211.c b/sys/net80211/ieee80211.c index 2e759652c0f4..22c690cd4a3c 100644 --- a/sys/net80211/ieee80211.c +++ b/sys/net80211/ieee80211.c @@ -465,6 +465,7 @@ ieee80211_vap_setup(struct ieee80211com *ic, struct ieee80211vap *vap, ieee80211_ht_vattach(vap); ieee80211_scan_vattach(vap); ieee80211_regdomain_vattach(vap); + ieee80211_radiotap_vattach(vap); return 0; } @@ -509,10 +510,11 @@ ieee80211_vap_attach(struct ieee80211vap *vap, vap->iv_output = ifp->if_output; ifp->if_output = ieee80211_output; /* NB: if_mtu set by ether_ifattach to ETHERMTU */ - bpfattach2(ifp, DLT_IEEE802_11, ifp->if_hdrlen, &vap->iv_rawbpf); IEEE80211_LOCK(ic); TAILQ_INSERT_TAIL(&ic->ic_vaps, vap, iv_next); + if (vap->iv_opmode == IEEE80211_M_MONITOR) + ic->ic_monvaps++; ieee80211_syncflag_locked(ic, IEEE80211_F_WME); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); @@ -573,6 +575,8 @@ ieee80211_vap_detach(struct ieee80211vap *vap) IEEE80211_LOCK(ic); KASSERT(vap->iv_state == IEEE80211_S_INIT , ("vap still running")); TAILQ_REMOVE(&ic->ic_vaps, vap, iv_next); + if (vap->iv_opmode == IEEE80211_M_MONITOR) + ic->ic_monvaps--; ieee80211_syncflag_locked(ic, IEEE80211_F_WME); #ifdef IEEE80211_SUPPORT_SUPERG ieee80211_syncflag_locked(ic, IEEE80211_F_TURBOP); @@ -581,16 +585,19 @@ ieee80211_vap_detach(struct ieee80211vap *vap) ieee80211_syncflag_locked(ic, IEEE80211_F_BURST); ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_HT); ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_USEHT40); + /* NB: this handles the bpfdetach done below */ + ieee80211_syncflag_ext_locked(ic, IEEE80211_FEXT_BPF); ieee80211_syncifflag_locked(ic, IFF_PROMISC); ieee80211_syncifflag_locked(ic, IFF_ALLMULTI); IEEE80211_UNLOCK(ic); /* XXX can't hold com lock */ - /* NB: bpfattach is called by ether_ifdetach and claims all taps */ + /* NB: bpfdetach is called by ether_ifdetach and claims all taps */ ether_ifdetach(ifp); ifmedia_removeall(&vap->iv_media); + ieee80211_radiotap_vdetach(vap); ieee80211_regdomain_vdetach(vap); ieee80211_scan_vdetach(vap); #ifdef IEEE80211_SUPPORT_SUPERG diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index 3b230e659a4f..8f3780899ff4 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -68,12 +68,11 @@ __FBSDID("$FreeBSD$"); static void adhoc_vattach(struct ieee80211vap *); static int adhoc_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int adhoc_input(struct ieee80211_node *, struct mbuf *, - int rssi, int noise, uint32_t rstamp); +static int adhoc_input(struct ieee80211_node *, struct mbuf *, int, int); static void adhoc_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int, int); static void ahdemo_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int, int); static void adhoc_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); void @@ -284,8 +283,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -adhoc_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -408,8 +406,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, } } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -536,8 +533,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* @@ -640,7 +637,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ goto out; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -659,8 +656,8 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -686,7 +683,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates) static void adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -731,8 +728,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } if (scan.capinfo & IEEE80211_CAPINFO_IBSS) { @@ -756,8 +752,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, } if (ni != NULL) { IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; } } break; @@ -912,7 +907,7 @@ adhoc_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, static void ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -922,7 +917,7 @@ ahdemo_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * a site-survey. */ if (ic->ic_flags & IEEE80211_F_SCAN) - adhoc_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp); + adhoc_recv_mgmt(ni, m0, subtype, rssi, nf); else vap->iv_stats.is_rx_mgtdiscard++; } diff --git a/sys/net80211/ieee80211_ddb.c b/sys/net80211/ieee80211_ddb.c index ea4e89f3213a..85451409a8be 100644 --- a/sys/net80211/ieee80211_ddb.c +++ b/sys/net80211/ieee80211_ddb.c @@ -255,9 +255,9 @@ _db_show_sta(const struct ieee80211_node *ni) db_printf("\trxfrag[0] %p rxfrag[1] %p rxfrag[2] %p\n", ni->ni_rxfrag[0], ni->ni_rxfrag[1], ni->ni_rxfrag[2]); _db_show_key("\tucastkey", 0, &ni->ni_ucastkey); - db_printf("\trstamp %u avgrssi 0x%x (rssi %d) noise %d\n", - ni->ni_rstamp, ni->ni_avgrssi, - IEEE80211_RSSI_GET(ni->ni_avgrssi), ni->ni_noise); + db_printf("\tavgrssi 0x%x (rssi %d) noise %d\n", + ni->ni_avgrssi, IEEE80211_RSSI_GET(ni->ni_avgrssi), + ni->ni_noise); db_printf("\tintval %u capinfo %b\n", ni->ni_intval, ni->ni_capinfo, IEEE80211_CAPINFO_BITS); db_printf("\tbssid %s", ether_sprintf(ni->ni_bssid)); diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index e96e71d3d40b..89292a606fdb 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -726,6 +727,29 @@ ieee80211_load_module(const char *modname) #endif } +static eventhandler_tag wlan_bpfevent; + +static void +bpf_track(void *arg, struct ifnet *ifp, int attach) +{ + /* NB: identify vap's by if_start */ + if (ifp->if_start == ieee80211_start) { + struct ieee80211vap *vap = ifp->if_softc; + /* + * Track bpf radiotap listener state. We mark the vap + * to indicate if any listener is present and the com + * to indicate if any listener exists on any associated + * vap. This flag is used by drivers to prepare radiotap + * state only when needed. + */ + if (attach) + ieee80211_syncflag_ext(vap, IEEE80211_FEXT_BPF); + /* NB: if_softc is NULL on vap detach */ + else if (vap != NULL && !bpf_peers_present(vap->iv_rawbpf)) + ieee80211_syncflag_ext(vap, -IEEE80211_FEXT_BPF); + } +} + /* * Module glue. * @@ -738,12 +762,17 @@ wlan_modevent(module_t mod, int type, void *unused) case MOD_LOAD: if (bootverbose) printf("wlan: <802.11 Link Layer>\n"); + wlan_bpfevent = EVENTHANDLER_REGISTER(bpf_track, + bpf_track, 0, EVENTHANDLER_PRI_ANY); + if (wlan_bpfevent == NULL) + return ENOMEM; if_clone_attach(&wlan_cloner); if_register_com_alloc(IFT_IEEE80211, wlan_alloc, wlan_free); return 0; case MOD_UNLOAD: if_deregister_com_alloc(IFT_IEEE80211); if_clone_detach(&wlan_cloner); + EVENTHANDLER_DEREGISTER(bpf_track, wlan_bpfevent); return 0; } return EINVAL; diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 5bf8baf840fa..9264a71a3970 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -67,11 +67,11 @@ __FBSDID("$FreeBSD$"); static void hostap_vattach(struct ieee80211vap *); static int hostap_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int hostap_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); + int rssi, int nf); static void hostap_deliver_data(struct ieee80211vap *, struct ieee80211_node *, struct mbuf *); static void hostap_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static void hostap_recv_ctl(struct ieee80211_node *, struct mbuf *, int); static void hostap_recv_pspoll(struct ieee80211_node *, struct mbuf *); @@ -418,8 +418,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -hostap_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -515,8 +514,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -699,8 +697,8 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* * Finally, strip the 802.11 header. @@ -834,7 +832,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] &= ~IEEE80211_FC1_WEP; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -852,8 +850,8 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -862,7 +860,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, static void hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status) + int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -940,7 +938,7 @@ hostap_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, static void hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp, + uint8_t *frm, uint8_t *efrm, int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -1042,8 +1040,7 @@ hostap_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, */ ni->ni_flags |= IEEE80211_NODE_ASSOCID; IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (!ieee80211_alloc_challenge(ni)) { /* NB: don't return error so they rexmit */ return; @@ -1624,7 +1621,7 @@ is11bclient(const uint8_t *rates, const uint8_t *xrates) static void hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; @@ -1679,8 +1676,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } /* @@ -1843,11 +1839,10 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } if (algo == IEEE80211_AUTH_ALG_SHARED) - hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, - noise, rstamp, seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - hostap_auth_open(ni, wh, rssi, noise, rstamp, + hostap_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, seq, status); + else if (algo == IEEE80211_AUTH_ALG_OPEN) + hostap_auth_open(ni, wh, rssi, nf, seq, status); else if (algo == IEEE80211_AUTH_ALG_LEAP) { authalgreject(ni, wh, algo, seq+1, IEEE80211_STATUS_ALG); @@ -2063,8 +2058,7 @@ hostap_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; ni->ni_intval = lintval; ni->ni_capinfo = capinfo; ni->ni_fhdwell = vap->iv_bss->ni_fhdwell; diff --git a/sys/net80211/ieee80211_ht.c b/sys/net80211/ieee80211_ht.c index 42c232def3af..198e95d1a860 100644 --- a/sys/net80211/ieee80211_ht.c +++ b/sys/net80211/ieee80211_ht.c @@ -364,8 +364,8 @@ static __inline void ampdu_dispatch(struct ieee80211_node *ni, struct mbuf *m) { m->m_flags |= M_AMPDU_MPDU; /* bypass normal processing */ - /* NB: rssi, noise, and rstamp are ignored w/ M_AMPDU_MPDU set */ - (void) ieee80211_input(ni, m, 0, 0, 0); + /* NB: rssi and noise are ignored w/ M_AMPDU_MPDU set */ + (void) ieee80211_input(ni, m, 0, 0); } /* diff --git a/sys/net80211/ieee80211_input.c b/sys/net80211/ieee80211_input.c index 2134e29da1d9..6e069189196e 100644 --- a/sys/net80211/ieee80211_input.c +++ b/sys/net80211/ieee80211_input.c @@ -55,8 +55,7 @@ __FBSDID("$FreeBSD$"); #endif int -ieee80211_input_all(struct ieee80211com *ic, - struct mbuf *m, int rssi, int noise, u_int32_t rstamp) +ieee80211_input_all(struct ieee80211com *ic, struct mbuf *m, int rssi, int nf) { struct ieee80211vap *vap; int type = -1; @@ -89,7 +88,7 @@ ieee80211_input_all(struct ieee80211com *ic, m = NULL; } ni = ieee80211_ref_node(vap->iv_bss); - type = ieee80211_input(ni, mcopy, rssi, noise, rstamp); + type = ieee80211_input(ni, mcopy, rssi, nf); ieee80211_free_node(ni); } if (m != NULL) /* no vaps, reclaim mbuf */ diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c index b1e98ebc1d72..119c87d0dff8 100644 --- a/sys/net80211/ieee80211_monitor.c +++ b/sys/net80211/ieee80211_monitor.c @@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$"); static void monitor_vattach(struct ieee80211vap *); static int monitor_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int monitor_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); + int rssi, int nf); void ieee80211_monitor_attach(struct ieee80211com *ic) @@ -124,13 +124,11 @@ monitor_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * Process a received frame in monitor mode. */ static int -monitor_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + ieee80211_radiotap_rx(vap, m); m_freem(m); return -1; } diff --git a/sys/net80211/ieee80211_node.c b/sys/net80211/ieee80211_node.c index c23a09258bdb..eb56b8dad55c 100644 --- a/sys/net80211/ieee80211_node.c +++ b/sys/net80211/ieee80211_node.c @@ -631,6 +631,7 @@ ieee80211_sync_curchan(struct ieee80211com *ic) ic->ic_rt = ieee80211_get_ratetable(ic->ic_curchan); IEEE80211_UNLOCK(ic); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); IEEE80211_LOCK(ic); } } @@ -754,7 +755,6 @@ ieee80211_sta_join(struct ieee80211vap *vap, struct ieee80211_channel *chan, IEEE80211_ADDR_COPY(ni->ni_bssid, se->se_bssid); ni->ni_esslen = se->se_ssid[1]; memcpy(ni->ni_essid, se->se_ssid+2, ni->ni_esslen); - ni->ni_rstamp = se->se_rstamp; ni->ni_tstamp.tsf = se->se_tstamp.tsf; ni->ni_intval = se->se_intval; ni->ni_capinfo = se->se_capinfo; @@ -2125,8 +2125,8 @@ ieee80211_dump_node(struct ieee80211_node_table *nt, struct ieee80211_node *ni) ni->ni_rxseqs[IEEE80211_NONQOS_TID] >> IEEE80211_SEQ_SEQ_SHIFT, ni->ni_rxseqs[IEEE80211_NONQOS_TID] & IEEE80211_SEQ_FRAG_MASK, ni->ni_rxfragstamp); - printf("\trstamp %u rssi %d noise %d intval %u capinfo 0x%x\n", - ni->ni_rstamp, node_getrssi(ni), ni->ni_noise, + printf("\trssi %d noise %d intval %u capinfo 0x%x\n", + node_getrssi(ni), ni->ni_noise, ni->ni_intval, ni->ni_capinfo); printf("\tbssid %s essid \"%.*s\" channel %u:0x%x\n", ether_sprintf(ni->ni_bssid), diff --git a/sys/net80211/ieee80211_node.h b/sys/net80211/ieee80211_node.h index 8f19ce736c9a..a118de5aed97 100644 --- a/sys/net80211/ieee80211_node.h +++ b/sys/net80211/ieee80211_node.h @@ -145,7 +145,6 @@ struct ieee80211_node { struct ieee80211_key ni_ucastkey; /* unicast key */ /* hardware */ - uint32_t ni_rstamp; /* recv timestamp */ uint32_t ni_avgrssi; /* recv ssi state */ int8_t ni_noise; /* noise floor */ diff --git a/sys/net80211/ieee80211_output.c b/sys/net80211/ieee80211_output.c index 6ee8f525dbd5..a46b228af5fc 100644 --- a/sys/net80211/ieee80211_output.c +++ b/sys/net80211/ieee80211_output.c @@ -307,10 +307,6 @@ ieee80211_start(struct ifnet *ifp) } } - /* XXX fragmented frames not handled */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - error = parent->if_transmit(parent, m); if (error != 0) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -420,9 +416,6 @@ ieee80211_output(struct ifnet *ifp, struct mbuf *m, if (ieee80211_classify(ni, m)) senderr(EIO); /* XXX */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - IEEE80211_NODE_STAT(ni, tx_data); if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { IEEE80211_NODE_STAT(ni, tx_mcast); diff --git a/sys/net80211/ieee80211_proto.c b/sys/net80211/ieee80211_proto.c index 467a3623dd18..99b995c83943 100644 --- a/sys/net80211/ieee80211_proto.c +++ b/sys/net80211/ieee80211_proto.c @@ -1107,6 +1107,7 @@ update_channel(void *arg, int npending) struct ieee80211com *ic = arg; ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); } /* diff --git a/sys/net80211/ieee80211_proto.h b/sys/net80211/ieee80211_proto.h index 3712c1eaf808..6a558092f291 100644 --- a/sys/net80211/ieee80211_proto.h +++ b/sys/net80211/ieee80211_proto.h @@ -60,10 +60,9 @@ void ieee80211_syncifflag_locked(struct ieee80211com *, int flag); void ieee80211_syncflag(struct ieee80211vap *, int flag); void ieee80211_syncflag_ext(struct ieee80211vap *, int flag); -#define ieee80211_input(ni, m, rssi, noise, rstamp) \ - ((ni)->ni_vap->iv_input(ni, m, rssi, noise, rstamp)) -int ieee80211_input_all(struct ieee80211com *, struct mbuf *, - int, int, uint32_t); +#define ieee80211_input(ni, m, rssi, nf) \ + ((ni)->ni_vap->iv_input(ni, m, rssi, nf)) +int ieee80211_input_all(struct ieee80211com *, struct mbuf *, int, int); struct ieee80211_bpf_params; int ieee80211_mgmt_output(struct ieee80211_node *, struct mbuf *, int, struct ieee80211_bpf_params *); diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c new file mode 100644 index 000000000000..2c4482f716e7 --- /dev/null +++ b/sys/net80211/ieee80211_radiotap.c @@ -0,0 +1,325 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +/* + * IEEE 802.11 radiotap support. + */ +#include "opt_wlan.h" + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include + +static int radiotap_offset(struct ieee80211_radiotap_header *, int); + +void +ieee80211_radiotap_attach(struct ieee80211com *ic, + struct ieee80211_radiotap_header *th, int tlen, uint32_t tx_radiotap, + struct ieee80211_radiotap_header *rh, int rlen, uint32_t rx_radiotap) +{ +#define B(_v) (1<<(_v)) + int off; + + th->it_len = htole16(roundup2(tlen, sizeof(uint32_t))); + th->it_present = htole32(tx_radiotap); + ic->ic_th = th; + /* calculate offset to channel data */ + off = -1; + if (tx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) + off = radiotap_offset(th, IEEE80211_RADIOTAP_CHANNEL); + else if (tx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) + off = radiotap_offset(th, IEEE80211_RADIOTAP_XCHANNEL); + if (off == -1) { + if_printf(ic->ic_ifp, "%s: no tx channel, radiotap 0x%x", + __func__, tx_radiotap); + /* NB: we handle this case but data will have no chan spec */ + } else + ic->ic_txchan = ((uint8_t *) th) + off; + + rh->it_len = htole16(roundup2(rlen, sizeof(uint32_t))); + rh->it_present = htole32(rx_radiotap); + ic->ic_rh = rh; + /* calculate offset to channel data */ + off = -1; + if (rx_radiotap & B(IEEE80211_RADIOTAP_CHANNEL)) + off = radiotap_offset(rh, IEEE80211_RADIOTAP_CHANNEL); + else if (rx_radiotap & B(IEEE80211_RADIOTAP_XCHANNEL)) + off = radiotap_offset(rh, IEEE80211_RADIOTAP_XCHANNEL); + if (off == -1) { + if_printf(ic->ic_ifp, "%s: no rx channel, radiotap 0x%x", + __func__, rx_radiotap); + /* NB: we handle this case but data will have no chan spec */ + } else + ic->ic_rxchan = ((uint8_t *) rh) + off; +#undef B +} + +void +ieee80211_radiotap_detach(struct ieee80211com *ic) +{ +} + +void +ieee80211_radiotap_vattach(struct ieee80211vap *vap) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_radiotap_header *th = ic->ic_th; + + KASSERT(th != NULL, ("no radiotap setup")); + + /* radiotap DLT for raw 802.11 frames */ + bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + le16toh(th->it_len), + &vap->iv_rawbpf); +} + +void +ieee80211_radiotap_vdetach(struct ieee80211vap *vap) +{ + /* NB: bpfattach is called by ether_ifdetach and claims all taps */ +} + +static void +set_channel(void *p, const struct ieee80211_channel *c) +{ + struct { + uint16_t freq; + uint16_t flags; + } *rc = p; + + rc->freq = htole16(c->ic_freq); + rc->flags = htole16(c->ic_flags); +} + +static void +set_xchannel(void *p, const struct ieee80211_channel *c) +{ + struct { + uint32_t flags; + uint16_t freq; + uint8_t ieee; + uint8_t maxpow; + } *rc = p; + + rc->flags = htole32(c->ic_flags); + rc->freq = htole16(c->ic_freq); + rc->ieee = c->ic_ieee; + rc->maxpow = c->ic_maxregpower; +} + +/* + * Update radiotap state on channel change. + */ +void +ieee80211_radiotap_chan_change(struct ieee80211com *ic) +{ + if (ic->ic_rxchan != NULL) { + struct ieee80211_radiotap_header *rh = ic->ic_rh; + + if (rh->it_present & (1<ic_rxchan, ic->ic_curchan); + else if (rh->it_present & (1<ic_rxchan, ic->ic_curchan); + } + if (ic->ic_txchan != NULL) { + struct ieee80211_radiotap_header *th = ic->ic_th; + + if (th->it_present & (1<ic_txchan, ic->ic_curchan); + else if (th->it_present & (1<ic_txchan, ic->ic_curchan); + } +} + +static void +dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m, + struct ieee80211_radiotap_header *rh) +{ + struct ieee80211com *ic = vap0->iv_ic; + int len = le16toh(rh->it_len); + + if (ieee80211_radiotap_active_vap(vap0)) + bpf_mtap2(vap0->iv_rawbpf, rh, len, m); + if (ic->ic_monvaps) { + struct ieee80211vap *vap; + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + if (vap->iv_opmode == IEEE80211_M_MONITOR && + vap != vap0 && ieee80211_radiotap_active_vap(vap)) + bpf_mtap2(vap->iv_rawbpf, rh, len, m); + } + } +} + +/* + * Dispatch radiotap data for transmitted packet. + */ +void +ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m) +{ + dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th); +} + +/* + * Dispatch radiotap data for received packet. + */ +void +ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m) +{ + dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh); +} + +/* + * Dispatch radiotap data for a packet received outside the normal + * rx processing path; this is used, for example, to handle frames + * received with errors that would otherwise be dropped. + */ +void +ieee80211_radiotap_rx_all(struct ieee80211com *ic, struct mbuf *m) +{ + struct ieee80211_radiotap_header *rh = ic->ic_rh; + int len = le16toh(rh->it_len); + struct ieee80211vap *vap; + + /* XXX locking? */ + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + if (ieee80211_radiotap_active_vap(vap)) + bpf_mtap2(vap->iv_rawbpf, rh, len, m); + } +} + +/* + * Return the offset of the specified item in the radiotap + * header description. If the item is not present or is not + * known -1 is returned. + */ +static int +radiotap_offset(struct ieee80211_radiotap_header *rh, int item) +{ + static const struct { + size_t align, width; + } items[] = { + [IEEE80211_RADIOTAP_TSFT] = { + .align = sizeof(uint64_t), + .width = sizeof(uint64_t), + }, + [IEEE80211_RADIOTAP_FLAGS] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_RATE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_CHANNEL] = { + .align = sizeof(uint16_t), + .width = 2*sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_FHSS] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DBM_ANTSIGNAL] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DBM_ANTNOISE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_LOCK_QUALITY] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_TX_ATTENUATION] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DB_TX_ATTENUATION] = { + .align = sizeof(uint16_t), + .width = sizeof(uint16_t), + }, + [IEEE80211_RADIOTAP_DBM_TX_POWER] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_ANTENNA] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DB_ANTSIGNAL] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_DB_ANTNOISE] = { + .align = sizeof(uint8_t), + .width = sizeof(uint8_t), + }, + [IEEE80211_RADIOTAP_XCHANNEL] = { + .align = sizeof(uint32_t), + .width = 2*sizeof(uint32_t), + }, + }; + uint32_t present = le32toh(rh->it_present); + int off, i; + + off = sizeof(struct ieee80211_radiotap_header); + for (i = 0; i < IEEE80211_RADIOTAP_EXT; i++) { + if ((present & (1< le16toh(rh->it_len)) { + /* NB: item does not fit in header data */ + printf("%s: item %d not in header data, " + "off %d width %zu len %d\n", __func__, i, + off, items[i].width, le16toh(rh->it_len)); + return -1; + } + return off; + } + off += items[i].width; + } + return -1; +} diff --git a/sys/net80211/ieee80211_scan.c b/sys/net80211/ieee80211_scan.c index c1f4a135fc8f..b41ed59a2131 100644 --- a/sys/net80211/ieee80211_scan.c +++ b/sys/net80211/ieee80211_scan.c @@ -920,6 +920,7 @@ scan_task(void *arg, int pending) * completed the channel change. */ ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); /* * Scan curchan. Drivers for "intelligent hardware" @@ -966,6 +967,7 @@ scan_task(void *arg, int pending) ieee80211_setupcurchan(ic, ic->ic_bsschan); IEEE80211_UNLOCK(ic); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); IEEE80211_LOCK(ic); } /* clear internal flags and any indication of a pick */ @@ -1095,7 +1097,7 @@ void ieee80211_add_scan(struct ieee80211vap *vap, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, - int subtype, int rssi, int noise, int rstamp) + int subtype, int rssi, int noise) { struct ieee80211com *ic = vap->iv_ic; struct ieee80211_scan_state *ss = ic->ic_scan; @@ -1115,7 +1117,7 @@ ieee80211_add_scan(struct ieee80211vap *vap, dump_probe_beacon(subtype, 1, wh->i_addr2, sp, rssi); #endif if (ss->ss_ops != NULL && - ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise, rstamp)) { + ss->ss_ops->scan_add(ss, sp, wh, subtype, rssi, noise)) { /* * If we've reached the min dwell time terminate * the timer so we'll switch to the next channel. diff --git a/sys/net80211/ieee80211_scan.h b/sys/net80211/ieee80211_scan.h index edba660ef029..84a57ff015d4 100644 --- a/sys/net80211/ieee80211_scan.h +++ b/sys/net80211/ieee80211_scan.h @@ -150,7 +150,7 @@ struct ieee80211_scanparams; void ieee80211_add_scan(struct ieee80211vap *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, - int subtype, int rssi, int noise, int rstamp); + int subtype, int rssi, int noise); void ieee80211_scan_timeout(struct ieee80211com *); void ieee80211_scan_assoc_success(struct ieee80211vap *, @@ -224,7 +224,6 @@ struct ieee80211_scan_entry { uint8_t se_ssid[2+IEEE80211_NWID_LEN]; uint8_t se_rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t se_xrates[2+IEEE80211_RATE_MAXSIZE]; - uint32_t se_rstamp; /* recv timestamp */ union { uint8_t data[8]; u_int64_t tsf; @@ -269,7 +268,7 @@ struct ieee80211_scanner { int (*scan_add)(struct ieee80211_scan_state *, const struct ieee80211_scanparams *, const struct ieee80211_frame *, - int subtype, int rssi, int noise, int rstamp); + int subtype, int rssi, int noise); /* age and/or purge entries in the cache */ void (*scan_age)(struct ieee80211_scan_state *); /* note that association failed for an entry */ diff --git a/sys/net80211/ieee80211_scan_sta.c b/sys/net80211/ieee80211_scan_sta.c index cef3db447fff..62ef39ed6959 100644 --- a/sys/net80211/ieee80211_scan_sta.c +++ b/sys/net80211/ieee80211_scan_sta.c @@ -219,7 +219,7 @@ static int sta_add(struct ieee80211_scan_state *ss, const struct ieee80211_scanparams *sp, const struct ieee80211_frame *wh, - int subtype, int rssi, int noise, int rstamp) + int subtype, int rssi, int noise) { #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) #define PICK1ST(_ss) \ @@ -278,7 +278,6 @@ sta_add(struct ieee80211_scan_state *ss, ise->se_rssi = IEEE80211_RSSI_GET(se->se_avgrssi); ise->se_noise = noise; } - ise->se_rstamp = rstamp; memcpy(ise->se_tstamp.data, sp->tstamp, sizeof(ise->se_tstamp)); ise->se_intval = sp->bintval; ise->se_capinfo = sp->capinfo; diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 33f6c27e93b1..9a529172ef04 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -66,10 +66,9 @@ __FBSDID("$FreeBSD$"); static void sta_vattach(struct ieee80211vap *); static void sta_beacon_miss(struct ieee80211vap *); static int sta_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int sta_input(struct ieee80211_node *, struct mbuf *, - int rssi, int noise, uint32_t rstamp); +static int sta_input(struct ieee80211_node *, struct mbuf *, int, int); static void sta_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static void sta_recv_ctl(struct ieee80211_node *, struct mbuf *, int subtype); void @@ -490,8 +489,7 @@ doprint(struct ieee80211vap *vap, int subtype) * by the 802.11 layer. */ static int -sta_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -566,8 +564,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -743,8 +740,8 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_tx(vap, m); need_tap = 0; /* @@ -869,7 +866,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, wh = mtod(m, struct ieee80211_frame *); wh->i_fc[1] &= ~IEEE80211_FC1_WEP; } - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); goto out; case IEEE80211_FC0_TYPE_CTL: @@ -888,8 +885,8 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap && bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -898,7 +895,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, static void sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, - int rssi, int noise, uint32_t rstamp, uint16_t seq, uint16_t status) + int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -927,7 +924,7 @@ sta_auth_open(struct ieee80211_node *ni, struct ieee80211_frame *wh, static void sta_auth_shared(struct ieee80211_node *ni, struct ieee80211_frame *wh, - uint8_t *frm, uint8_t *efrm, int rssi, int noise, uint32_t rstamp, + uint8_t *frm, uint8_t *efrm, int rssi, int nf, uint16_t seq, uint16_t status) { struct ieee80211vap *vap = ni->ni_vap; @@ -1128,7 +1125,7 @@ startbgscan(struct ieee80211vap *vap) static void sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { #define ISPROBE(_st) ((_st) == IEEE80211_FC0_SUBTYPE_PROBE_RESP) #define ISREASSOC(_st) ((_st) == IEEE80211_FC0_SUBTYPE_REASSOC_RESP) @@ -1264,7 +1261,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, */ if (ic->ic_flags & IEEE80211_F_SCAN) { ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + subtype, rssi, nf); } else if (contbgscan(vap)) { ieee80211_bg_scan(vap, 0); } else if (startbgscan(vap)) { @@ -1293,8 +1290,7 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, ieee80211_probe_curchan(vap, 1); ic->ic_flags_ext &= ~IEEE80211_FEXT_PROBECHAN; } - ieee80211_add_scan(vap, &scan, wh, - subtype, rssi, noise, rstamp); + ieee80211_add_scan(vap, &scan, wh, subtype, rssi, nf); return; } break; @@ -1329,11 +1325,10 @@ sta_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, return; } if (algo == IEEE80211_AUTH_ALG_SHARED) - sta_auth_shared(ni, wh, frm + 6, efrm, rssi, - noise, rstamp, seq, status); - else if (algo == IEEE80211_AUTH_ALG_OPEN) - sta_auth_open(ni, wh, rssi, noise, rstamp, + sta_auth_shared(ni, wh, frm + 6, efrm, rssi, nf, seq, status); + else if (algo == IEEE80211_AUTH_ALG_OPEN) + sta_auth_open(ni, wh, rssi, nf, seq, status); else { IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "auth", "unsupported alg %d", algo); diff --git a/sys/net80211/ieee80211_superg.c b/sys/net80211/ieee80211_superg.c index de5df0923fac..d75917b89e3f 100644 --- a/sys/net80211/ieee80211_superg.c +++ b/sys/net80211/ieee80211_superg.c @@ -503,9 +503,6 @@ ff_transmit(struct ieee80211_node *ni, struct mbuf *m) struct ifnet *ifp = vap->iv_ifp; struct ifnet *parent = ni->ni_ic->ic_ifp; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - error = parent->if_transmit(parent, m); if (error != 0) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -835,6 +832,7 @@ ieee80211_dturbo_switch(struct ieee80211vap *vap, int newflags) ic->ic_curchan = chan; ic->ic_rt = ieee80211_get_ratetable(chan); ic->ic_set_channel(ic); + ieee80211_radiotap_chan_change(ic); /* NB: do not need to reset ERP state 'cuz we're in sta mode */ } diff --git a/sys/net80211/ieee80211_tdma.c b/sys/net80211/ieee80211_tdma.c index f9dd31760773..8747b4e9cd18 100644 --- a/sys/net80211/ieee80211_tdma.c +++ b/sys/net80211/ieee80211_tdma.c @@ -108,12 +108,12 @@ static void tdma_vdetach(struct ieee80211vap *vap); static int tdma_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void tdma_beacon_miss(struct ieee80211vap *vap); static void tdma_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, uint32_t rstamp); + int subtype, int rssi, int nf); static int tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma, struct ieee80211_node *ni, int pickslot); static int tdma_process_params(struct ieee80211_node *ni, - const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh); + const u_int8_t *ie, int rssi, int nf, const struct ieee80211_frame *wh); static void settxparms(struct ieee80211vap *vap, enum ieee80211_phymode mode, int rate) @@ -304,7 +304,7 @@ tdma_beacon_miss(struct ieee80211vap *vap) static void tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, uint32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211com *ic = ni->ni_ic; struct ieee80211vap *vap = ni->ni_vap; @@ -367,7 +367,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * Process tdma ie. The contents are used to sync * the slot timing, reconfigure the bss, etc. */ - (void) tdma_process_params(ni, scan.tdma, rstamp, wh); + (void) tdma_process_params(ni, scan.tdma, rssi, nf, wh); return; } /* @@ -375,7 +375,7 @@ tdma_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, * 2x parsing of the frame but should happen infrequently */ } - ts->tdma_recv_mgmt(ni, m0, subtype, rssi, noise, rstamp); + ts->tdma_recv_mgmt(ni, m0, subtype, rssi, nf); } /* @@ -497,8 +497,8 @@ tdma_update(struct ieee80211vap *vap, const struct ieee80211_tdma_param *tdma, * Process received TDMA parameters. */ static int -tdma_process_params(struct ieee80211_node *ni, - const u_int8_t *ie, u_int32_t rstamp, const struct ieee80211_frame *wh) +tdma_process_params(struct ieee80211_node *ni, const u_int8_t *ie, + int rssi, int nf, const struct ieee80211_frame *wh) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211_tdma_state *ts = vap->iv_tdma; @@ -563,12 +563,16 @@ tdma_process_params(struct ieee80211_node *ni, /* XXX reschedule swbmiss timer on parameter change */ } else if (tdma->tdma_slot == ts->tdma_slot+1) { uint64_t tstamp; +#if 0 + uint32_t rstamp = (uint32_t) le64toh(rs->tsf); int32_t rtt; +#endif /* * Use returned timstamp to calculate the * roundtrip time. */ memcpy(&tstamp, tdma->tdma_tstamp, 8); +#if 0 /* XXX use only 15 bits of rstamp */ rtt = rstamp - (le64toh(tstamp) & 0x7fff); if (rtt < 0) @@ -578,6 +582,7 @@ tdma_process_params(struct ieee80211_node *ni, "tdma rtt %5u [rstamp %5u tstamp %llu]\n", rtt, rstamp, (unsigned long long) le64toh(tstamp)); +#endif } else if (tdma->tdma_slot == ts->tdma_slot && le64toh(ni->ni_tstamp.tsf) > vap->iv_bss->ni_tstamp.tsf) { /* diff --git a/sys/net80211/ieee80211_tdma.h b/sys/net80211/ieee80211_tdma.h index 41ca09ec57fb..2fe591f73e3e 100644 --- a/sys/net80211/ieee80211_tdma.h +++ b/sys/net80211/ieee80211_tdma.h @@ -81,7 +81,7 @@ struct ieee80211_tdma_state { int (*tdma_newstate)(struct ieee80211vap *, enum ieee80211_state, int arg); void (*tdma_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, uint32_t); + struct mbuf *, int, int, int); void (*tdma_opdetach)(struct ieee80211vap *); }; diff --git a/sys/net80211/ieee80211_var.h b/sys/net80211/ieee80211_var.h index 09b63d251eaa..27095f4a8a1a 100644 --- a/sys/net80211/ieee80211_var.h +++ b/sys/net80211/ieee80211_var.h @@ -51,6 +51,7 @@ #include #include #include +#include #include #define IEEE80211_TXPOWER_MAX 100 /* .5 dbM (XXX units?) */ @@ -209,6 +210,13 @@ struct ieee80211com { /* optional state for Atheros SuperG protocol extensions */ struct ieee80211_superg *ic_superg; + /* radiotap handling */ + struct ieee80211_radiotap_header *ic_th;/* tx radiotap headers */ + void *ic_txchan; /* channel state in ic_th */ + struct ieee80211_radiotap_header *ic_rh;/* rx radiotap headers */ + void *ic_rxchan; /* channel state in ic_rh */ + int ic_monvaps; /* # monitor mode vaps */ + /* virtual ap create/delete */ struct ieee80211vap* (*ic_vap_create)(struct ieee80211com *, const char name[IFNAMSIZ], int unit, @@ -421,10 +429,9 @@ struct ieee80211vap { void (*iv_opdetach)(struct ieee80211vap *); /* receive processing */ int (*iv_input)(struct ieee80211_node *, - struct mbuf *, int rssi, int noise, - uint32_t rstamp); + struct mbuf *, int, int); void (*iv_recv_mgmt)(struct ieee80211_node *, - struct mbuf *, int, int, int, uint32_t); + struct mbuf *, int, int, int); void (*iv_recv_ctl)(struct ieee80211_node *, struct mbuf *, int); void (*iv_deliver_data)(struct ieee80211vap *, @@ -522,6 +529,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_FEXT_DOTD 0x00001000 /* CONF: 11d enabled */ #define IEEE80211_FEXT_STATEWAIT 0x00002000 /* STATUS: awaiting state chg */ #define IEEE80211_FEXT_REINIT 0x00004000 /* STATUS: INIT state first */ +#define IEEE80211_FEXT_BPF 0x00008000 /* STATUS: BPF tap present */ /* NB: immutable: should be set only when creating a vap */ #define IEEE80211_FEXT_WDSLEGACY 0x00010000 /* CONF: legacy WDS operation */ #define IEEE80211_FEXT_PROBECHAN 0x00020000 /* CONF: probe passive channel*/ @@ -540,7 +548,7 @@ MALLOC_DECLARE(M_80211_VAP); #define IEEE80211_FEXT_BITS \ "\20\1NONHT_PR\2INACT\3SCANWAIT\4BGSCAN\5WPS\6TSN\7SCANREQ\10RESUME" \ "\0114ADDR\12NONEPR_PR\13SWBMISS\14DFS\15DOTD\16STATEWAIT\17REINIT" \ - "\22WDSLEGACY\23PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \ + "\20BPF\21WDSLEGACY\22PROBECHAN\24HT\25AMDPU_TX\26AMPDU_TX\27AMSDU_TX" \ "\30AMSDU_RX\31USEHT40\32PUREN\33SHORTGI20\34SHORTGI40\35HTCOMPAT" \ "\36RIFS" @@ -637,6 +645,31 @@ struct ieee80211_channel *ieee80211_find_channel_byieee(struct ieee80211com *, int ieee80211_setmode(struct ieee80211com *, enum ieee80211_phymode); enum ieee80211_phymode ieee80211_chan2mode(const struct ieee80211_channel *); +void ieee80211_radiotap_attach(struct ieee80211com *, + struct ieee80211_radiotap_header *th, int tlen, + uint32_t tx_radiotap, + struct ieee80211_radiotap_header *rh, int rlen, + uint32_t rx_radiotap); +void ieee80211_radiotap_detach(struct ieee80211com *); +void ieee80211_radiotap_vattach(struct ieee80211vap *); +void ieee80211_radiotap_vdetach(struct ieee80211vap *); +void ieee80211_radiotap_chan_change(struct ieee80211com *); +void ieee80211_radiotap_tx(struct ieee80211vap *, struct mbuf *); +void ieee80211_radiotap_rx(struct ieee80211vap *, struct mbuf *); +void ieee80211_radiotap_rx_all(struct ieee80211com *, struct mbuf *); + +static __inline int +ieee80211_radiotap_active(const struct ieee80211com *ic) +{ + return (ic->ic_flags_ext & IEEE80211_FEXT_BPF) != 0; +} + +static __inline int +ieee80211_radiotap_active_vap(const struct ieee80211vap *vap) +{ + return (vap->iv_flags_ext & IEEE80211_FEXT_BPF) != 0; +} + /* * Enqueue a task on the state thread. */ diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index 6ab8f119e31a..85ab5448814b 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -63,10 +63,9 @@ __FBSDID("$FreeBSD$"); static void wds_vattach(struct ieee80211vap *); static int wds_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int wds_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp); +static int wds_input(struct ieee80211_node *ni, struct mbuf *m, int, int); static void wds_recv_mgmt(struct ieee80211_node *, struct mbuf *, - int subtype, int rssi, int noise, u_int32_t rstamp); + int subtype, int, int); void ieee80211_wds_attach(struct ieee80211com *ic) @@ -199,12 +198,12 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) * Flush pending frames now that were setup. */ if (ni != NULL && IEEE80211_NODE_WDSQ_QLEN(ni) != 0) { - int8_t rssi, noise; + int8_t rssi, nf; IEEE80211_NOTE(vap, IEEE80211_MSG_WDS, ni, "flush wds queue, %u packets queued", IEEE80211_NODE_WDSQ_QLEN(ni)); - ic->ic_node_getsignal(ni, &rssi, &noise); + ic->ic_node_getsignal(ni, &rssi, &nf); for (;;) { struct mbuf *m; @@ -213,8 +212,7 @@ ieee80211_create_wds(struct ieee80211vap *vap, struct ieee80211_channel *chan) IEEE80211_NODE_WDSQ_UNLOCK(ni); if (m == NULL) break; - /* XXX cheat and re-use last rstamp */ - ieee80211_input(ni, m, rssi, noise, ni->ni_rstamp); + ieee80211_input(ni, m, rssi, nf); } } return (ni == NULL ? ENOENT : 0); @@ -292,9 +290,6 @@ ieee80211_dwds_mcast(struct ieee80211vap *vap0, struct mbuf *m) mcopy->m_flags |= M_MCAST; mcopy->m_pkthdr.rcvif = (void *) ni; - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - err = parent->if_transmit(parent, mcopy); if (err) { /* NB: IFQ_HANDOFF reclaims mbuf */ @@ -470,8 +465,7 @@ wds_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) * by the 802.11 layer. */ static int -wds_input(struct ieee80211_node *ni, struct mbuf *m, - int rssi, int noise, uint32_t rstamp) +wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { #define SEQ_LEQ(a,b) ((int)((a)-(b)) <= 0) #define HAS_SEQ(type) ((type & 0x4) == 0) @@ -553,8 +547,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, goto out; } IEEE80211_RSSI_LPF(ni->ni_avgrssi, rssi); - ni->ni_noise = noise; - ni->ni_rstamp = rstamp; + ni->ni_noise = nf; if (HAS_SEQ(type)) { uint8_t tid = ieee80211_gettid(wh); if (IEEE80211_QOS_HAS_SEQ(wh) && @@ -686,8 +679,8 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, } /* copy to listener after decrypt */ - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); need_tap = 0; /* @@ -786,16 +779,14 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, vap->iv_stats.is_rx_mgtdiscard++; /* XXX */ goto out; } - if (bpf_peers_present(vap->iv_rawbpf)) - bpf_mtap(vap->iv_rawbpf, m); - vap->iv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); - m_freem(m); - return IEEE80211_FC0_TYPE_MGT; + vap->iv_recv_mgmt(ni, m, subtype, rssi, nf); + goto out; case IEEE80211_FC0_TYPE_CTL: vap->iv_stats.is_rx_ctl++; IEEE80211_NODE_STAT(ni, rx_ctrl); goto out; + default: IEEE80211_DISCARD(vap, IEEE80211_MSG_ANY, wh, "bad", "frame type 0x%x", type); @@ -806,8 +797,8 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, ifp->if_ierrors++; out: if (m != NULL) { - if (bpf_peers_present(vap->iv_rawbpf) && need_tap) - bpf_mtap(vap->iv_rawbpf, m); + if (need_tap) + ieee80211_radiotap_rx(vap, m); m_freem(m); } return type; @@ -816,7 +807,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, static void wds_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m0, - int subtype, int rssi, int noise, u_int32_t rstamp) + int subtype, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; struct ieee80211com *ic = ni->ni_ic; From 23790ac0d7d74b32f372e898a82e5903e9f11cb3 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 20 May 2009 20:05:56 +0000 Subject: [PATCH 343/544] bump for net80211 monitor mode changes --- UPDATING | 8 ++++++++ sys/sys/param.h | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/UPDATING b/UPDATING index 7fffa1ba06eb..bb4dadec1246 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,14 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090520: + 802.11 monitor mode support was revised and driver api's + were changed. Drivers dependent on net80211 now support + DLT_IEEE802_11_RADIO instead of DLT_IEEE802_11. No + user-visible data structures were changed but applications + that use DLT_IEEE802_11 may require changes. + Bump __FreeBSD_version to 800088. + 20090430: The layout of the following structs has changed: sysctl_oid, socket, ifnet, inpcbinfo, tcpcb, syncache_head, vnet_inet, diff --git a/sys/sys/param.h b/sys/sys/param.h index 3aea1012a2f9..4b02e6ad98a4 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800087 /* Master, propagated to newvers */ +#define __FreeBSD_version 800088 /* Master, propagated to newvers */ #ifndef LOCORE #include From f6ac50113fec1ba50269837b0165d01ac905fa7e Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 20 May 2009 20:18:01 +0000 Subject: [PATCH 344/544] Prepare to distribute sysctl code to reduce global definitions: o expose net.wlan sysctl node o expose ieee80211_sysctl_msecs_ticks Reviewed by: rpaulo, thompsa --- sys/net80211/ieee80211_freebsd.c | 2 +- sys/net80211/ieee80211_freebsd.h | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 89292a606fdb..3caf79079a26 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -160,7 +160,7 @@ ieee80211_vap_destroy(struct ieee80211vap *vap) if_clone_destroyif(&wlan_cloner, vap->iv_ifp); } -static int +int ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS) { int msecs = ticks_to_msecs(*(int *)arg1); diff --git a/sys/net80211/ieee80211_freebsd.h b/sys/net80211/ieee80211_freebsd.h index 3ed9ece9f448..846bb95b04e7 100644 --- a/sys/net80211/ieee80211_freebsd.h +++ b/sys/net80211/ieee80211_freebsd.h @@ -32,6 +32,7 @@ #include #include #include +#include #include /* @@ -276,6 +277,9 @@ void ieee80211_sysctl_detach(struct ieee80211com *); void ieee80211_sysctl_vattach(struct ieee80211vap *); void ieee80211_sysctl_vdetach(struct ieee80211vap *); +SYSCTL_DECL(_net_wlan); +int ieee80211_sysctl_msecs_ticks(SYSCTL_HANDLER_ARGS); + void ieee80211_load_module(const char *); /* From c9d763bf41867664a939868b483b3c54bdb8e0a5 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Wed, 20 May 2009 21:07:15 +0000 Subject: [PATCH 345/544] When an interface address is removed and the last prefix route is also being deleted, the link-layer address table (arp or nd6) will flush those L2 llinfo entries that match the removed prefix. Reviewed by: kmacy --- sys/net/if_llatbl.c | 17 +++++++++++++++++ sys/net/if_llatbl.h | 5 +++++ sys/netinet/in.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ sys/netinet6/in6.c | 25 +++++++++++++++++++++++++ 4 files changed, 91 insertions(+) diff --git a/sys/net/if_llatbl.c b/sys/net/if_llatbl.c index 7ef1c9a20050..b5da1ea44360 100644 --- a/sys/net/if_llatbl.c +++ b/sys/net/if_llatbl.c @@ -195,6 +195,23 @@ lltable_drain(int af) IFNET_RUNLOCK(); } +void +lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask) +{ + struct lltable *llt; + + IFNET_RLOCK(); + SLIST_FOREACH(llt, &lltables, llt_link) { + if (llt->llt_af != af) + continue; + + llt->llt_prefix_free(llt, prefix, mask); + } + IFNET_RUNLOCK(); +} + + + /* * Create a new lltable. */ diff --git a/sys/net/if_llatbl.h b/sys/net/if_llatbl.h index 3b3086f75f76..4d721efc35f7 100644 --- a/sys/net/if_llatbl.h +++ b/sys/net/if_llatbl.h @@ -147,6 +147,9 @@ struct lltable { struct llentry * (*llt_new)(const struct sockaddr *, u_int); void (*llt_free)(struct lltable *, struct llentry *); + void (*llt_prefix_free)(struct lltable *, + const struct sockaddr *prefix, + const struct sockaddr *mask); struct llentry * (*llt_lookup)(struct lltable *, u_int flags, const struct sockaddr *l3addr); int (*llt_rtcheck)(struct ifnet *, @@ -174,6 +177,8 @@ MALLOC_DECLARE(M_LLTABLE); struct lltable *lltable_init(struct ifnet *, int); void lltable_free(struct lltable *); +void lltable_prefix_free(int, struct sockaddr *, + struct sockaddr *); void lltable_drain(int); int lltable_sysctl_dumparp(int, struct sysctl_req *); diff --git a/sys/netinet/in.c b/sys/netinet/in.c index eaa8c7e87480..6f408eb92860 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -1013,6 +1013,7 @@ in_scrubprefix(struct in_ifaddr *target) struct in_ifaddr *ia; struct in_addr prefix, mask, p; int error; + struct sockaddr_in prefix0, mask0; struct rt_addrinfo info; struct sockaddr_dl null_sdl; @@ -1081,6 +1082,20 @@ in_scrubprefix(struct in_ifaddr *target) } } + /* + * remove all L2 entries on the given prefix + */ + bzero(&prefix0, sizeof(prefix0)); + prefix0.sin_len = sizeof(prefix0); + prefix0.sin_family = AF_INET; + prefix0.sin_addr.s_addr = target->ia_subnet; + bzero(&mask0, sizeof(mask0)); + mask0.sin_len = sizeof(mask0); + mask0.sin_family = AF_INET; + mask0.sin_addr.s_addr = target->ia_subnetmask; + lltable_prefix_free(AF_INET, (struct sockaddr *)&prefix0, + (struct sockaddr *)&mask0); + /* * As no-one seem to have this prefix, we can remove the route. */ @@ -1232,6 +1247,34 @@ in_lltable_free(struct lltable *llt, struct llentry *lle) free(lle, M_LLTABLE); } + +#define IN_ARE_MASKED_ADDR_EQUAL(d, a, m) ( \ + (((ntohl((d)->sin_addr.s_addr) ^ (a)->sin_addr.s_addr) & (m)->sin_addr.s_addr)) == 0 ) + +static void +in_lltable_prefix_free(struct lltable *llt, + const struct sockaddr *prefix, + const struct sockaddr *mask) +{ + const struct sockaddr_in *pfx = (const struct sockaddr_in *)prefix; + const struct sockaddr_in *msk = (const struct sockaddr_in *)mask; + struct llentry *lle, *next; + register int i; + + for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { + LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { + + if (IN_ARE_MASKED_ADDR_EQUAL((struct sockaddr_in *)L3_ADDR(lle), + pfx, msk)) { + callout_drain(&lle->la_timer); + LLE_WLOCK(lle); + llentry_free(lle); + } + } + } +} + + static int in_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr) { @@ -1422,6 +1465,7 @@ in_domifattach(struct ifnet *ifp) if (llt != NULL) { llt->llt_new = in_lltable_new; llt->llt_free = in_lltable_free; + llt->llt_prefix_free = in_lltable_prefix_free; llt->llt_rtcheck = in_lltable_rtcheck; llt->llt_lookup = in_lltable_lookup; llt->llt_dump = in_lltable_dump; diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index a2321ff94c1a..60d56a8ae8e7 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -2284,6 +2284,30 @@ in6_lltable_free(struct lltable *llt, struct llentry *lle) free(lle, M_LLTABLE); } +static void +in6_lltable_prefix_free(struct lltable *llt, + const struct sockaddr *prefix, + const struct sockaddr *mask) +{ + const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix; + const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask; + struct llentry *lle, *next; + register int i; + + for (i=0; i < LLTBL_HASHTBL_SIZE; i++) { + LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { + if (IN6_ARE_MASKED_ADDR_EQUAL( + &((struct sockaddr_in6 *)L3_ADDR(lle))->sin6_addr, + &pfx->sin6_addr, + &msk->sin6_addr)) { + callout_drain(&lle->la_timer); + LLE_WLOCK(lle); + llentry_free(lle); + } + } + } +} + static int in6_lltable_rtcheck(struct ifnet *ifp, const struct sockaddr *l3addr) { @@ -2490,6 +2514,7 @@ in6_domifattach(struct ifnet *ifp) if (ext->lltable != NULL) { ext->lltable->llt_new = in6_lltable_new; ext->lltable->llt_free = in6_lltable_free; + ext->lltable->llt_prefix_free = in6_lltable_prefix_free; ext->lltable->llt_rtcheck = in6_lltable_rtcheck; ext->lltable->llt_lookup = in6_lltable_lookup; ext->lltable->llt_dump = in6_lltable_dump; From 9e31449738aa74508575c8ff4a01ac3c1594b484 Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 21:31:47 +0000 Subject: [PATCH 346/544] Last commit was in error, revert. --- sys/dev/ata/ata-all.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 1131ee1fae28..4530767f3aaa 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -663,7 +663,7 @@ ata_getparam(struct ata_device *atadev, int init) btrim(atacap->serial, sizeof(atacap->serial)); bpack(atacap->serial, atacap->serial, sizeof(atacap->serial)); - if (bootverbose || 1) + if (bootverbose) printf("ata%d-%s: pio=%s wdma=%s udma=%s cable=%s wire\n", device_get_unit(ch->dev), ata_unit2str(atadev), From 89c81b88f141fb1d561d5bd76046b1d02f7feebe Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 22:00:39 +0000 Subject: [PATCH 347/544] Revert junk from last commit. These are WIP and not ready (and don't match the description of the last commit). --- sys/dev/pci/pci.c | 87 ------------------------------------------- sys/dev/pci/pci_pci.c | 15 -------- sys/dev/pci/pcib_if.m | 14 ------- 3 files changed, 116 deletions(-) diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index af1691b1855a..3b330c7b8301 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -418,38 +418,6 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg) #undef REG } -/* - * This is a lame example: we should have some way of managing this table - * from userland. The user should be able to tell us from the boot loader - * or at runtime what mapping to do. - */ -static struct pci_remap_entry -{ - uint16_t vendor; - uint16_t device; - uint16_t mapped_vendor; - uint16_t mapped_device; -} pci_remap[] = -{ - { 0x1039, 0x0901, 0x1039, 0x0900 } /* Map sis 901 to sis 900 */ -}; -static int pci_remap_entries = 1; - -static void -pci_apply_remap_table(pcicfgregs *cfg) -{ - int i; - - for (i = 0; i < pci_remap_entries; i++) { - if (cfg->vendor == pci_remap[i].vendor && - cfg->device == pci_remap[i].device) { - cfg->vendor = pci_remap[i].mapped_vendor; - cfg->device = pci_remap[i].mapped_device; - return; - } - } -} - /* read configuration header into pcicfgregs structure */ struct pci_devinfo * pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size) @@ -496,7 +464,6 @@ pci_read_device(device_t pcib, int d, int b, int s, int f, size_t size) pci_fixancient(cfg); pci_hdrtypedata(pcib, b, s, f, cfg); - pci_apply_remap_table(cfg); if (REG(PCIR_STATUS, 2) & PCIM_STATUS_CAPPRESENT) pci_read_extcap(pcib, cfg); @@ -2652,59 +2619,6 @@ pci_add_resources(device_t bus, device_t dev, int force, uint32_t prefetchmask) } } -/* - * After we've added the children to the pci bus device, we need to fixup - * the children in various ways. This function fixes things that require - * multiple passes to get right, such as bus number and some resource - * things (although the latter hasn't been implemented yet). This must be - * done before the children are probe/attached, sicne by that point these - * things must be fixed. - */ -static void -pci_fix_bridges(device_t dev) -{ - int i, numdevs, error, secbus, subbus; - device_t child, *devlist; - - if ((error = device_get_children(dev, &devlist, &numdevs))) - return; - /* - * First pass, get the bus numbers that are in use - */ - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - switch (pci_read_config(child, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) { - default: - continue; - case 1: /* PCI-PCI bridge */ - case 2: /* CardBus bridge -- offsets are the same */ - secbus = pci_read_config(child, PCIR_SECBUS_1, 1); - subbus = pci_read_config(child, PCIR_SUBBUS_1, 1); - break; - } - printf("%d:%d:%d:%d sec %d sub %d\n", pcib_get_domain(dev), - pci_get_bus(child), pci_get_slot(child), - pci_get_function(child), secbus, subbus); - } -#if 0 - /* - * Second pass, Fix the bus numbers, as needed - */ - for (i = 0; i < numdevs; i++) { - child = devlist[i]; - switch (pci_read_config(dev, PCIR_HDRTYPE, 1) & PCIM_HDRTYPE) { - case 1: /* PCI-PCI bridge */ - break; - case 2: /* CardBus bridge */ - break; - default: - continue; - } - } -#endif - free(devlist, M_TEMP); -} - void pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size) { @@ -2736,7 +2650,6 @@ pci_add_children(device_t dev, int domain, int busno, size_t dinfo_size) } } #undef REG - pci_fix_bridges(dev); } void diff --git a/sys/dev/pci/pci_pci.c b/sys/dev/pci/pci_pci.c index 8bb2eff39156..15cad92484d7 100644 --- a/sys/dev/pci/pci_pci.c +++ b/sys/dev/pci/pci_pci.c @@ -52,13 +52,6 @@ __FBSDID("$FreeBSD$"); #include "pcib_if.h" -// #define KLUDGE_O_MATIC -#ifdef KLUDGE_O_MATIC -int hack_unit = 1; -u_long mem_base = 0xc0400000ul; -u_long mem_limit = 0x00100000ul; -#endif - static int pcib_probe(device_t dev); static device_method_t pcib_methods[] = { @@ -331,14 +324,6 @@ pcib_attach(device_t dev) struct pcib_softc *sc; device_t child; -#ifdef KLUDGE_O_MATIC - if (device_get_unit(dev) == hack_unit) { - pci_write_config(dev, PCIR_COMMAND, - PCIM_CMD_MEMEN | pci_read_config(dev, PCIR_COMMAND, 1), 1); - pci_write_config(dev, PCIR_MEMBASE_1, mem_base >> 16, 2); - pci_write_config(dev, PCIR_MEMLIMIT_1, mem_limit >> 16, 2); - } -#endif pcib_attach_common(dev); sc = device_get_softc(dev); if (sc->secbus != 0) { diff --git a/sys/dev/pci/pcib_if.m b/sys/dev/pci/pcib_if.m index 765e6449a312..0b7e8bc62c9b 100644 --- a/sys/dev/pci/pcib_if.m +++ b/sys/dev/pci/pcib_if.m @@ -144,17 +144,3 @@ METHOD int map_msi { uint64_t *addr; uint32_t *data; }; - -# -# Return the range of busses passed through this bridge. For normal -# pci-pci bridges (and compatible things like pci-x and pcie), this will -# just be the secbus and subbus configuration registers. For non-standard -# bridges, or for host bridges which have no standard, this will be the -# same data read from either device specific registers of from "perfect -# knowledge" of what they must be. -# -METHOD int bus_range { - device_t pcib; - u_int *secbus; - u_int *subbus; -}; From a2f237f8b7685f786de04dfc2d5b4cff637e1527 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Wed, 20 May 2009 22:01:43 +0000 Subject: [PATCH 348/544] Add regression tests for the date(1) + argument for user-defined format strings. PR: bin/127514 Submitted by: edwin@ MFC after: 1 week --- tools/regression/bin/date/Makefile | 4 ++ tools/regression/bin/date/regress.sh | 89 ++++++++++++++++++++++++++++ tools/regression/bin/date/regress.t | 6 ++ 3 files changed, 99 insertions(+) create mode 100644 tools/regression/bin/date/Makefile create mode 100644 tools/regression/bin/date/regress.sh create mode 100644 tools/regression/bin/date/regress.t diff --git a/tools/regression/bin/date/Makefile b/tools/regression/bin/date/Makefile new file mode 100644 index 000000000000..2c9ca5943505 --- /dev/null +++ b/tools/regression/bin/date/Makefile @@ -0,0 +1,4 @@ +# $FreeBSD$ + +all: + sh regress.sh diff --git a/tools/regression/bin/date/regress.sh b/tools/regression/bin/date/regress.sh new file mode 100644 index 000000000000..463e49c8f8fd --- /dev/null +++ b/tools/regression/bin/date/regress.sh @@ -0,0 +1,89 @@ +#!/bin/sh + +# +# Regression tests for date(1) +# +# Submitted by Edwin Groothuis +# +# $FreeBSD$ +# + +# +# These two date/times have been chosen carefully, they +# create both the single digit and double/multidigit version of +# the values. +# +# To create a new one, make sure you are using the UTC timezone! +# + +TEST1=3222243 # 1970-02-07 07:04:03 +TEST2=1005600000 # 2001-11-12 21:11:12 + +export LANG=C +export TZ=UTC +count=0 + +check() +{ + S=$1 + A1=$2 + A2=$3 + + count=`expr ${count} + 1` + + if [ -z "${A2}" ]; then A2=${A1}; fi + + R=`date -r ${TEST1} +%${S}` + if [ "${R}" = "${A1}" ]; then + echo "${count}a. ${S} - ok" + else + echo "${count}a. ${S} - not ok (got ${R}, expected ${A1})" + fi + + R=`date -r ${TEST2} +%${S}` + if [ "${R}" = "${A2}" ]; then + echo "${count}b. ${S} - ok" + else + echo "${count}b. ${S} - not ok (got ${R}, expected ${A2})" + fi +} + +check A Saturday Monday +check a Sat Mon +check B February November +check b Feb Nov +check C 19 20 +check c "Sat Feb 7 07:04:03 1970" "Mon Nov 12 21:20:00 2001" +check D 02/07/70 11/12/01 +check d 07 12 +check e " 7" 12 +check F "1970-02-07" "2001-11-12" +check G 1970 2001 +check g 70 01 +check H 07 21 +check h Feb Nov +check I 07 09 +check j 038 316 +check k " 7" 21 +check l " 7" " 9" +check M 04 20 +check m 02 11 +check p AM PM +check R 07:04 21:20 +check r "07:04:03 AM" "09:20:00 PM" +check S 03 00 +check s ${TEST1} ${TEST2} +check U 05 45 +check u 6 1 +check V 06 46 +check v " 7-Feb-1970" "12-Nov-2001" +check W 05 46 +check w 6 1 +check X "07:04:03" "21:20:00" +check x "02/07/70" "11/12/01" +check Y 1970 2001 +check y 70 01 +check Z UTC UTC +check z +0000 +0000 +check % % % +check + "Sat Feb 7 07:04:03 UTC 1970" "Mon Nov 12 21:20:00 UTC 2001" diff --git a/tools/regression/bin/date/regress.t b/tools/regression/bin/date/regress.t new file mode 100644 index 000000000000..c36d8342d32a --- /dev/null +++ b/tools/regression/bin/date/regress.t @@ -0,0 +1,6 @@ +#!/bin/sh +# $FreeBSD$ + +cd `dirname $0` + +sh regress.sh From 1fdc45cd2ebd4ae70453b1cf6465841fca911cc1 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Wed, 20 May 2009 22:19:22 +0000 Subject: [PATCH 349/544] A few more style changes as well as a more broad allowance for errors to be given by the caller. Change output to be easier for use in scripts. Submitted by: bce --- usr.bin/perror/perror.c | 46 +++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/usr.bin/perror/perror.c b/usr.bin/perror/perror.c index 4ef79cbd9959..19b79ce830cb 100644 --- a/usr.bin/perror/perror.c +++ b/usr.bin/perror/perror.c @@ -31,48 +31,40 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include -#define MAX_ERR 256 - -static void -usage() -{ - - fprintf(stderr, "usage: perror number\n"); - fprintf(stderr, "number must be between 1 and %d\n", ELAST); - exit(1); -} +static void usage(); int main(int argc, char **argv) { - - char errstr[MAX_ERR]; char *cp; - int errnum; + char *errstr; + long errnum; if (argc != 2) usage(); + errno = 0; + errnum = strtol(argv[1], &cp, 0); - if (((errnum == 0) && (errno == EINVAL)) || (*cp != '\0')) { - fprintf(stderr, "Argument %s not a number.\n", argv[1]); - usage(); - } + if (errno != 0) + err(1, NULL); - if ((errnum <=0) || (errnum > ELAST)) { - fprintf(stderr, "Number %d out of range.\n", errnum); - usage(); - } - - if (strerror_r(errnum, errstr, sizeof(errstr)) < 0) { - fprintf(stderr, "Could not find error number %d.\n", errnum); - usage(); - } + if ((errstr = strerror(errnum)) == NULL) + err(1, NULL); - printf("Error %d is \"%s\"\n", errnum, errstr); + printf("%s\n", errstr); exit(0); } + +static void +usage() +{ + fprintf(stderr, "usage: perror number\n"); + exit(1); +} + From 68fc5ce70be924d656e19ec679f3c19a4b90dc7c Mon Sep 17 00:00:00 2001 From: Warner Losh Date: Wed, 20 May 2009 22:28:55 +0000 Subject: [PATCH 350/544] Revert last junk... --- sys/dev/wi/if_wavelan_ieee.h | 3 +++ sys/dev/wi/if_wi.c | 5 ++--- sys/dev/wi/if_wivar.h | 3 --- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/sys/dev/wi/if_wavelan_ieee.h b/sys/dev/wi/if_wavelan_ieee.h index 82bc9e509c2c..0061e638bd0d 100644 --- a/sys/dev/wi/if_wavelan_ieee.h +++ b/sys/dev/wi/if_wavelan_ieee.h @@ -58,11 +58,14 @@ * value. */ #define WI_MAX_DATALEN 512 + +#if 0 struct wi_req { u_int16_t wi_len; u_int16_t wi_type; u_int16_t wi_val[WI_MAX_DATALEN]; }; +#endif /* * Private LTV records (interpreted only by the driver). This is diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 5cdec5f8506e..6e2c586c309a 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -145,6 +145,7 @@ static int wi_alloc_fid(struct wi_softc *, int, int *); static void wi_read_nicid(struct wi_softc *); static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); +static int wi_cmd(struct wi_softc *, int, int, int, int); static int wi_seek_bap(struct wi_softc *, int, int); static int wi_read_bap(struct wi_softc *, int, int, void *, int); static int wi_write_bap(struct wi_softc *, int, int, void *, int); @@ -1801,7 +1802,7 @@ wi_write_wep(struct wi_softc *sc, struct ieee80211vap *vap) return error; } -int +static int wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) { int i, s = 0; @@ -2120,5 +2121,3 @@ wi_free(device_t dev) sc->mem = NULL; } } - -MODULE_VERSION(wi, 1); diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index c5bc1391ad4e..fd622bd754f2 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -184,6 +184,3 @@ void wi_init(void *); void wi_intr(void *); int wi_mgmt_xmit(struct wi_softc *, caddr_t, int); void wi_stop(struct wi_softc *, int); - -/* KLUDGE */ -int wi_cmd(struct wi_softc *, int, int, int, int); From 74904f7d58b9ddbedaf01e28432a8968295033b2 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Wed, 20 May 2009 23:33:40 +0000 Subject: [PATCH 351/544] update for net80211 rx api change --- sys/dev/if_ndis/if_ndis.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index 8f5054bb945b..71a6b2323acc 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -3306,7 +3306,6 @@ ndis_scan_results(struct ndis_softc *sc) struct ieee80211_channel *saved_chan; int i, j; int error, len, rssi, noise, freq, chanflag; - static long rstamp; uint8_t ssid[2+IEEE80211_NWID_LEN]; uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; @@ -3337,7 +3336,6 @@ ndis_scan_results(struct ndis_softc *sc) } DPRINTF(("%s: %d results\n", __func__, bl->nblx_items)); - rstamp++; wb = &bl->nblx_bssid[0]; for (i = 0; i < bl->nblx_items; i++) { memset(&sp, 0, sizeof(sp)); @@ -3408,7 +3406,7 @@ ndis_scan_results(struct ndis_softc *sc) DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n", ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag, rssi)); - ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise, rstamp); + ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise); wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); } free(bl, M_DEVBUF); From f29a072444d6e31d57f7edd94f952395ae7bb22e Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 00:04:17 +0000 Subject: [PATCH 352/544] - rename usb2_mode to usb_mode [1] - change variable types to use the enum Submitted by: Hans Petter Selasky [1] --- sys/dev/usb/bluetooth/ng_ubt.c | 2 +- sys/dev/usb/bluetooth/ubtbcmfw.c | 2 +- sys/dev/usb/controller/at91dci.c | 8 +++--- sys/dev/usb/controller/atmegadci.c | 8 +++--- sys/dev/usb/controller/ehci.c | 4 +-- sys/dev/usb/controller/musb_otg.c | 8 +++--- sys/dev/usb/controller/ohci.c | 4 +-- sys/dev/usb/controller/uhci.c | 4 +-- sys/dev/usb/controller/uss820dci.c | 8 +++--- sys/dev/usb/input/uhid.c | 2 +- sys/dev/usb/input/ukbd.c | 2 +- sys/dev/usb/input/ums.c | 2 +- sys/dev/usb/misc/udbp.c | 2 +- sys/dev/usb/misc/ufm.c | 2 +- sys/dev/usb/net/if_aue.c | 2 +- sys/dev/usb/net/if_axe.c | 2 +- sys/dev/usb/net/if_cdce.c | 6 ++--- sys/dev/usb/net/if_cue.c | 2 +- sys/dev/usb/net/if_kue.c | 2 +- sys/dev/usb/net/if_rue.c | 2 +- sys/dev/usb/net/if_udav.c | 2 +- sys/dev/usb/serial/u3g.c | 2 +- sys/dev/usb/serial/uark.c | 2 +- sys/dev/usb/serial/ubsa.c | 2 +- sys/dev/usb/serial/ubser.c | 2 +- sys/dev/usb/serial/uchcom.c | 2 +- sys/dev/usb/serial/ucycom.c | 2 +- sys/dev/usb/serial/ufoma.c | 2 +- sys/dev/usb/serial/uftdi.c | 2 +- sys/dev/usb/serial/ugensa.c | 2 +- sys/dev/usb/serial/uipaq.c | 2 +- sys/dev/usb/serial/ulpt.c | 2 +- sys/dev/usb/serial/umct.c | 2 +- sys/dev/usb/serial/umodem.c | 2 +- sys/dev/usb/serial/umoscom.c | 2 +- sys/dev/usb/serial/uplcom.c | 2 +- sys/dev/usb/serial/uslcom.c | 2 +- sys/dev/usb/serial/uvisor.c | 2 +- sys/dev/usb/serial/uvscom.c | 2 +- sys/dev/usb/storage/umass.c | 2 +- sys/dev/usb/storage/urio.c | 2 +- sys/dev/usb/storage/ustorage_fs.c | 2 +- sys/dev/usb/usb_busdma.c | 2 +- sys/dev/usb/usb_compat_linux.c | 4 +-- sys/dev/usb/usb_core.h | 12 ++++----- sys/dev/usb/usb_dev.c | 4 +-- sys/dev/usb/usb_device.c | 42 +++++++++++++++--------------- sys/dev/usb/usb_device.h | 4 +-- sys/dev/usb/usb_generic.c | 18 ++++++------- sys/dev/usb/usb_hub.c | 18 ++++++------- sys/dev/usb/usb_hub.h | 3 +-- sys/dev/usb/usb_request.c | 4 +-- sys/dev/usb/usb_revision.h | 19 +++++++------- sys/dev/usb/usb_transfer.c | 18 ++++++------- sys/dev/usb/wlan/if_rum.c | 2 +- sys/dev/usb/wlan/if_uath.c | 2 +- sys/dev/usb/wlan/if_upgt.c | 2 +- sys/dev/usb/wlan/if_ural.c | 2 +- sys/dev/usb/wlan/if_zyd.c | 2 +- 59 files changed, 138 insertions(+), 138 deletions(-) diff --git a/sys/dev/usb/bluetooth/ng_ubt.c b/sys/dev/usb/bluetooth/ng_ubt.c index a5a19ded53dd..4d97791f9c8c 100644 --- a/sys/dev/usb/bluetooth/ng_ubt.c +++ b/sys/dev/usb/bluetooth/ng_ubt.c @@ -399,7 +399,7 @@ ubt_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bIfaceIndex != 0) diff --git a/sys/dev/usb/bluetooth/ubtbcmfw.c b/sys/dev/usb/bluetooth/ubtbcmfw.c index 1932a3971a95..2c53e8259b79 100644 --- a/sys/dev/usb/bluetooth/ubtbcmfw.c +++ b/sys/dev/usb/bluetooth/ubtbcmfw.c @@ -174,7 +174,7 @@ ubtbcmfw_probe(device_t dev) struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bIfaceIndex != 0) diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index 0dfb4fefd253..a806800b415b 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -1193,7 +1193,7 @@ at91dci_device_done(struct usb2_xfer *xfer, usb2_error_t error) DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n", xfer, xfer->pipe, error); - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { ep_no = (xfer->endpoint & UE_ADDR); /* disable endpoint interrupt */ @@ -1337,7 +1337,7 @@ at91dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); /* check mode */ - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } @@ -2264,12 +2264,12 @@ at91dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *ede DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_rt_addr); if (udev->device_index != sc->sc_rt_addr) { - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index f296e30142a4..82665363c3de 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -1076,7 +1076,7 @@ atmegadci_device_done(struct usb2_xfer *xfer, usb2_error_t error) DPRINTFN(9, "xfer=%p, pipe=%p, error=%d\n", xfer, xfer->pipe, error); - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { ep_no = (xfer->endpoint & UE_ADDR); /* select endpoint number */ @@ -1187,7 +1187,7 @@ atmegadci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); /* check mode */ - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } @@ -2094,12 +2094,12 @@ atmegadci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *e DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d,%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_rt_addr, udev->device_index); if (udev->device_index != sc->sc_rt_addr) { - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 9bb9304ab2d6..99db9b31af62 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -3649,10 +3649,10 @@ ehci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_addr); - if (udev->flags.usb2_mode != USB_MODE_HOST) { + if (udev->flags.usb_mode != USB_MODE_HOST) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 1feb8a4a6fae..198840cf379d 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1441,7 +1441,7 @@ musbotg_device_done(struct usb2_xfer *xfer, usb2_error_t error) DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n", xfer, xfer->pipe, error); - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { musbotg_ep_int_set(xfer, 0); @@ -1645,7 +1645,7 @@ musbotg_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); /* check mode */ - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } @@ -2673,12 +2673,12 @@ musbotg_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *ede DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_rt_addr); if (udev->device_index != sc->sc_rt_addr) { - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index 6cff48ae3145..fe88461cc2da 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c @@ -2570,10 +2570,10 @@ ohci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_addr); - if (udev->flags.usb2_mode != USB_MODE_HOST) { + if (udev->flags.usb_mode != USB_MODE_HOST) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c index 29235b368dd0..1c52eec26872 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -3050,10 +3050,10 @@ uhci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_addr); - if (udev->flags.usb2_mode != USB_MODE_HOST) { + if (udev->flags.usb_mode != USB_MODE_HOST) { /* not supported */ return; } diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index 371304ef6178..67f74d897952 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -1173,7 +1173,7 @@ uss820dci_device_done(struct usb2_xfer *xfer, usb2_error_t error) DPRINTFN(2, "xfer=%p, pipe=%p, error=%d\n", xfer, xfer->pipe, error); - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { uss820dci_intr_set(xfer, 0); } /* dequeue transfer and start next transfer */ @@ -1279,7 +1279,7 @@ uss820dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) DPRINTFN(5, "pipe=%p\n", pipe); /* check mode */ - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } @@ -2298,12 +2298,12 @@ uss820dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *e DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d)\n", pipe, udev->address, - edesc->bEndpointAddress, udev->flags.usb2_mode, + edesc->bEndpointAddress, udev->flags.usb_mode, sc->sc_rt_addr); if (udev->device_index != sc->sc_rt_addr) { - if (udev->flags.usb2_mode != USB_MODE_DEVICE) { + if (udev->flags.usb_mode != USB_MODE_DEVICE) { /* not supported */ return; } diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index 78931bdb7c48..106b79245f65 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -599,7 +599,7 @@ uhid_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->use_generic == 0) { diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 58e815169a73..3f528ec4e08a 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -598,7 +598,7 @@ ukbd_probe(device_t dev) if (sw == NULL) { return (ENXIO); } - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } /* check that the keyboard speaks the boot protocol: */ diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c index 6ed030de3d67..a9656c436f90 100644 --- a/sys/dev/usb/input/ums.c +++ b/sys/dev/usb/input/ums.c @@ -339,7 +339,7 @@ ums_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); id = usb2_get_interface_descriptor(uaa->iface); diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c index e8acba81cfe8..c72df51dcee4 100644 --- a/sys/dev/usb/misc/udbp.c +++ b/sys/dev/usb/misc/udbp.c @@ -279,7 +279,7 @@ udbp_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } /* diff --git a/sys/dev/usb/misc/ufm.c b/sys/dev/usb/misc/ufm.c index f33065fa0eee..08808bbb5824 100644 --- a/sys/dev/usb/misc/ufm.c +++ b/sys/dev/usb/misc/ufm.c @@ -112,7 +112,7 @@ ufm_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if ((uaa->info.idVendor == USB_VENDOR_CYPRESS) && diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c index e1cd066b4edd..763d0c32c725 100644 --- a/sys/dev/usb/net/if_aue.c +++ b/sys/dev/usb/net/if_aue.c @@ -628,7 +628,7 @@ aue_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != AUE_CONFIG_INDEX) return (ENXIO); diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c index 6240e77d7ad6..83dde03d487b 100644 --- a/sys/dev/usb/net/if_axe.c +++ b/sys/dev/usb/net/if_axe.c @@ -662,7 +662,7 @@ axe_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != AXE_CONFIG_IDX) return (ENXIO); diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index eec58fc114e1..72c50f0c4053 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -105,7 +105,7 @@ static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { .flags = {.pipe_bof = 1,.short_frames_ok = 1,.short_xfer_ok = 1,.ext_buffer = 1,}, .callback = cdce_bulk_read_callback, .timeout = 0, /* no timeout */ - .usb_mode = USB_MODE_MAX, /* both modes */ + .usb_mode = USB_MODE_DUAL, /* both modes */ }, [CDCE_BULK_TX] = { @@ -118,7 +118,7 @@ static const struct usb2_config cdce_config[CDCE_N_TRANSFER] = { .flags = {.pipe_bof = 1,.force_short_xfer = 1,.ext_buffer = 1,}, .callback = cdce_bulk_write_callback, .timeout = 10000, /* 10 seconds */ - .usb_mode = USB_MODE_MAX, /* both modes */ + .usb_mode = USB_MODE_DUAL, /* both modes */ }, [CDCE_INTR_RX] = { @@ -361,7 +361,7 @@ cdce_attach(device_t dev) sc->sc_ue.ue_eaddr[i / 2] |= c; } - if (uaa->usb2_mode == USB_MODE_DEVICE) { + if (uaa->usb_mode == USB_MODE_DEVICE) { /* * Do not use the same MAC address like the peer ! */ diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c index e487280cda38..eca9a8e90081 100644 --- a/sys/dev/usb/net/if_cue.c +++ b/sys/dev/usb/net/if_cue.c @@ -360,7 +360,7 @@ cue_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != CUE_CONFIG_IDX) return (ENXIO); diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c index c72210cc8269..dfdaefac3911 100644 --- a/sys/dev/usb/net/if_kue.c +++ b/sys/dev/usb/net/if_kue.c @@ -436,7 +436,7 @@ kue_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != KUE_CONFIG_IDX) return (ENXIO); diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c index 578394397234..176ff1d25775 100644 --- a/sys/dev/usb/net/if_rue.c +++ b/sys/dev/usb/net/if_rue.c @@ -546,7 +546,7 @@ rue_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != RUE_CONFIG_IDX) return (ENXIO); diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c index 85155162c519..d301e8dfd0c4 100644 --- a/sys/dev/usb/net/if_udav.c +++ b/sys/dev/usb/net/if_udav.c @@ -211,7 +211,7 @@ udav_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != UDAV_CONFIG_INDEX) return (ENXIO); diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 9c15ef782b58..d26a9b6e90f3 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -420,7 +420,7 @@ u3g_probe(device_t self) { struct usb2_attach_arg *uaa = device_get_ivars(self); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != U3G_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uark.c b/sys/dev/usb/serial/uark.c index bc0bace12188..4ea6dbdfe903 100644 --- a/sys/dev/usb/serial/uark.c +++ b/sys/dev/usb/serial/uark.c @@ -161,7 +161,7 @@ uark_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != 0) { diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c index a52c828b5152..dae6036c93e3 100644 --- a/sys/dev/usb/serial/ubsa.c +++ b/sys/dev/usb/serial/ubsa.c @@ -268,7 +268,7 @@ ubsa_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UBSA_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c index 6ec67ae1e9f1..803b9b87fa8f 100644 --- a/sys/dev/usb/serial/ubser.c +++ b/sys/dev/usb/serial/ubser.c @@ -205,7 +205,7 @@ ubser_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } /* check if this is a BWCT vendor specific ubser interface */ diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index 413fb125cd4a..4bdcaf80cfe4 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -281,7 +281,7 @@ uchcom_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UCHCOM_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/ucycom.c b/sys/dev/usb/serial/ucycom.c index a044c007286b..28ebbb8cfc9f 100644 --- a/sys/dev/usb/serial/ucycom.c +++ b/sys/dev/usb/serial/ucycom.c @@ -179,7 +179,7 @@ ucycom_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != 0) { diff --git a/sys/dev/usb/serial/ufoma.c b/sys/dev/usb/serial/ufoma.c index 62471e724ef8..fb27061b554e 100644 --- a/sys/dev/usb/serial/ufoma.c +++ b/sys/dev/usb/serial/ufoma.c @@ -322,7 +322,7 @@ ufoma_probe(device_t dev) struct usb2_config_descriptor *cd; usb2_mcpc_acm_descriptor *mad; - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } id = usb2_get_interface_descriptor(uaa->iface); diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index 8a6e7e11ac12..e11326a8820c 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -240,7 +240,7 @@ uftdi_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UFTDI_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/ugensa.c b/sys/dev/usb/serial/ugensa.c index f370e1b310fd..483a2dc2ac43 100644 --- a/sys/dev/usb/serial/ugensa.c +++ b/sys/dev/usb/serial/ugensa.c @@ -161,7 +161,7 @@ ugensa_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UGENSA_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c index 24dbd25618bf..353570ac9711 100644 --- a/sys/dev/usb/serial/uipaq.c +++ b/sys/dev/usb/serial/uipaq.c @@ -1078,7 +1078,7 @@ uipaq_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UIPAQ_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c index 024325ee7433..64413270d422 100644 --- a/sys/dev/usb/serial/ulpt.c +++ b/sys/dev/usb/serial/ulpt.c @@ -471,7 +471,7 @@ ulpt_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if ((uaa->info.bInterfaceClass == UICLASS_PRINTER) && diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index db3ddb46ce59..2b3faac8eef3 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -208,7 +208,7 @@ umct_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UMCT_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 35186fd93a10..87e06b46057a 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -257,7 +257,7 @@ umodem_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } error = usb2_lookup_id_by_uaa(umodem_devs, sizeof(umodem_devs), uaa); diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c index f2820aec0d4c..368780b48e49 100644 --- a/sys/dev/usb/serial/umoscom.c +++ b/sys/dev/usb/serial/umoscom.c @@ -274,7 +274,7 @@ umoscom_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UMOSCOM_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index 24a4b36eb049..3bbb32af6e0d 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -306,7 +306,7 @@ uplcom_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UPLCOM_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c index 5df0abb0867c..cdf843942868 100644 --- a/sys/dev/usb/serial/uslcom.c +++ b/sys/dev/usb/serial/uslcom.c @@ -206,7 +206,7 @@ uslcom_probe(device_t dev) DPRINTFN(11, "\n"); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != USLCOM_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c index 54de2e29b8ee..a74a03fbb260 100644 --- a/sys/dev/usb/serial/uvisor.c +++ b/sys/dev/usb/serial/uvisor.c @@ -273,7 +273,7 @@ uvisor_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UVISOR_CONFIG_INDEX) { diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c index cfda9f8cca0a..7e1fb19b8a2c 100644 --- a/sys/dev/usb/serial/uvscom.c +++ b/sys/dev/usb/serial/uvscom.c @@ -257,7 +257,7 @@ uvscom_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->info.bConfigIndex != UVSCOM_CONFIG_INDEX) { diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index bca5d998e554..b87f1bd1f898 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -1428,7 +1428,7 @@ umass_probe(device_t dev) struct usb2_attach_arg *uaa = device_get_ivars(dev); struct umass_probe_proto temp; - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->use_generic == 0) { diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c index 0c27aa04d6cc..442e38da4447 100644 --- a/sys/dev/usb/storage/urio.c +++ b/sys/dev/usb/storage/urio.c @@ -189,7 +189,7 @@ urio_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if ((((uaa->info.idVendor == USB_VENDOR_DIAMOND) && diff --git a/sys/dev/usb/storage/ustorage_fs.c b/sys/dev/usb/storage/ustorage_fs.c index 8e8a50981a41..02319440337c 100644 --- a/sys/dev/usb/storage/ustorage_fs.c +++ b/sys/dev/usb/storage/ustorage_fs.c @@ -317,7 +317,7 @@ ustorage_fs_probe(device_t dev) struct usb2_attach_arg *uaa = device_get_ivars(dev); struct usb2_interface_descriptor *id; - if (uaa->usb2_mode != USB_MODE_DEVICE) { + if (uaa->usb_mode != USB_MODE_DEVICE) { return (ENXIO); } if (uaa->use_generic == 0) { diff --git a/sys/dev/usb/usb_busdma.c b/sys/dev/usb/usb_busdma.c index c8f30ed28b0b..5fb67c58b658 100644 --- a/sys/dev/usb/usb_busdma.c +++ b/sys/dev/usb/usb_busdma.c @@ -1279,7 +1279,7 @@ usb2_bdma_work_loop(struct usb2_xfer_queue *pq) if (xfer->flags_int.control_xfr && xfer->flags_int.control_hdr) { /* special case */ - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { /* The device controller writes to memory */ xfer->frbuffers[0].isread = 1; } else { diff --git a/sys/dev/usb/usb_compat_linux.c b/sys/dev/usb/usb_compat_linux.c index 85dba849659f..c7906c2be657 100644 --- a/sys/dev/usb/usb_compat_linux.c +++ b/sys/dev/usb/usb_compat_linux.c @@ -194,7 +194,7 @@ usb_linux_probe(device_t dev) struct usb_driver *udrv; int err = ENXIO; - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } mtx_lock(&Giant); @@ -640,7 +640,7 @@ usb_control_msg(struct usb_device *dev, struct usb_host_endpoint *uhe, } return (err); } - if (dev->bsd_udev->flags.usb2_mode != USB_MODE_HOST) { + if (dev->bsd_udev->flags.usb_mode != USB_MODE_HOST) { /* not supported */ return (-EINVAL); } diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index 7a1c1e93c8de..a31474edeb92 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -233,7 +233,7 @@ * The following macro will tell if an USB transfer is currently * receiving or transferring data. */ -#define USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb2_mode == \ +#define USB_GET_DATA_ISREAD(xfer) ((xfer)->flags_int.usb_mode == \ USB_MODE_DEVICE ? (((xfer)->endpoint & UE_DIR_IN) ? 0 : 1) : \ (((xfer)->endpoint & UE_DIR_IN) ? 1 : 0)) @@ -354,6 +354,8 @@ struct usb2_xfer_flags { * flags. */ struct usb2_xfer_flags_int { + + enum usb_hc_mode usb_mode; /* shadow copy of "udev->usb_mode" */ uint16_t control_rem; /* remainder in bytes */ uint8_t open:1; /* set if USB pipe has been opened */ @@ -381,7 +383,6 @@ struct usb2_xfer_flags_int { uint8_t bdma_setup:1; /* set if BUS-DMA has been setup */ #endif uint8_t isochronous_xfr:1; /* set if isochronous transfer */ - uint8_t usb2_mode:1; /* shadow copy of "udev->usb2_mode" */ uint8_t curr_dma_set:1; /* used by USB HC/DC driver */ uint8_t can_cancel_immed:1; /* set if USB transfer can be * cancelled immediately */ @@ -399,13 +400,12 @@ struct usb2_config { #define USB_DEFAULT_INTERVAL 0 usb2_timeout_t timeout; /* transfer timeout in milliseconds */ struct usb2_xfer_flags flags; /* transfer flags */ + enum usb_hc_mode usb_mode; /* host or device mode */ uint8_t type; /* pipe type */ uint8_t endpoint; /* pipe number */ uint8_t direction; /* pipe direction */ uint8_t ep_index; /* pipe index match to use */ uint8_t if_index; /* "ifaces" index to use */ - uint8_t usb_mode; /* see "USB_MODE_XXX", - * "USB_MODE_MAX" means any mode! */ }; /* @@ -495,7 +495,7 @@ struct usb2_attach_arg { const void *driver_info; /* for internal use */ struct usb2_device *device; /* current device */ struct usb2_interface *iface; /* current interface */ - uint8_t usb2_mode; /* see USB_MODE_XXX */ + enum usb_hc_mode usb_mode; /* host or device mode */ uint8_t port; uint8_t use_generic; /* hint for generic drivers */ }; @@ -529,7 +529,7 @@ uint8_t usb2_clear_stall_callback(struct usb2_xfer *xfer1, uint8_t usb2_get_interface_altindex(struct usb2_interface *iface); usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev, uint8_t iface_index, uint8_t alt_index); -uint8_t usb2_get_mode(struct usb2_device *udev); +enum usb_hc_mode usb2_get_mode(struct usb2_device *udev); uint8_t usb2_get_speed(struct usb2_device *udev); uint32_t usb2_get_isoc_fps(struct usb2_device *udev); usb2_error_t usb2_transfer_setup(struct usb2_device *udev, diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index 33c536373668..b537f33cf5cd 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -597,13 +597,13 @@ usb2_dev_get_pipe(struct usb2_device *udev, uint8_t ep_index, uint8_t dir) pipe = &udev->default_pipe; } else { if (dir == USB_FIFO_RX) { - if (udev->flags.usb2_mode == USB_MODE_HOST) { + if (udev->flags.usb_mode == USB_MODE_HOST) { ep_dir = UE_DIR_IN; } else { ep_dir = UE_DIR_OUT; } } else { - if (udev->flags.usb2_mode == USB_MODE_HOST) { + if (udev->flags.usb_mode == USB_MODE_HOST) { ep_dir = UE_DIR_OUT; } else { ep_dir = UE_DIR_IN; diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 2463c1f2dba9..2cb593a80c62 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -187,8 +187,8 @@ usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index, /* check USB mode */ - if ((setup->usb_mode != USB_MODE_MAX) && - (udev->flags.usb2_mode != setup->usb_mode)) { + if (setup->usb_mode != USB_MODE_DUAL && + udev->flags.usb_mode != setup->usb_mode) { /* wrong mode - no pipe */ return (NULL); } @@ -197,11 +197,11 @@ usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index, if (setup->direction == UE_DIR_RX) { ea_mask = (UE_DIR_IN | UE_DIR_OUT); - ea_val = (udev->flags.usb2_mode == USB_MODE_DEVICE) ? + ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ? UE_DIR_OUT : UE_DIR_IN; } else if (setup->direction == UE_DIR_TX) { ea_mask = (UE_DIR_IN | UE_DIR_OUT); - ea_val = (udev->flags.usb2_mode == USB_MODE_DEVICE) ? + ea_val = (udev->flags.usb_mode == USB_MODE_DEVICE) ? UE_DIR_IN : UE_DIR_OUT; } else if (setup->direction == UE_DIR_ANY) { /* match any endpoint direction */ @@ -416,7 +416,7 @@ usb2_unconfigure(struct usb2_device *udev, uint8_t flag) /* free "cdesc" after "ifaces" and "pipes", if any */ if (udev->cdesc != NULL) { - if (udev->flags.usb2_mode != USB_MODE_DEVICE) + if (udev->flags.usb_mode != USB_MODE_DEVICE) free(udev->cdesc, M_USB); udev->cdesc = NULL; } @@ -475,7 +475,7 @@ usb2_set_config_index(struct usb2_device *udev, uint8_t index) goto done; } /* get the full config descriptor */ - if (udev->flags.usb2_mode == USB_MODE_DEVICE) { + if (udev->flags.usb_mode == USB_MODE_DEVICE) { /* save some memory */ err = usb2_req_get_descriptor_ptr(udev, &cdp, (UDESC_CONFIG << 8) | index); @@ -495,7 +495,7 @@ usb2_set_config_index(struct usb2_device *udev, uint8_t index) selfpowered = 0; if ((!udev->flags.uq_bus_powered) && (cdp->bmAttributes & UC_SELF_POWERED) && - (udev->flags.usb2_mode == USB_MODE_HOST)) { + (udev->flags.usb_mode == USB_MODE_HOST)) { /* May be self powered. */ if (cdp->bmAttributes & UC_BUS_POWERED) { /* Must ask device. */ @@ -533,7 +533,7 @@ usb2_set_config_index(struct usb2_device *udev, uint8_t index) goto done; } /* Only update "self_powered" in USB Host Mode */ - if (udev->flags.usb2_mode == USB_MODE_HOST) { + if (udev->flags.usb_mode == USB_MODE_HOST) { udev->flags.self_powered = selfpowered; } udev->power = power; @@ -815,7 +815,7 @@ usb2_set_alt_interface_index(struct usb2_device *udev, err = USB_ERR_INVAL; goto done; } - if (udev->flags.usb2_mode == USB_MODE_DEVICE) { + if (udev->flags.usb_mode == USB_MODE_DEVICE) { usb2_detach_device(udev, iface_index, USB_UNCFG_FLAG_FREE_SUBDEV); } else { @@ -1178,7 +1178,7 @@ usb2_init_attach_arg(struct usb2_device *udev, bzero(uaa, sizeof(*uaa)); uaa->device = udev; - uaa->usb2_mode = udev->flags.usb2_mode; + uaa->usb_mode = udev->flags.usb_mode; uaa->port = udev->port_no; uaa->info.idVendor = UGETW(udev->ddesc.idVendor); @@ -1416,8 +1416,8 @@ usb2_clear_stall_proc(struct usb2_proc_msg *_pm) *------------------------------------------------------------------------*/ struct usb2_device * usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, - struct usb2_device *parent_hub, uint8_t depth, - uint8_t port_index, uint8_t port_no, uint8_t speed, uint8_t usb2_mode) + struct usb2_device *parent_hub, uint8_t depth, uint8_t port_index, + uint8_t port_no, uint8_t speed, enum usb_hc_mode mode) { struct usb2_attach_arg uaa; struct usb2_device *udev; @@ -1429,9 +1429,9 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, uint8_t device_index; DPRINTF("parent_dev=%p, bus=%p, parent_hub=%p, depth=%u, " - "port_index=%u, port_no=%u, speed=%u, usb2_mode=%u\n", + "port_index=%u, port_no=%u, speed=%u, usb_mode=%u\n", parent_dev, bus, parent_hub, depth, port_index, port_no, - speed, usb2_mode); + speed, mode); /* * Find an unused device index. In USB Host mode this is the @@ -1509,7 +1509,7 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, udev->ddesc.bMaxPacketSize = USB_MAX_IPACKET; udev->speed = speed; - udev->flags.usb2_mode = usb2_mode; + udev->flags.usb_mode = mode; /* search for our High Speed USB HUB, if any */ @@ -1548,7 +1548,7 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, /* Create a link from /dev/ugenX.X to the default endpoint */ make_dev_alias(udev->default_dev, udev->ugen_name); #endif - if (udev->flags.usb2_mode == USB_MODE_HOST) { + if (udev->flags.usb_mode == USB_MODE_HOST) { err = usb2_req_set_address(udev, NULL, device_index); @@ -1703,7 +1703,7 @@ usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, usb2_check_strings(udev); #endif - if (udev->flags.usb2_mode == USB_MODE_HOST) { + if (udev->flags.usb_mode == USB_MODE_HOST) { uint8_t config_index; uint8_t config_quirk; uint8_t set_config_failed = 0; @@ -1981,7 +1981,7 @@ usb2_free_device(struct usb2_device *udev, uint8_t flag) udev->default_dev->si_drv1); #endif - if (udev->flags.usb2_mode == USB_MODE_DEVICE) { + if (udev->flags.usb_mode == USB_MODE_DEVICE) { /* stop receiving any control transfers (Device Side Mode) */ usb2_transfer_unsetup(udev->default_xfer, USB_DEFAULT_XFER_MAX); } @@ -2239,10 +2239,10 @@ usb2_check_strings(struct usb2_device *udev) * Returns: * See: USB_MODE_XXX */ -uint8_t +enum usb_hc_mode usb2_get_mode(struct usb2_device *udev) { - return (udev->flags.usb2_mode); + return (udev->flags.usb_mode); } /* @@ -2452,7 +2452,7 @@ usb2_peer_can_wakeup(struct usb2_device *udev) const struct usb2_config_descriptor *cdp; cdp = udev->cdesc; - if ((cdp != NULL) && (udev->flags.usb2_mode == USB_MODE_HOST)) { + if ((cdp != NULL) && (udev->flags.usb_mode == USB_MODE_HOST)) { return (cdp->bmAttributes & UC_REMOTE_WAKEUP); } return (0); /* not supported */ diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h index 4aa385f59eea..9aba3fb27b63 100644 --- a/sys/dev/usb/usb_device.h +++ b/sys/dev/usb/usb_device.h @@ -83,7 +83,7 @@ struct usb2_interface { * The following structure defines the USB device flags. */ struct usb2_device_flags { - uint8_t usb2_mode:1; /* USB mode (see USB_MODE_XXX) */ + enum usb_hc_mode usb_mode; /* host or device mode */ uint8_t self_powered:1; /* set if USB device is self powered */ uint8_t no_strings:1; /* set if USB device does not support * strings */ @@ -190,7 +190,7 @@ extern int usb2_template; struct usb2_device *usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, struct usb2_device *parent_hub, uint8_t depth, uint8_t port_index, uint8_t port_no, uint8_t speed, - uint8_t usb2_mode); + enum usb_hc_mode mode); struct usb2_pipe *usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index, const struct usb2_config *setup); struct usb2_pipe *usb2_get_pipe_by_addr(struct usb2_device *udev, uint8_t ea_val); diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index d7d73b88d693..54308b86292c 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -233,7 +233,7 @@ ugen_open_pipe_write(struct usb2_fifo *f) usb2_config[0].direction = UE_DIR_TX; usb2_config[0].interval = USB_DEFAULT_INTERVAL; usb2_config[0].flags.proxy_buffer = 1; - usb2_config[0].usb_mode = USB_MODE_MAX; /* both modes */ + usb2_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ switch (ed->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: @@ -301,7 +301,7 @@ ugen_open_pipe_read(struct usb2_fifo *f) usb2_config[0].direction = UE_DIR_RX; usb2_config[0].interval = USB_DEFAULT_INTERVAL; usb2_config[0].flags.proxy_buffer = 1; - usb2_config[0].usb_mode = USB_MODE_MAX; /* both modes */ + usb2_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ switch (ed->bmAttributes & UE_XFERTYPE) { case UE_INTERRUPT: @@ -584,7 +584,7 @@ ugen_set_config(struct usb2_fifo *f, uint8_t index) { DPRINTFN(2, "index %u\n", index); - if (f->udev->flags.usb2_mode != USB_MODE_HOST) { + if (f->udev->flags.usb_mode != USB_MODE_HOST) { /* not possible in device side mode */ return (ENOTTY); } @@ -615,7 +615,7 @@ ugen_set_interface(struct usb2_fifo *f, { DPRINTFN(2, "%u, %u\n", iface_index, alt_index); - if (f->udev->flags.usb2_mode != USB_MODE_HOST) { + if (f->udev->flags.usb_mode != USB_MODE_HOST) { /* not possible in device side mode */ return (ENOTTY); } @@ -821,7 +821,7 @@ usb2_gen_fill_deviceinfo(struct usb2_fifo *f, struct usb2_device_info *di) di->udi_config_index = udev->curr_config_index; di->udi_power = udev->flags.self_powered ? 0 : udev->power; di->udi_speed = udev->speed; - di->udi_mode = udev->flags.usb2_mode; + di->udi_mode = udev->flags.usb_mode; di->udi_power_mode = udev->power_mode; di->udi_suspended = udev->flags.peer_suspended; @@ -1465,10 +1465,10 @@ ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags) usb2_config[0].timeout = 0; /* no timeout */ usb2_config[0].frames = u.popen->max_frames; usb2_config[0].bufsize = u.popen->max_bufsize; - usb2_config[0].usb_mode = USB_MODE_MAX; /* both modes */ + usb2_config[0].usb_mode = USB_MODE_DUAL; /* both modes */ if (usb2_config[0].type == UE_CONTROL) { - if (f->udev->flags.usb2_mode != USB_MODE_HOST) { + if (f->udev->flags.usb_mode != USB_MODE_HOST) { error = EINVAL; break; } @@ -1477,7 +1477,7 @@ ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags) isread = ((usb2_config[0].endpoint & (UE_DIR_IN | UE_DIR_OUT)) == UE_DIR_IN); - if (f->udev->flags.usb2_mode != USB_MODE_HOST) { + if (f->udev->flags.usb_mode != USB_MODE_HOST) { isread = !isread; } /* check permissions */ @@ -1530,7 +1530,7 @@ ugen_ioctl(struct usb2_fifo *f, u_long cmd, void *addr, int fflags) error = EINVAL; break; } - if (f->udev->flags.usb2_mode != USB_MODE_HOST) { + if (f->udev->flags.usb_mode != USB_MODE_HOST) { error = EINVAL; break; } diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index f92072bacc8e..bce58e50f86e 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -223,7 +223,7 @@ uhub_explore_sub(struct uhub_softc *sc, struct usb2_port *up) } /* start control transfer, if device mode */ - if (child->flags.usb2_mode == USB_MODE_DEVICE) { + if (child->flags.usb_mode == USB_MODE_DEVICE) { usb2_default_transfer_setup(child); } /* if a HUB becomes present, do a recursive HUB explore */ @@ -276,7 +276,7 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) usb2_error_t err; uint8_t timeout; uint8_t speed; - uint8_t usb2_mode; + enum usb_hc_mode mode; DPRINTF("reattaching port %d\n", portno); @@ -404,14 +404,14 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) * NOTE: This part is currently FreeBSD specific. */ if (sc->sc_st.port_status & UPS_PORT_MODE_DEVICE) - usb2_mode = USB_MODE_DEVICE; + mode = USB_MODE_DEVICE; else - usb2_mode = USB_MODE_HOST; + mode = USB_MODE_HOST; /* need to create a new child */ child = usb2_alloc_device(sc->sc_dev, udev->bus, udev, - udev->depth + 1, portno - 1, portno, speed, usb2_mode); + udev->depth + 1, portno - 1, portno, speed, mode); if (child == NULL) { DPRINTFN(0, "could not allocate new device!\n"); goto error; @@ -495,7 +495,7 @@ uhub_suspend_resume_port(struct uhub_softc *sc, uint8_t portno) */ if (is_suspend == 0) usb2_dev_resume_peer(child); - else if (child->flags.usb2_mode == USB_MODE_DEVICE) + else if (child->flags.usb_mode == USB_MODE_DEVICE) usb2_dev_suspend_peer(child); } done: @@ -638,7 +638,7 @@ uhub_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } /* @@ -1505,7 +1505,7 @@ usb2_transfer_power_ref(struct usb2_xfer *xfer, int val) if (xfer->flags_int.control_xfr) { udev->pwr_save.read_refs += val; - if (xfer->flags_int.usb2_mode == USB_MODE_HOST) { + if (xfer->flags_int.usb_mode == USB_MODE_HOST) { /* * it is not allowed to suspend during a control * transfer @@ -1706,7 +1706,7 @@ usb2_dev_resume_peer(struct usb2_device *udev) DPRINTF("udev=%p\n", udev); - if ((udev->flags.usb2_mode == USB_MODE_DEVICE) && + if ((udev->flags.usb_mode == USB_MODE_DEVICE) && (udev->flags.remote_wakeup == 0)) { /* * If the host did not set the remote wakeup feature, we can diff --git a/sys/dev/usb/usb_hub.h b/sys/dev/usb/usb_hub.h index 0c8905d6de97..74df2b959202 100644 --- a/sys/dev/usb/usb_hub.h +++ b/sys/dev/usb/usb_hub.h @@ -34,8 +34,7 @@ struct usb2_port { uint8_t restartcnt; #define USB_RESTART_MAX 5 uint8_t device_index; /* zero means not valid */ - uint8_t usb2_mode:1; /* current USB mode */ - uint8_t unused:7; + enum usb_hc_mode usb_mode; /* host or device mode */ }; /* diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index 8b18bbc5cb5c..aa454cb9025d 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -176,7 +176,7 @@ static usb2_handle_request_t * usb2_get_hr_func(struct usb2_device *udev) { /* figure out if there is a Handle Request function */ - if (udev->flags.usb2_mode == USB_MODE_DEVICE) + if (udev->flags.usb_mode == USB_MODE_DEVICE) return (usb2_temp_get_desc_p); else if (udev->parent_hub == NULL) return (udev->bus->methods->roothub_exec); @@ -1485,7 +1485,7 @@ usb2_req_re_enumerate(struct usb2_device *udev, struct mtx *mtx) uint8_t old_addr; uint8_t do_retry = 1; - if (udev->flags.usb2_mode != USB_MODE_HOST) { + if (udev->flags.usb_mode != USB_MODE_HOST) { return (USB_ERR_INVAL); } old_addr = udev->address; diff --git a/sys/dev/usb/usb_revision.h b/sys/dev/usb/usb_revision.h index 18b2d67020f6..978d8d59fb52 100644 --- a/sys/dev/usb/usb_revision.h +++ b/sys/dev/usb/usb_revision.h @@ -36,8 +36,8 @@ enum usb2_speed { USB_SPEED_FULL, USB_SPEED_HIGH, USB_SPEED_SUPER, - USB_SPEED_MAX }; +#define USB_SPEED_MAX (USB_SPEED_SUPER+1) /* * The "USB_REV" macros defines all the supported USB revisions. @@ -49,18 +49,19 @@ enum usb2_revision { USB_REV_1_1, USB_REV_2_0, USB_REV_2_5, - USB_REV_3_0, - USB_REV_MAX + USB_REV_3_0 }; +#define USB_REV_MAX (USB_REV_3_0+1) /* - * The "USB_MODE" macros defines all the supported USB modes. + * Supported host contoller modes. */ -enum usb2_mode { - USB_MODE_HOST, - USB_MODE_DEVICE, - USB_MODE_MAX +enum usb_hc_mode { + USB_MODE_HOST, /* initiates transfers */ + USB_MODE_DEVICE, /* bus transfer target */ + USB_MODE_DUAL /* can be host or device */ }; +#define USB_MODE_MAX (USB_MODE_DUAL+1) /* * The "USB_MODE" macros defines all the supported device states. @@ -71,6 +72,6 @@ enum usb2_dev_state { USB_STATE_POWERED, USB_STATE_ADDRESSED, USB_STATE_CONFIGURED, - USB_STATE_MAX, }; +#define USB_STATE_MAX (USB_STATE_CONFIGURED+1) #endif /* _USB2_REVISION_H_ */ diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index d3c289645616..f63a46c6abcc 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -63,7 +63,7 @@ static const struct usb2_config usb2_control_ep_cfg[USB_DEFAULT_XFER_MAX] = { .bufsize = USB_EP0_BUFSIZE, /* bytes */ .flags = {.proxy_buffer = 1,}, .callback = &usb2_request_callback, - .usb_mode = USB_MODE_MAX, /* both modes */ + .usb_mode = USB_MODE_DUAL, /* both modes */ }, /* This transfer is used for generic clear stall only */ @@ -101,7 +101,7 @@ static void usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, static void usb2_request_callback(struct usb2_xfer *xfer) { - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) usb2_handle_request_callback(xfer); else usb2_do_request_callback(xfer); @@ -327,7 +327,7 @@ usb2_transfer_setup_sub(struct usb2_setup_params *parm) xfer->max_packet_size = UGETW(edesc->wMaxPacketSize); xfer->max_packet_count = 1; /* make a shadow copy: */ - xfer->flags_int.usb2_mode = parm->udev->flags.usb2_mode; + xfer->flags_int.usb_mode = parm->udev->flags.usb_mode; parm->bufsize = setup->bufsize; @@ -858,8 +858,8 @@ usb2_transfer_setup(struct usb2_device *udev, if ((pipe == NULL) || (pipe->methods == NULL)) { if (setup->flags.no_pipe_ok) continue; - if ((setup->usb_mode != USB_MODE_MAX) && - (setup->usb_mode != udev->flags.usb2_mode)) + if ((setup->usb_mode != USB_MODE_DUAL) && + (setup->usb_mode != udev->flags.usb_mode)) continue; parm.err = USB_ERR_NO_PIPE; goto done; @@ -1256,7 +1256,7 @@ usb2_start_hardware_sub(struct usb2_xfer *xfer) xfer->flags_int.control_hdr = 0; /* setup control transfer */ - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { usb2_control_transfer_init(xfer); } } @@ -1275,7 +1275,7 @@ usb2_start_hardware_sub(struct usb2_xfer *xfer) goto error; } /* check USB mode */ - if (xfer->flags_int.usb2_mode == USB_MODE_DEVICE) { + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { /* check number of frames */ if (xfer->nframes != 1) { @@ -2241,7 +2241,7 @@ usb2_pipe_start(struct usb2_xfer_queue *pq) udev = info->udev; pipe->is_stalled = 1; - if (udev->flags.usb2_mode == USB_MODE_DEVICE) { + if (udev->flags.usb_mode == USB_MODE_DEVICE) { (udev->bus->methods->set_stall) ( udev, NULL, pipe); } else if (udev->default_xfer[1]) { @@ -2574,7 +2574,7 @@ usb2_default_transfer_setup(struct usb2_device *udev) ((xfer->address == udev->address) && (udev->default_ep_desc.wMaxPacketSize[0] == udev->ddesc.bMaxPacketSize)); - if (udev->flags.usb2_mode == USB_MODE_DEVICE) { + if (udev->flags.usb_mode == USB_MODE_DEVICE) { if (no_resetup) { /* * NOTE: checking "xfer->address" and diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index 9d8e575ffabb..d4fac36db3cf 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -411,7 +411,7 @@ rum_match(device_t self) { struct usb2_attach_arg *uaa = device_get_ivars(self); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != 0) return (ENXIO); diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index f5f1b1a24afc..59ebdb3e1d36 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -329,7 +329,7 @@ uath_match(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != UATH_CONFIG_INDEX) return (ENXIO); diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index c10e8ec61544..b82d90d252bc 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -232,7 +232,7 @@ upgt_match(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != UPGT_CONFIG_INDEX) return (ENXIO); diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index 732b52039c20..d36ba5c92c21 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -414,7 +414,7 @@ ural_match(device_t self) { struct usb2_attach_arg *uaa = device_get_ivars(self); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != 0) return (ENXIO); diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index ecf1e88c5848..bad6a9d83dfd 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -320,7 +320,7 @@ zyd_match(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != ZYD_CONFIG_INDEX) return (ENXIO); From 8d2dd5dd85cd6e9aa0e51054c23ac5f2d4109b18 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 01:05:21 +0000 Subject: [PATCH 353/544] Use enums for speed and rev data types. --- sys/dev/usb/controller/usb_controller.c | 2 +- sys/dev/usb/template/usb_template.c | 16 ++++++++-------- sys/dev/usb/usb_bus.h | 2 +- sys/dev/usb/usb_compat_linux.h | 2 +- sys/dev/usb/usb_controller.h | 2 +- sys/dev/usb/usb_core.h | 4 ++-- sys/dev/usb/usb_device.c | 8 ++++---- sys/dev/usb/usb_device.h | 10 +++++----- sys/dev/usb/usb_hub.c | 6 +++--- sys/dev/usb/usb_revision.h | 6 +++--- sys/dev/usb/usb_transfer.c | 18 +++++++++--------- sys/dev/usb/usb_transfer.h | 2 +- 12 files changed, 39 insertions(+), 39 deletions(-) diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index cf30051a5c2b..66ea1727d583 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -290,7 +290,7 @@ usb2_bus_attach(struct usb2_proc_msg *pm) struct usb2_device *child; device_t dev; usb2_error_t err; - uint8_t speed; + enum usb_dev_speed speed; bus = ((struct usb2_bus_msg *)pm)->bus; dev = bus->bdev; diff --git a/sys/dev/usb/template/usb_template.c b/sys/dev/usb/template/usb_template.c index cc407965df2c..de704ffa1b36 100644 --- a/sys/dev/usb/template/usb_template.c +++ b/sys/dev/usb/template/usb_template.c @@ -167,7 +167,7 @@ usb2_make_endpoint_desc(struct usb2_temp_setup *temp, temp->err = USB_ERR_INVAL; return; } - mps = ted->pPacketSize->mps[temp->usb2_speed]; + mps = ted->pPacketSize->mps[temp->usb_speed]; if (mps == 0) { /* not initialized */ temp->err = USB_ERR_INVAL; @@ -194,9 +194,9 @@ usb2_make_endpoint_desc(struct usb2_temp_setup *temp, /* setup bInterval parameter */ if (ted->pIntervals && - ted->pIntervals->bInterval[temp->usb2_speed]) { + ted->pIntervals->bInterval[temp->usb_speed]) { ed->bInterval = - ted->pIntervals->bInterval[temp->usb2_speed]; + ted->pIntervals->bInterval[temp->usb_speed]; } else { switch (et) { case UE_BULK: @@ -204,7 +204,7 @@ usb2_make_endpoint_desc(struct usb2_temp_setup *temp, ed->bInterval = 0; /* not used */ break; case UE_INTERRUPT: - switch (temp->usb2_speed) { + switch (temp->usb_speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: ed->bInterval = 1; /* 1 ms */ @@ -215,7 +215,7 @@ usb2_make_endpoint_desc(struct usb2_temp_setup *temp, } break; default: /* UE_ISOCHRONOUS */ - switch (temp->usb2_speed) { + switch (temp->usb_speed) { case USB_SPEED_LOW: case USB_SPEED_FULL: ed->bInterval = 1; /* 1 ms */ @@ -435,7 +435,7 @@ usb2_make_device_desc(struct usb2_temp_setup *temp, USETW(utd->udq.bcdUSB, 0x0200); utd->udq.bMaxPacketSize0 = 0; - switch (temp->usb2_speed) { + switch (temp->usb_speed) { case USB_SPEED_LOW: USETW(utd->udd.bcdUSB, 0x0110); utd->udd.bMaxPacketSize = 8; @@ -622,9 +622,9 @@ usb2_hw_ep_get_needs(struct usb2_hw_ep_scratch *ues, struct usb2_descriptor *desc; struct usb2_interface_descriptor *id; struct usb2_endpoint_descriptor *ed; + enum usb_dev_speed speed; uint16_t wMaxPacketSize; uint16_t temp; - uint8_t speed; uint8_t ep_no; ep_iface = ues->ep_max; @@ -1192,7 +1192,7 @@ usb2_temp_setup(struct usb2_device *udev, bzero(uts, sizeof(*uts)); - uts->usb2_speed = udev->speed; + uts->usb_speed = udev->speed; uts->self_powered = udev->flags.self_powered; /* first pass */ diff --git a/sys/dev/usb/usb_bus.h b/sys/dev/usb/usb_bus.h index e778c6c28ea9..66c2fac3934d 100644 --- a/sys/dev/usb/usb_bus.h +++ b/sys/dev/usb/usb_bus.h @@ -93,7 +93,7 @@ struct usb2_bus { uint8_t alloc_failed; /* Set if memory allocation failed. */ uint8_t driver_added_refcount; /* Current driver generation count */ - uint8_t usbrev; /* USB revision. See "USB_REV_XXX". */ + enum usb_revision usbrev; /* USB revision. See "USB_REV_XXX". */ uint8_t devices_max; /* maximum number of USB devices */ uint8_t do_probe; /* set if USB BUS should be re-probed */ diff --git a/sys/dev/usb/usb_compat_linux.h b/sys/dev/usb/usb_compat_linux.h index c63d82e42daa..44db8e2b7c2b 100644 --- a/sys/dev/usb/usb_compat_linux.h +++ b/sys/dev/usb/usb_compat_linux.h @@ -370,7 +370,7 @@ struct usb_device { uint16_t devnum; - uint8_t speed; /* USB_SPEED_XXX */ + enum usb_dev_speed speed; /* USB_SPEED_XXX */ } __aligned(USB_HOST_ALIGN); /* diff --git a/sys/dev/usb/usb_controller.h b/sys/dev/usb/usb_controller.h index 70b65514b38a..48c20cbefce4 100644 --- a/sys/dev/usb/usb_controller.h +++ b/sys/dev/usb/usb_controller.h @@ -171,7 +171,7 @@ struct usb2_hw_ep_scratch { struct usb2_temp_setup { void *buf; usb2_size_t size; - uint8_t usb2_speed; + enum usb_dev_speed usb_speed; uint8_t self_powered; uint8_t bNumEndpoints; uint8_t bInterfaceNumber; diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index a31474edeb92..eec357d3f908 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -515,7 +515,7 @@ typedef struct malloc_type *usb2_malloc_type; /* prototypes */ const char *usb2_errstr(usb2_error_t error); -const char *usb2_statestr(enum usb2_dev_state state); +const char *usb2_statestr(enum usb_dev_state state); struct usb2_config_descriptor *usb2_get_config_descriptor( struct usb2_device *udev); struct usb2_device_descriptor *usb2_get_device_descriptor( @@ -530,7 +530,7 @@ uint8_t usb2_get_interface_altindex(struct usb2_interface *iface); usb2_error_t usb2_set_alt_interface_index(struct usb2_device *udev, uint8_t iface_index, uint8_t alt_index); enum usb_hc_mode usb2_get_mode(struct usb2_device *udev); -uint8_t usb2_get_speed(struct usb2_device *udev); +enum usb_dev_speed usb2_get_speed(struct usb2_device *udev); uint32_t usb2_get_isoc_fps(struct usb2_device *udev); usb2_error_t usb2_transfer_setup(struct usb2_device *udev, const uint8_t *ifaces, struct usb2_xfer **pxfer, diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 2cb593a80c62..20bc029d9772 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -99,7 +99,7 @@ static const char* statestr[USB_STATE_MAX] = { }; const char * -usb2_statestr(enum usb2_dev_state state) +usb2_statestr(enum usb_dev_state state) { return ((state < USB_STATE_MAX) ? statestr[state] : "UNKNOWN"); } @@ -1417,7 +1417,7 @@ usb2_clear_stall_proc(struct usb2_proc_msg *_pm) struct usb2_device * usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, struct usb2_device *parent_hub, uint8_t depth, uint8_t port_index, - uint8_t port_no, uint8_t speed, enum usb_hc_mode mode) + uint8_t port_no, enum usb_dev_speed speed, enum usb_hc_mode mode) { struct usb2_attach_arg uaa; struct usb2_device *udev; @@ -2249,7 +2249,7 @@ usb2_get_mode(struct usb2_device *udev) * Returns: * See: USB_SPEED_XXX */ -uint8_t +enum usb_dev_speed usb2_get_speed(struct usb2_device *udev) { return (udev->speed); @@ -2459,7 +2459,7 @@ usb2_peer_can_wakeup(struct usb2_device *udev) } void -usb2_set_device_state(struct usb2_device *udev, enum usb2_dev_state state) +usb2_set_device_state(struct usb2_device *udev, enum usb_dev_state state) { KASSERT(state < USB_STATE_MAX, ("invalid udev state")); diff --git a/sys/dev/usb/usb_device.h b/sys/dev/usb/usb_device.h index 9aba3fb27b63..d262d3e51344 100644 --- a/sys/dev/usb/usb_device.h +++ b/sys/dev/usb/usb_device.h @@ -145,7 +145,8 @@ struct usb2_device { #endif usb2_ticks_t plugtime; /* copy of "ticks" */ - enum usb2_dev_state state; + enum usb_dev_state state; + enum usb_dev_speed speed; uint16_t refcount; #define USB_DEV_REF_MAX 0xffff @@ -157,7 +158,6 @@ struct usb2_device { uint8_t curr_config_index; /* current configuration index */ uint8_t curr_config_no; /* current configuration number */ uint8_t depth; /* distance from root HUB */ - uint8_t speed; /* low/full/high speed */ uint8_t port_index; /* parent HUB port index */ uint8_t port_no; /* parent HUB port number */ uint8_t hs_hub_addr; /* high-speed HUB address */ @@ -189,8 +189,8 @@ extern int usb2_template; struct usb2_device *usb2_alloc_device(device_t parent_dev, struct usb2_bus *bus, struct usb2_device *parent_hub, uint8_t depth, - uint8_t port_index, uint8_t port_no, uint8_t speed, - enum usb_hc_mode mode); + uint8_t port_index, uint8_t port_no, + enum usb_dev_speed speed, enum usb_hc_mode mode); struct usb2_pipe *usb2_get_pipe(struct usb2_device *udev, uint8_t iface_index, const struct usb2_config *setup); struct usb2_pipe *usb2_get_pipe_by_addr(struct usb2_device *udev, uint8_t ea_val); @@ -213,6 +213,6 @@ void usb_linux_free_device(struct usb_device *dev); uint8_t usb2_peer_can_wakeup(struct usb2_device *udev); struct usb2_pipe *usb2_pipe_foreach(struct usb2_device *udev, struct usb2_pipe *pipe); void usb2_set_device_state(struct usb2_device *udev, - enum usb2_dev_state state); + enum usb_dev_state state); #endif /* _USB2_DEVICE_H_ */ diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index bce58e50f86e..2c921bd47475 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -273,10 +273,10 @@ uhub_reattach_port(struct uhub_softc *sc, uint8_t portno) { struct usb2_device *child; struct usb2_device *udev; + enum usb_dev_speed speed; + enum usb_hc_mode mode; usb2_error_t err; uint8_t timeout; - uint8_t speed; - enum usb_hc_mode mode; DPRINTF("reattaching port %d\n", portno); @@ -1098,7 +1098,7 @@ usb2_intr_schedule_adjust(struct usb2_device *udev, int16_t len, uint8_t slot) { struct usb2_bus *bus = udev->bus; struct usb2_hub *hub; - uint8_t speed; + enum usb_dev_speed speed; USB_BUS_LOCK_ASSERT(bus, MA_OWNED); diff --git a/sys/dev/usb/usb_revision.h b/sys/dev/usb/usb_revision.h index 978d8d59fb52..d367e6c4f42e 100644 --- a/sys/dev/usb/usb_revision.h +++ b/sys/dev/usb/usb_revision.h @@ -30,7 +30,7 @@ /* * The "USB_SPEED" macros defines all the supported USB speeds. */ -enum usb2_speed { +enum usb_dev_speed { USB_SPEED_VARIABLE, USB_SPEED_LOW, USB_SPEED_FULL, @@ -42,7 +42,7 @@ enum usb2_speed { /* * The "USB_REV" macros defines all the supported USB revisions. */ -enum usb2_revision { +enum usb_revision { USB_REV_UNKNOWN, USB_REV_PRE_1_0, USB_REV_1_0, @@ -66,7 +66,7 @@ enum usb_hc_mode { /* * The "USB_MODE" macros defines all the supported device states. */ -enum usb2_dev_state { +enum usb_dev_state { USB_STATE_DETACHED, USB_STATE_ATTACHED, USB_STATE_POWERED, diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index f63a46c6abcc..1dd444b815fc 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -93,7 +93,7 @@ static void usb2_dma_delay_done_cb(void *); static void usb2_transfer_start_cb(void *); static uint8_t usb2_callback_wrapper_sub(struct usb2_xfer *); static void usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, - uint8_t type, uint8_t usb_speed); + uint8_t type, enum usb_dev_speed speed); /*------------------------------------------------------------------------* * usb2_request_callback @@ -2742,8 +2742,8 @@ usb2_do_poll(struct usb2_xfer **ppxfer, uint16_t max) } static void -usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, - uint8_t type, uint8_t usb_speed) +usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, + uint8_t type, enum usb_dev_speed speed) { static const uint16_t intr_range_max[USB_SPEED_MAX] = { [USB_SPEED_LOW] = 8, @@ -2783,16 +2783,16 @@ usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, switch (type) { case UE_INTERRUPT: - ptr->range.max = intr_range_max[usb_speed]; + ptr->range.max = intr_range_max[speed]; break; case UE_ISOCHRONOUS: - ptr->range.max = isoc_range_max[usb_speed]; + ptr->range.max = isoc_range_max[speed]; break; default: if (type == UE_BULK) - temp = bulk_min[usb_speed]; + temp = bulk_min[speed]; else /* UE_CONTROL */ - temp = control_min[usb_speed]; + temp = control_min[speed]; /* default is fixed */ ptr->fixed[0] = temp; @@ -2800,13 +2800,13 @@ usb2_get_std_packet_size(struct usb2_std_packet_size *ptr, ptr->fixed[2] = temp; ptr->fixed[3] = temp; - if (usb_speed == USB_SPEED_FULL) { + if (speed == USB_SPEED_FULL) { /* multiple sizes */ ptr->fixed[1] = 16; ptr->fixed[2] = 32; ptr->fixed[3] = 64; } - if ((usb_speed == USB_SPEED_VARIABLE) && + if ((speed == USB_SPEED_VARIABLE) && (type == UE_BULK)) { /* multiple sizes */ ptr->fixed[2] = 1024; diff --git a/sys/dev/usb/usb_transfer.h b/sys/dev/usb/usb_transfer.h index a15e8a3c0c96..c385dd822d1f 100644 --- a/sys/dev/usb/usb_transfer.h +++ b/sys/dev/usb/usb_transfer.h @@ -104,7 +104,7 @@ struct usb2_setup_params { uint16_t hc_max_frame_size; uint16_t hc_max_packet_size; uint8_t hc_max_packet_count; - uint8_t speed; + enum usb_dev_speed speed; uint8_t dma_tag_max; usb2_error_t err; }; From 596c08801d91a8bc75614bbf5e059439c0e8c31c Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 21 May 2009 01:14:12 +0000 Subject: [PATCH 354/544] Add a function to sys/nlm/nlm_prot_impl.c that returns a unique lock sysid to be used for non-nlm remote locking. This is required for the experimental nfsv4 server, so that it can acquire byte range locks correctly on behalf of nfsv4 clients. Reviewed by: dfr Approved by: kib (mentor) --- sys/nlm/nlm.h | 5 +++++ sys/nlm/nlm_prot_impl.c | 14 ++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/sys/nlm/nlm.h b/sys/nlm/nlm.h index 27b921fa5cec..d2c5ee1610a5 100644 --- a/sys/nlm/nlm.h +++ b/sys/nlm/nlm.h @@ -210,6 +210,11 @@ struct vop_reclaim_args; extern int nlm_advlock(struct vop_advlock_args *ap); extern int nlm_reclaim(struct vop_reclaim_args *ap); +/* + * Acquire the next sysid for remote locks not handled by the NLM. + */ +extern uint32_t nlm_acquire_next_sysid(void); + #endif #endif diff --git a/sys/nlm/nlm_prot_impl.c b/sys/nlm/nlm_prot_impl.c index a46d4327b0b0..6ee6baa282ac 100644 --- a/sys/nlm/nlm_prot_impl.c +++ b/sys/nlm/nlm_prot_impl.c @@ -834,6 +834,20 @@ nlm_create_host(const char* caller_name) return (host); } +/* + * Acquire the next sysid for remote locks not handled by the NLM. + */ +uint32_t +nlm_acquire_next_sysid(void) +{ + uint32_t next_sysid; + + mtx_lock(&nlm_global_lock); + next_sysid = nlm_next_sysid++; + mtx_unlock(&nlm_global_lock); + return (next_sysid); +} + /* * Return non-zero if the address parts of the two sockaddrs are the * same. From 9360ae40732b59f08fc5b328b57f0a20e9aac216 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 01:48:42 +0000 Subject: [PATCH 355/544] Rename the usb sysctl tree from hw.usb2.* back to hw.usb.*. Submitted by: Hans Petter Selasky --- UPDATING | 4 ++++ sys/dev/usb/controller/at91dci.c | 4 ++-- sys/dev/usb/controller/atmegadci.c | 4 ++-- sys/dev/usb/controller/ehci.c | 6 +++--- sys/dev/usb/controller/musb_otg.c | 4 ++-- sys/dev/usb/controller/ohci.c | 4 ++-- sys/dev/usb/controller/uhci.c | 6 +++--- sys/dev/usb/controller/usb_controller.c | 4 ++-- sys/dev/usb/controller/uss820dci.c | 4 ++-- sys/dev/usb/input/uhid.c | 4 ++-- sys/dev/usb/input/ukbd.c | 4 ++-- sys/dev/usb/input/ums.c | 4 ++-- sys/dev/usb/misc/udbp.c | 4 ++-- sys/dev/usb/net/if_aue.c | 4 ++-- sys/dev/usb/net/if_axe.c | 4 ++-- sys/dev/usb/net/if_cdce.c | 4 ++-- sys/dev/usb/net/if_cue.c | 4 ++-- sys/dev/usb/net/if_kue.c | 4 ++-- sys/dev/usb/net/if_rue.c | 4 ++-- sys/dev/usb/net/if_udav.c | 4 ++-- sys/dev/usb/serial/u3g.c | 4 ++-- sys/dev/usb/serial/ubsa.c | 4 ++-- sys/dev/usb/serial/ubser.c | 4 ++-- sys/dev/usb/serial/uchcom.c | 4 ++-- sys/dev/usb/serial/uftdi.c | 4 ++-- sys/dev/usb/serial/ulpt.c | 4 ++-- sys/dev/usb/serial/umodem.c | 4 ++-- sys/dev/usb/serial/umoscom.c | 4 ++-- sys/dev/usb/serial/uplcom.c | 4 ++-- sys/dev/usb/serial/usb_serial.c | 4 ++-- sys/dev/usb/serial/uslcom.c | 4 ++-- sys/dev/usb/serial/uvisor.c | 4 ++-- sys/dev/usb/serial/uvscom.c | 4 ++-- sys/dev/usb/storage/umass.c | 4 ++-- sys/dev/usb/storage/urio.c | 4 ++-- sys/dev/usb/storage/ustorage_fs.c | 4 ++-- sys/dev/usb/usb_debug.c | 4 ++-- sys/dev/usb/usb_debug.h | 2 +- sys/dev/usb/usb_dev.c | 4 ++-- sys/dev/usb/usb_device.c | 2 +- sys/dev/usb/usb_generic.c | 4 ++-- sys/dev/usb/usb_hub.c | 6 +++--- sys/dev/usb/usb_process.c | 4 ++-- sys/dev/usb/usb_request.c | 6 +++--- sys/dev/usb/wlan/if_rum.c | 4 ++-- sys/dev/usb/wlan/if_uath.c | 10 +++++----- sys/dev/usb/wlan/if_ural.c | 4 ++-- sys/dev/usb/wlan/if_zyd.c | 4 ++-- 48 files changed, 103 insertions(+), 99 deletions(-) diff --git a/UPDATING b/UPDATING index bb4dadec1246..11ca4b1d35e2 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090520: + The sysctl tree for the usb stack has renamed from hw.usb2.* to + hw.usb.* and is now consistent again with previous releases. + 20090520: 802.11 monitor mode support was revised and driver api's were changed. Drivers dependent on net80211 now support diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index a806800b415b..e65fc37ec4f0 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -73,8 +73,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int at91dcidebug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, at91dci, CTLFLAG_RW, 0, "USB at91dci"); -SYSCTL_INT(_hw_usb2_at91dci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, at91dci, CTLFLAG_RW, 0, "USB at91dci"); +SYSCTL_INT(_hw_usb_at91dci, OID_AUTO, debug, CTLFLAG_RW, &at91dcidebug, 0, "at91dci debug level"); #endif diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index 82665363c3de..a4b1274fc649 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -65,8 +65,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int atmegadci_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, atmegadci, CTLFLAG_RW, 0, "USB ATMEGA DCI"); -SYSCTL_INT(_hw_usb2_atmegadci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, atmegadci, CTLFLAG_RW, 0, "USB ATMEGA DCI"); +SYSCTL_INT(_hw_usb_atmegadci, OID_AUTO, debug, CTLFLAG_RW, &atmegadci_debug, 0, "ATMEGA DCI debug level"); #endif diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 99db9b31af62..6156cb8a906c 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -73,10 +73,10 @@ __FBSDID("$FreeBSD$"); static int ehcidebug = 0; static int ehcinohighspeed = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci"); -SYSCTL_INT(_hw_usb2_ehci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ehci, CTLFLAG_RW, 0, "USB ehci"); +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, debug, CTLFLAG_RW, &ehcidebug, 0, "Debug level"); -SYSCTL_INT(_hw_usb2_ehci, OID_AUTO, no_hs, CTLFLAG_RW, +SYSCTL_INT(_hw_usb_ehci, OID_AUTO, no_hs, CTLFLAG_RW, &ehcinohighspeed, 0, "Disable High Speed USB"); static void ehci_dump_regs(ehci_softc_t *sc); diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 198840cf379d..39b7612a07b9 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -67,8 +67,8 @@ #if USB_DEBUG static int musbotgdebug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg"); -SYSCTL_INT(_hw_usb2_musbotg, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, musbotg, CTLFLAG_RW, 0, "USB musbotg"); +SYSCTL_INT(_hw_usb_musbotg, OID_AUTO, debug, CTLFLAG_RW, &musbotgdebug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index fe88461cc2da..4b407ab368f8 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c @@ -61,8 +61,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ohcidebug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci"); -SYSCTL_INT(_hw_usb2_ohci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci"); +SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW, &ohcidebug, 0, "ohci debug level"); static void ohci_dumpregs(ohci_softc_t *); static void ohci_dump_tds(ohci_td_t *); diff --git a/sys/dev/usb/controller/uhci.c b/sys/dev/usb/controller/uhci.c index 1c52eec26872..7a6ba1628b91 100644 --- a/sys/dev/usb/controller/uhci.c +++ b/sys/dev/usb/controller/uhci.c @@ -66,10 +66,10 @@ __FBSDID("$FreeBSD$"); static int uhcidebug = 0; static int uhcinoloop = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uhci, CTLFLAG_RW, 0, "USB uhci"); -SYSCTL_INT(_hw_usb2_uhci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uhci, CTLFLAG_RW, 0, "USB uhci"); +SYSCTL_INT(_hw_usb_uhci, OID_AUTO, debug, CTLFLAG_RW, &uhcidebug, 0, "uhci debug level"); -SYSCTL_INT(_hw_usb2_uhci, OID_AUTO, loop, CTLFLAG_RW, +SYSCTL_INT(_hw_usb_uhci, OID_AUTO, loop, CTLFLAG_RW, &uhcinoloop, 0, "uhci noloop"); static void uhci_dumpregs(uhci_softc_t *sc); static void uhci_dump_tds(uhci_td_t *td); diff --git a/sys/dev/usb/controller/usb_controller.c b/sys/dev/usb/controller/usb_controller.c index 66ea1727d583..93e9c32e9db4 100644 --- a/sys/dev/usb/controller/usb_controller.c +++ b/sys/dev/usb/controller/usb_controller.c @@ -55,8 +55,8 @@ static void usb2_post_init(void *); #if USB_DEBUG static int usb2_ctrl_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller"); -SYSCTL_INT(_hw_usb2_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, ctrl, CTLFLAG_RW, 0, "USB controller"); +SYSCTL_INT(_hw_usb_ctrl, OID_AUTO, debug, CTLFLAG_RW, &usb2_ctrl_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index 67f74d897952..5a857d0d819f 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -62,8 +62,8 @@ #if USB_DEBUG static int uss820dcidebug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci"); -SYSCTL_INT(_hw_usb2_uss820dci, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uss820dci, CTLFLAG_RW, 0, "USB uss820dci"); +SYSCTL_INT(_hw_usb_uss820dci, OID_AUTO, debug, CTLFLAG_RW, &uss820dcidebug, 0, "uss820dci debug level"); #endif diff --git a/sys/dev/usb/input/uhid.c b/sys/dev/usb/input/uhid.c index 106b79245f65..da3b5a3473e5 100644 --- a/sys/dev/usb/input/uhid.c +++ b/sys/dev/usb/input/uhid.c @@ -76,8 +76,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uhid_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid"); -SYSCTL_INT(_hw_usb2_uhid, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uhid, CTLFLAG_RW, 0, "USB uhid"); +SYSCTL_INT(_hw_usb_uhid, OID_AUTO, debug, CTLFLAG_RW, &uhid_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/input/ukbd.c b/sys/dev/usb/input/ukbd.c index 3f528ec4e08a..d8d76c7fd144 100644 --- a/sys/dev/usb/input/ukbd.c +++ b/sys/dev/usb/input/ukbd.c @@ -86,8 +86,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ukbd_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd"); -SYSCTL_INT(_hw_usb2_ukbd, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ukbd, CTLFLAG_RW, 0, "USB ukbd"); +SYSCTL_INT(_hw_usb_ukbd, OID_AUTO, debug, CTLFLAG_RW, &ukbd_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/input/ums.c b/sys/dev/usb/input/ums.c index a9656c436f90..9b7d1fd8699c 100644 --- a/sys/dev/usb/input/ums.c +++ b/sys/dev/usb/input/ums.c @@ -72,8 +72,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ums_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums"); -SYSCTL_INT(_hw_usb2_ums, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ums, CTLFLAG_RW, 0, "USB ums"); +SYSCTL_INT(_hw_usb_ums, OID_AUTO, debug, CTLFLAG_RW, &ums_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/misc/udbp.c b/sys/dev/usb/misc/udbp.c index c72df51dcee4..1a7f8af5b024 100644 --- a/sys/dev/usb/misc/udbp.c +++ b/sys/dev/usb/misc/udbp.c @@ -83,8 +83,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int udbp_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp"); -SYSCTL_INT(_hw_usb2_udbp, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, udbp, CTLFLAG_RW, 0, "USB udbp"); +SYSCTL_INT(_hw_usb_udbp, OID_AUTO, debug, CTLFLAG_RW, &udbp_debug, 0, "udbp debug level"); #endif diff --git a/sys/dev/usb/net/if_aue.c b/sys/dev/usb/net/if_aue.c index 763d0c32c725..4902c1cd5d54 100644 --- a/sys/dev/usb/net/if_aue.c +++ b/sys/dev/usb/net/if_aue.c @@ -89,8 +89,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int aue_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, aue, CTLFLAG_RW, 0, "USB aue"); -SYSCTL_INT(_hw_usb2_aue, OID_AUTO, debug, CTLFLAG_RW, &aue_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, aue, CTLFLAG_RW, 0, "USB aue"); +SYSCTL_INT(_hw_usb_aue, OID_AUTO, debug, CTLFLAG_RW, &aue_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_axe.c b/sys/dev/usb/net/if_axe.c index 83dde03d487b..f720c4ec3ca0 100644 --- a/sys/dev/usb/net/if_axe.c +++ b/sys/dev/usb/net/if_axe.c @@ -112,8 +112,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int axe_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe"); -SYSCTL_INT(_hw_usb2_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, axe, CTLFLAG_RW, 0, "USB axe"); +SYSCTL_INT(_hw_usb_axe, OID_AUTO, debug, CTLFLAG_RW, &axe_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_cdce.c b/sys/dev/usb/net/if_cdce.c index 72c50f0c4053..0c1e4c1dc35a 100644 --- a/sys/dev/usb/net/if_cdce.c +++ b/sys/dev/usb/net/if_cdce.c @@ -88,8 +88,8 @@ static uint32_t cdce_m_crc32(struct mbuf *, uint32_t, uint32_t); #if USB_DEBUG static int cdce_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet"); -SYSCTL_INT(_hw_usb2_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, cdce, CTLFLAG_RW, 0, "USB CDC-Ethernet"); +SYSCTL_INT(_hw_usb_cdce, OID_AUTO, debug, CTLFLAG_RW, &cdce_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_cue.c b/sys/dev/usb/net/if_cue.c index eca9a8e90081..f5bb9aca20d9 100644 --- a/sys/dev/usb/net/if_cue.c +++ b/sys/dev/usb/net/if_cue.c @@ -109,8 +109,8 @@ static void cue_reset(struct cue_softc *); #if USB_DEBUG static int cue_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue"); -SYSCTL_INT(_hw_usb2_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, cue, CTLFLAG_RW, 0, "USB cue"); +SYSCTL_INT(_hw_usb_cue, OID_AUTO, debug, CTLFLAG_RW, &cue_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_kue.c b/sys/dev/usb/net/if_kue.c index dfdaefac3911..91b25b3ca27a 100644 --- a/sys/dev/usb/net/if_kue.c +++ b/sys/dev/usb/net/if_kue.c @@ -151,8 +151,8 @@ static void kue_reset(struct kue_softc *); #if USB_DEBUG static int kue_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, kue, CTLFLAG_RW, 0, "USB kue"); -SYSCTL_INT(_hw_usb2_kue, OID_AUTO, debug, CTLFLAG_RW, &kue_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, kue, CTLFLAG_RW, 0, "USB kue"); +SYSCTL_INT(_hw_usb_kue, OID_AUTO, debug, CTLFLAG_RW, &kue_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_rue.c b/sys/dev/usb/net/if_rue.c index 176ff1d25775..645177934ae1 100644 --- a/sys/dev/usb/net/if_rue.c +++ b/sys/dev/usb/net/if_rue.c @@ -86,8 +86,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int rue_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue"); -SYSCTL_INT(_hw_usb2_rue, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, rue, CTLFLAG_RW, 0, "USB rue"); +SYSCTL_INT(_hw_usb_rue, OID_AUTO, debug, CTLFLAG_RW, &rue_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/net/if_udav.c b/sys/dev/usb/net/if_udav.c index d301e8dfd0c4..3d3a05802fec 100644 --- a/sys/dev/usb/net/if_udav.c +++ b/sys/dev/usb/net/if_udav.c @@ -174,8 +174,8 @@ static const struct usb2_ether_methods udav_ue_methods = { #if USB_DEBUG static int udav_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav"); -SYSCTL_INT(_hw_usb2_udav, OID_AUTO, debug, CTLFLAG_RW, &udav_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, udav, CTLFLAG_RW, 0, "USB udav"); +SYSCTL_INT(_hw_usb_udav, OID_AUTO, debug, CTLFLAG_RW, &udav_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index d26a9b6e90f3..02c2bb57592d 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -53,8 +53,8 @@ #if USB_DEBUG static int u3g_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, u3g, CTLFLAG_RW, 0, "USB 3g"); -SYSCTL_INT(_hw_usb2_u3g, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, u3g, CTLFLAG_RW, 0, "USB 3g"); +SYSCTL_INT(_hw_usb_u3g, OID_AUTO, debug, CTLFLAG_RW, &u3g_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/ubsa.c b/sys/dev/usb/serial/ubsa.c index dae6036c93e3..78b0fd5822e9 100644 --- a/sys/dev/usb/serial/ubsa.c +++ b/sys/dev/usb/serial/ubsa.c @@ -83,8 +83,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ubsa_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa"); -SYSCTL_INT(_hw_usb2_ubsa, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ubsa, CTLFLAG_RW, 0, "USB ubsa"); +SYSCTL_INT(_hw_usb_ubsa, OID_AUTO, debug, CTLFLAG_RW, &ubsa_debug, 0, "ubsa debug level"); #endif diff --git a/sys/dev/usb/serial/ubser.c b/sys/dev/usb/serial/ubser.c index 803b9b87fa8f..74100b481eff 100644 --- a/sys/dev/usb/serial/ubser.c +++ b/sys/dev/usb/serial/ubser.c @@ -104,8 +104,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ubser_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser"); -SYSCTL_INT(_hw_usb2_ubser, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ubser, CTLFLAG_RW, 0, "USB ubser"); +SYSCTL_INT(_hw_usb_ubser, OID_AUTO, debug, CTLFLAG_RW, &ubser_debug, 0, "ubser debug level"); #endif diff --git a/sys/dev/usb/serial/uchcom.c b/sys/dev/usb/serial/uchcom.c index 4bdcaf80cfe4..58cf12554826 100644 --- a/sys/dev/usb/serial/uchcom.c +++ b/sys/dev/usb/serial/uchcom.c @@ -91,8 +91,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uchcom_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uchcom, CTLFLAG_RW, 0, "USB uchcom"); -SYSCTL_INT(_hw_usb2_uchcom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uchcom, CTLFLAG_RW, 0, "USB uchcom"); +SYSCTL_INT(_hw_usb_uchcom, OID_AUTO, debug, CTLFLAG_RW, &uchcom_debug, 0, "uchcom debug level"); #endif diff --git a/sys/dev/usb/serial/uftdi.c b/sys/dev/usb/serial/uftdi.c index e11326a8820c..f79922fc075a 100644 --- a/sys/dev/usb/serial/uftdi.c +++ b/sys/dev/usb/serial/uftdi.c @@ -70,8 +70,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uftdi_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi"); -SYSCTL_INT(_hw_usb2_uftdi, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uftdi, CTLFLAG_RW, 0, "USB uftdi"); +SYSCTL_INT(_hw_usb_uftdi, OID_AUTO, debug, CTLFLAG_RW, &uftdi_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/ulpt.c b/sys/dev/usb/serial/ulpt.c index 64413270d422..80df2ce57a0e 100644 --- a/sys/dev/usb/serial/ulpt.c +++ b/sys/dev/usb/serial/ulpt.c @@ -68,8 +68,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ulpt_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt"); -SYSCTL_INT(_hw_usb2_ulpt, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ulpt, CTLFLAG_RW, 0, "USB ulpt"); +SYSCTL_INT(_hw_usb_ulpt, OID_AUTO, debug, CTLFLAG_RW, &ulpt_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/umodem.c b/sys/dev/usb/serial/umodem.c index 87e06b46057a..785ac9b3e25f 100644 --- a/sys/dev/usb/serial/umodem.c +++ b/sys/dev/usb/serial/umodem.c @@ -103,8 +103,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int umodem_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem"); -SYSCTL_INT(_hw_usb2_umodem, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, umodem, CTLFLAG_RW, 0, "USB umodem"); +SYSCTL_INT(_hw_usb_umodem, OID_AUTO, debug, CTLFLAG_RW, &umodem_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/umoscom.c b/sys/dev/usb/serial/umoscom.c index 368780b48e49..a6549e553d0a 100644 --- a/sys/dev/usb/serial/umoscom.c +++ b/sys/dev/usb/serial/umoscom.c @@ -38,8 +38,8 @@ #if USB_DEBUG static int umoscom_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, umoscom, CTLFLAG_RW, 0, "USB umoscom"); -SYSCTL_INT(_hw_usb2_umoscom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, umoscom, CTLFLAG_RW, 0, "USB umoscom"); +SYSCTL_INT(_hw_usb_umoscom, OID_AUTO, debug, CTLFLAG_RW, &umoscom_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/uplcom.c b/sys/dev/usb/serial/uplcom.c index 3bbb32af6e0d..f01f7448ac0e 100644 --- a/sys/dev/usb/serial/uplcom.c +++ b/sys/dev/usb/serial/uplcom.c @@ -105,8 +105,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uplcom_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom"); -SYSCTL_INT(_hw_usb2_uplcom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uplcom, CTLFLAG_RW, 0, "USB uplcom"); +SYSCTL_INT(_hw_usb_uplcom, OID_AUTO, debug, CTLFLAG_RW, &uplcom_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/usb_serial.c b/sys/dev/usb/serial/usb_serial.c index 6f5558acdfb5..23d61f240540 100644 --- a/sys/dev/usb/serial/usb_serial.c +++ b/sys/dev/usb/serial/usb_serial.c @@ -87,8 +87,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int usb2_com_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); -SYSCTL_INT(_hw_usb2_ucom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ucom, CTLFLAG_RW, 0, "USB ucom"); +SYSCTL_INT(_hw_usb_ucom, OID_AUTO, debug, CTLFLAG_RW, &usb2_com_debug, 0, "ucom debug level"); #endif diff --git a/sys/dev/usb/serial/uslcom.c b/sys/dev/usb/serial/uslcom.c index cdf843942868..f09a4706fa38 100644 --- a/sys/dev/usb/serial/uslcom.c +++ b/sys/dev/usb/serial/uslcom.c @@ -39,8 +39,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uslcom_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom"); -SYSCTL_INT(_hw_usb2_uslcom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uslcom, CTLFLAG_RW, 0, "USB uslcom"); +SYSCTL_INT(_hw_usb_uslcom, OID_AUTO, debug, CTLFLAG_RW, &uslcom_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/uvisor.c b/sys/dev/usb/serial/uvisor.c index a74a03fbb260..efab25f23d7d 100644 --- a/sys/dev/usb/serial/uvisor.c +++ b/sys/dev/usb/serial/uvisor.c @@ -76,8 +76,8 @@ #if USB_DEBUG static int uvisor_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor"); -SYSCTL_INT(_hw_usb2_uvisor, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uvisor, CTLFLAG_RW, 0, "USB uvisor"); +SYSCTL_INT(_hw_usb_uvisor, OID_AUTO, debug, CTLFLAG_RW, &uvisor_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/serial/uvscom.c b/sys/dev/usb/serial/uvscom.c index 7e1fb19b8a2c..a784ec47aabb 100644 --- a/sys/dev/usb/serial/uvscom.c +++ b/sys/dev/usb/serial/uvscom.c @@ -58,8 +58,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int uvscom_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom"); -SYSCTL_INT(_hw_usb2_uvscom, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uvscom, CTLFLAG_RW, 0, "USB uvscom"); +SYSCTL_INT(_hw_usb_uvscom, OID_AUTO, debug, CTLFLAG_RW, &uvscom_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/storage/umass.c b/sys/dev/usb/storage/umass.c index b87f1bd1f898..f66573b62a81 100644 --- a/sys/dev/usb/storage/umass.c +++ b/sys/dev/usb/storage/umass.c @@ -159,8 +159,8 @@ __FBSDID("$FreeBSD$"); #define UDMASS_ALL 0xffff0000 /* all of the above */ static int umass_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass"); -SYSCTL_INT(_hw_usb2_umass, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, umass, CTLFLAG_RW, 0, "USB umass"); +SYSCTL_INT(_hw_usb_umass, OID_AUTO, debug, CTLFLAG_RW, &umass_debug, 0, "umass debug level"); #else #define DIF(...) do { } while (0) diff --git a/sys/dev/usb/storage/urio.c b/sys/dev/usb/storage/urio.c index 442e38da4447..3064d223d906 100644 --- a/sys/dev/usb/storage/urio.c +++ b/sys/dev/usb/storage/urio.c @@ -67,8 +67,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int urio_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio"); -SYSCTL_INT(_hw_usb2_urio, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, urio, CTLFLAG_RW, 0, "USB urio"); +SYSCTL_INT(_hw_usb_urio, OID_AUTO, debug, CTLFLAG_RW, &urio_debug, 0, "urio debug level"); #endif diff --git a/sys/dev/usb/storage/ustorage_fs.c b/sys/dev/usb/storage/ustorage_fs.c index 02319440337c..02a21aeda1df 100644 --- a/sys/dev/usb/storage/ustorage_fs.c +++ b/sys/dev/usb/storage/ustorage_fs.c @@ -52,8 +52,8 @@ #if USB_DEBUG static int ustorage_fs_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs"); -SYSCTL_INT(_hw_usb2_ustorage_fs, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, ustorage_fs, CTLFLAG_RW, 0, "USB ustorage_fs"); +SYSCTL_INT(_hw_usb_ustorage_fs, OID_AUTO, debug, CTLFLAG_RW, &ustorage_fs_debug, 0, "ustorage_fs debug level"); #endif diff --git a/sys/dev/usb/usb_debug.c b/sys/dev/usb/usb_debug.c index da317fe4b791..de75f8933500 100644 --- a/sys/dev/usb/usb_debug.c +++ b/sys/dev/usb/usb_debug.c @@ -39,8 +39,8 @@ */ int usb2_debug = 0; -SYSCTL_NODE(_hw, OID_AUTO, usb2, CTLFLAG_RW, 0, "USB debugging"); -SYSCTL_INT(_hw_usb2, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw, OID_AUTO, usb, CTLFLAG_RW, 0, "USB debugging"); +SYSCTL_INT(_hw_usb, OID_AUTO, debug, CTLFLAG_RW, &usb2_debug, 0, "Debug level"); /*------------------------------------------------------------------------* diff --git a/sys/dev/usb/usb_debug.h b/sys/dev/usb/usb_debug.h index 3d1f87220c0b..9ddd597ed2b0 100644 --- a/sys/dev/usb/usb_debug.h +++ b/sys/dev/usb/usb_debug.h @@ -30,7 +30,7 @@ #define _USB2_DEBUG_H_ /* Declare parent SYSCTL USB node. */ -SYSCTL_DECL(_hw_usb2); +SYSCTL_DECL(_hw_usb); /* Declare global USB debug variable. */ extern int usb2_debug; diff --git a/sys/dev/usb/usb_dev.c b/sys/dev/usb/usb_dev.c index b537f33cf5cd..e20c31e7064c 100644 --- a/sys/dev/usb/usb_dev.c +++ b/sys/dev/usb/usb_dev.c @@ -59,8 +59,8 @@ #if USB_DEBUG static int usb2_fifo_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device"); -SYSCTL_INT(_hw_usb2_dev, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, dev, CTLFLAG_RW, 0, "USB device"); +SYSCTL_INT(_hw_usb_dev, OID_AUTO, debug, CTLFLAG_RW, &usb2_fifo_debug, 0, "Debug Level"); #endif diff --git a/sys/dev/usb/usb_device.c b/sys/dev/usb/usb_device.c index 20bc029d9772..c1dde2334b25 100644 --- a/sys/dev/usb/usb_device.c +++ b/sys/dev/usb/usb_device.c @@ -87,7 +87,7 @@ static void usb2_cdev_cleanup(void *); int usb2_template = 0; -SYSCTL_INT(_hw_usb2, OID_AUTO, template, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, template, CTLFLAG_RW, &usb2_template, 0, "Selected USB device side template"); static const char* statestr[USB_STATE_MAX] = { diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c index 54308b86292c..02aba15b222c 100644 --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -105,8 +105,8 @@ struct usb2_fifo_methods usb2_ugen_methods = { #if USB_DEBUG static int ugen_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic"); -SYSCTL_INT(_hw_usb2_ugen, OID_AUTO, debug, CTLFLAG_RW, &ugen_debug, +SYSCTL_NODE(_hw_usb, OID_AUTO, ugen, CTLFLAG_RW, 0, "USB generic"); +SYSCTL_INT(_hw_usb_ugen, OID_AUTO, debug, CTLFLAG_RW, &ugen_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/usb_hub.c b/sys/dev/usb/usb_hub.c index 2c921bd47475..31d84a4be432 100644 --- a/sys/dev/usb/usb_hub.c +++ b/sys/dev/usb/usb_hub.c @@ -57,15 +57,15 @@ #if USB_DEBUG static int uhub_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB"); -SYSCTL_INT(_hw_usb2_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, uhub, CTLFLAG_RW, 0, "USB HUB"); +SYSCTL_INT(_hw_usb_uhub, OID_AUTO, debug, CTLFLAG_RW, &uhub_debug, 0, "Debug level"); #endif #if USB_HAVE_POWERD static int usb2_power_timeout = 30; /* seconds */ -SYSCTL_INT(_hw_usb2, OID_AUTO, power_timeout, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, power_timeout, CTLFLAG_RW, &usb2_power_timeout, 0, "USB power timeout"); #endif diff --git a/sys/dev/usb/usb_process.c b/sys/dev/usb/usb_process.c index 5ec46d1328a1..86882d2d0125 100644 --- a/sys/dev/usb/usb_process.c +++ b/sys/dev/usb/usb_process.c @@ -55,8 +55,8 @@ #if USB_DEBUG static int usb2_proc_debug; -SYSCTL_NODE(_hw_usb2, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process"); -SYSCTL_INT(_hw_usb2_proc, OID_AUTO, debug, CTLFLAG_RW, &usb2_proc_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, proc, CTLFLAG_RW, 0, "USB process"); +SYSCTL_INT(_hw_usb_proc, OID_AUTO, debug, CTLFLAG_RW, &usb2_proc_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/usb_request.c b/sys/dev/usb/usb_request.c index aa454cb9025d..6eeb59dd3349 100644 --- a/sys/dev/usb/usb_request.c +++ b/sys/dev/usb/usb_request.c @@ -53,11 +53,11 @@ static int usb2_pr_poll_delay = USB_PORT_RESET_DELAY; static int usb2_pr_recovery_delay = USB_PORT_RESET_RECOVERY; static int usb2_ss_delay = 0; -SYSCTL_INT(_hw_usb2, OID_AUTO, pr_poll_delay, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, pr_poll_delay, CTLFLAG_RW, &usb2_pr_poll_delay, 0, "USB port reset poll delay in ms"); -SYSCTL_INT(_hw_usb2, OID_AUTO, pr_recovery_delay, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, pr_recovery_delay, CTLFLAG_RW, &usb2_pr_recovery_delay, 0, "USB port reset recovery delay in ms"); -SYSCTL_INT(_hw_usb2, OID_AUTO, ss_delay, CTLFLAG_RW, +SYSCTL_INT(_hw_usb, OID_AUTO, ss_delay, CTLFLAG_RW, &usb2_ss_delay, 0, "USB status stage delay in ms"); #endif diff --git a/sys/dev/usb/wlan/if_rum.c b/sys/dev/usb/wlan/if_rum.c index d4fac36db3cf..5fa08992bbb5 100644 --- a/sys/dev/usb/wlan/if_rum.c +++ b/sys/dev/usb/wlan/if_rum.c @@ -85,8 +85,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int rum_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum"); -SYSCTL_INT(_hw_usb2_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, rum, CTLFLAG_RW, 0, "USB rum"); +SYSCTL_INT(_hw_usb_rum, OID_AUTO, debug, CTLFLAG_RW, &rum_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 59ebdb3e1d36..0403193cfcee 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -116,19 +116,19 @@ __FBSDID("$FreeBSD$"); #include #include -SYSCTL_NODE(_hw_usb2, OID_AUTO, uath, CTLFLAG_RW, 0, "USB Atheros"); +SYSCTL_NODE(_hw_usb, OID_AUTO, uath, CTLFLAG_RW, 0, "USB Atheros"); static int uath_countrycode = CTRY_DEFAULT; /* country code */ -SYSCTL_INT(_hw_usb2_uath, OID_AUTO, countrycode, CTLFLAG_RW, &uath_countrycode, +SYSCTL_INT(_hw_usb_uath, OID_AUTO, countrycode, CTLFLAG_RW, &uath_countrycode, 0, "country code"); -TUNABLE_INT("hw.usb2.uath.countrycode", &uath_countrycode); +TUNABLE_INT("hw.usb.uath.countrycode", &uath_countrycode); static int uath_regdomain = 0; /* regulatory domain */ -SYSCTL_INT(_hw_usb2_uath, OID_AUTO, regdomain, CTLFLAG_RD, &uath_regdomain, +SYSCTL_INT(_hw_usb_uath, OID_AUTO, regdomain, CTLFLAG_RD, &uath_regdomain, 0, "regulatory domain"); #ifdef UATH_DEBUG int uath_debug = 0; -SYSCTL_INT(_hw_usb2_uath, OID_AUTO, debug, CTLFLAG_RW, &uath_debug, 0, +SYSCTL_INT(_hw_usb_uath, OID_AUTO, debug, CTLFLAG_RW, &uath_debug, 0, "uath debug level"); TUNABLE_INT("hw.usb.uath.debug", &uath_debug); enum { diff --git a/sys/dev/usb/wlan/if_ural.c b/sys/dev/usb/wlan/if_ural.c index d36ba5c92c21..7ff6a5e2bd4b 100644 --- a/sys/dev/usb/wlan/if_ural.c +++ b/sys/dev/usb/wlan/if_ural.c @@ -87,8 +87,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int ural_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural"); -SYSCTL_INT(_hw_usb2_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, ural, CTLFLAG_RW, 0, "USB ural"); +SYSCTL_INT(_hw_usb_ural, OID_AUTO, debug, CTLFLAG_RW, &ural_debug, 0, "Debug level"); #endif diff --git a/sys/dev/usb/wlan/if_zyd.c b/sys/dev/usb/wlan/if_zyd.c index bad6a9d83dfd..e08bcd0b604a 100644 --- a/sys/dev/usb/wlan/if_zyd.c +++ b/sys/dev/usb/wlan/if_zyd.c @@ -82,8 +82,8 @@ __FBSDID("$FreeBSD$"); #if USB_DEBUG static int zyd_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd"); -SYSCTL_INT(_hw_usb2_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, +SYSCTL_NODE(_hw_usb, OID_AUTO, zyd, CTLFLAG_RW, 0, "USB zyd"); +SYSCTL_INT(_hw_usb_zyd, OID_AUTO, debug, CTLFLAG_RW, &zyd_debug, 0, "zyd debug level"); enum { From b839e625b03206c402cdd9e8551195f828400b2f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 21 May 2009 01:50:27 +0000 Subject: [PATCH 356/544] Modify sys/fs/nfsserver/nfs_nfsdport.c to use nlm_acquire_next_sysid() to set the l_sysid for locks correctly. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdport.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index d45b52dbab68..b48682e98bd2 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -42,6 +42,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include +#include extern u_int32_t newnfs_true, newnfs_false, newnfs_xdrneg1; extern int nfsv4root_set; @@ -56,6 +58,7 @@ struct mtx nfs_cache_mutex; struct mtx nfs_v4root_mutex; struct nfsrvfh nfs_rootfh, nfs_pubfh; int nfs_pubfhset = 0, nfs_rootfhset = 0; +static uint32_t nfsv4_sysid = 0; static int nfssvc_srvcall(struct thread *, struct nfssvc_args *, struct ucred *); @@ -2777,8 +2780,10 @@ nfsvno_localconflict(struct vnode *vp, int ftype, u_int64_t first, * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 * bytes, so it can't be put in l_sysid. */ + if (nfsv4_sysid == 0) + nfsv4_sysid = nlm_acquire_next_sysid(); fl.l_pid = (pid_t)0; - fl.l_sysid = 0; + fl.l_sysid = (int)nfsv4_sysid; NFSVOPUNLOCK(vp, 0, td); error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_GETLK, &fl, @@ -2837,8 +2842,10 @@ nfsvno_advlock(struct vnode *vp, int ftype, u_int64_t first, * Since an NFSv4 lockowner is a ClientID plus an array of up to 1024 * bytes, so it can't be put in l_sysid. */ + if (nfsv4_sysid == 0) + nfsv4_sysid = nlm_acquire_next_sysid(); fl.l_pid = (pid_t)0; - fl.l_sysid = 0; + fl.l_sysid = (int)nfsv4_sysid; NFSVOPUNLOCK(vp, 0, td); error = VOP_ADVLOCK(vp, (caddr_t)td->td_proc, F_SETLK, &fl, From fadc970b778f682f4c7d290f426597967ddae9bb Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 02:09:12 +0000 Subject: [PATCH 357/544] Fix a few variable renames of usb2_mode outside dev/usb. --- sys/dev/ata/ata-usb.c | 2 +- sys/dev/if_ndis/if_ndis_usb.c | 2 +- sys/dev/sound/usb/uaudio.c | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/sys/dev/ata/ata-usb.c b/sys/dev/ata/ata-usb.c index bf1a5e4c8800..8fc1005b377d 100644 --- a/sys/dev/ata/ata-usb.c +++ b/sys/dev/ata/ata-usb.c @@ -281,7 +281,7 @@ atausb2_probe(device_t dev) struct usb2_attach_arg *uaa = device_get_ivars(dev); struct usb2_interface_descriptor *id; - if (uaa->usb2_mode != USB_MODE_HOST) { + if (uaa->usb_mode != USB_MODE_HOST) { return (ENXIO); } if (uaa->use_generic == 0) { diff --git a/sys/dev/if_ndis/if_ndis_usb.c b/sys/dev/if_ndis/if_ndis_usb.c index ec9741bf270d..5e4895b1eb63 100644 --- a/sys/dev/if_ndis/if_ndis_usb.c +++ b/sys/dev/if_ndis/if_ndis_usb.c @@ -136,7 +136,7 @@ ndisusb_match(device_t self) struct drvdb_ent *db; struct usb2_attach_arg *uaa = device_get_ivars(self); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->info.bConfigIndex != NDISUSB_CONFIG_NO) return (ENXIO); diff --git a/sys/dev/sound/usb/uaudio.c b/sys/dev/sound/usb/uaudio.c index 9cd51042b44c..613a638343aa 100644 --- a/sys/dev/sound/usb/uaudio.c +++ b/sys/dev/sound/usb/uaudio.c @@ -80,14 +80,14 @@ static int uaudio_default_channels = 2; #if USB_DEBUG static int uaudio_debug = 0; -SYSCTL_NODE(_hw_usb2, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio"); -SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, debug, CTLFLAG_RW, +SYSCTL_NODE(_hw_usb, OID_AUTO, uaudio, CTLFLAG_RW, 0, "USB uaudio"); +SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, debug, CTLFLAG_RW, &uaudio_debug, 0, "uaudio debug level"); -SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_rate, CTLFLAG_RW, +SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_rate, CTLFLAG_RW, &uaudio_default_rate, 0, "uaudio default sample rate"); -SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_bits, CTLFLAG_RW, +SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_bits, CTLFLAG_RW, &uaudio_default_bits, 0, "uaudio default sample bits"); -SYSCTL_INT(_hw_usb2_uaudio, OID_AUTO, default_channels, CTLFLAG_RW, +SYSCTL_INT(_hw_usb_uaudio, OID_AUTO, default_channels, CTLFLAG_RW, &uaudio_default_channels, 0, "uaudio default sample channels"); #endif @@ -532,7 +532,7 @@ uaudio_probe(device_t dev) { struct usb2_attach_arg *uaa = device_get_ivars(dev); - if (uaa->usb2_mode != USB_MODE_HOST) + if (uaa->usb_mode != USB_MODE_HOST) return (ENXIO); if (uaa->use_generic == 0) From f6bc943047f37ee4312fbbf78574b314dfe7c6ad Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:12:10 +0000 Subject: [PATCH 358/544] bus_dma(9) conversion and make nge(4) work on all architectures. o Header file cleanup. o bus_dma(9) conversion. - Removed all consumers of vtophys(9) and converted to use bus_dma(9). - 64bit DMA support was disabled because DP83821 is not capable of handling the DMA request. 64bit DMA request on DP83820 requires different descriptor structures and it's hard to dynamically change descriptor format at run time so I disabled it. Note, this is the same behavior as previous one but previously nge(4) didn't explicitly disable 64bit mode on DP83820. - Added Tx/Rx descriptor ring alignment requirements(8 bytes alignment). - Limit maximum number of Tx DMA segments to 16. In fact, controller does not seem to have limitations on number of Tx DMA segments but 16 should be enough for most cases and m_collapse(9) will handle highly fragmented frames without consuming a lot of CPU cycles. - Added Rx buffer alignment requirements(8 bytes alignment). This means driver should fixup received frames to align on 16bits boundary on strict-alignment architectures. - Nuked driver private data structure in descriptor ring. - Added endianness support code in Tx/Rx descriptor access. o Prefer faster memory mapped register access to I/O mapped access. Added fall-back mechanism to use alternative register access. The hardware supports both memory and I/O mapped access. o Added suspend/resume methods but it wasn't tested as controller I have does not support PCI PME. o Removed swap argument in nge_read_eeprom() since endianness should be handled after reading EEPROM. o Implemented experimental 802.3x full-duplex flow-control. ATM it was commented out but will be activated after we have generic flow-control framework in mii(4) layer. o Rearranged promiscuous mode settings and simplified logic. o Always disable Rx filter prior to changing Rx filter functions as indicated in DP83820/DP83821 datasheet. o Added an explicit DELAY in timeout loop of nge_reset(). o Added a sysctl variable dev.nge.%d.int_holdoff to control interrupt moderation. Valid ranges are 1 to 255(default 1) in units of 100us. The actual delivery of interrupt would be delayed based on the sysctl value. The interface has to be brought down and up again before a change takes effect. With proper tuning value, users do not need to resort to polling(4) anymore. o Added ALTQ(4) support. o Added missing IFCAP_VLAN_HWCSUM as nge(4) can offload Tx/Rx checksum calculation on VLAN tagged frames as well as VLAN tag insertion/stripping. Also add IFCAP_VLAN_MTU capability as nge(4) can handle VLAN tagged oversized frames. o Fixed media header length for VLAN. o Rearranged nge_detach routine such that it's now used for general clean-up routine. o Enabled MWI. o Accessing EEPROM takes very long time so read 6 bytes ethernet address with one call instead of 3 separate accesses. o Don't set if_mtu in device attach, it's already set in ether_ifattach(). o Don't do any special things for TBI interface. Remove TBI specific media handling in the driver and have gentbi(4) handle it. Add glue code to read/write TBI PHY registers in miibus method. This change removes a lot of PHY handling code in driver and now its functionality is handled by mii(4). o Alignment fixup code is now applied only for strict-alignment architectures. Previously the code was applied for all architectures except i386. With this change amd64 will get instant Rx performance boost. o When driver fails to allocate a new mbuf, update if_qdrops so users can see what was wrong in Rx path. o Added a workaround for a hardware bug which resulted in short VLAN tagged frames(e.g. ARP) was rejected as if runt frame was received. With this workaround nge(4) now accepts the short VLAN tagged frame and nge(4) can take full advantage of hardware VLAN tag stripping. I have no idea how this bug wasn't known so far, without the workaround nge(4) may never work on VLAN environments. o Fixed Rx checksum offload logic such that it now honors active interface capability configured with ifconfig(8). o In nge_start()/nge_txencap(), always leave at least one free descriptor as indicated in datasheet. Without this the hardware would be confused with ring descriptor structure(e.g. no clue for the end of descriptor ring). o Removed dead-code that checks interrupts on PHY hardware. The code was designed to detect link state changes but it was disabled as driving nge_tick clock would break auto-negotiation timer. This code is no longer needed as nge(4) now uses mii(4) and link state change handling is done with mii callback. o Rearranged ethernet address programming logic such that it works on strict-alignment architectures. o Added IFCAP_VLAN_HWTAGGING/IFCAP_VLAN_HWCSUM handler in nge_ioctl() such that the functionality is configurable with ifconfig(8). DP83820/DP83821 can do checksum offload for VLAN tagged frames so enable Tx/Rx checksum offload for VLAN interfaces. o Simplified IFCAP_POLLING selection logic in nge_ioctl(). o Fixed module unload panic when bpf listeners are active. o Tx/Rx descriptor ring address uses 64bit DMA address for readability. High address part of DMA would be 0 as nge(4) disabled 64bit DMA transfers so it's ok for DP83821. o Removed volatile keyword in softc as bus_dmamap_sync(9) should take care of this. o Removed extra driver private structures in descriptor ring. These extra elements are not part of descriptor structure. Embedding private driver structure into descriptor ring is not good idea as its size may be different on 32bit/64bit architectures. o Added miibus_linkchg method handler to catch link state changes. o Removed unneeded nge_ifmedia in softc. All TBI access is handled in gentbi(4). There is no difference between TBI and non-TBI case now. o Removed "gigabit link up" message handling in nge_tick. Link state change notification is already performed by mii(4) and checking link state by accessing PHY registers in periodic timer handler of driver is wrong. All link state and speed/duplex monitoring should be handled in PHY driver. o Use our own timer for watchdog instead of if_watchdog/if_timer interface. o Added hardware MAC statistics counter, users canget current MAC statistics from dev.nge.%d.stats sysctl node(%d is unit number of a device). o Removed unused macros, NGE_LASTDESC, NGE_MODE, NGE_OWNDESC, NGE_RXBYTES. o Increased number of Tx/Rx descriptors from 128 to 256. From my experience on gigabit ethernet controllers, number of descriptors should be 256 or higher to get an optimal performance on gigabit link. o Increased jumbo frame length to 9022 bytes to cope with other gigabit ethernet drivers. Experimentation shows no problems with 9022 bytes. o Removed unused member variables in softc. o Switched from bus_space_{read|write}_4 to bus_{read|write}_4. o Added support for WOL. --- sys/dev/nge/if_nge.c | 2329 ++++++++++++++++++++++++++------------- sys/dev/nge/if_ngereg.h | 212 ++-- 2 files changed, 1680 insertions(+), 861 deletions(-) diff --git a/sys/dev/nge/if_nge.c b/sys/dev/nge/if_nge.c index 988305d6cf04..1e929b01c6be 100644 --- a/sys/dev/nge/if_nge.c +++ b/sys/dev/nge/if_nge.c @@ -94,13 +94,20 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include -#include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include +#include #include #include #include @@ -109,32 +116,23 @@ __FBSDID("$FreeBSD$"); #include #include -#include - -#include /* for vtophys */ -#include /* for vtophys */ -#include -#include -#include -#include - #include #include #include #include -#define NGE_USEIOSPACE +#include #include +/* "device miibus" required. See GENERIC if you get errors here. */ +#include "miibus_if.h" + MODULE_DEPEND(nge, pci, 1, 1, 1); MODULE_DEPEND(nge, ether, 1, 1, 1); MODULE_DEPEND(nge, miibus, 1, 1, 1); -/* "device miibus" required. See GENERIC if you get errors here. */ -#include "miibus_if.h" - #define NGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) /* @@ -149,33 +147,38 @@ static struct nge_type nge_devs[] = { static int nge_probe(device_t); static int nge_attach(device_t); static int nge_detach(device_t); +static int nge_shutdown(device_t); +static int nge_suspend(device_t); +static int nge_resume(device_t); -static int nge_newbuf(struct nge_softc *, struct nge_desc *, struct mbuf *); -static int nge_encap(struct nge_softc *, struct mbuf *, uint32_t *); -#ifdef NGE_FIXUP_RX -static __inline void nge_fixup_rx (struct mbuf *); +static __inline void nge_discard_rxbuf(struct nge_softc *, int); +static int nge_newbuf(struct nge_softc *, int); +static int nge_encap(struct nge_softc *, struct mbuf **); +#ifndef __NO_STRICT_ALIGNMENT +static __inline void nge_fixup_rx(struct mbuf *); #endif static void nge_rxeof(struct nge_softc *); static void nge_txeof(struct nge_softc *); static void nge_intr(void *); static void nge_tick(void *); +static void nge_stats_update(struct nge_softc *); static void nge_start(struct ifnet *); static void nge_start_locked(struct ifnet *); static int nge_ioctl(struct ifnet *, u_long, caddr_t); static void nge_init(void *); static void nge_init_locked(struct nge_softc *); +static int nge_stop_mac(struct nge_softc *); static void nge_stop(struct nge_softc *); -static void nge_watchdog(struct ifnet *); -static int nge_shutdown(device_t); -static int nge_ifmedia_upd(struct ifnet *); -static void nge_ifmedia_upd_locked(struct ifnet *); -static void nge_ifmedia_sts(struct ifnet *, struct ifmediareq *); +static void nge_wol(struct nge_softc *); +static void nge_watchdog(struct nge_softc *); +static int nge_mediachange(struct ifnet *); +static void nge_mediastatus(struct ifnet *, struct ifmediareq *); static void nge_delay(struct nge_softc *); static void nge_eeprom_idle(struct nge_softc *); static void nge_eeprom_putbyte(struct nge_softc *, int); static void nge_eeprom_getword(struct nge_softc *, int, uint16_t *); -static void nge_read_eeprom(struct nge_softc *, caddr_t, int, int, int); +static void nge_read_eeprom(struct nge_softc *, caddr_t, int, int); static void nge_mii_sync(struct nge_softc *); static void nge_mii_send(struct nge_softc *, uint32_t, int); @@ -186,18 +189,16 @@ static int nge_miibus_readreg(device_t, int, int); static int nge_miibus_writereg(device_t, int, int, int); static void nge_miibus_statchg(device_t); -static void nge_setmulti(struct nge_softc *); +static void nge_rxfilter(struct nge_softc *); static void nge_reset(struct nge_softc *); +static void nge_dmamap_cb(void *, bus_dma_segment_t *, int, int); +static int nge_dma_alloc(struct nge_softc *); +static void nge_dma_free(struct nge_softc *); static int nge_list_rx_init(struct nge_softc *); static int nge_list_tx_init(struct nge_softc *); - -#ifdef NGE_USEIOSPACE -#define NGE_RES SYS_RES_IOPORT -#define NGE_RID NGE_PCI_LOIO -#else -#define NGE_RES SYS_RES_MEMORY -#define NGE_RID NGE_PCI_LOMEM -#endif +static void nge_sysctl_node(struct nge_softc *); +static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int); +static int sysctl_hw_nge_int_holdoff(SYSCTL_HANDLER_ARGS); static device_method_t nge_methods[] = { /* Device interface */ @@ -205,6 +206,8 @@ static device_method_t nge_methods[] = { DEVMETHOD(device_attach, nge_attach), DEVMETHOD(device_detach, nge_detach), DEVMETHOD(device_shutdown, nge_shutdown), + DEVMETHOD(device_suspend, nge_suspend), + DEVMETHOD(device_resume, nge_resume), /* bus interface */ DEVMETHOD(bus_print_child, bus_generic_print_child), @@ -215,7 +218,7 @@ static device_method_t nge_methods[] = { DEVMETHOD(miibus_writereg, nge_miibus_writereg), DEVMETHOD(miibus_statchg, nge_miibus_statchg), - { 0, 0 } + { NULL, NULL } }; static driver_t nge_driver = { @@ -350,7 +353,7 @@ nge_eeprom_getword(struct nge_softc *sc, int addr, uint16_t *dest) * Read a sequence of words from the EEPROM. */ static void -nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) +nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt) { int i; uint16_t word = 0, *ptr; @@ -358,10 +361,7 @@ nge_read_eeprom(struct nge_softc *sc, caddr_t dest, int off, int cnt, int swap) for (i = 0; i < cnt; i++) { nge_eeprom_getword(sc, off + i, &word); ptr = (uint16_t *)(dest + (i * 2)); - if (swap) - *ptr = ntohs(word); - else - *ptr = word; + *ptr = word; } } @@ -540,8 +540,48 @@ nge_miibus_readreg(device_t dev, int phy, int reg) { struct nge_softc *sc; struct nge_mii_frame frame; + int rv; sc = device_get_softc(dev); + if ((sc->nge_flags & NGE_FLAG_TBI) != 0) { + /* Pretend PHY is at address 0. */ + if (phy != 0) + return (0); + switch (reg) { + case MII_BMCR: + reg = NGE_TBI_BMCR; + break; + case MII_BMSR: + /* 83820/83821 has different bit layout for BMSR. */ + rv = BMSR_ANEG | BMSR_EXTCAP | BMSR_EXTSTAT; + reg = CSR_READ_4(sc, NGE_TBI_BMSR); + if ((reg & NGE_TBIBMSR_ANEG_DONE) != 0) + rv |= BMSR_ACOMP; + if ((reg & NGE_TBIBMSR_LINKSTAT) != 0) + rv |= BMSR_LINK; + return (rv); + case MII_ANAR: + reg = NGE_TBI_ANAR; + break; + case MII_ANLPAR: + reg = NGE_TBI_ANLPAR; + break; + case MII_ANER: + reg = NGE_TBI_ANER; + break; + case MII_EXTSR: + reg = NGE_TBI_ESR; + break; + case MII_PHYIDR1: + case MII_PHYIDR2: + return (0); + default: + device_printf(sc->nge_dev, + "bad phy register read : %d\n", reg); + return (0); + } + return (CSR_READ_4(sc, reg)); + } bzero((char *)&frame, sizeof(frame)); @@ -559,6 +599,39 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data) struct nge_mii_frame frame; sc = device_get_softc(dev); + if ((sc->nge_flags & NGE_FLAG_TBI) != 0) { + /* Pretend PHY is at address 0. */ + if (phy != 0) + return (0); + switch (reg) { + case MII_BMCR: + reg = NGE_TBI_BMCR; + break; + case MII_BMSR: + return (0); + case MII_ANAR: + reg = NGE_TBI_ANAR; + break; + case MII_ANLPAR: + reg = NGE_TBI_ANLPAR; + break; + case MII_ANER: + reg = NGE_TBI_ANER; + break; + case MII_EXTSR: + reg = NGE_TBI_ESR; + break; + case MII_PHYIDR1: + case MII_PHYIDR2: + return (0); + default: + device_printf(sc->nge_dev, + "bad phy register write : %d\n", reg); + return (0); + } + CSR_WRITE_4(sc, reg, data); + return (0); + } bzero((char *)&frame, sizeof(frame)); @@ -570,90 +643,213 @@ nge_miibus_writereg(device_t dev, int phy, int reg, int data) return (0); } +/* + * media status/link state change handler. + */ static void nge_miibus_statchg(device_t dev) { - int status; struct nge_softc *sc; struct mii_data *mii; + struct ifnet *ifp; + struct nge_txdesc *txd; + uint32_t done, reg, status; + int i; sc = device_get_softc(dev); - if (sc->nge_tbi) { - if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) - == IFM_AUTO) { - status = CSR_READ_4(sc, NGE_TBI_ANLPAR); - if (status == 0 || status & NGE_TBIANAR_FDX) { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } else { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } + NGE_LOCK_ASSERT(sc); - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) - != IFM_FDX) { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } else { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } - } else { - mii = device_get_softc(sc->nge_miibus); + mii = device_get_softc(sc->nge_miibus); + ifp = sc->nge_ifp; + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + return; - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } else { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } - - /* If we have a 1000Mbps link, set the mode_1000 bit. */ - if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T || - IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX) { - NGE_SETBIT(sc, NGE_CFG, NGE_CFG_MODE_1000); - } else { - NGE_CLRBIT(sc, NGE_CFG, NGE_CFG_MODE_1000); + sc->nge_flags &= ~NGE_FLAG_LINK; + if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == + (IFM_AVALID | IFM_ACTIVE)) { + switch (IFM_SUBTYPE(mii->mii_media_active)) { + case IFM_10_T: + case IFM_100_TX: + case IFM_1000_T: + case IFM_1000_SX: + case IFM_1000_LX: + case IFM_1000_CX: + sc->nge_flags |= NGE_FLAG_LINK; + break; + default: + break; } } + + /* Stop Tx/Rx MACs. */ + if (nge_stop_mac(sc) == ETIMEDOUT) + device_printf(sc->nge_dev, + "%s: unable to stop Tx/Rx MAC\n", __func__); + nge_txeof(sc); + nge_rxeof(sc); + if (sc->nge_head != NULL) { + m_freem(sc->nge_head); + sc->nge_head = sc->nge_tail = NULL; + } + + /* Release queued frames. */ + for (i = 0; i < NGE_TX_RING_CNT; i++) { + txd = &sc->nge_cdata.nge_txdesc[i]; + if (txd->tx_m != NULL) { + bus_dmamap_sync(sc->nge_cdata.nge_tx_tag, + txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->nge_cdata.nge_tx_tag, + txd->tx_dmamap); + m_freem(txd->tx_m); + txd->tx_m = NULL; + } + } + + /* Program MAC with resolved speed/duplex. */ + if ((sc->nge_flags & NGE_FLAG_LINK) != 0) { + if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0) { + NGE_SETBIT(sc, NGE_TX_CFG, + (NGE_TXCFG_IGN_HBEAT | NGE_TXCFG_IGN_CARR)); + NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); +#ifdef notyet + /* Enable flow-control. */ + if ((IFM_OPTIONS(mii->mii_media_active) & + (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)) != 0) + NGE_SETBIT(sc, NGE_PAUSECSR, + NGE_PAUSECSR_PAUSE_ENB); +#endif + } else { + NGE_CLRBIT(sc, NGE_TX_CFG, + (NGE_TXCFG_IGN_HBEAT | NGE_TXCFG_IGN_CARR)); + NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); + NGE_CLRBIT(sc, NGE_PAUSECSR, NGE_PAUSECSR_PAUSE_ENB); + } + /* If we have a 1000Mbps link, set the mode_1000 bit. */ + reg = CSR_READ_4(sc, NGE_CFG); + switch (IFM_SUBTYPE(mii->mii_media_active)) { + case IFM_1000_SX: + case IFM_1000_LX: + case IFM_1000_CX: + case IFM_1000_T: + reg |= NGE_CFG_MODE_1000; + break; + default: + reg &= ~NGE_CFG_MODE_1000; + break; + } + CSR_WRITE_4(sc, NGE_CFG, reg); + + /* Reset Tx/Rx MAC. */ + reg = CSR_READ_4(sc, NGE_CSR); + reg |= NGE_CSR_TX_RESET | NGE_CSR_RX_RESET; + CSR_WRITE_4(sc, NGE_CSR, reg); + /* Check the completion of reset. */ + done = 0; + for (i = 0; i < NGE_TIMEOUT; i++) { + DELAY(1); + status = CSR_READ_4(sc, NGE_ISR); + if ((status & NGE_ISR_RX_RESET_DONE) != 0) + done |= NGE_ISR_RX_RESET_DONE; + if ((status & NGE_ISR_TX_RESET_DONE) != 0) + done |= NGE_ISR_TX_RESET_DONE; + if (done == + (NGE_ISR_TX_RESET_DONE | NGE_ISR_RX_RESET_DONE)) + break; + } + if (i == NGE_TIMEOUT) + device_printf(sc->nge_dev, + "%s: unable to reset Tx/Rx MAC\n", __func__); + /* Reuse Rx buffer and reset consumer pointer. */ + sc->nge_cdata.nge_rx_cons = 0; + /* + * It seems that resetting Rx/Tx MAC results in + * resetting Tx/Rx descriptor pointer registers such + * that reloading Tx/Rx lists address are needed. + */ + CSR_WRITE_4(sc, NGE_RX_LISTPTR_HI, + NGE_ADDR_HI(sc->nge_rdata.nge_rx_ring_paddr)); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_LO, + NGE_ADDR_LO(sc->nge_rdata.nge_rx_ring_paddr)); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_HI, + NGE_ADDR_HI(sc->nge_rdata.nge_tx_ring_paddr)); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_LO, + NGE_ADDR_LO(sc->nge_rdata.nge_tx_ring_paddr)); + /* Reinitialize Tx buffers. */ + nge_list_tx_init(sc); + + /* Restart Rx MAC. */ + reg = CSR_READ_4(sc, NGE_CSR); + reg |= NGE_CSR_RX_ENABLE; + CSR_WRITE_4(sc, NGE_CSR, reg); + for (i = 0; i < NGE_TIMEOUT; i++) { + if ((CSR_READ_4(sc, NGE_CSR) & NGE_CSR_RX_ENABLE) != 0) + break; + DELAY(1); + } + if (i == NGE_TIMEOUT) + device_printf(sc->nge_dev, + "%s: unable to restart Rx MAC\n", __func__); + } + + /* Data LED off for TBI mode */ + if ((sc->nge_flags & NGE_FLAG_TBI) != 0) + CSR_WRITE_4(sc, NGE_GPIO, + CSR_READ_4(sc, NGE_GPIO) & ~NGE_GPIO_GP3_OUT); } static void -nge_setmulti(struct nge_softc *sc) +nge_rxfilter(struct nge_softc *sc) { struct ifnet *ifp; struct ifmultiaddr *ifma; - uint32_t h = 0, i, filtsave; + uint32_t h, i, rxfilt; int bit, index; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; - if (ifp->if_flags & IFF_ALLMULTI || ifp->if_flags & IFF_PROMISC) { - NGE_CLRBIT(sc, NGE_RXFILT_CTL, - NGE_RXFILTCTL_MCHASH|NGE_RXFILTCTL_UCHASH); - NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLMULTI); - return; + /* Make sure to stop Rx filtering. */ + rxfilt = CSR_READ_4(sc, NGE_RXFILT_CTL); + rxfilt &= ~NGE_RXFILTCTL_ENABLE; + CSR_WRITE_4(sc, NGE_RXFILT_CTL, rxfilt); + CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); + + rxfilt &= ~(NGE_RXFILTCTL_ALLMULTI | NGE_RXFILTCTL_ALLPHYS); + rxfilt &= ~NGE_RXFILTCTL_BROAD; + /* + * We don't want to use the hash table for matching unicast + * addresses. + */ + rxfilt &= ~(NGE_RXFILTCTL_MCHASH | NGE_RXFILTCTL_UCHASH); + + /* + * For the NatSemi chip, we have to explicitly enable the + * reception of ARP frames, as well as turn on the 'perfect + * match' filter where we store the station address, otherwise + * we won't receive unicasts meant for this host. + */ + rxfilt |= NGE_RXFILTCTL_ARP | NGE_RXFILTCTL_PERFECT; + + /* + * Set the capture broadcast bit to capture broadcast frames. + */ + if ((ifp->if_flags & IFF_BROADCAST) != 0) + rxfilt |= NGE_RXFILTCTL_BROAD; + + if ((ifp->if_flags & IFF_PROMISC) != 0 || + (ifp->if_flags & IFF_ALLMULTI) != 0) { + rxfilt |= NGE_RXFILTCTL_ALLMULTI; + if ((ifp->if_flags & IFF_PROMISC) != 0) + rxfilt |= NGE_RXFILTCTL_ALLPHYS; + goto done; } /* * We have to explicitly enable the multicast hash table * on the NatSemi chip if we want to use it, which we do. - * We also have to tell it that we don't want to use the - * hash table for matching unicast addresses. */ - NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_MCHASH); - NGE_CLRBIT(sc, NGE_RXFILT_CTL, - NGE_RXFILTCTL_ALLMULTI|NGE_RXFILTCTL_UCHASH); - - filtsave = CSR_READ_4(sc, NGE_RXFILT_CTL); + rxfilt |= NGE_RXFILTCTL_MCHASH; /* first, zot all the existing hash bits */ for (i = 0; i < NGE_MCAST_FILTER_LEN; i += 2) { @@ -681,12 +877,18 @@ nge_setmulti(struct nge_softc *sc) } IF_ADDR_UNLOCK(ifp); - CSR_WRITE_4(sc, NGE_RXFILT_CTL, filtsave); +done: + CSR_WRITE_4(sc, NGE_RXFILT_CTL, rxfilt); + /* Turn the receive filter on. */ + rxfilt |= NGE_RXFILTCTL_ENABLE; + CSR_WRITE_4(sc, NGE_RXFILT_CTL, rxfilt); + CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); } static void nge_reset(struct nge_softc *sc) { + uint32_t v; int i; NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RESET); @@ -694,6 +896,7 @@ nge_reset(struct nge_softc *sc) for (i = 0; i < NGE_TIMEOUT; i++) { if (!(CSR_READ_4(sc, NGE_CSR) & NGE_CSR_RESET)) break; + DELAY(1); } if (i == NGE_TIMEOUT) @@ -708,6 +911,18 @@ nge_reset(struct nge_softc *sc) */ CSR_WRITE_4(sc, NGE_CLKRUN, NGE_CLKRUN_PMESTS); CSR_WRITE_4(sc, NGE_CLKRUN, 0); + + /* Clear WOL events which may interfere normal Rx filter opertaion. */ + CSR_WRITE_4(sc, NGE_WOLCSR, 0); + + /* + * Only DP83820 supports 64bits addressing/data transfers and + * 64bit addressing requires different descriptor structures. + * To make it simple, disable 64bit addressing/data transfers. + */ + v = CSR_READ_4(sc, NGE_CFG); + v &= ~(NGE_CFG_64BIT_ADDR_ENB | NGE_CFG_64BIT_DATA_ENB); + CSR_WRITE_4(sc, NGE_CFG, v); } /* @@ -740,11 +955,13 @@ nge_probe(device_t dev) static int nge_attach(device_t dev) { - u_char eaddr[ETHER_ADDR_LEN]; + uint8_t eaddr[ETHER_ADDR_LEN]; + uint16_t ea[ETHER_ADDR_LEN/2], ea_temp, reg; struct nge_softc *sc; - struct ifnet *ifp = NULL; - int error = 0, rid; + struct ifnet *ifp; + int error, i, rid; + error = 0; sc = device_get_softc(dev); sc->nge_dev = dev; @@ -756,18 +973,35 @@ nge_attach(device_t dev) */ pci_enable_busmaster(dev); - rid = NGE_RID; - sc->nge_res = bus_alloc_resource_any(dev, NGE_RES, &rid, RF_ACTIVE); +#ifdef NGE_USEIOSPACE + sc->nge_res_type = SYS_RES_IOPORT; + sc->nge_res_id = PCIR_BAR(0); +#else + sc->nge_res_type = SYS_RES_MEMORY; + sc->nge_res_id = PCIR_BAR(1); +#endif + sc->nge_res = bus_alloc_resource_any(dev, sc->nge_res_type, + &sc->nge_res_id, RF_ACTIVE); if (sc->nge_res == NULL) { - device_printf(dev, "couldn't map ports/memory\n"); - error = ENXIO; - goto fail; + if (sc->nge_res_type == SYS_RES_MEMORY) { + sc->nge_res_type = SYS_RES_IOPORT; + sc->nge_res_id = PCIR_BAR(0); + } else { + sc->nge_res_type = SYS_RES_MEMORY; + sc->nge_res_id = PCIR_BAR(1); + } + sc->nge_res = bus_alloc_resource_any(dev, sc->nge_res_type, + &sc->nge_res_id, RF_ACTIVE); + if (sc->nge_res == NULL) { + device_printf(dev, "couldn't allocate %s resources\n", + sc->nge_res_type == SYS_RES_MEMORY ? "memory" : + "I/O"); + NGE_LOCK_DESTROY(sc); + return (ENXIO); + } } - sc->nge_btag = rman_get_bustag(sc->nge_res); - sc->nge_bhandle = rman_get_bushandle(sc->nge_res); - /* Allocate interrupt */ rid = 0; sc->nge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, @@ -779,83 +1013,77 @@ nge_attach(device_t dev) goto fail; } + /* Enable MWI. */ + reg = pci_read_config(dev, PCIR_COMMAND, 2); + reg |= PCIM_CMD_MWRICEN; + pci_write_config(dev, PCIR_COMMAND, reg, 2); + /* Reset the adapter. */ nge_reset(sc); /* * Get station address from the EEPROM. */ - nge_read_eeprom(sc, (caddr_t)&eaddr[4], NGE_EE_NODEADDR, 1, 0); - nge_read_eeprom(sc, (caddr_t)&eaddr[2], NGE_EE_NODEADDR + 1, 1, 0); - nge_read_eeprom(sc, (caddr_t)&eaddr[0], NGE_EE_NODEADDR + 2, 1, 0); + nge_read_eeprom(sc, (caddr_t)ea, NGE_EE_NODEADDR, 3); + for (i = 0; i < ETHER_ADDR_LEN / 2; i++) + ea[i] = le16toh(ea[i]); + ea_temp = ea[0]; + ea[0] = ea[2]; + ea[2] = ea_temp; + bcopy(ea, eaddr, sizeof(eaddr)); - sc->nge_ldata = contigmalloc(sizeof(struct nge_list_data), M_DEVBUF, - M_NOWAIT|M_ZERO, 0, 0xffffffff, PAGE_SIZE, 0); - - if (sc->nge_ldata == NULL) { - device_printf(dev, "no memory for list buffers!\n"); + if (nge_dma_alloc(sc) != 0) { error = ENXIO; goto fail; } + nge_sysctl_node(sc); + ifp = sc->nge_ifp = if_alloc(IFT_ETHER); if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); + device_printf(dev, "can not allocate ifnet structure\n"); error = ENOSPC; goto fail; } ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); - ifp->if_mtu = ETHERMTU; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = nge_ioctl; ifp->if_start = nge_start; - ifp->if_watchdog = nge_watchdog; ifp->if_init = nge_init; - ifp->if_snd.ifq_maxlen = NGE_TX_LIST_CNT - 1; + ifp->if_snd.ifq_drv_maxlen = NGE_TX_RING_CNT - 1; + IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen); + IFQ_SET_READY(&ifp->if_snd); ifp->if_hwassist = NGE_CSUM_FEATURES; - ifp->if_capabilities = IFCAP_HWCSUM | IFCAP_VLAN_HWTAGGING; + ifp->if_capabilities = IFCAP_HWCSUM; + /* + * It seems that some hardwares doesn't provide 3.3V auxiliary + * supply(3VAUX) to drive PME such that checking PCI power + * management capability is necessary. + */ + if (pci_find_extcap(sc->nge_dev, PCIY_PMG, &i) == 0) + ifp->if_capabilities |= IFCAP_WOL; ifp->if_capenable = ifp->if_capabilities; -#ifdef DEVICE_POLLING - ifp->if_capabilities |= IFCAP_POLLING; -#endif + + if ((CSR_READ_4(sc, NGE_CFG) & NGE_CFG_TBI_EN) != 0) { + sc->nge_flags |= NGE_FLAG_TBI; + device_printf(dev, "Using TBI\n"); + /* Configure GPIO. */ + CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) + | NGE_GPIO_GP4_OUT + | NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB + | NGE_GPIO_GP3_OUTENB + | NGE_GPIO_GP3_IN | NGE_GPIO_GP4_IN); + } /* * Do MII setup. */ - /* XXX: leaked on error */ - if (mii_phy_probe(dev, &sc->nge_miibus, - nge_ifmedia_upd, nge_ifmedia_sts)) { - if (CSR_READ_4(sc, NGE_CFG) & NGE_CFG_TBI_EN) { - sc->nge_tbi = 1; - device_printf(dev, "Using TBI\n"); - - sc->nge_miibus = dev; - - ifmedia_init(&sc->nge_ifmedia, 0, nge_ifmedia_upd, - nge_ifmedia_sts); -#define ADD(m, c) ifmedia_add(&sc->nge_ifmedia, (m), (c), NULL) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, 0), 0); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, 0, 0), 0); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, 0),0); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0), 0); -#undef ADD - device_printf(dev, " 1000baseSX, 1000baseSX-FDX, auto\n"); - - ifmedia_set(&sc->nge_ifmedia, - IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, 0)); - - CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) - | NGE_GPIO_GP4_OUT - | NGE_GPIO_GP1_OUTENB | NGE_GPIO_GP2_OUTENB - | NGE_GPIO_GP3_OUTENB - | NGE_GPIO_GP3_IN | NGE_GPIO_GP4_IN); - - } else { - device_printf(dev, "MII without any PHY!\n"); - error = ENXIO; - goto fail; - } + error = mii_phy_probe(dev, &sc->nge_miibus, nge_mediachange, + nge_mediastatus); + if (error != 0) { + device_printf(dev, "no PHY found!\n"); + goto fail; } /* @@ -863,6 +1091,20 @@ nge_attach(device_t dev) */ ether_ifattach(ifp, eaddr); + /* VLAN capability setup. */ + ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; + ifp->if_capabilities |= IFCAP_VLAN_HWCSUM; + ifp->if_capenable = ifp->if_capabilities; +#ifdef DEVICE_POLLING + ifp->if_capabilities |= IFCAP_POLLING; +#endif + /* + * Tell the upper layer(s) we support long frames. + * Must appear after the call to ether_ifattach() because + * ether_ifattach() sets ifi_hdrlen to the default value. + */ + ifp->if_data.ifi_hdrlen = sizeof(struct ether_vlan_header); + /* * Hookup IRQ last. */ @@ -873,19 +1115,9 @@ nge_attach(device_t dev) goto fail; } - return (0); - fail: - if (sc->nge_ldata) - contigfree(sc->nge_ldata, - sizeof(struct nge_list_data), M_DEVBUF); - if (ifp) - if_free(ifp); - if (sc->nge_irq) - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); - if (sc->nge_res) - bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); - NGE_LOCK_DESTROY(sc); + if (error != 0) + nge_detach(dev); return (error); } @@ -899,68 +1131,339 @@ nge_detach(device_t dev) ifp = sc->nge_ifp; #ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) + if (ifp != NULL && ifp->if_capenable & IFCAP_POLLING) ether_poll_deregister(ifp); #endif - NGE_LOCK(sc); - nge_reset(sc); - nge_stop(sc); - NGE_UNLOCK(sc); - callout_drain(&sc->nge_stat_ch); - ether_ifdetach(ifp); - bus_generic_detach(dev); - if (!sc->nge_tbi) { - device_delete_child(dev, sc->nge_miibus); + if (device_is_attached(dev)) { + NGE_LOCK(sc); + sc->nge_flags |= NGE_FLAG_DETACH; + nge_stop(sc); + NGE_UNLOCK(sc); + callout_drain(&sc->nge_stat_ch); + if (ifp != NULL) + ether_ifdetach(ifp); } - bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); - bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); - bus_release_resource(dev, NGE_RES, NGE_RID, sc->nge_res); - contigfree(sc->nge_ldata, sizeof(struct nge_list_data), M_DEVBUF); - if_free(ifp); + if (sc->nge_miibus != NULL) { + device_delete_child(dev, sc->nge_miibus); + sc->nge_miibus = NULL; + } + bus_generic_detach(dev); + if (sc->nge_intrhand != NULL) + bus_teardown_intr(dev, sc->nge_irq, sc->nge_intrhand); + if (sc->nge_irq != NULL) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->nge_irq); + if (sc->nge_res != NULL) + bus_release_resource(dev, sc->nge_res_type, sc->nge_res_id, + sc->nge_res); + + nge_dma_free(sc); + if (ifp != NULL) + if_free(ifp); NGE_LOCK_DESTROY(sc); return (0); } +struct nge_dmamap_arg { + bus_addr_t nge_busaddr; +}; + +static void +nge_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error) +{ + struct nge_dmamap_arg *ctx; + + if (error != 0) + return; + ctx = arg; + ctx->nge_busaddr = segs[0].ds_addr; +} + +static int +nge_dma_alloc(struct nge_softc *sc) +{ + struct nge_dmamap_arg ctx; + struct nge_txdesc *txd; + struct nge_rxdesc *rxd; + int error, i; + + /* Create parent DMA tag. */ + error = bus_dma_tag_create( + bus_get_dma_tag(sc->nge_dev), /* parent */ + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR_32BIT, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsize */ + 0, /* nsegments */ + BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->nge_cdata.nge_parent_tag); + if (error != 0) { + device_printf(sc->nge_dev, "failed to create parent DMA tag\n"); + goto fail; + } + /* Create tag for Tx ring. */ + error = bus_dma_tag_create(sc->nge_cdata.nge_parent_tag,/* parent */ + NGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + NGE_TX_RING_SIZE, /* maxsize */ + 1, /* nsegments */ + NGE_TX_RING_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->nge_cdata.nge_tx_ring_tag); + if (error != 0) { + device_printf(sc->nge_dev, "failed to create Tx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Rx ring. */ + error = bus_dma_tag_create(sc->nge_cdata.nge_parent_tag,/* parent */ + NGE_RING_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + NGE_RX_RING_SIZE, /* maxsize */ + 1, /* nsegments */ + NGE_RX_RING_SIZE, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->nge_cdata.nge_rx_ring_tag); + if (error != 0) { + device_printf(sc->nge_dev, + "failed to create Rx ring DMA tag\n"); + goto fail; + } + + /* Create tag for Tx buffers. */ + error = bus_dma_tag_create(sc->nge_cdata.nge_parent_tag,/* parent */ + 1, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES * NGE_MAXTXSEGS, /* maxsize */ + NGE_MAXTXSEGS, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->nge_cdata.nge_tx_tag); + if (error != 0) { + device_printf(sc->nge_dev, "failed to create Tx DMA tag\n"); + goto fail; + } + + /* Create tag for Rx buffers. */ + error = bus_dma_tag_create(sc->nge_cdata.nge_parent_tag,/* parent */ + NGE_RX_ALIGN, 0, /* alignment, boundary */ + BUS_SPACE_MAXADDR, /* lowaddr */ + BUS_SPACE_MAXADDR, /* highaddr */ + NULL, NULL, /* filter, filterarg */ + MCLBYTES, /* maxsize */ + 1, /* nsegments */ + MCLBYTES, /* maxsegsize */ + 0, /* flags */ + NULL, NULL, /* lockfunc, lockarg */ + &sc->nge_cdata.nge_rx_tag); + if (error != 0) { + device_printf(sc->nge_dev, "failed to create Rx DMA tag\n"); + goto fail; + } + + /* Allocate DMA'able memory and load the DMA map for Tx ring. */ + error = bus_dmamem_alloc(sc->nge_cdata.nge_tx_ring_tag, + (void **)&sc->nge_rdata.nge_tx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->nge_cdata.nge_tx_ring_map); + if (error != 0) { + device_printf(sc->nge_dev, + "failed to allocate DMA'able memory for Tx ring\n"); + goto fail; + } + + ctx.nge_busaddr = 0; + error = bus_dmamap_load(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_cdata.nge_tx_ring_map, sc->nge_rdata.nge_tx_ring, + NGE_TX_RING_SIZE, nge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.nge_busaddr == 0) { + device_printf(sc->nge_dev, + "failed to load DMA'able memory for Tx ring\n"); + goto fail; + } + sc->nge_rdata.nge_tx_ring_paddr = ctx.nge_busaddr; + + /* Allocate DMA'able memory and load the DMA map for Rx ring. */ + error = bus_dmamem_alloc(sc->nge_cdata.nge_rx_ring_tag, + (void **)&sc->nge_rdata.nge_rx_ring, BUS_DMA_WAITOK | + BUS_DMA_COHERENT | BUS_DMA_ZERO, &sc->nge_cdata.nge_rx_ring_map); + if (error != 0) { + device_printf(sc->nge_dev, + "failed to allocate DMA'able memory for Rx ring\n"); + goto fail; + } + + ctx.nge_busaddr = 0; + error = bus_dmamap_load(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_cdata.nge_rx_ring_map, sc->nge_rdata.nge_rx_ring, + NGE_RX_RING_SIZE, nge_dmamap_cb, &ctx, 0); + if (error != 0 || ctx.nge_busaddr == 0) { + device_printf(sc->nge_dev, + "failed to load DMA'able memory for Rx ring\n"); + goto fail; + } + sc->nge_rdata.nge_rx_ring_paddr = ctx.nge_busaddr; + + /* Create DMA maps for Tx buffers. */ + for (i = 0; i < NGE_TX_RING_CNT; i++) { + txd = &sc->nge_cdata.nge_txdesc[i]; + txd->tx_m = NULL; + txd->tx_dmamap = NULL; + error = bus_dmamap_create(sc->nge_cdata.nge_tx_tag, 0, + &txd->tx_dmamap); + if (error != 0) { + device_printf(sc->nge_dev, + "failed to create Tx dmamap\n"); + goto fail; + } + } + /* Create DMA maps for Rx buffers. */ + if ((error = bus_dmamap_create(sc->nge_cdata.nge_rx_tag, 0, + &sc->nge_cdata.nge_rx_sparemap)) != 0) { + device_printf(sc->nge_dev, + "failed to create spare Rx dmamap\n"); + goto fail; + } + for (i = 0; i < NGE_RX_RING_CNT; i++) { + rxd = &sc->nge_cdata.nge_rxdesc[i]; + rxd->rx_m = NULL; + rxd->rx_dmamap = NULL; + error = bus_dmamap_create(sc->nge_cdata.nge_rx_tag, 0, + &rxd->rx_dmamap); + if (error != 0) { + device_printf(sc->nge_dev, + "failed to create Rx dmamap\n"); + goto fail; + } + } + +fail: + return (error); +} + +static void +nge_dma_free(struct nge_softc *sc) +{ + struct nge_txdesc *txd; + struct nge_rxdesc *rxd; + int i; + + /* Tx ring. */ + if (sc->nge_cdata.nge_tx_ring_tag) { + if (sc->nge_cdata.nge_tx_ring_map) + bus_dmamap_unload(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_cdata.nge_tx_ring_map); + if (sc->nge_cdata.nge_tx_ring_map && + sc->nge_rdata.nge_tx_ring) + bus_dmamem_free(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_rdata.nge_tx_ring, + sc->nge_cdata.nge_tx_ring_map); + sc->nge_rdata.nge_tx_ring = NULL; + sc->nge_cdata.nge_tx_ring_map = NULL; + bus_dma_tag_destroy(sc->nge_cdata.nge_tx_ring_tag); + sc->nge_cdata.nge_tx_ring_tag = NULL; + } + /* Rx ring. */ + if (sc->nge_cdata.nge_rx_ring_tag) { + if (sc->nge_cdata.nge_rx_ring_map) + bus_dmamap_unload(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_cdata.nge_rx_ring_map); + if (sc->nge_cdata.nge_rx_ring_map && + sc->nge_rdata.nge_rx_ring) + bus_dmamem_free(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_rdata.nge_rx_ring, + sc->nge_cdata.nge_rx_ring_map); + sc->nge_rdata.nge_rx_ring = NULL; + sc->nge_cdata.nge_rx_ring_map = NULL; + bus_dma_tag_destroy(sc->nge_cdata.nge_rx_ring_tag); + sc->nge_cdata.nge_rx_ring_tag = NULL; + } + /* Tx buffers. */ + if (sc->nge_cdata.nge_tx_tag) { + for (i = 0; i < NGE_TX_RING_CNT; i++) { + txd = &sc->nge_cdata.nge_txdesc[i]; + if (txd->tx_dmamap) { + bus_dmamap_destroy(sc->nge_cdata.nge_tx_tag, + txd->tx_dmamap); + txd->tx_dmamap = NULL; + } + } + bus_dma_tag_destroy(sc->nge_cdata.nge_tx_tag); + sc->nge_cdata.nge_tx_tag = NULL; + } + /* Rx buffers. */ + if (sc->nge_cdata.nge_rx_tag) { + for (i = 0; i < NGE_RX_RING_CNT; i++) { + rxd = &sc->nge_cdata.nge_rxdesc[i]; + if (rxd->rx_dmamap) { + bus_dmamap_destroy(sc->nge_cdata.nge_rx_tag, + rxd->rx_dmamap); + rxd->rx_dmamap = NULL; + } + } + if (sc->nge_cdata.nge_rx_sparemap) { + bus_dmamap_destroy(sc->nge_cdata.nge_rx_tag, + sc->nge_cdata.nge_rx_sparemap); + sc->nge_cdata.nge_rx_sparemap = 0; + } + bus_dma_tag_destroy(sc->nge_cdata.nge_rx_tag); + sc->nge_cdata.nge_rx_tag = NULL; + } + + if (sc->nge_cdata.nge_parent_tag) { + bus_dma_tag_destroy(sc->nge_cdata.nge_parent_tag); + sc->nge_cdata.nge_parent_tag = NULL; + } +} + /* * Initialize the transmit descriptors. */ static int nge_list_tx_init(struct nge_softc *sc) { - struct nge_list_data *ld; - struct nge_ring_data *cd; + struct nge_ring_data *rd; + struct nge_txdesc *txd; + bus_addr_t addr; int i; - cd = &sc->nge_cdata; - ld = sc->nge_ldata; + sc->nge_cdata.nge_tx_prod = 0; + sc->nge_cdata.nge_tx_cons = 0; + sc->nge_cdata.nge_tx_cnt = 0; - for (i = 0; i < NGE_TX_LIST_CNT; i++) { - if (i == (NGE_TX_LIST_CNT - 1)) { - ld->nge_tx_list[i].nge_nextdesc = - &ld->nge_tx_list[0]; - ld->nge_tx_list[i].nge_next = - vtophys(&ld->nge_tx_list[0]); - } else { - ld->nge_tx_list[i].nge_nextdesc = - &ld->nge_tx_list[i + 1]; - ld->nge_tx_list[i].nge_next = - vtophys(&ld->nge_tx_list[i + 1]); - } - ld->nge_tx_list[i].nge_mbuf = NULL; - ld->nge_tx_list[i].nge_ptr = 0; - ld->nge_tx_list[i].nge_ctl = 0; + rd = &sc->nge_rdata; + bzero(rd->nge_tx_ring, sizeof(struct nge_desc) * NGE_TX_RING_CNT); + for (i = 0; i < NGE_TX_RING_CNT; i++) { + if (i == NGE_TX_RING_CNT - 1) + addr = NGE_TX_RING_ADDR(sc, 0); + else + addr = NGE_TX_RING_ADDR(sc, i + 1); + rd->nge_tx_ring[i].nge_next = htole32(NGE_ADDR_LO(addr)); + txd = &sc->nge_cdata.nge_txdesc[i]; + txd->tx_m = NULL; } - cd->nge_tx_prod = cd->nge_tx_cons = cd->nge_tx_cnt = 0; + bus_dmamap_sync(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_cdata.nge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); return (0); } - /* * Initialize the RX descriptors and allocate mbufs for them. Note that * we arrange the descriptors in a closed ring, so that the last descriptor @@ -969,67 +1472,94 @@ nge_list_tx_init(struct nge_softc *sc) static int nge_list_rx_init(struct nge_softc *sc) { - struct nge_list_data *ld; - struct nge_ring_data *cd; + struct nge_ring_data *rd; + bus_addr_t addr; int i; - ld = sc->nge_ldata; - cd = &sc->nge_cdata; - - for (i = 0; i < NGE_RX_LIST_CNT; i++) { - if (nge_newbuf(sc, &ld->nge_rx_list[i], NULL) == ENOBUFS) - return (ENOBUFS); - if (i == (NGE_RX_LIST_CNT - 1)) { - ld->nge_rx_list[i].nge_nextdesc = - &ld->nge_rx_list[0]; - ld->nge_rx_list[i].nge_next = - vtophys(&ld->nge_rx_list[0]); - } else { - ld->nge_rx_list[i].nge_nextdesc = - &ld->nge_rx_list[i + 1]; - ld->nge_rx_list[i].nge_next = - vtophys(&ld->nge_rx_list[i + 1]); - } - } - - cd->nge_rx_prod = 0; + sc->nge_cdata.nge_rx_cons = 0; sc->nge_head = sc->nge_tail = NULL; + rd = &sc->nge_rdata; + bzero(rd->nge_rx_ring, sizeof(struct nge_desc) * NGE_RX_RING_CNT); + for (i = 0; i < NGE_RX_RING_CNT; i++) { + if (nge_newbuf(sc, i) != 0) + return (ENOBUFS); + if (i == NGE_RX_RING_CNT - 1) + addr = NGE_RX_RING_ADDR(sc, 0); + else + addr = NGE_RX_RING_ADDR(sc, i + 1); + rd->nge_rx_ring[i].nge_next = htole32(NGE_ADDR_LO(addr)); + } + + bus_dmamap_sync(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_cdata.nge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + return (0); } +static __inline void +nge_discard_rxbuf(struct nge_softc *sc, int idx) +{ + struct nge_desc *desc; + + desc = &sc->nge_rdata.nge_rx_ring[idx]; + desc->nge_cmdsts = htole32(MCLBYTES - sizeof(uint64_t)); + desc->nge_extsts = 0; +} + /* * Initialize an RX descriptor and attach an MBUF cluster. */ static int -nge_newbuf(struct nge_softc *sc, struct nge_desc *c, struct mbuf *m) +nge_newbuf(struct nge_softc *sc, int idx) { + struct nge_desc *desc; + struct nge_rxdesc *rxd; + struct mbuf *m; + bus_dma_segment_t segs[1]; + bus_dmamap_t map; + int nsegs; - if (m == NULL) { - m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); - if (m == NULL) - return (ENOBUFS); - } else - m->m_data = m->m_ext.ext_buf; - + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + if (m == NULL) + return (ENOBUFS); m->m_len = m->m_pkthdr.len = MCLBYTES; - m_adj(m, sizeof(uint64_t)); - c->nge_mbuf = m; - c->nge_ptr = vtophys(mtod(m, caddr_t)); - c->nge_ctl = m->m_len; - c->nge_extsts = 0; + if (bus_dmamap_load_mbuf_sg(sc->nge_cdata.nge_rx_tag, + sc->nge_cdata.nge_rx_sparemap, m, segs, &nsegs, 0) != 0) { + m_freem(m); + return (ENOBUFS); + } + KASSERT(nsegs == 1, ("%s: %d segments returned!", __func__, nsegs)); + + rxd = &sc->nge_cdata.nge_rxdesc[idx]; + if (rxd->rx_m != NULL) { + bus_dmamap_sync(sc->nge_cdata.nge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->nge_cdata.nge_rx_tag, rxd->rx_dmamap); + } + map = rxd->rx_dmamap; + rxd->rx_dmamap = sc->nge_cdata.nge_rx_sparemap; + sc->nge_cdata.nge_rx_sparemap = map; + bus_dmamap_sync(sc->nge_cdata.nge_rx_tag, rxd->rx_dmamap, + BUS_DMASYNC_PREREAD); + rxd->rx_m = m; + desc = &sc->nge_rdata.nge_rx_ring[idx]; + desc->nge_ptr = htole32(NGE_ADDR_LO(segs[0].ds_addr)); + desc->nge_cmdsts = htole32(segs[0].ds_len); + desc->nge_extsts = 0; return (0); } -#ifdef NGE_FIXUP_RX +#ifndef __NO_STRICT_ALIGNMENT static __inline void nge_fixup_rx(struct mbuf *m) { - int i; - uint16_t *src, *dst; + int i; + uint16_t *src, *dst; src = mtod(m, uint16_t *); dst = src - 1; @@ -1038,8 +1568,6 @@ nge_fixup_rx(struct mbuf *m) *dst++ = *src++; m->m_data -= ETHER_ALIGN; - - return; } #endif @@ -1053,16 +1581,22 @@ nge_rxeof(struct nge_softc *sc) struct mbuf *m; struct ifnet *ifp; struct nge_desc *cur_rx; - int i, total_len = 0; - uint32_t rxstat; + struct nge_rxdesc *rxd; + int cons, prog, total_len; + uint32_t cmdsts, extsts; NGE_LOCK_ASSERT(sc); + ifp = sc->nge_ifp; - i = sc->nge_cdata.nge_rx_prod; + cons = sc->nge_cdata.nge_rx_cons; - while (NGE_OWNDESC(&sc->nge_ldata->nge_rx_list[i])) { - uint32_t extsts; + bus_dmamap_sync(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_cdata.nge_rx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + for (prog = 0; prog < NGE_RX_RING_CNT && + (ifp->if_drv_flags & IFF_DRV_RUNNING) != 0; + NGE_INC(cons, NGE_RX_RING_CNT)) { #ifdef DEVICE_POLLING if (ifp->if_capenable & IFCAP_POLLING) { if (sc->rxcycles <= 0) @@ -1070,16 +1604,26 @@ nge_rxeof(struct nge_softc *sc) sc->rxcycles--; } #endif + cur_rx = &sc->nge_rdata.nge_rx_ring[cons]; + cmdsts = le32toh(cur_rx->nge_cmdsts); + extsts = le32toh(cur_rx->nge_extsts); + if ((cmdsts & NGE_CMDSTS_OWN) == 0) + break; + prog++; + rxd = &sc->nge_cdata.nge_rxdesc[cons]; + m = rxd->rx_m; + total_len = cmdsts & NGE_CMDSTS_BUFLEN; - cur_rx = &sc->nge_ldata->nge_rx_list[i]; - rxstat = cur_rx->nge_rxstat; - extsts = cur_rx->nge_extsts; - m = cur_rx->nge_mbuf; - cur_rx->nge_mbuf = NULL; - total_len = NGE_RXBYTES(cur_rx); - NGE_INC(i, NGE_RX_LIST_CNT); - - if (rxstat & NGE_CMDSTS_MORE) { + if ((cmdsts & NGE_CMDSTS_MORE) != 0) { + if (nge_newbuf(sc, cons) != 0) { + ifp->if_iqdrops++; + if (sc->nge_head != NULL) { + m_freem(sc->nge_head); + sc->nge_head = sc->nge_tail = NULL; + } + nge_discard_rxbuf(sc, cons); + continue; + } m->m_len = total_len; if (sc->nge_head == NULL) { m->m_pkthdr.len = total_len; @@ -1090,7 +1634,6 @@ nge_rxeof(struct nge_softc *sc) sc->nge_tail->m_next = m; sc->nge_tail = m; } - nge_newbuf(sc, cur_rx, NULL); continue; } @@ -1100,28 +1643,39 @@ nge_rxeof(struct nge_softc *sc) * it should simply get re-used next time this descriptor * comes up in the ring. */ - if (!(rxstat & NGE_CMDSTS_PKT_OK)) { - ifp->if_ierrors++; - if (sc->nge_head != NULL) { - m_freem(sc->nge_head); - sc->nge_head = sc->nge_tail = NULL; + if ((cmdsts & NGE_CMDSTS_PKT_OK) == 0) { + if ((cmdsts & NGE_RXSTAT_RUNT) && + total_len >= (ETHER_MIN_LEN - ETHER_CRC_LEN - 4)) { + /* + * Work-around hardware bug, accept runt frames + * if its length is larger than or equal to 56. + */ + } else { + /* + * Input error counters are updated by hardware. + */ + if (sc->nge_head != NULL) { + m_freem(sc->nge_head); + sc->nge_head = sc->nge_tail = NULL; + } + nge_discard_rxbuf(sc, cons); + continue; } - nge_newbuf(sc, cur_rx, m); - continue; } /* Try conjure up a replacement mbuf. */ - if (nge_newbuf(sc, cur_rx, NULL)) { - ifp->if_ierrors++; + if (nge_newbuf(sc, cons) != 0) { + ifp->if_iqdrops++; if (sc->nge_head != NULL) { m_freem(sc->nge_head); sc->nge_head = sc->nge_tail = NULL; } - nge_newbuf(sc, cur_rx, m); + nge_discard_rxbuf(sc, cons); continue; } + /* Chain received mbufs. */ if (sc->nge_head != NULL) { m->m_len = total_len; m->m_flags &= ~M_PKTHDR; @@ -1139,40 +1693,42 @@ nge_rxeof(struct nge_softc *sc) */ /* * By popular demand, ignore the alignment problems - * on the Intel x86 platform. The performance hit + * on the non-strict alignment platform. The performance hit * incurred due to unaligned accesses is much smaller * than the hit produced by forcing buffer copies all * the time, especially with jumbo frames. We still * need to fix up the alignment everywhere else though. */ -#ifdef NGE_FIXUP_RX +#ifndef __NO_STRICT_ALIGNMENT nge_fixup_rx(m); #endif - - ifp->if_ipackets++; m->m_pkthdr.rcvif = ifp; + ifp->if_ipackets++; - /* Do IP checksum checking. */ - if (extsts & NGE_RXEXTSTS_IPPKT) - m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; - if (!(extsts & NGE_RXEXTSTS_IPCSUMERR)) - m->m_pkthdr.csum_flags |= CSUM_IP_VALID; - if ((extsts & NGE_RXEXTSTS_TCPPKT && - !(extsts & NGE_RXEXTSTS_TCPCSUMERR)) || - (extsts & NGE_RXEXTSTS_UDPPKT && - !(extsts & NGE_RXEXTSTS_UDPCSUMERR))) { - m->m_pkthdr.csum_flags |= - CSUM_DATA_VALID|CSUM_PSEUDO_HDR; - m->m_pkthdr.csum_data = 0xffff; + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) { + /* Do IP checksum checking. */ + if ((extsts & NGE_RXEXTSTS_IPPKT) != 0) + m->m_pkthdr.csum_flags |= CSUM_IP_CHECKED; + if ((extsts & NGE_RXEXTSTS_IPCSUMERR) == 0) + m->m_pkthdr.csum_flags |= CSUM_IP_VALID; + if ((extsts & NGE_RXEXTSTS_TCPPKT && + !(extsts & NGE_RXEXTSTS_TCPCSUMERR)) || + (extsts & NGE_RXEXTSTS_UDPPKT && + !(extsts & NGE_RXEXTSTS_UDPCSUMERR))) { + m->m_pkthdr.csum_flags |= + CSUM_DATA_VALID | CSUM_PSEUDO_HDR; + m->m_pkthdr.csum_data = 0xffff; + } } /* * If we received a packet with a vlan tag, pass it * to vlan_input() instead of ether_input(). */ - if (extsts & NGE_RXEXTSTS_VLANPKT) { + if ((extsts & NGE_RXEXTSTS_VLANPKT) != 0 && + (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) { m->m_pkthdr.ether_vtag = - ntohs(extsts & NGE_RXEXTSTS_VTCI); + bswap16(extsts & NGE_RXEXTSTS_VTCI); m->m_flags |= M_VLANTAG; } NGE_UNLOCK(sc); @@ -1180,67 +1736,76 @@ nge_rxeof(struct nge_softc *sc) NGE_LOCK(sc); } - sc->nge_cdata.nge_rx_prod = i; + if (prog > 0) { + sc->nge_cdata.nge_rx_cons = cons; + bus_dmamap_sync(sc->nge_cdata.nge_rx_ring_tag, + sc->nge_cdata.nge_rx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + } } /* * A frame was downloaded to the chip. It's safe for us to clean up * the list buffers. */ - static void nge_txeof(struct nge_softc *sc) { - struct nge_desc *cur_tx; + struct nge_desc *cur_tx; + struct nge_txdesc *txd; struct ifnet *ifp; - uint32_t idx; + uint32_t cmdsts; + int cons, prod; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; + cons = sc->nge_cdata.nge_tx_cons; + prod = sc->nge_cdata.nge_tx_prod; + if (cons == prod) + return; + + bus_dmamap_sync(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_cdata.nge_tx_ring_map, + BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); + /* * Go through our tx list and free mbufs for those * frames that have been transmitted. */ - idx = sc->nge_cdata.nge_tx_cons; - while (idx != sc->nge_cdata.nge_tx_prod) { - cur_tx = &sc->nge_ldata->nge_tx_list[idx]; - - if (NGE_OWNDESC(cur_tx)) + for (; cons != prod; NGE_INC(cons, NGE_TX_RING_CNT)) { + cur_tx = &sc->nge_rdata.nge_tx_ring[cons]; + cmdsts = le32toh(cur_tx->nge_cmdsts); + if ((cmdsts & NGE_CMDSTS_OWN) != 0) break; - - if (cur_tx->nge_ctl & NGE_CMDSTS_MORE) { - sc->nge_cdata.nge_tx_cnt--; - NGE_INC(idx, NGE_TX_LIST_CNT); - continue; - } - - if (!(cur_tx->nge_ctl & NGE_CMDSTS_PKT_OK)) { - ifp->if_oerrors++; - if (cur_tx->nge_txstat & NGE_TXSTAT_EXCESSCOLLS) - ifp->if_collisions++; - if (cur_tx->nge_txstat & NGE_TXSTAT_OUTOFWINCOLL) - ifp->if_collisions++; - } - - ifp->if_collisions += - (cur_tx->nge_txstat & NGE_TXSTAT_COLLCNT) >> 16; - - ifp->if_opackets++; - if (cur_tx->nge_mbuf != NULL) { - m_freem(cur_tx->nge_mbuf); - cur_tx->nge_mbuf = NULL; - ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - } - sc->nge_cdata.nge_tx_cnt--; - NGE_INC(idx, NGE_TX_LIST_CNT); + ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; + if ((cmdsts & NGE_CMDSTS_MORE) != 0) + continue; + + txd = &sc->nge_cdata.nge_txdesc[cons]; + bus_dmamap_sync(sc->nge_cdata.nge_tx_tag, txd->tx_dmamap, + BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->nge_cdata.nge_tx_tag, txd->tx_dmamap); + if ((cmdsts & NGE_CMDSTS_PKT_OK) == 0) { + ifp->if_oerrors++; + if ((cmdsts & NGE_TXSTAT_EXCESSCOLLS) != 0) + ifp->if_collisions++; + if ((cmdsts & NGE_TXSTAT_OUTOFWINCOLL) != 0) + ifp->if_collisions++; + } else + ifp->if_opackets++; + + ifp->if_collisions += (cmdsts & NGE_TXSTAT_COLLCNT) >> 16; + KASSERT(txd->tx_m != NULL, ("%s: freeing NULL mbuf!\n", + __func__)); + m_freem(txd->tx_m); + txd->tx_m = NULL; } - sc->nge_cdata.nge_tx_cons = idx; - - if (idx == sc->nge_cdata.nge_tx_prod) - ifp->if_timer = 0; + sc->nge_cdata.nge_tx_cons = cons; + if (sc->nge_cdata.nge_tx_cnt == 0) + sc->nge_watchdog_timer = 0; } static void @@ -1248,55 +1813,90 @@ nge_tick(void *xsc) { struct nge_softc *sc; struct mii_data *mii; - struct ifnet *ifp; sc = xsc; NGE_LOCK_ASSERT(sc); - ifp = sc->nge_ifp; - - if (sc->nge_tbi) { - if (!sc->nge_link) { - if (CSR_READ_4(sc, NGE_TBI_BMSR) - & NGE_TBIBMSR_ANEG_DONE) { - if (bootverbose) - device_printf(sc->nge_dev, - "gigabit link up\n"); - nge_miibus_statchg(sc->nge_miibus); - sc->nge_link++; - if (ifp->if_snd.ifq_head != NULL) - nge_start_locked(ifp); - } - } - } else { - mii = device_get_softc(sc->nge_miibus); - mii_tick(mii); - - if (!sc->nge_link) { - if (mii->mii_media_status & IFM_ACTIVE && - IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) { - sc->nge_link++; - if (IFM_SUBTYPE(mii->mii_media_active) - == IFM_1000_T && bootverbose) - device_printf(sc->nge_dev, - "gigabit link up\n"); - if (ifp->if_snd.ifq_head != NULL) - nge_start_locked(ifp); - } - } - } + mii = device_get_softc(sc->nge_miibus); + mii_tick(mii); + /* + * For PHYs that does not reset established link, it is + * necessary to check whether driver still have a valid + * link(e.g link state change callback is not called). + * Otherwise, driver think it lost link because driver + * initialization routine clears link state flag. + */ + if ((sc->nge_flags & NGE_FLAG_LINK) == 0) + nge_miibus_statchg(sc->nge_dev); + nge_stats_update(sc); + nge_watchdog(sc); callout_reset(&sc->nge_stat_ch, hz, nge_tick, sc); } +static void +nge_stats_update(struct nge_softc *sc) +{ + struct ifnet *ifp; + struct nge_stats now, *stats, *nstats; + + NGE_LOCK_ASSERT(sc); + + ifp = sc->nge_ifp; + stats = &now; + stats->rx_pkts_errs = + CSR_READ_4(sc, NGE_MIB_RXERRPKT) & 0xFFFF; + stats->rx_crc_errs = + CSR_READ_4(sc, NGE_MIB_RXERRFCS) & 0xFFFF; + stats->rx_fifo_oflows = + CSR_READ_4(sc, NGE_MIB_RXERRMISSEDPKT) & 0xFFFF; + stats->rx_align_errs = + CSR_READ_4(sc, NGE_MIB_RXERRALIGN) & 0xFFFF; + stats->rx_sym_errs = + CSR_READ_4(sc, NGE_MIB_RXERRSYM) & 0xFFFF; + stats->rx_pkts_jumbos = + CSR_READ_4(sc, NGE_MIB_RXERRGIANT) & 0xFFFF; + stats->rx_len_errs = + CSR_READ_4(sc, NGE_MIB_RXERRRANGLEN) & 0xFFFF; + stats->rx_unctl_frames = + CSR_READ_4(sc, NGE_MIB_RXBADOPCODE) & 0xFFFF; + stats->rx_pause = + CSR_READ_4(sc, NGE_MIB_RXPAUSEPKTS) & 0xFFFF; + stats->tx_pause = + CSR_READ_4(sc, NGE_MIB_TXPAUSEPKTS) & 0xFFFF; + stats->tx_seq_errs = + CSR_READ_4(sc, NGE_MIB_TXERRSQE) & 0xFF; + + /* + * Since we've accept errored frames exclude Rx length errors. + */ + ifp->if_ierrors += stats->rx_pkts_errs + stats->rx_crc_errs + + stats->rx_fifo_oflows + stats->rx_sym_errs; + + nstats = &sc->nge_stats; + nstats->rx_pkts_errs += stats->rx_pkts_errs; + nstats->rx_crc_errs += stats->rx_crc_errs; + nstats->rx_fifo_oflows += stats->rx_fifo_oflows; + nstats->rx_align_errs += stats->rx_align_errs; + nstats->rx_sym_errs += stats->rx_sym_errs; + nstats->rx_pkts_jumbos += stats->rx_pkts_jumbos; + nstats->rx_len_errs += stats->rx_len_errs; + nstats->rx_unctl_frames += stats->rx_unctl_frames; + nstats->rx_pause += stats->rx_pause; + nstats->tx_pause += stats->tx_pause; + nstats->tx_seq_errs += stats->tx_seq_errs; +} + #ifdef DEVICE_POLLING static poll_handler_t nge_poll; static void nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { - struct nge_softc *sc = ifp->if_softc; + struct nge_softc *sc; + + sc = ifp->if_softc; NGE_LOCK(sc); - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { NGE_UNLOCK(sc); return; } @@ -1306,12 +1906,12 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) * So before returning to intr mode we must make sure that all * possible pending sources of interrupts have been served. * In practice this means run to completion the *eof routines, - * and then call the interrupt routine + * and then call the interrupt routine. */ sc->rxcycles = count; nge_rxeof(sc); nge_txeof(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) nge_start_locked(ifp); if (sc->rxcycles > 0 || cmd == POLL_AND_CHECK_STATUS) { @@ -1320,14 +1920,14 @@ nge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) /* Reading the ISR register clears all interrupts. */ status = CSR_READ_4(sc, NGE_ISR); - if (status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW)) + if ((status & (NGE_ISR_RX_ERR|NGE_ISR_RX_OFLOW)) != 0) nge_rxeof(sc); - if (status & (NGE_ISR_RX_IDLE)) + if ((status & NGE_ISR_RX_IDLE) != 0) NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); - if (status & NGE_ISR_SYSERR) { - nge_reset(sc); + if ((status & NGE_ISR_SYSERR) != 0) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; nge_init_locked(sc); } } @@ -1342,87 +1942,66 @@ nge_intr(void *arg) struct ifnet *ifp; uint32_t status; - sc = arg; + sc = (struct nge_softc *)arg; ifp = sc->nge_ifp; NGE_LOCK(sc); -#ifdef DEVICE_POLLING - if (ifp->if_capenable & IFCAP_POLLING) { - NGE_UNLOCK(sc); - return; - } -#endif - /* Supress unwanted interrupts */ - if (!(ifp->if_flags & IFF_UP)) { - nge_stop(sc); - NGE_UNLOCK(sc); - return; - } + if ((sc->nge_flags & NGE_FLAG_SUSPENDED) != 0) + goto done_locked; + + /* Reading the ISR register clears all interrupts. */ + status = CSR_READ_4(sc, NGE_ISR); + if (status == 0xffffffff || (status & NGE_INTRS) == 0) + goto done_locked; +#ifdef DEVICE_POLLING + if ((ifp->if_capenable & IFCAP_POLLING) != 0) + goto done_locked; +#endif + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + goto done_locked; /* Disable interrupts. */ CSR_WRITE_4(sc, NGE_IER, 0); /* Data LED on for TBI mode */ - if (sc->nge_tbi) - CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) - | NGE_GPIO_GP3_OUT); + if ((sc->nge_flags & NGE_FLAG_TBI) != 0) + CSR_WRITE_4(sc, NGE_GPIO, + CSR_READ_4(sc, NGE_GPIO) | NGE_GPIO_GP3_OUT); - for (;;) { - /* Reading the ISR register clears all interrupts. */ - status = CSR_READ_4(sc, NGE_ISR); - - if ((status & NGE_INTRS) == 0) - break; - - if ((status & NGE_ISR_TX_DESC_OK) || - (status & NGE_ISR_TX_ERR) || - (status & NGE_ISR_TX_OK) || - (status & NGE_ISR_TX_IDLE)) + for (; (status & NGE_INTRS) != 0;) { + if ((status & (NGE_ISR_TX_DESC_OK | NGE_ISR_TX_ERR | + NGE_ISR_TX_OK | NGE_ISR_TX_IDLE)) != 0) nge_txeof(sc); - if ((status & NGE_ISR_RX_DESC_OK) || - (status & NGE_ISR_RX_ERR) || - (status & NGE_ISR_RX_OFLOW) || - (status & NGE_ISR_RX_FIFO_OFLOW) || - (status & NGE_ISR_RX_IDLE) || - (status & NGE_ISR_RX_OK)) + if ((status & (NGE_ISR_RX_DESC_OK | NGE_ISR_RX_ERR | + NGE_ISR_RX_OFLOW | NGE_ISR_RX_FIFO_OFLOW | + NGE_ISR_RX_IDLE | NGE_ISR_RX_OK)) != 0) nge_rxeof(sc); - if ((status & NGE_ISR_RX_IDLE)) + if ((status & NGE_ISR_RX_IDLE) != 0) NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); - if (status & NGE_ISR_SYSERR) { - nge_reset(sc); + if ((status & NGE_ISR_SYSERR) != 0) { ifp->if_drv_flags &= ~IFF_DRV_RUNNING; nge_init_locked(sc); } - -#if 0 - /* - * XXX: nge_tick() is not ready to be called this way - * it screws up the aneg timeout because mii_tick() is - * only to be called once per second. - */ - if (status & NGE_IMR_PHY_INTR) { - sc->nge_link = 0; - nge_tick(sc); - } -#endif + /* Reading the ISR register clears all interrupts. */ + status = CSR_READ_4(sc, NGE_ISR); } /* Re-enable interrupts. */ CSR_WRITE_4(sc, NGE_IER, 1); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) nge_start_locked(ifp); /* Data LED off for TBI mode */ + if ((sc->nge_flags & NGE_FLAG_TBI) != 0) + CSR_WRITE_4(sc, NGE_GPIO, + CSR_READ_4(sc, NGE_GPIO) & ~NGE_GPIO_GP3_OUT); - if (sc->nge_tbi) - CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) - & ~NGE_GPIO_GP3_OUT); - +done_locked: NGE_UNLOCK(sc); } @@ -1431,62 +2010,99 @@ nge_intr(void *arg) * pointers to the fragment pointers. */ static int -nge_encap(struct nge_softc *sc, struct mbuf *m_head, uint32_t *txidx) +nge_encap(struct nge_softc *sc, struct mbuf **m_head) { - struct nge_desc *f = NULL; + struct nge_txdesc *txd, *txd_last; + struct nge_desc *desc; struct mbuf *m; - int frag, cur, cnt = 0; + bus_dmamap_t map; + bus_dma_segment_t txsegs[NGE_MAXTXSEGS]; + int error, i, nsegs, prod, si; - /* - * Start packing the mbufs in this chain into - * the fragment pointers. Stop when we run out - * of fragments or hit the end of the mbuf chain. - */ - m = m_head; - cur = frag = *txidx; + NGE_LOCK_ASSERT(sc); - for (m = m_head; m != NULL; m = m->m_next) { - if (m->m_len != 0) { - if ((NGE_TX_LIST_CNT - - (sc->nge_cdata.nge_tx_cnt + cnt)) < 2) - return (ENOBUFS); - f = &sc->nge_ldata->nge_tx_list[frag]; - f->nge_ctl = NGE_CMDSTS_MORE | m->m_len; - f->nge_ptr = vtophys(mtod(m, vm_offset_t)); - if (cnt != 0) - f->nge_ctl |= NGE_CMDSTS_OWN; - cur = frag; - NGE_INC(frag, NGE_TX_LIST_CNT); - cnt++; + m = *m_head; + prod = sc->nge_cdata.nge_tx_prod; + txd = &sc->nge_cdata.nge_txdesc[prod]; + txd_last = txd; + map = txd->tx_dmamap; + error = bus_dmamap_load_mbuf_sg(sc->nge_cdata.nge_tx_tag, map, + *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); + if (error == EFBIG) { + m = m_collapse(*m_head, M_DONTWAIT, NGE_MAXTXSEGS); + if (m == NULL) { + m_freem(*m_head); + *m_head = NULL; + return (ENOBUFS); } + *m_head = m; + error = bus_dmamap_load_mbuf_sg(sc->nge_cdata.nge_tx_tag, + map, *m_head, txsegs, &nsegs, BUS_DMA_NOWAIT); + if (error != 0) { + m_freem(*m_head); + *m_head = NULL; + return (error); + } + } else if (error != 0) + return (error); + if (nsegs == 0) { + m_freem(*m_head); + *m_head = NULL; + return (EIO); } - if (m != NULL) + /* Check number of available descriptors. */ + if (sc->nge_cdata.nge_tx_cnt + nsegs >= (NGE_TX_RING_CNT - 1)) { + bus_dmamap_unload(sc->nge_cdata.nge_tx_tag, map); return (ENOBUFS); - - sc->nge_ldata->nge_tx_list[*txidx].nge_extsts = 0; - if (m_head->m_pkthdr.csum_flags) { - if (m_head->m_pkthdr.csum_flags & CSUM_IP) - sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= - NGE_TXEXTSTS_IPCSUM; - if (m_head->m_pkthdr.csum_flags & CSUM_TCP) - sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= - NGE_TXEXTSTS_TCPCSUM; - if (m_head->m_pkthdr.csum_flags & CSUM_UDP) - sc->nge_ldata->nge_tx_list[*txidx].nge_extsts |= - NGE_TXEXTSTS_UDPCSUM; } - if (m_head->m_flags & M_VLANTAG) { - sc->nge_ldata->nge_tx_list[cur].nge_extsts |= - (NGE_TXEXTSTS_VLANPKT|htons(m_head->m_pkthdr.ether_vtag)); - } + bus_dmamap_sync(sc->nge_cdata.nge_tx_tag, map, BUS_DMASYNC_PREWRITE); - sc->nge_ldata->nge_tx_list[cur].nge_mbuf = m_head; - sc->nge_ldata->nge_tx_list[cur].nge_ctl &= ~NGE_CMDSTS_MORE; - sc->nge_ldata->nge_tx_list[*txidx].nge_ctl |= NGE_CMDSTS_OWN; - sc->nge_cdata.nge_tx_cnt += cnt; - *txidx = frag; + si = prod; + for (i = 0; i < nsegs; i++) { + desc = &sc->nge_rdata.nge_tx_ring[prod]; + desc->nge_ptr = htole32(NGE_ADDR_LO(txsegs[i].ds_addr)); + if (i == 0) + desc->nge_cmdsts = htole32(txsegs[i].ds_len | + NGE_CMDSTS_MORE); + else + desc->nge_cmdsts = htole32(txsegs[i].ds_len | + NGE_CMDSTS_MORE | NGE_CMDSTS_OWN); + desc->nge_extsts = 0; + sc->nge_cdata.nge_tx_cnt++; + NGE_INC(prod, NGE_TX_RING_CNT); + } + /* Update producer index. */ + sc->nge_cdata.nge_tx_prod = prod; + + prod = (prod + NGE_TX_RING_CNT - 1) % NGE_TX_RING_CNT; + desc = &sc->nge_rdata.nge_tx_ring[prod]; + /* Check if we have a VLAN tag to insert. */ + if ((m->m_flags & M_VLANTAG) != 0) + desc->nge_extsts |= htole32(NGE_TXEXTSTS_VLANPKT | + bswap16(m->m_pkthdr.ether_vtag)); + /* Set EOP on the last desciptor. */ + desc->nge_cmdsts &= htole32(~NGE_CMDSTS_MORE); + + /* Set checksum offload in the first descriptor. */ + desc = &sc->nge_rdata.nge_tx_ring[si]; + if ((m->m_pkthdr.csum_flags & NGE_CSUM_FEATURES) != 0) { + if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) + desc->nge_extsts |= htole32(NGE_TXEXTSTS_IPCSUM); + if ((m->m_pkthdr.csum_flags & CSUM_TCP) != 0) + desc->nge_extsts |= htole32(NGE_TXEXTSTS_TCPCSUM); + if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0) + desc->nge_extsts |= htole32(NGE_TXEXTSTS_UDPCSUM); + } + /* Lastly, turn the first descriptor ownership to hardware. */ + desc->nge_cmdsts |= htole32(NGE_CMDSTS_OWN); + + txd = &sc->nge_cdata.nge_txdesc[prod]; + map = txd_last->tx_dmamap; + txd_last->tx_dmamap = txd->tx_dmamap; + txd->tx_dmamap = map; + txd->tx_m = m; return (0); } @@ -1513,46 +2129,53 @@ static void nge_start_locked(struct ifnet *ifp) { struct nge_softc *sc; - struct mbuf *m_head = NULL; - uint32_t idx; + struct mbuf *m_head; + int enq; sc = ifp->if_softc; - if (!sc->nge_link) + NGE_LOCK_ASSERT(sc); + + if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != + IFF_DRV_RUNNING || (sc->nge_flags & NGE_FLAG_LINK) == 0) return; - idx = sc->nge_cdata.nge_tx_prod; - - if (ifp->if_drv_flags & IFF_DRV_OACTIVE) - return; - - while (sc->nge_ldata->nge_tx_list[idx].nge_mbuf == NULL) { - IF_DEQUEUE(&ifp->if_snd, m_head); + for (enq = 0; !IFQ_DRV_IS_EMPTY(&ifp->if_snd) && + sc->nge_cdata.nge_tx_cnt < NGE_TX_RING_CNT - 2; ) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m_head); if (m_head == NULL) break; - - if (nge_encap(sc, m_head, &idx)) { - IF_PREPEND(&ifp->if_snd, m_head); + /* + * Pack the data into the transmit ring. If we + * don't have room, set the OACTIVE flag and wait + * for the NIC to drain the ring. + */ + if (nge_encap(sc, &m_head)) { + if (m_head == NULL) + break; + IFQ_DRV_PREPEND(&ifp->if_snd, m_head); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } + enq++; /* * If there's a BPF listener, bounce a copy of this frame * to him. */ ETHER_BPF_MTAP(ifp, m_head); - } - /* Transmit */ - sc->nge_cdata.nge_tx_prod = idx; - NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_ENABLE); + if (enq > 0) { + bus_dmamap_sync(sc->nge_cdata.nge_tx_ring_tag, + sc->nge_cdata.nge_tx_ring_map, + BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + /* Transmit */ + NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_ENABLE); - /* - * Set a timeout in case the chip goes out to lunch. - */ - ifp->if_timer = 5; + /* Set a timeout in case the chip goes out to lunch. */ + sc->nge_watchdog_timer = 5; + } } static void @@ -1570,10 +2193,12 @@ nge_init_locked(struct nge_softc *sc) { struct ifnet *ifp = sc->nge_ifp; struct mii_data *mii; + uint8_t *eaddr; + uint32_t reg; NGE_LOCK_ASSERT(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) return; /* @@ -1581,22 +2206,23 @@ nge_init_locked(struct nge_softc *sc) */ nge_stop(sc); - if (sc->nge_tbi) { - mii = NULL; - } else { - mii = device_get_softc(sc->nge_miibus); - } + /* Reset the adapter. */ + nge_reset(sc); - /* Set MAC address */ + /* Disable Rx filter prior to programming Rx filter. */ + CSR_WRITE_4(sc, NGE_RXFILT_CTL, 0); + CSR_BARRIER_WRITE_4(sc, NGE_RXFILT_CTL); + + mii = device_get_softc(sc->nge_miibus); + + /* Set MAC address. */ + eaddr = IF_LLADDR(sc->nge_ifp); CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR0); - CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((uint16_t *)IF_LLADDR(sc->nge_ifp))[0]); + CSR_WRITE_4(sc, NGE_RXFILT_DATA, (eaddr[1] << 8) | eaddr[0]); CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR1); - CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((uint16_t *)IF_LLADDR(sc->nge_ifp))[1]); + CSR_WRITE_4(sc, NGE_RXFILT_DATA, (eaddr[3] << 8) | eaddr[2]); CSR_WRITE_4(sc, NGE_RXFILT_CTL, NGE_FILTADDR_PAR2); - CSR_WRITE_4(sc, NGE_RXFILT_DATA, - ((uint16_t *)IF_LLADDR(sc->nge_ifp))[2]); + CSR_WRITE_4(sc, NGE_RXFILT_DATA, (eaddr[5] << 8) | eaddr[4]); /* Init circular RX list. */ if (nge_list_rx_init(sc) == ENOBUFS) { @@ -1620,13 +2246,6 @@ nge_init_locked(struct nge_softc *sc) NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ARP); NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_PERFECT); - /* If we want promiscuous mode, set the allframes bit. */ - if (ifp->if_flags & IFF_PROMISC) { - NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS); - } else { - NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ALLPHYS); - } - /* * Set the capture broadcast bit to capture broadcast frames. */ @@ -1636,39 +2255,65 @@ nge_init_locked(struct nge_softc *sc) NGE_CLRBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_BROAD); } - /* - * Load the multicast filter. - */ - nge_setmulti(sc); - - /* Turn the receive filter on */ + /* Turn the receive filter on. */ NGE_SETBIT(sc, NGE_RXFILT_CTL, NGE_RXFILTCTL_ENABLE); + /* Set Rx filter. */ + nge_rxfilter(sc); + + /* Disable PRIQ ctl. */ + CSR_WRITE_4(sc, NGE_PRIOQCTL, 0); + + /* + * Set pause frames paramters. + * Rx stat FIFO hi-threshold : 2 or more packets + * Rx stat FIFO lo-threshold : less than 2 packets + * Rx data FIFO hi-threshold : 2K or more bytes + * Rx data FIFO lo-threshold : less than 2K bytes + * pause time : (512ns * 0xffff) -> 33.55ms + */ + CSR_WRITE_4(sc, NGE_PAUSECSR, + NGE_PAUSECSR_PAUSE_ON_MCAST | + NGE_PAUSECSR_PAUSE_ON_DA | + ((1 << 24) & NGE_PAUSECSR_RX_STATFIFO_THR_HI) | + ((1 << 22) & NGE_PAUSECSR_RX_STATFIFO_THR_LO) | + ((1 << 20) & NGE_PAUSECSR_RX_DATAFIFO_THR_HI) | + ((1 << 18) & NGE_PAUSECSR_RX_DATAFIFO_THR_LO) | + NGE_PAUSECSR_CNT); + /* * Load the address of the RX and TX lists. */ - CSR_WRITE_4(sc, NGE_RX_LISTPTR, - vtophys(&sc->nge_ldata->nge_rx_list[0])); - CSR_WRITE_4(sc, NGE_TX_LISTPTR, - vtophys(&sc->nge_ldata->nge_tx_list[0])); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_HI, + NGE_ADDR_HI(sc->nge_rdata.nge_rx_ring_paddr)); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_LO, + NGE_ADDR_LO(sc->nge_rdata.nge_rx_ring_paddr)); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_HI, + NGE_ADDR_HI(sc->nge_rdata.nge_tx_ring_paddr)); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_LO, + NGE_ADDR_LO(sc->nge_rdata.nge_tx_ring_paddr)); - /* Set RX configuration */ + /* Set RX configuration. */ CSR_WRITE_4(sc, NGE_RX_CFG, NGE_RXCFG); + + CSR_WRITE_4(sc, NGE_VLAN_IP_RXCTL, 0); /* * Enable hardware checksum validation for all IPv4 * packets, do not reject packets with bad checksums. */ - CSR_WRITE_4(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_IPCSUM_ENB); + if ((ifp->if_capenable & IFCAP_RXCSUM) != 0) + NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_IPCSUM_ENB); /* * Tell the chip to detect and strip VLAN tag info from * received frames. The tag will be provided in the extsts * field in the RX descriptors. */ - NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL, - NGE_VIPRXCTL_TAG_DETECT_ENB|NGE_VIPRXCTL_TAG_STRIP_ENB); + NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_TAG_DETECT_ENB); + if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) + NGE_SETBIT(sc, NGE_VLAN_IP_RXCTL, NGE_VIPRXCTL_TAG_STRIP_ENB); - /* Set TX configuration */ + /* Set TX configuration. */ CSR_WRITE_4(sc, NGE_TX_CFG, NGE_TXCFG); /* @@ -1682,40 +2327,14 @@ nge_init_locked(struct nge_softc *sc) */ NGE_SETBIT(sc, NGE_VLAN_IP_TXCTL, NGE_VIPTXCTL_TAG_PER_PKT); - /* Set full/half duplex mode. */ - if (sc->nge_tbi) { - if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) - == IFM_FDX) { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } else { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } - } else { - if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } else { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - } - } - - nge_tick(sc); - /* * Enable the delivery of PHY interrupts based on * link/speed/duplex status changes. Also enable the * extsts field in the DMA descriptors (needed for * TCP/IP checksum offload on transmit). */ - NGE_SETBIT(sc, NGE_CFG, NGE_CFG_PHYINTR_SPD| - NGE_CFG_PHYINTR_LNK|NGE_CFG_PHYINTR_DUP|NGE_CFG_EXTSTS_ENB); + NGE_SETBIT(sc, NGE_CFG, NGE_CFG_PHYINTR_SPD | + NGE_CFG_PHYINTR_LNK | NGE_CFG_PHYINTR_DUP | NGE_CFG_EXTSTS_ENB); /* * Configure interrupt holdoff (moderation). We can @@ -1723,7 +2342,15 @@ nge_init_locked(struct nge_softc *sc) * period. Units are in 100us, and the max setting * is 25500us (0xFF x 100us). Default is a 100us holdoff. */ - CSR_WRITE_4(sc, NGE_IHR, 0x01); + CSR_WRITE_4(sc, NGE_IHR, sc->nge_int_holdoff); + + /* + * Enable MAC statistics counters and clear. + */ + reg = CSR_READ_4(sc, NGE_MIBCTL); + reg &= ~NGE_MIBCTL_FREEZE_CNT; + reg |= NGE_MIBCTL_CLEAR_CNT; + CSR_WRITE_4(sc, NGE_MIBCTL, reg); /* * Enable interrupts. @@ -1734,17 +2361,17 @@ nge_init_locked(struct nge_softc *sc) * ... only enable interrupts if we are not polling, make sure * they are off otherwise. */ - if (ifp->if_capenable & IFCAP_POLLING) + if ((ifp->if_capenable & IFCAP_POLLING) != 0) CSR_WRITE_4(sc, NGE_IER, 0); else #endif CSR_WRITE_4(sc, NGE_IER, 1); - /* Enable receiver and transmitter. */ - NGE_CLRBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE); - NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); + sc->nge_flags &= ~NGE_FLAG_LINK; + mii_mediachg(mii); - nge_ifmedia_upd_locked(ifp); + sc->nge_watchdog_timer = 0; + callout_reset(&sc->nge_stat_ch, hz, nge_tick, sc); ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; @@ -1754,119 +2381,42 @@ nge_init_locked(struct nge_softc *sc) * Set media options. */ static int -nge_ifmedia_upd(struct ifnet *ifp) +nge_mediachange(struct ifnet *ifp) { struct nge_softc *sc; + struct mii_data *mii; + struct mii_softc *miisc; + int error; sc = ifp->if_softc; NGE_LOCK(sc); - nge_ifmedia_upd_locked(ifp); - NGE_UNLOCK(sc); - return (0); -} - -static void -nge_ifmedia_upd_locked(struct ifnet *ifp) -{ - struct nge_softc *sc; - struct mii_data *mii; - - sc = ifp->if_softc; - NGE_LOCK_ASSERT(sc); - - if (sc->nge_tbi) { - if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) - == IFM_AUTO) { - CSR_WRITE_4(sc, NGE_TBI_ANAR, - CSR_READ_4(sc, NGE_TBI_ANAR) - | NGE_TBIANAR_HDX | NGE_TBIANAR_FDX - | NGE_TBIANAR_PS1 | NGE_TBIANAR_PS2); - CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG - | NGE_TBIBMCR_RESTART_ANEG); - CSR_WRITE_4(sc, NGE_TBI_BMCR, NGE_TBIBMCR_ENABLE_ANEG); - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media - & IFM_GMASK) == IFM_FDX) { - NGE_SETBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_SETBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - - CSR_WRITE_4(sc, NGE_TBI_ANAR, 0); - CSR_WRITE_4(sc, NGE_TBI_BMCR, 0); - } else { - NGE_CLRBIT(sc, NGE_TX_CFG, - (NGE_TXCFG_IGN_HBEAT|NGE_TXCFG_IGN_CARR)); - NGE_CLRBIT(sc, NGE_RX_CFG, NGE_RXCFG_RX_FDX); - - CSR_WRITE_4(sc, NGE_TBI_ANAR, 0); - CSR_WRITE_4(sc, NGE_TBI_BMCR, 0); - } - - CSR_WRITE_4(sc, NGE_GPIO, CSR_READ_4(sc, NGE_GPIO) - & ~NGE_GPIO_GP3_OUT); - } else { - mii = device_get_softc(sc->nge_miibus); - sc->nge_link = 0; - if (mii->mii_instance) { - struct mii_softc *miisc; - - LIST_FOREACH(miisc, &mii->mii_phys, mii_list) - mii_phy_reset(miisc); - } - mii_mediachg(mii); + mii = device_get_softc(sc->nge_miibus); + if (mii->mii_instance) { + LIST_FOREACH(miisc, &mii->mii_phys, mii_list) + mii_phy_reset(miisc); } + error = mii_mediachg(mii); + NGE_UNLOCK(sc); + + return (error); } /* * Report current media status. */ static void -nge_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) +nge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) { struct nge_softc *sc; struct mii_data *mii; sc = ifp->if_softc; - NGE_LOCK(sc); - if (sc->nge_tbi) { - ifmr->ifm_status = IFM_AVALID; - ifmr->ifm_active = IFM_ETHER; - - if (CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { - ifmr->ifm_status |= IFM_ACTIVE; - } - if (CSR_READ_4(sc, NGE_TBI_BMCR) & NGE_TBIBMCR_LOOPBACK) - ifmr->ifm_active |= IFM_LOOP; - if (!CSR_READ_4(sc, NGE_TBI_BMSR) & NGE_TBIBMSR_ANEG_DONE) { - ifmr->ifm_active |= IFM_NONE; - ifmr->ifm_status = 0; - NGE_UNLOCK(sc); - return; - } - ifmr->ifm_active |= IFM_1000_SX; - if (IFM_SUBTYPE(sc->nge_ifmedia.ifm_cur->ifm_media) - == IFM_AUTO) { - ifmr->ifm_active |= IFM_AUTO; - if (CSR_READ_4(sc, NGE_TBI_ANLPAR) - & NGE_TBIANAR_FDX) { - ifmr->ifm_active |= IFM_FDX; - }else if (CSR_READ_4(sc, NGE_TBI_ANLPAR) - & NGE_TBIANAR_HDX) { - ifmr->ifm_active |= IFM_HDX; - } - } else if ((sc->nge_ifmedia.ifm_cur->ifm_media & IFM_GMASK) - == IFM_FDX) - ifmr->ifm_active |= IFM_FDX; - else - ifmr->ifm_active |= IFM_HDX; - - } else { - mii = device_get_softc(sc->nge_miibus); - mii_pollstat(mii); - ifmr->ifm_active = mii->mii_media_active; - ifmr->ifm_status = mii->mii_media_status; - } + mii = device_get_softc(sc->nge_miibus); + mii_pollstat(mii); NGE_UNLOCK(sc); + ifmr->ifm_active = mii->mii_media_active; + ifmr->ifm_status = mii->mii_media_status; } static int @@ -1875,11 +2425,11 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) struct nge_softc *sc = ifp->if_softc; struct ifreq *ifr = (struct ifreq *) data; struct mii_data *mii; - int error = 0; + int error = 0, mask; switch (command) { case SIOCSIFMTU: - if (ifr->ifr_mtu > NGE_JUMBO_MTU) + if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > NGE_JUMBO_MTU) error = EINVAL; else { NGE_LOCK(sc); @@ -1891,37 +2441,28 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) */ if (ifr->ifr_mtu >= 8152) { ifp->if_capenable &= ~IFCAP_TXCSUM; - ifp->if_hwassist = 0; + ifp->if_hwassist &= ~NGE_CSUM_FEATURES; } else { ifp->if_capenable |= IFCAP_TXCSUM; - ifp->if_hwassist = NGE_CSUM_FEATURES; + ifp->if_hwassist |= NGE_CSUM_FEATURES; } NGE_UNLOCK(sc); + VLAN_CAPABILITIES(ifp); } break; case SIOCSIFFLAGS: NGE_LOCK(sc); - if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING && - ifp->if_flags & IFF_PROMISC && - !(sc->nge_if_flags & IFF_PROMISC)) { - NGE_SETBIT(sc, NGE_RXFILT_CTL, - NGE_RXFILTCTL_ALLPHYS| - NGE_RXFILTCTL_ALLMULTI); - } else if (ifp->if_drv_flags & IFF_DRV_RUNNING && - !(ifp->if_flags & IFF_PROMISC) && - sc->nge_if_flags & IFF_PROMISC) { - NGE_CLRBIT(sc, NGE_RXFILT_CTL, - NGE_RXFILTCTL_ALLPHYS); - if (!(ifp->if_flags & IFF_ALLMULTI)) - NGE_CLRBIT(sc, NGE_RXFILT_CTL, - NGE_RXFILTCTL_ALLMULTI); + if ((ifp->if_flags & IFF_UP) != 0) { + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + if ((ifp->if_flags ^ sc->nge_if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) + nge_rxfilter(sc); } else { - ifp->if_drv_flags &= ~IFF_DRV_RUNNING; - nge_init_locked(sc); + if ((sc->nge_flags & NGE_FLAG_DETACH) == 0) + nge_init_locked(sc); } } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) nge_stop(sc); } sc->nge_if_flags = ifp->if_flags; @@ -1931,47 +2472,87 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCADDMULTI: case SIOCDELMULTI: NGE_LOCK(sc); - nge_setmulti(sc); + nge_rxfilter(sc); NGE_UNLOCK(sc); error = 0; break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: - if (sc->nge_tbi) { - error = ifmedia_ioctl(ifp, ifr, &sc->nge_ifmedia, - command); - } else { - mii = device_get_softc(sc->nge_miibus); - error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, - command); - } + mii = device_get_softc(sc->nge_miibus); + error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); break; case SIOCSIFCAP: + NGE_LOCK(sc); + mask = ifr->ifr_reqcap ^ ifp->if_capenable; #ifdef DEVICE_POLLING - if (ifr->ifr_reqcap & IFCAP_POLLING && - !(ifp->if_capenable & IFCAP_POLLING)) { - error = ether_poll_register(nge_poll, ifp); - if (error) - return (error); - NGE_LOCK(sc); - /* Disable interrupts */ - CSR_WRITE_4(sc, NGE_IER, 0); - ifp->if_capenable |= IFCAP_POLLING; - NGE_UNLOCK(sc); - return (error); - - } - if (!(ifr->ifr_reqcap & IFCAP_POLLING) && - ifp->if_capenable & IFCAP_POLLING) { - error = ether_poll_deregister(ifp); - /* Enable interrupts. */ - NGE_LOCK(sc); - CSR_WRITE_4(sc, NGE_IER, 1); - ifp->if_capenable &= ~IFCAP_POLLING; - NGE_UNLOCK(sc); - return (error); + if ((mask & IFCAP_POLLING) != 0 && + (IFCAP_POLLING & ifp->if_capabilities) != 0) { + ifp->if_capenable ^= IFCAP_POLLING; + if ((IFCAP_POLLING & ifp->if_capenable) != 0) { + error = ether_poll_register(nge_poll, ifp); + if (error != 0) { + NGE_UNLOCK(sc); + break; + } + /* Disable interrupts. */ + CSR_WRITE_4(sc, NGE_IER, 0); + } else { + error = ether_poll_deregister(ifp); + /* Enable interrupts. */ + CSR_WRITE_4(sc, NGE_IER, 1); + } } #endif /* DEVICE_POLLING */ + if ((mask & IFCAP_TXCSUM) != 0 && + (IFCAP_TXCSUM & ifp->if_capabilities) != 0) { + ifp->if_capenable ^= IFCAP_TXCSUM; + if ((IFCAP_TXCSUM & ifp->if_capenable) != 0) + ifp->if_hwassist |= NGE_CSUM_FEATURES; + else + ifp->if_hwassist &= ~NGE_CSUM_FEATURES; + } + if ((mask & IFCAP_RXCSUM) != 0 && + (IFCAP_RXCSUM & ifp->if_capabilities) != 0) + ifp->if_capenable ^= IFCAP_RXCSUM; + + if ((mask & IFCAP_WOL) != 0 && + (ifp->if_capabilities & IFCAP_WOL) != 0) { + if ((mask & IFCAP_WOL_UCAST) != 0) + ifp->if_capenable ^= IFCAP_WOL_UCAST; + if ((mask & IFCAP_WOL_MCAST) != 0) + ifp->if_capenable ^= IFCAP_WOL_MCAST; + if ((mask & IFCAP_WOL_MAGIC) != 0) + ifp->if_capenable ^= IFCAP_WOL_MAGIC; + } + + if ((mask & IFCAP_VLAN_HWCSUM) != 0 && + (ifp->if_capabilities & IFCAP_VLAN_HWCSUM) != 0) + ifp->if_capenable ^= IFCAP_VLAN_HWCSUM; + if ((mask & IFCAP_VLAN_HWTAGGING) != 0 && + (ifp->if_capabilities & IFCAP_VLAN_HWTAGGING) != 0) { + ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { + if ((ifp->if_capenable & + IFCAP_VLAN_HWTAGGING) != 0) + NGE_SETBIT(sc, + NGE_VLAN_IP_RXCTL, + NGE_VIPRXCTL_TAG_STRIP_ENB); + else + NGE_CLRBIT(sc, + NGE_VLAN_IP_RXCTL, + NGE_VIPRXCTL_TAG_STRIP_ENB); + } + } + /* + * Both VLAN hardware tagging and checksum offload is + * required to do checksum offload on VLAN interface. + */ + if ((ifp->if_capenable & IFCAP_TXCSUM) == 0) + ifp->if_capenable &= ~IFCAP_VLAN_HWCSUM; + if ((ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0) + ifp->if_capenable &= ~IFCAP_VLAN_HWCSUM; + NGE_UNLOCK(sc); + VLAN_CAPABILITIES(ifp); break; default: error = ether_ioctl(ifp, command, data); @@ -1982,25 +2563,50 @@ nge_ioctl(struct ifnet *ifp, u_long command, caddr_t data) } static void -nge_watchdog(struct ifnet *ifp) +nge_watchdog(struct nge_softc *sc) { - struct nge_softc *sc; + struct ifnet *ifp; - sc = ifp->if_softc; + NGE_LOCK_ASSERT(sc); + if (sc->nge_watchdog_timer == 0 || --sc->nge_watchdog_timer) + return; + + ifp = sc->nge_ifp; ifp->if_oerrors++; if_printf(ifp, "watchdog timeout\n"); - NGE_LOCK(sc); - nge_stop(sc); - nge_reset(sc); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; nge_init_locked(sc); - if (ifp->if_snd.ifq_head != NULL) + if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) nge_start_locked(ifp); +} - NGE_UNLOCK(sc); +static int +nge_stop_mac(struct nge_softc *sc) +{ + uint32_t reg; + int i; + + NGE_LOCK_ASSERT(sc); + + reg = CSR_READ_4(sc, NGE_CSR); + if ((reg & (NGE_CSR_TX_ENABLE | NGE_CSR_RX_ENABLE)) != 0) { + reg &= ~(NGE_CSR_TX_ENABLE | NGE_CSR_RX_ENABLE); + reg |= NGE_CSR_TX_DISABLE | NGE_CSR_RX_DISABLE; + CSR_WRITE_4(sc, NGE_CSR, reg); + for (i = 0; i < NGE_TIMEOUT; i++) { + DELAY(1); + if ((CSR_READ_4(sc, NGE_CSR) & + (NGE_CSR_RX_ENABLE | NGE_CSR_TX_ENABLE)) == 0) + break; + } + if (i == NGE_TIMEOUT) + return (ETIMEDOUT); + } + + return (0); } /* @@ -2010,58 +2616,120 @@ nge_watchdog(struct ifnet *ifp) static void nge_stop(struct nge_softc *sc) { + struct nge_txdesc *txd; + struct nge_rxdesc *rxd; int i; struct ifnet *ifp; - struct mii_data *mii; NGE_LOCK_ASSERT(sc); ifp = sc->nge_ifp; - ifp->if_timer = 0; - if (sc->nge_tbi) { - mii = NULL; - } else { - mii = device_get_softc(sc->nge_miibus); - } - - callout_stop(&sc->nge_stat_ch); - CSR_WRITE_4(sc, NGE_IER, 0); - CSR_WRITE_4(sc, NGE_IMR, 0); - NGE_SETBIT(sc, NGE_CSR, NGE_CSR_TX_DISABLE|NGE_CSR_RX_DISABLE); - DELAY(1000); - CSR_WRITE_4(sc, NGE_TX_LISTPTR, 0); - CSR_WRITE_4(sc, NGE_RX_LISTPTR, 0); - - if (!sc->nge_tbi) - mii_down(mii); - - sc->nge_link = 0; - - /* - * Free data in the RX lists. - */ - for (i = 0; i < NGE_RX_LIST_CNT; i++) { - if (sc->nge_ldata->nge_rx_list[i].nge_mbuf != NULL) { - m_freem(sc->nge_ldata->nge_rx_list[i].nge_mbuf); - sc->nge_ldata->nge_rx_list[i].nge_mbuf = NULL; - } - } - bzero((char *)&sc->nge_ldata->nge_rx_list, - sizeof(sc->nge_ldata->nge_rx_list)); - - /* - * Free the TX list buffers. - */ - for (i = 0; i < NGE_TX_LIST_CNT; i++) { - if (sc->nge_ldata->nge_tx_list[i].nge_mbuf != NULL) { - m_freem(sc->nge_ldata->nge_tx_list[i].nge_mbuf); - sc->nge_ldata->nge_tx_list[i].nge_mbuf = NULL; - } - } - - bzero((char *)&sc->nge_ldata->nge_tx_list, - sizeof(sc->nge_ldata->nge_tx_list)); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + sc->nge_flags &= ~NGE_FLAG_LINK; + callout_stop(&sc->nge_stat_ch); + sc->nge_watchdog_timer = 0; + + CSR_WRITE_4(sc, NGE_IER, 0); + CSR_WRITE_4(sc, NGE_IMR, 0); + if (nge_stop_mac(sc) == ETIMEDOUT) + device_printf(sc->nge_dev, + "%s: unable to stop Tx/Rx MAC\n", __func__); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_HI, 0); + CSR_WRITE_4(sc, NGE_TX_LISTPTR_LO, 0); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_HI, 0); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_LO, 0); + nge_stats_update(sc); + if (sc->nge_head != NULL) { + m_freem(sc->nge_head); + sc->nge_head = sc->nge_tail = NULL; + } + + /* + * Free RX and TX mbufs still in the queues. + */ + for (i = 0; i < NGE_RX_RING_CNT; i++) { + rxd = &sc->nge_cdata.nge_rxdesc[i]; + if (rxd->rx_m != NULL) { + bus_dmamap_sync(sc->nge_cdata.nge_rx_tag, + rxd->rx_dmamap, BUS_DMASYNC_POSTREAD); + bus_dmamap_unload(sc->nge_cdata.nge_rx_tag, + rxd->rx_dmamap); + m_freem(rxd->rx_m); + rxd->rx_m = NULL; + } + } + for (i = 0; i < NGE_TX_RING_CNT; i++) { + txd = &sc->nge_cdata.nge_txdesc[i]; + if (txd->tx_m != NULL) { + bus_dmamap_sync(sc->nge_cdata.nge_tx_tag, + txd->tx_dmamap, BUS_DMASYNC_POSTWRITE); + bus_dmamap_unload(sc->nge_cdata.nge_tx_tag, + txd->tx_dmamap); + m_freem(txd->tx_m); + txd->tx_m = NULL; + } + } +} + +/* + * Before setting WOL bits, caller should have stopped Receiver. + */ +static void +nge_wol(struct nge_softc *sc) +{ + struct ifnet *ifp; + uint32_t reg; + uint16_t pmstat; + int pmc; + + NGE_LOCK_ASSERT(sc); + + if (pci_find_extcap(sc->nge_dev, PCIY_PMG, &pmc) != 0) + return; + + ifp = sc->nge_ifp; + if ((ifp->if_capenable & IFCAP_WOL) == 0) { + /* Disable WOL & disconnect CLKRUN to save power. */ + CSR_WRITE_4(sc, NGE_WOLCSR, 0); + CSR_WRITE_4(sc, NGE_CLKRUN, 0); + } else { + if (nge_stop_mac(sc) == ETIMEDOUT) + device_printf(sc->nge_dev, + "%s: unable to stop Tx/Rx MAC\n", __func__); + /* + * Make sure wake frames will be buffered in the Rx FIFO. + * (i.e. Silent Rx mode.) + */ + CSR_WRITE_4(sc, NGE_RX_LISTPTR_HI, 0); + CSR_BARRIER_WRITE_4(sc, NGE_RX_LISTPTR_HI); + CSR_WRITE_4(sc, NGE_RX_LISTPTR_LO, 0); + CSR_BARRIER_WRITE_4(sc, NGE_RX_LISTPTR_LO); + /* Enable Rx again. */ + NGE_SETBIT(sc, NGE_CSR, NGE_CSR_RX_ENABLE); + CSR_BARRIER_WRITE_4(sc, NGE_CSR); + + /* Configure WOL events. */ + reg = 0; + if ((ifp->if_capenable & IFCAP_WOL_UCAST) != 0) + reg |= NGE_WOLCSR_WAKE_ON_UNICAST; + if ((ifp->if_capenable & IFCAP_WOL_MCAST) != 0) + reg |= NGE_WOLCSR_WAKE_ON_MULTICAST; + if ((ifp->if_capenable & IFCAP_WOL_MAGIC) != 0) + reg |= NGE_WOLCSR_WAKE_ON_MAGICPKT; + CSR_WRITE_4(sc, NGE_WOLCSR, reg); + + /* Activate CLKRUN. */ + reg = CSR_READ_4(sc, NGE_CLKRUN); + reg |= NGE_CLKRUN_PMEENB | NGE_CLNRUN_CLKRUN_ENB; + CSR_WRITE_4(sc, NGE_CLKRUN, reg); + } + + /* Request PME. */ + pmstat = pci_read_config(sc->nge_dev, pmc + PCIR_POWER_STATUS, 2); + pmstat &= ~(PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE); + if ((ifp->if_capenable & IFCAP_WOL) != 0) + pmstat |= PCIM_PSTAT_PME | PCIM_PSTAT_PMEENABLE; + pci_write_config(sc->nge_dev, pmc + PCIR_POWER_STATUS, pmstat, 2); } /* @@ -2070,15 +2738,158 @@ nge_stop(struct nge_softc *sc) */ static int nge_shutdown(device_t dev) +{ + + return (nge_suspend(dev)); +} + +static int +nge_suspend(device_t dev) { struct nge_softc *sc; sc = device_get_softc(dev); NGE_LOCK(sc); - nge_reset(sc); nge_stop(sc); + nge_wol(sc); + sc->nge_flags |= NGE_FLAG_SUSPENDED; NGE_UNLOCK(sc); return (0); } + +static int +nge_resume(device_t dev) +{ + struct nge_softc *sc; + struct ifnet *ifp; + uint16_t pmstat; + int pmc; + + sc = device_get_softc(dev); + + NGE_LOCK(sc); + ifp = sc->nge_ifp; + if (pci_find_extcap(sc->nge_dev, PCIY_PMG, &pmc) == 0) { + /* Disable PME and clear PME status. */ + pmstat = pci_read_config(sc->nge_dev, + pmc + PCIR_POWER_STATUS, 2); + if ((pmstat & PCIM_PSTAT_PMEENABLE) != 0) { + pmstat &= ~PCIM_PSTAT_PMEENABLE; + pci_write_config(sc->nge_dev, + pmc + PCIR_POWER_STATUS, pmstat, 2); + } + } + if (ifp->if_flags & IFF_UP) { + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; + nge_init_locked(sc); + } + + sc->nge_flags &= ~NGE_FLAG_SUSPENDED; + NGE_UNLOCK(sc); + + return (0); +} + +#define NGE_SYSCTL_STAT_ADD32(c, h, n, p, d) \ + SYSCTL_ADD_UINT(c, h, OID_AUTO, n, CTLFLAG_RD, p, 0, d) + +static void +nge_sysctl_node(struct nge_softc *sc) +{ + struct sysctl_ctx_list *ctx; + struct sysctl_oid_list *child, *parent; + struct sysctl_oid *tree; + struct nge_stats *stats; + int error; + + ctx = device_get_sysctl_ctx(sc->nge_dev); + child = SYSCTL_CHILDREN(device_get_sysctl_tree(sc->nge_dev)); + SYSCTL_ADD_PROC(ctx, child, OID_AUTO, "int_holdoff", + CTLTYPE_INT | CTLFLAG_RW, &sc->nge_int_holdoff, 0, + sysctl_hw_nge_int_holdoff, "I", "NGE interrupt moderation"); + /* Pull in device tunables. */ + sc->nge_int_holdoff = NGE_INT_HOLDOFF_DEFAULT; + error = resource_int_value(device_get_name(sc->nge_dev), + device_get_unit(sc->nge_dev), "int_holdoff", &sc->nge_int_holdoff); + if (error == 0) { + if (sc->nge_int_holdoff < NGE_INT_HOLDOFF_MIN || + sc->nge_int_holdoff > NGE_INT_HOLDOFF_MAX ) { + device_printf(sc->nge_dev, + "int_holdoff value out of range; " + "using default: %d(%d us)\n", + NGE_INT_HOLDOFF_DEFAULT, + NGE_INT_HOLDOFF_DEFAULT * 100); + sc->nge_int_holdoff = NGE_INT_HOLDOFF_DEFAULT; + } + } + + stats = &sc->nge_stats; + tree = SYSCTL_ADD_NODE(ctx, child, OID_AUTO, "stats", CTLFLAG_RD, + NULL, "NGE statistics"); + parent = SYSCTL_CHILDREN(tree); + + /* Rx statistics. */ + tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "rx", CTLFLAG_RD, + NULL, "Rx MAC statistics"); + child = SYSCTL_CHILDREN(tree); + NGE_SYSCTL_STAT_ADD32(ctx, child, "pkts_errs", + &stats->rx_pkts_errs, + "Packet errors including both wire errors and FIFO overruns"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "crc_errs", + &stats->rx_crc_errs, "CRC errors"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "fifo_oflows", + &stats->rx_fifo_oflows, "FIFO overflows"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "align_errs", + &stats->rx_align_errs, "Frame alignment errors"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "sym_errs", + &stats->rx_sym_errs, "One or more symbol errors"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "pkts_jumbos", + &stats->rx_pkts_jumbos, + "Packets received with length greater than 1518 bytes"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "len_errs", + &stats->rx_len_errs, "In Range Length errors"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "unctl_frames", + &stats->rx_unctl_frames, "Control frames with unsupported opcode"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "pause", + &stats->rx_pause, "Pause frames"); + + /* Tx statistics. */ + tree = SYSCTL_ADD_NODE(ctx, parent, OID_AUTO, "tx", CTLFLAG_RD, + NULL, "Tx MAC statistics"); + child = SYSCTL_CHILDREN(tree); + NGE_SYSCTL_STAT_ADD32(ctx, child, "pause", + &stats->tx_pause, "Pause frames"); + NGE_SYSCTL_STAT_ADD32(ctx, child, "seq_errs", + &stats->tx_seq_errs, + "Loss of collision heartbeat during transmission"); +} + +#undef NGE_SYSCTL_STAT_ADD32 + +static int +sysctl_int_range(SYSCTL_HANDLER_ARGS, int low, int high) +{ + int error, value; + + if (arg1 == NULL) + return (EINVAL); + value = *(int *)arg1; + error = sysctl_handle_int(oidp, &value, 0, req); + if (error != 0 || req->newptr == NULL) + return (error); + if (value < low || value > high) + return (EINVAL); + *(int *)arg1 = value; + + return (0); +} + +static int +sysctl_hw_nge_int_holdoff(SYSCTL_HANDLER_ARGS) +{ + + return (sysctl_int_range(oidp, arg1, arg2, req, NGE_INT_HOLDOFF_MIN, + NGE_INT_HOLDOFF_MAX)); +} diff --git a/sys/dev/nge/if_ngereg.h b/sys/dev/nge/if_ngereg.h index e4d5e527cf15..4ad1bf9be2ab 100644 --- a/sys/dev/nge/if_ngereg.h +++ b/sys/dev/nge/if_ngereg.h @@ -302,9 +302,23 @@ #define NGE_RXDMA_256BYTES 0x00600000 #define NGE_RXDMA_512BYTES 0x00700000 +/* + * DP83820/DP83821 with H/W VLAN stripping does not accept short VLAN + * tagged packets such as ARP, short icmp echo request, etc. It seems + * that MAC checks frame length for VLAN tagged packets after stripping + * the VLAN tag. For short VLAN tagged packets it would would be 56 + * (64 - CRC - VLAN info) bytes in length after stripping VLAN tag. + * If the VLAN tag stripped frames are less than 60 bytes in length + * the hardware think it received runt packets! + * Therefore we should accept runt frames to get VLAN tagged ARP + * packets. In addition, it is known that some revisions of + * DP83820/DP83821 have another bug that prevent fragmented IP packets + * from accepting. So we also should accept errored frames. + */ #define NGE_RXCFG \ - (NGE_RXCFG_DRAIN(64)|NGE_RXDMA_256BYTES|\ - NGE_RXCFG_RX_GIANTS|NGE_RXCFG_RX_NOCRC) + (NGE_RXCFG_DRAIN(64) | NGE_RXDMA_256BYTES| \ + NGE_RXCFG_RX_RANGEERR | NGE_RXCFG_RX_BADPKTS | NGE_RXCFG_RX_RUNT | \ + NGE_RXCFG_RX_GIANTS | NGE_RXCFG_RX_NOCRC) /* Priority queue control */ #define NGE_PRIOQCTL_TXPRIO_ENB 0x00000001 @@ -320,13 +334,14 @@ #define NGE_WOLCSR_WAKE_ON_PHYINTR 0x00000001 #define NGE_WOLCSR_WAKE_ON_UNICAST 0x00000002 #define NGE_WOLCSR_WAKE_ON_MULTICAST 0x00000004 -#define NGR_WOLCSR_WAKE_ON_BROADCAST 0x00000008 +#define NGE_WOLCSR_WAKE_ON_BROADCAST 0x00000008 #define NGE_WOLCSR_WAKE_ON_ARP 0x00000010 #define NGE_WOLCSR_WAKE_ON_PAT0_MATCH 0x00000020 #define NGE_WOLCSR_WAKE_ON_PAT1_MATCH 0x00000040 #define NGE_WOLCSR_WAKE_ON_PAT2_MATCH 0x00000080 #define NGE_WOLCSR_WAKE_ON_PAT3_MATCH 0x00000100 -#define NGE_WOLCSR_SECUREON_ENB 0x00000200 +#define NGE_WOLCSR_WAKE_ON_MAGICPKT 0x00000200 +#define NGE_WOLCSR_SECUREON_ENB 0x00000400 #define NGE_WOLCSR_SECUREON_HACK 0x00200000 #define NGE_WOLCSR_PHYINTR 0x00400000 #define NGE_WOLCSR_UNICAST 0x00800000 @@ -464,58 +479,25 @@ * also an optional extended status field for VLAN and TCP/IP checksum * functions. We use the checksum feature so we enable the use of this * field. Descriptors must be 64-bit aligned. - * After this, we include some additional structure members for - * use by the driver. Note that for this structure will be a different - * size on the alpha, but that's okay as long as it's a multiple of 4 - * bytes in size. - * */ struct nge_desc_64 { /* Hardware descriptor section */ - volatile uint32_t nge_next_lo; - volatile uint32_t nge_next_hi; - volatile uint32_t nge_ptr_lo; - volatile uint32_t nge_ptr_hi; - volatile uint32_t nge_cmdsts; -#define nge_rxstat nge_cmdsts -#define nge_txstat nge_cmdsts -#define nge_ctl nge_cmdsts - volatile uint32_t nge_extsts; - /* Driver software section */ - union { - struct mbuf *nge_mbuf; - uint64_t nge_dummy; - } nge_mb_u; - union { - struct nge_desc_32 *nge_nextdesc; - uint64_t nge_dummy; - } nge_nd_u; + uint32_t nge_next_lo; + uint32_t nge_next_hi; + uint32_t nge_ptr_lo; + uint32_t nge_ptr_hi; + uint32_t nge_cmdsts; + uint32_t nge_extsts; }; struct nge_desc_32 { /* Hardware descriptor section */ - volatile uint32_t nge_next; - volatile uint32_t nge_ptr; - volatile uint32_t nge_cmdsts; -#define nge_rxstat nge_cmdsts -#define nge_txstat nge_cmdsts -#define nge_ctl nge_cmdsts - volatile uint32_t nge_extsts; - /* Driver software section */ - union { - struct mbuf *nge_mbuf; - uint64_t nge_dummy; - } nge_mb_u; - union { - struct nge_desc_32 *nge_nextdesc; - uint64_t nge_dummy; - } nge_nd_u; + uint32_t nge_next; + uint32_t nge_ptr; + uint32_t nge_cmdsts; + uint32_t nge_extsts; }; -#define nge_mbuf nge_mb_u.nge_mbuf -#define nge_nextdesc nge_nd_u.nge_nextdesc - - #define nge_desc nge_desc_32 #define NGE_CMDSTS_BUFLEN 0x0000FFFF @@ -525,11 +507,7 @@ struct nge_desc_32 { #define NGE_CMDSTS_MORE 0x40000000 #define NGE_CMDSTS_OWN 0x80000000 -#define NGE_LASTDESC(x) (!((x)->nge_ctl & NGE_CMDSTS_MORE)) -#define NGE_MORE(x) ((x)->nge_ctl & NGE_CMDSTS_MORE) -#define NGE_OWNDESC(x) ((x)->nge_ctl & NGE_CMDSTS_OWN) -#define NGE_INC(x, y) (x) = (x + 1) % y -#define NGE_RXBYTES(x) ((x)->nge_ctl & NGE_CMDSTS_BUFLEN) +#define NGE_INC(x, y) (x) = ((x) + 1) % y #define NGE_RXSTAT_RANGELENERR 0x00010000 #define NGE_RXSTAT_LOOPBK 0x00020000 @@ -571,34 +549,54 @@ struct nge_desc_32 { #define NGE_RXEXTSTS_UDPPKT 0x00200000 #define NGE_RXEXTSTS_UDPCSUMERR 0x00400000 -#define NGE_RX_LIST_CNT 128 -#define NGE_TX_LIST_CNT 128 +#define NGE_TX_RING_CNT 256 +#define NGE_RX_RING_CNT 256 +#define NGE_TX_RING_SIZE sizeof(struct nge_desc) * NGE_TX_RING_CNT +#define NGE_RX_RING_SIZE sizeof(struct nge_desc) * NGE_RX_RING_CNT +#define NGE_RING_ALIGN sizeof(uint64_t) +#define NGE_RX_ALIGN sizeof(uint64_t) +#define NGE_MAXTXSEGS 16 -struct nge_list_data { - struct nge_desc nge_rx_list[NGE_RX_LIST_CNT]; - struct nge_desc nge_tx_list[NGE_TX_LIST_CNT]; -#ifdef notyet - int vge_tx_prodidx; - int vge_rx_prodidx; - int vge_tx_considx; - int vge_tx_free; +#define NGE_ADDR_LO(x) ((uint64_t)(x) & 0xffffffff) +#define NGE_ADDR_HI(x) ((uint64_t)(x) >> 32) +#define NGE_TX_RING_ADDR(sc, i) \ + ((sc)->nge_rdata.nge_tx_ring_paddr + sizeof(struct nge_desc) * (i)) +#define NGE_RX_RING_ADDR(sc, i) \ + ((sc)->nge_rdata.nge_rx_ring_paddr + sizeof(struct nge_desc) * (i)) - struct nge_desc *nge_tx_list; - struct mbuf *nge_tx_mbuf[NGE_TX_DESC_CNT] - bus_dmamap_t nge_tx_dmamap[NGE_TX_DESC_CNT]; - bus_dma_tag_t nge_tx_list_tag; - bus_dmamap_t nge_tx_list_map[NGE_TX_DESC_CNT]; - bus_addr_t nge_tx_list_add[NGE_TX_DESC_CNT]; - - struct nge_desc *nge_rx_list; - struct mbuf *nge_rx_mbuf[NGE_RX_DESC_CNT] - bus_dmamap_t nge_rx_dmamap[NGE_RX_DESC_CNT]; - bus_dma_tag_t nge_rx_list_tag; - bus_dmamap_t nge_rx_list_map[NGE_RX_DESC_CNT]; - bus_addr_t nge_rx_list_addr[NGE_RX_DESC_CNT]; -#endif +struct nge_txdesc { + struct mbuf *tx_m; + bus_dmamap_t tx_dmamap; }; +struct nge_rxdesc { + struct mbuf *rx_m; + bus_dmamap_t rx_dmamap; +}; + +struct nge_chain_data { + bus_dma_tag_t nge_parent_tag; + bus_dma_tag_t nge_tx_tag; + struct nge_txdesc nge_txdesc[NGE_TX_RING_CNT]; + bus_dma_tag_t nge_rx_tag; + struct nge_rxdesc nge_rxdesc[NGE_RX_RING_CNT]; + bus_dma_tag_t nge_tx_ring_tag; + bus_dma_tag_t nge_rx_ring_tag; + bus_dmamap_t nge_tx_ring_map; + bus_dmamap_t nge_rx_ring_map; + bus_dmamap_t nge_rx_sparemap; + int nge_tx_prod; + int nge_tx_cons; + int nge_tx_cnt; + int nge_rx_cons; +}; + +struct nge_ring_data { + struct nge_desc *nge_tx_ring; + bus_addr_t nge_tx_ring_paddr; + struct nge_desc *nge_rx_ring; + bus_addr_t nge_rx_ring_paddr; +}; /* * NatSemi PCI vendor ID. @@ -633,44 +631,50 @@ struct nge_mii_frame { #define NGE_MII_WRITEOP 0x01 #define NGE_MII_TURNAROUND 0x02 -#define NGE_JUMBO_FRAMELEN 9018 -#define NGE_JUMBO_MTU (NGE_JUMBO_FRAMELEN-ETHER_HDR_LEN-ETHER_CRC_LEN) +#define NGE_JUMBO_FRAMELEN 9022 +#define NGE_JUMBO_MTU \ + (NGE_JUMBO_FRAMELEN - sizeof(struct ether_vlan_header) - ETHER_CRC_LEN) -#if !defined(__i386__) -#define NGE_FIXUP_RX -#endif - -struct nge_ring_data { - int nge_rx_prod; - int nge_tx_prod; - int nge_tx_cons; - int nge_tx_cnt; +/* Statistics counters. */ +struct nge_stats { + uint32_t rx_pkts_errs; + uint32_t rx_crc_errs; + uint32_t rx_fifo_oflows; + uint32_t rx_align_errs; + uint32_t rx_sym_errs; + uint32_t rx_pkts_jumbos; + uint32_t rx_len_errs; + uint32_t rx_unctl_frames; + uint32_t rx_pause; + uint32_t tx_pause; + uint32_t tx_seq_errs; }; struct nge_softc { struct ifnet *nge_ifp; device_t nge_dev; - bus_space_handle_t nge_bhandle; - bus_space_tag_t nge_btag; struct resource *nge_res; + int nge_res_type; + int nge_res_id; struct resource *nge_irq; void *nge_intrhand; device_t nge_miibus; int nge_if_flags; - uint8_t nge_type; - uint8_t nge_link; - uint8_t nge_width; -#define NGE_WIDTH_32BITS 0 -#define NGE_WIDTH_64BITS 1 - struct nge_list_data *nge_ldata; - struct nge_ring_data nge_cdata; + uint32_t nge_flags; +#define NGE_FLAG_TBI 0x0002 +#define NGE_FLAG_SUSPENDED 0x2000 +#define NGE_FLAG_DETACH 0x4000 +#define NGE_FLAG_LINK 0x8000 + struct nge_chain_data nge_cdata; + struct nge_ring_data nge_rdata; struct callout nge_stat_ch; + struct nge_stats nge_stats; struct mtx nge_mtx; - uint8_t nge_tbi; - struct ifmedia nge_ifmedia; #ifdef DEVICE_POLLING int rxcycles; #endif + int nge_watchdog_timer; + int nge_int_holdoff; struct mbuf *nge_head; struct mbuf *nge_tail; }; @@ -686,14 +690,18 @@ struct nge_softc { * register space access macros */ #define CSR_WRITE_4(sc, reg, val) \ - bus_space_write_4(sc->nge_btag, sc->nge_bhandle, reg, val) + bus_write_4((sc)->nge_res, reg, val) +#define CSR_BARRIER_WRITE_4(sc, reg) \ + bus_barrier((sc)->nge_res, reg, 4, BUS_SPACE_BARRIER_WRITE) #define CSR_READ_4(sc, reg) \ - bus_space_read_4(sc->nge_btag, sc->nge_bhandle, reg) + bus_read_4((sc)->nge_res, reg) #define NGE_TIMEOUT 1000 -#define NGE_RXLEN 1536 -#define NGE_MIN_FRAMELEN 60 + +#define NGE_INT_HOLDOFF_DEFAULT 1 +#define NGE_INT_HOLDOFF_MIN 0 +#define NGE_INT_HOLDOFF_MAX 255 /* * PCI low memory base and low I/O base register, and From 460da499736bd86fb72a5d004dfe12f98c774fed Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:19:01 +0000 Subject: [PATCH 359/544] Add nge(4), nge(4) should work on all architectures. --- sys/sparc64/conf/GENERIC | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/sparc64/conf/GENERIC b/sys/sparc64/conf/GENERIC index e1c80547ef19..a3dad1cb31ef 100644 --- a/sys/sparc64/conf/GENERIC +++ b/sys/sparc64/conf/GENERIC @@ -177,6 +177,7 @@ device dc # DEC/Intel 21143 and various workalikes device fxp # Intel EtherExpress PRO/100B (82557, 82558) device gem # Sun GEM/Sun ERI/Apple GMAC device hme # Sun HME (Happy Meal Ethernet) +device nge # NatSemi DP83820 gigabit Ethernet #device pcn # AMD Am79C97x PCI 10/100 (precedence over 'le') device re # RealTek 8139C+/8169/8169S/8110S device rl # RealTek 8129/8139 From 88f3df72efc72022245cdb46f0f27a7381232646 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 02:26:51 +0000 Subject: [PATCH 360/544] Print out device attachment. --- sys/dev/usb/wlan/if_uath.c | 1 + sys/dev/usb/wlan/if_upgt.c | 1 + 2 files changed, 2 insertions(+) diff --git a/sys/dev/usb/wlan/if_uath.c b/sys/dev/usb/wlan/if_uath.c index 0403193cfcee..34acd52bc0c2 100644 --- a/sys/dev/usb/wlan/if_uath.c +++ b/sys/dev/usb/wlan/if_uath.c @@ -355,6 +355,7 @@ uath_attach(device_t dev) #ifdef UATH_DEBUG sc->sc_debug = uath_debug; #endif + device_set_usb2_desc(dev); /* * Only post-firmware devices here. diff --git a/sys/dev/usb/wlan/if_upgt.c b/sys/dev/usb/wlan/if_upgt.c index b82d90d252bc..0a7d0a48c0ab 100644 --- a/sys/dev/usb/wlan/if_upgt.c +++ b/sys/dev/usb/wlan/if_upgt.c @@ -257,6 +257,7 @@ upgt_attach(device_t dev) #ifdef UPGT_DEBUG sc->sc_debug = upgt_debug; #endif + device_set_usb2_desc(dev); mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF); From ecf900c60c7e8128febbaed2a174cf6a49ba2d5e Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:39:47 +0000 Subject: [PATCH 361/544] Document sysctl variable dev.nge.%d.int_holdoff. --- share/man/man4/nge.4 | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/share/man/man4/nge.4 b/share/man/man4/nge.4 index 4db964ffb0a4..6c0400db9246 100644 --- a/share/man/man4/nge.4 +++ b/share/man/man4/nge.4 @@ -31,7 +31,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 23, 2009 +.Dd May 21, 2009 .Dt NGE 4 .Os .Sh NAME @@ -182,6 +182,21 @@ Surecom Technology EP-320G-TX .It Trendware TEG-PCITX (32-bit PCI) and TEG-PCITX2 (64-bit PCI) .El +.Sh SYSCTL VARIABLES +The following variables are available as both +.Xr sysctl 8 +variables and +.Xr loader 8 +tunables: +.Bl -tag -width "xxxxxx" +.It Va dev.nge.%d.int_holdoff +Maximum amount of time to delay interrupt processing in units of +100us. +The accepted range is 0 to 255, the default is 1(100us). +Value 0 completely disables the interrupt moderation. +The interface has to be brought down and up again before a change +takes effect. +.El .Sh DIAGNOSTICS .Bl -diag .It "nge%d: couldn't map memory" From e222fbb65c6e9957e8b0e50655fcd50b70f057ad Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:42:15 +0000 Subject: [PATCH 362/544] DP83821 also supports jumbo frames. --- share/man/man4/nge.4 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man4/nge.4 b/share/man/man4/nge.4 index 6c0400db9246..3e43c4f59a69 100644 --- a/share/man/man4/nge.4 +++ b/share/man/man4/nge.4 @@ -69,8 +69,8 @@ Most cards also use the DP83861 10/100/1000 copper gigabit transceiver chip, which supports autonegotiation of 10, 100 and 1000Mbps modes in full or half duplex. .Pp -The DP83820 also supports jumbo frames, which can be configured -via the interface MTU setting. +The DP83820 and DP83821 also support jumbo frames, which can be +configured via the interface MTU setting. Selecting an MTU larger than 1500 bytes with the .Xr ifconfig 8 utility configures the adapter to receive and transmit jumbo frames. From fe060748706a02dffb71d70136ed74dae45b1247 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:44:32 +0000 Subject: [PATCH 363/544] nge(4) supports altq(4). Xr altq --- share/man/man4/nge.4 | 1 + 1 file changed, 1 insertion(+) diff --git a/share/man/man4/nge.4 b/share/man/man4/nge.4 index 3e43c4f59a69..fac9bd0c46e3 100644 --- a/share/man/man4/nge.4 +++ b/share/man/man4/nge.4 @@ -220,6 +220,7 @@ The device has stopped responding to the network, or there is a problem with the network connection (cable). .El .Sh SEE ALSO +.Xr altq 4 , .Xr arp 4 , .Xr miibus 4 , .Xr netintro 4 , From d4cb58f64ced44d739ed588f152cd4a9b83c26cb Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Thu, 21 May 2009 02:47:46 +0000 Subject: [PATCH 364/544] Add nge(4) to the list of drivers supporting ALTQ. --- share/man/man4/altq.4 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/share/man/man4/altq.4 b/share/man/man4/altq.4 index ff22c2e26961..5f5cae22294a 100644 --- a/share/man/man4/altq.4 +++ b/share/man/man4/altq.4 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd March 12, 2009 +.Dd May 21, 2009 .Dt ALTQ 4 .Os .Sh NAME @@ -140,6 +140,7 @@ They have been applied to the following hardware drivers: .Xr mxge 4 , .Xr my 4 , .Xr nfe 4 , +.Xr nge 4 , .Xr npe 4 , .Xr nve 4 , .Xr ral 4 , From c3e8a587239e9b925acbef2f0a89ef3b5f4b881b Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 21 May 2009 04:00:31 +0000 Subject: [PATCH 365/544] force type match --- sys/dev/wi/if_wi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 6e2c586c309a..745d68e4d827 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -1382,7 +1382,7 @@ wi_rx_intr(struct wi_softc *sc) rstamp = (le16toh(frmhdr.wi_rx_tstamp0) << 16) | le16toh(frmhdr.wi_rx_tstamp1); - tap->wr_tsf = htole64(rstamp); + tap->wr_tsf = htole64((uint64_t)rstamp); /* XXX replace divide by table */ tap->wr_rate = frmhdr.wi_rx_rate / 5; tap->wr_flags = 0; From 62e1ba833c3dcf9e7dc0b179eddc6d5e7e06ab67 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Thu, 21 May 2009 09:45:47 +0000 Subject: [PATCH 366/544] Consolidate and clean up the first section of ip_output.c in light of the last year or two's work on routing: - Combine iproute initialization and flowtable lookup blocks, eliminating unnecessary tests for known-zero'd iproute fields. - Add a comment indicating (a) why the route entry returned by the flowtable is considered stable and (b) that the flowtable lookup must occur after the setup of the mbuf flow ID. - Assert the inpcb lock before any use of inpcb fields. Reviewed by: kmacy --- sys/netinet/ip_output.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 35905e80d42b..6e4f8792aad0 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -150,20 +150,25 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags, #endif M_ASSERTPKTHDR(m); - if (ro == NULL) { - ro = &iproute; - bzero(ro, sizeof (*ro)); - } - if (inp != NULL) { - M_SETFIB(m, inp->inp_inc.inc_fibnum); INP_LOCK_ASSERT(inp); + M_SETFIB(m, inp->inp_inc.inc_fibnum); if (inp->inp_flags & (INP_HW_FLOWID|INP_SW_FLOWID)) { m->m_pkthdr.flowid = inp->inp_flowid; m->m_flags |= M_FLOWID; } } - if ((ro == &iproute) && (ro->ro_rt == NULL) && (ro->ro_lle == NULL)) { + + if (ro == NULL) { + ro = &iproute; + bzero(ro, sizeof (*ro)); + + /* + * The flow table returns route entries valid for up to 30 + * seconds; we rely on the remainder of ip_output() taking no + * longer than that long for the stability of ro_rt. The + * flow ID assignment must have happened before this point. + */ if (flowtable_lookup(ip_ft, m, ro) == 0) nortfree = 1; } From 7406bf9f516aebc4e5b7afef7a622fd686831475 Mon Sep 17 00:00:00 2001 From: Christian Brueffer Date: Thu, 21 May 2009 10:04:51 +0000 Subject: [PATCH 367/544] nge(4) should work on all archs now. --- release/doc/share/misc/dev.archlist.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/release/doc/share/misc/dev.archlist.txt b/release/doc/share/misc/dev.archlist.txt index 8aeb8204de70..af6d1c4cae23 100644 --- a/release/doc/share/misc/dev.archlist.txt +++ b/release/doc/share/misc/dev.archlist.txt @@ -93,7 +93,6 @@ ncv i386,pc98 nfe i386,amd64 ng_bt3c i386,pc98,amd64 ng_ubt i386,pc98,amd64 -nge i386,pc98,amd64 nsp i386,pc98 nve i386,amd64 nxge i386,amd64 From 2a476ed9ed163f9813639deb03cfdce46c09dd97 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 21 May 2009 11:37:56 +0000 Subject: [PATCH 368/544] Skip interleaved RAM target on MPC85xx during renitialization of the local access windows. This eliminates hangs on systems which are configured to use interleaved mode: prior to this fix we were simply cutting ourselves from access to the main memory in this case. Obtained from: Freescale, Semihalf --- sys/powerpc/mpc85xx/ocpbus.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/powerpc/mpc85xx/ocpbus.c b/sys/powerpc/mpc85xx/ocpbus.c index 216ca416bda9..817cf69e6b70 100644 --- a/sys/powerpc/mpc85xx/ocpbus.c +++ b/sys/powerpc/mpc85xx/ocpbus.c @@ -255,7 +255,8 @@ ocpbus_attach(device_t dev) if ((sr & 0x80000000) == 0) continue; tgt = (sr & 0x01f00000) >> 20; - if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2) + if (tgt == OCP85XX_TGTIF_RAM1 || tgt == OCP85XX_TGTIF_RAM2 || + tgt == OCP85XX_TGTIF_RAM_INTL) continue; ccsr_write4(OCP85XX_LAWSR(i), sr & 0x7fffffff); From 28bb01e5baae7072a7ee75e5d0305d7028ddbc97 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 21 May 2009 11:43:37 +0000 Subject: [PATCH 369/544] Initial support for SMP on PowerPC MPC85xx. Tested with Freescale dual-core MPC8572DS development system. Obtained from: Freescale, Semihalf --- sys/conf/files.powerpc | 1 + sys/powerpc/booke/clock.c | 38 ++++-- sys/powerpc/booke/locore.S | 192 +++++++++++++++++++++++++++++- sys/powerpc/booke/machdep.c | 21 ++++ sys/powerpc/booke/mp_cpudep.c | 80 +++++++++++++ sys/powerpc/booke/platform_bare.c | 39 ++++++ sys/powerpc/booke/pmap.c | 100 +++++++++++++++- sys/powerpc/booke/trap_subr.S | 96 ++++++++++++++- sys/powerpc/booke/vm_machdep.c | 7 +- sys/powerpc/include/mutex.h | 2 + sys/powerpc/include/pcpu.h | 2 + sys/powerpc/include/spr.h | 3 + sys/powerpc/mpc85xx/ocpbus.h | 22 +++- sys/powerpc/powerpc/genassym.c | 1 + sys/powerpc/powerpc/mp_machdep.c | 12 ++ sys/powerpc/powerpc/openpic.c | 2 + 16 files changed, 598 insertions(+), 20 deletions(-) create mode 100644 sys/powerpc/booke/mp_cpudep.c diff --git a/sys/conf/files.powerpc b/sys/conf/files.powerpc index d1707054abcf..91b5668997ca 100644 --- a/sys/conf/files.powerpc +++ b/sys/conf/files.powerpc @@ -91,6 +91,7 @@ powerpc/booke/copyinout.c optional e500 powerpc/booke/interrupt.c optional e500 powerpc/booke/locore.S optional e500 no-obj powerpc/booke/machdep.c optional e500 +powerpc/booke/mp_cpudep.c optional e500 smp powerpc/booke/platform_bare.c optional mpc85xx powerpc/booke/pmap.c optional e500 powerpc/booke/swtch.S optional e500 diff --git a/sys/powerpc/booke/clock.c b/sys/powerpc/booke/clock.c index 7f9848e6d977..63f9f3ae7119 100644 --- a/sys/powerpc/booke/clock.c +++ b/sys/powerpc/booke/clock.c @@ -63,6 +63,8 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include +#include #include #include @@ -97,7 +99,6 @@ static struct timecounter decr_timecounter = { void decr_intr(struct trapframe *frame) { - u_long msr; /* * Check whether we are initialized. @@ -111,13 +112,17 @@ decr_intr(struct trapframe *frame) */ mtspr(SPR_TSR, TSR_DIS); - /* - * Reenable interrupts - */ - msr = mfmsr(); - mtmsr(msr | PSL_EE); + CTR1(KTR_INTR, "%s: DEC interrupt", __func__); + + if (PCPU_GET(cpuid) == 0) + hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); + else + hardclock_cpu(TRAPF_USERMODE(frame)); + + statclock(TRAPF_USERMODE(frame)); + if (profprocs != 0) + profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); - hardclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); } void @@ -125,10 +130,12 @@ cpu_initclocks(void) { decr_tc_init(); + stathz = hz; + profhz = hz; } void -decr_init (void) +decr_init(void) { struct cpuref cpu; unsigned int msr; @@ -148,9 +155,24 @@ decr_init (void) mtspr(SPR_DECAR, ticks_per_intr); mtspr(SPR_TCR, mfspr(SPR_TCR) | TCR_DIE | TCR_ARE); + set_cputicker(mftb, ticks_per_sec, 0); + mtmsr(msr); } +#ifdef SMP +void +decr_ap_init(void) +{ + + /* Set auto-reload value and enable DEC interrupts in TCR */ + mtspr(SPR_DECAR, ticks_per_intr); + mtspr(SPR_TCR, mfspr(SPR_TCR) | TCR_DIE | TCR_ARE); + + CTR2(KTR_INTR, "%s: set TCR=%p", __func__, mfspr(SPR_TCR)); +} +#endif + void decr_tc_init(void) { diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index f62d9948145d..a14e26cb892d 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski + * Copyright (C) 2007-2009 Semihalf, Rafal Jaworowski * Copyright (C) 2006 Semihalf, Marian Balakowicz * All rights reserved. * @@ -28,6 +28,8 @@ #include "assym.s" +#include + #include #include #include @@ -162,6 +164,9 @@ __start: lis %r3, KERNBASE@h ori %r3, %r3, KERNBASE@l /* EPN = KERNBASE */ +#ifdef SMP + ori %r3, %r3, MAS2_M@l /* WIMGE = 0b00100 */ +#endif mtspr SPR_MAS2, %r3 isync @@ -201,6 +206,17 @@ __start: lis %r3, kernload@ha addi %r3, %r3, kernload@l stw %r28, 0(%r3) +#ifdef SMP + /* + * APs need a separate copy of kernload info within the __boot_page + * area so they can access this value very early, before their TLBs + * are fully set up and the kernload global location is available. + */ + lis %r3, kernload_ap@ha + addi %r3, %r3, kernload_ap@l + stw %r28, 0(%r3) + msync +#endif /* * Setup a temporary stack @@ -236,6 +252,168 @@ __start: /* NOT REACHED */ 5: b 5b + +#ifdef SMP +/************************************************************************/ +/* AP Boot page */ +/************************************************************************/ + .text + .globl __boot_page + .align 12 +__boot_page: + bl 1f + +kernload_ap: + .long 0 + +/* + * Initial configuration + */ +1: + /* Set HIDs */ + lis %r3, HID0_E500_DEFAULT_SET@h + ori %r3, %r3, HID0_E500_DEFAULT_SET@l + mtspr SPR_HID0, %r3 + isync + lis %r3, HID1_E500_DEFAULT_SET@h + ori %r3, %r3, HID1_E500_DEFAULT_SET@l + mtspr SPR_HID1, %r3 + isync + + /* Enable branch prediction */ + li %r3, BUCSR_BPEN + mtspr SPR_BUCSR, %r3 + isync + + /* Invalidate all entries in TLB0 */ + li %r3, 0 + bl tlb_inval_all + +/* + * Find TLB1 entry which is translating us now + */ + bl 2f +2: mflr %r3 + bl tlb1_find_current /* the entry number found is in r30 */ + + bl tlb1_inval_all_but_current +/* + * Create temporary translation in AS=1 and switch to it + */ + bl tlb1_temp_mapping_as1 + + mfmsr %r3 + ori %r3, %r3, (PSL_IS | PSL_DS) + bl 3f +3: mflr %r4 + addi %r4, %r4, 20 + mtspr SPR_SRR0, %r4 + mtspr SPR_SRR1, %r3 + rfi /* Switch context */ + +/* + * Invalidate initial entry + */ + mr %r3, %r30 + bl tlb1_inval_entry + +/* + * Setup final mapping in TLB1[1] and switch to it + */ + /* Final kernel mapping, map in 16 MB of RAM */ + lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ + li %r4, 1 /* Entry 1 */ + rlwimi %r3, %r4, 16, 4, 15 + mtspr SPR_MAS0, %r3 + isync + + li %r3, (TLB_SIZE_16M << MAS1_TSIZE_SHIFT)@l + oris %r3, %r3, (MAS1_VALID | MAS1_IPROT)@h + mtspr SPR_MAS1, %r3 /* note TS was not filled, so it's TS=0 */ + isync + + lis %r3, KERNBASE@h + ori %r3, %r3, KERNBASE@l /* EPN = KERNBASE */ +#if SMP + ori %r3, %r3, MAS2_M@l /* WIMGE = 0b00100 */ +#endif + mtspr SPR_MAS2, %r3 + isync + + /* Retrieve kernel load [physical] address from kernload_ap */ + bl 4f +4: mflr %r3 + rlwinm %r3, %r3, 0, 0, 19 + lis %r4, kernload_ap@h + ori %r4, %r4, kernload_ap@l + lis %r5, __boot_page@h + ori %r5, %r5, __boot_page@l + sub %r4, %r4, %r5 /* offset of kernload_ap within __boot_page */ + lwzx %r3, %r4, %r3 + + /* Set RPN and protection */ + ori %r3, %r3, (MAS3_SX | MAS3_SW | MAS3_SR)@l + mtspr SPR_MAS3, %r3 + isync + tlbwe + isync + msync + + /* Switch to the final mapping */ + bl 5f +5: mflr %r3 + rlwinm %r3, %r3, 0, 0xfff /* Offset from boot page start */ + add %r3, %r3, %r5 /* Make this virtual address */ + addi %r3, %r3, 32 + li %r4, 0 /* Note AS=0 */ + mtspr SPR_SRR0, %r3 + mtspr SPR_SRR1, %r4 + rfi + +/* + * At this point we're running at virtual addresses KERNBASE and beyond so + * it's allowed to directly access all locations the kernel was linked + * against. + */ + +/* + * Invalidate temp mapping + */ + mr %r3, %r29 + bl tlb1_inval_entry + +/* + * Setup a temporary stack + */ + lis %r1, tmpstack@ha + addi %r1, %r1, tmpstack@l + addi %r1, %r1, (TMPSTACKSZ - 8) + +/* + * Initialise exception vector offsets + */ + bl ivor_setup + + /* + * Assign our pcpu instance + */ + lis %r3, ap_pcpu@h + ori %r3, %r3, ap_pcpu@l + lwz %r3, 0(%r3) + mtsprg0 %r3 + + bl pmap_bootstrap_ap + + bl cpudep_ap_bootstrap + /* Switch to the idle thread's kstack */ + mr %r1, %r3 + + bl machdep_ap_bootstrap + + /* NOT REACHED */ +6: b 6b +#endif /* SMP */ + /* * Invalidate all entries in the given TLB. * @@ -369,6 +547,18 @@ tlb1_inval_all_but_current: bne 1b blr +#ifdef SMP +__boot_page_padding: + /* + * Boot page needs to be exactly 4K, with the last word of this page + * acting as the reset vector, so we need to stuff the remainder. + * Upon release from holdoff CPU fetches the last word of the boot + * page. + */ + .space 4092 - (__boot_page_padding - __boot_page) + b __boot_page +#endif /* SMP */ + /************************************************************************/ /* locore subroutines */ /************************************************************************/ diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index 6d37653fcbc4..c753fd55d54a 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -378,6 +378,9 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) /* Initialize TLB1 handling */ tlb1_init(bootinfo->bi_bar_base); + /* Reset Time Base */ + mttb(0); + /* Init params/tunables that can be overridden by the loader. */ init_param1(); @@ -408,6 +411,11 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) debugf(" MSR = 0x%08x\n", mfmsr()); debugf(" HID0 = 0x%08x\n", mfspr(SPR_HID0)); debugf(" HID1 = 0x%08x\n", mfspr(SPR_HID1)); + debugf(" BUCSR = 0x%08x\n", mfspr(SPR_BUCSR)); + + __asm __volatile("msync; isync"); + csr = ccsr_read4(OCP85XX_L2CTL); + debugf(" L2CTL = 0x%08x\n", csr); print_bootinfo(); print_kernel_section_addr(); @@ -479,12 +487,25 @@ e500_init(u_int32_t startkernel, u_int32_t endkernel, void *mdp) return (((uintptr_t)thread0.td_pcb - 16) & ~15); } +#define RES_GRANULE 32 +extern uint32_t tlb0_miss_locks[]; + /* Initialise a struct pcpu. */ void cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz) { pcpu->pc_tid_next = TID_MIN; + +#ifdef SMP + uint32_t *ptr; + int words_per_gran = RES_GRANULE / sizeof(uint32_t); + + ptr = &tlb0_miss_locks[cpuid * words_per_gran]; + pcpu->pc_booke_tlb_lock = ptr; + *ptr = MTX_UNOWNED; + *(ptr + 1) = 0; /* recurse counter */ +#endif } /* Set set up registers on exec. */ diff --git a/sys/powerpc/booke/mp_cpudep.c b/sys/powerpc/booke/mp_cpudep.c new file mode 100644 index 000000000000..59629814d618 --- /dev/null +++ b/sys/powerpc/booke/mp_cpudep.c @@ -0,0 +1,80 @@ +/*- + * Copyright (c) 2008-2009 Semihalf, Rafal Jaworowski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +extern void dcache_enable(void); +extern void dcache_inval(void); +extern void icache_enable(void); +extern void icache_inval(void); + +volatile void *ap_pcpu; + +uint32_t +cpudep_ap_bootstrap() +{ + uint32_t msr, sp, csr; + + /* Enable L1 caches */ + csr = mfspr(SPR_L1CSR0); + if ((csr & L1CSR0_DCE) == 0) { + dcache_inval(); + dcache_enable(); + } + + csr = mfspr(SPR_L1CSR1); + if ((csr & L1CSR1_ICE) == 0) { + icache_inval(); + icache_enable(); + } + + /* Set MSR */ + msr = PSL_ME; + mtmsr(msr); + + /* Assign pcpu fields, return ptr to this AP's idle thread kstack */ + pcpup->pc_curthread = pcpup->pc_idlethread; + pcpup->pc_curpcb = pcpup->pc_curthread->td_pcb; + sp = pcpup->pc_curpcb->pcb_sp; + + /* XXX shouldn't the pcb_sp be checked/forced for alignment here?? */ + + return (sp); +} diff --git a/sys/powerpc/booke/platform_bare.c b/sys/powerpc/booke/platform_bare.c index 8f0be7e471d5..a9ee450d078c 100644 --- a/sys/powerpc/booke/platform_bare.c +++ b/sys/powerpc/booke/platform_bare.c @@ -50,6 +50,12 @@ __FBSDID("$FreeBSD$"); #include "platform_if.h" +#ifdef SMP +extern void *ap_pcpu; +extern uint8_t __boot_page[]; /* Boot page body */ +extern uint32_t kernload; /* Kernel physical load address */ +#endif + static int cpu; static int bare_probe(platform_t); @@ -179,7 +185,40 @@ bare_smp_get_bsp(platform_t plat, struct cpuref *cpuref) static int bare_smp_start_cpu(platform_t plat, struct pcpu *pc) { +#ifdef SMP + uint32_t bptr, eebpcr; + int timeout; + eebpcr = ccsr_read4(OCP85XX_EEBPCR); + if ((eebpcr & (pc->pc_cpumask << 24)) != 0) { + printf("%s: CPU=%d already out of hold-off state!\n", + __func__, pc->pc_cpuid); + return (ENXIO); + } + + ap_pcpu = pc; + __asm __volatile("msync; isync"); + + /* + * Set BPTR to the physical address of the boot page + */ + bptr = ((uint32_t)__boot_page - KERNBASE) + kernload; + ccsr_write4(OCP85XX_BPTR, (bptr >> 12) | 0x80000000); + + /* + * Release AP from hold-off state + */ + eebpcr |= (pc->pc_cpumask << 24); + ccsr_write4(OCP85XX_EEBPCR, eebpcr); + __asm __volatile("isync; msync"); + + timeout = 500; + while (!pc->pc_awake && timeout--) + DELAY(1000); /* wait 1ms */ + + return ((pc->pc_awake) ? 0 : EBUSY); +#else /* No SMP support */ return (ENXIO); +#endif } diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index 7089764c633a..ff8a6d4d8ca1 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2007-2008 Semihalf, Rafal Jaworowski + * Copyright (C) 2007-2009 Semihalf, Rafal Jaworowski * Copyright (C) 2006 Semihalf, Marian Balakowicz * All rights reserved. * @@ -63,6 +63,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -266,6 +267,8 @@ static vm_offset_t ptbl_buf_pool_vabase; /* Pointer to ptbl_buf structures. */ static struct ptbl_buf *ptbl_bufs; +void pmap_bootstrap_ap(volatile uint32_t *); + /* * Kernel MMU interface */ @@ -387,6 +390,54 @@ static mmu_def_t booke_mmu = { }; MMU_DEF(booke_mmu); +static inline void +tlb_miss_lock(void) +{ +#ifdef SMP + struct pcpu *pc; + + if (!smp_started) + return; + + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + if (pc != pcpup) { + + CTR3(KTR_PMAP, "%s: tlb miss LOCK of CPU=%d, " + "tlb_lock=%p", __func__, pc->pc_cpuid, pc->pc_booke_tlb_lock); + + KASSERT((pc->pc_cpuid != PCPU_GET(cpuid)), + ("tlb_miss_lock: tried to lock self")); + + tlb_lock(pc->pc_booke_tlb_lock); + + CTR1(KTR_PMAP, "%s: locked", __func__); + } + } +#endif +} + +static inline void +tlb_miss_unlock(void) +{ +#ifdef SMP + struct pcpu *pc; + + if (!smp_started) + return; + + SLIST_FOREACH(pc, &cpuhead, pc_allcpu) { + if (pc != pcpup) { + CTR2(KTR_PMAP, "%s: tlb miss UNLOCK of CPU=%d", + __func__, pc->pc_cpuid); + + tlb_unlock(pc->pc_booke_tlb_lock); + + CTR1(KTR_PMAP, "%s: unlocked", __func__); + } + } +#endif +} + /* Return number of entries in TLB0. */ static __inline void tlb0_get_tlbconf(void) @@ -552,9 +603,11 @@ ptbl_free(mmu_t mmu, pmap_t pmap, unsigned int pdir_idx) * don't attempt to look up the page tables we are releasing. */ mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); pmap->pm_pdir[pdir_idx] = NULL; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); for (i = 0; i < PTBL_PAGES; i++) { @@ -778,11 +831,13 @@ pte_remove(mmu_t mmu, pmap_t pmap, vm_offset_t va, uint8_t flags) } mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); tlb0_flush_entry(va); pte->flags = 0; pte->rpn = 0; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); pmap->pm_stats.resident_count--; @@ -849,6 +904,7 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, uint32_t flags) pmap->pm_stats.resident_count++; mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); tlb0_flush_entry(va); if (pmap->pm_pdir[pdir_idx] == NULL) { @@ -862,6 +918,7 @@ pte_enter(mmu_t mmu, pmap_t pmap, vm_page_t m, vm_offset_t va, uint32_t flags) pte->rpn = VM_PAGE_TO_PHYS(m) & ~PTE_PA_MASK; pte->flags |= (PTE_VALID | flags); + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } @@ -1189,6 +1246,27 @@ mmu_booke_bootstrap(mmu_t mmu, vm_offset_t start, vm_offset_t kernelend) debugf("mmu_booke_bootstrap: exit\n"); } +void +pmap_bootstrap_ap(volatile uint32_t *trcp __unused) +{ + int i; + + /* + * Finish TLB1 configuration: the BSP already set up its TLB1 and we + * have the snapshot of its contents in the s/w tlb1[] table, so use + * these values directly to (re)program AP's TLB1 hardware. + */ + for (i = 0; i < tlb1_idx; i ++) { + /* Skip invalid entries */ + if (!(tlb1[i].mas1 & MAS1_VALID)) + continue; + + tlb1_write_entry(i); + } + + set_mas4_defaults(); +} + /* * Get the physical page address for the given pmap/virtual address. */ @@ -1303,6 +1381,7 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa) pte = &(kernel_pmap->pm_pdir[pdir_idx][ptbl_idx]); mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); if (PTE_ISVALID(pte)) { @@ -1324,6 +1403,7 @@ mmu_booke_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa) __syncicache((void *)va, PAGE_SIZE); } + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } @@ -1353,12 +1433,14 @@ mmu_booke_kremove(mmu_t mmu, vm_offset_t va) } mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); /* Invalidate entry in TLB0, update PTE. */ tlb0_flush_entry(va); pte->flags = 0; pte->rpn = 0; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } @@ -1527,10 +1609,12 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, * update the PTE. */ mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); tlb0_flush_entry(va); pte->flags = flags; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } else { @@ -1821,6 +1905,7 @@ mmu_booke_protect(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva, m = PHYS_TO_VM_PAGE(PTE_PA(pte)); mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); /* Handle modified pages. */ if (PTE_ISMODIFIED(pte)) @@ -1834,6 +1919,7 @@ mmu_booke_protect(mmu_t mmu, pmap_t pmap, vm_offset_t sva, vm_offset_t eva, pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED | PTE_REFERENCED); + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } } @@ -1863,6 +1949,7 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m) m = PHYS_TO_VM_PAGE(PTE_PA(pte)); mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); /* Handle modified pages. */ if (PTE_ISMODIFIED(pte)) @@ -1876,6 +1963,7 @@ mmu_booke_remove_write(mmu_t mmu, vm_page_t m) pte->flags &= ~(PTE_UW | PTE_SW | PTE_MODIFIED | PTE_REFERENCED); + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } } @@ -2085,6 +2173,7 @@ mmu_booke_clear_modify(mmu_t mmu, vm_page_t m) goto make_sure_to_unlock; mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); if (pte->flags & (PTE_SW | PTE_UW | PTE_MODIFIED)) { tlb0_flush_entry(pv->pv_va); @@ -2092,6 +2181,7 @@ mmu_booke_clear_modify(mmu_t mmu, vm_page_t m) PTE_REFERENCED); } + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } make_sure_to_unlock: @@ -2129,10 +2219,12 @@ mmu_booke_ts_referenced(mmu_t mmu, vm_page_t m) if (PTE_ISREFERENCED(pte)) { mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); tlb0_flush_entry(pv->pv_va); pte->flags &= ~PTE_REFERENCED; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); if (++count > 4) { @@ -2168,10 +2260,12 @@ mmu_booke_clear_reference(mmu_t mmu, vm_page_t m) if (PTE_ISREFERENCED(pte)) { mtx_lock_spin(&tlbivax_mutex); + tlb_miss_lock(); tlb0_flush_entry(pv->pv_va); pte->flags &= ~PTE_REFERENCED; + tlb_miss_unlock(); mtx_unlock_spin(&tlbivax_mutex); } } @@ -2884,7 +2978,9 @@ set_mas4_defaults(void) /* Defaults: TLB0, PID0, TSIZED=4K */ mas4 = MAS4_TLBSELD0; mas4 |= (TLB_SIZE_4K << MAS4_TSIZED_SHIFT) & MAS4_TSIZED_MASK; - +#ifdef SMP + mas4 |= MAS4_MD; +#endif mtspr(SPR_MAS4, mas4); __asm __volatile("isync"); } diff --git a/sys/powerpc/booke/trap_subr.S b/sys/powerpc/booke/trap_subr.S index db5fdaaef2cb..2e67725dc4f4 100644 --- a/sys/powerpc/booke/trap_subr.S +++ b/sys/powerpc/booke/trap_subr.S @@ -1,5 +1,5 @@ /*- - * Copyright (C) 2006-2008 Semihalf, Rafal Jaworowski + * Copyright (C) 2006-2009 Semihalf, Rafal Jaworowski * Copyright (C) 2006 Semihalf, Marian Balakowicz * Copyright (C) 2006 Juniper Networks, Inc. * All rights reserved. @@ -75,12 +75,17 @@ * SPRG1 - all interrupts except TLB miss, critical, machine check * SPRG2 - critical * SPRG3 - machine check + * SPRG4-6 - scratch * */ /* Get the per-CPU data structure */ #define GET_CPUINFO(r) mfsprg0 r +#define RES_GRANULE 32 +#define RES_LOCK 0 /* offset to the 'lock' word */ +#define RES_RECURSE 4 /* offset to the 'recurse' word */ + /* * Standard interrupt prolog * @@ -265,7 +270,7 @@ /* calculate TLB nesting level and TLBSAVE instance address */ \ GET_CPUINFO(%r1); /* Per-cpu structure */ \ lwz %r28, PC_BOOKE_TLB_LEVEL(%r1); \ - rlwinm %r29, %r28, 6, 24, 25; /* 4 x TLBSAVE_LEN */ \ + rlwinm %r29, %r28, 6, 23, 25; /* 4 x TLBSAVE_LEN */ \ addi %r28, %r28, 1; \ stw %r28, PC_BOOKE_TLB_LEVEL(%r1); \ addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \ @@ -300,7 +305,7 @@ lwz %r28, PC_BOOKE_TLB_LEVEL(%r1); \ subi %r28, %r28, 1; \ stw %r28, PC_BOOKE_TLB_LEVEL(%r1); \ - rlwinm %r29, %r28, 6, 24, 25; /* 4 x TLBSAVE_LEN */ \ + rlwinm %r29, %r28, 6, 23, 25; /* 4 x TLBSAVE_LEN */ \ addi %r29, %r29, PC_BOOKE_TLBSAVE@l; \ add %r1, %r1, %r29; \ \ @@ -318,6 +323,55 @@ lmw %r20, (TLBSAVE_BOOKE_R20)(%r1); \ mfsprg4 %r1 +#ifdef SMP +#define TLB_LOCK \ + GET_CPUINFO(%r20); \ + lwz %r21, PC_CURTHREAD(%r20); \ + lwz %r22, PC_BOOKE_TLB_LOCK(%r20); \ + \ +1: lwarx %r23, 0, %r22; \ + cmpwi %r23, MTX_UNOWNED; \ + beq 2f; \ + \ + /* check if this is recursion */ \ + cmplw cr0, %r21, %r23; \ + bne- 1b; \ + \ +2: /* try to acquire lock */ \ + stwcx. %r21, 0, %r22; \ + bne- 1b; \ + \ + /* got it, update recursion counter */ \ + lwz %r21, RES_RECURSE(%r22); \ + addi %r21, %r21, 1; \ + stw %r21, RES_RECURSE(%r22); \ + isync; \ + msync + +#define TLB_UNLOCK \ + GET_CPUINFO(%r20); \ + lwz %r21, PC_CURTHREAD(%r20); \ + lwz %r22, PC_BOOKE_TLB_LOCK(%r20); \ + \ + /* update recursion counter */ \ + lwz %r23, RES_RECURSE(%r22); \ + subi %r23, %r23, 1; \ + stw %r23, RES_RECURSE(%r22); \ + \ + cmpwi %r23, 0; \ + bne 1f; \ + isync; \ + msync; \ + \ + /* release the lock */ \ + li %r23, MTX_UNOWNED; \ + stw %r23, 0(%r22); \ +1: isync; \ + msync +#else +#define TLB_LOCK +#define TLB_UNLOCK +#endif /* SMP */ #define INTERRUPT(label) \ .globl label; \ @@ -461,6 +515,7 @@ INTERRUPT(int_watchdog) ****************************************************************************/ INTERRUPT(int_data_tlb_error) TLB_PROLOG + TLB_LOCK mfdear %r31 @@ -503,6 +558,7 @@ tlb_miss_handle: bl tlb_fill_entry tlb_miss_return: + TLB_UNLOCK TLB_RESTORE rfi @@ -648,6 +704,7 @@ tlb_fill_entry: ****************************************************************************/ INTERRUPT(int_inst_tlb_error) TLB_PROLOG + TLB_LOCK mfsrr0 %r31 /* faulting address */ @@ -796,3 +853,36 @@ dbleave: FRAME_LEAVE(SPR_SRR0, SPR_SRR1) rfi #endif /* KDB */ + +#ifdef SMP +ENTRY(tlb_lock) + GET_CPUINFO(%r5) + lwz %r5, PC_CURTHREAD(%r5) +1: lwarx %r4, 0, %r3 + cmpwi %r4, MTX_UNOWNED + bne 1b + stwcx. %r5, 0, %r3 + bne- 1b + isync + msync + blr + +ENTRY(tlb_unlock) + isync + msync + li %r4, MTX_UNOWNED + stw %r4, 0(%r3) + isync + msync + blr +/* + * TLB miss spin locks. For each CPU we have a reservation granule (32 bytes); + * only a single word from this granule will actually be used as a spin lock + * for mutual exclusion between TLB miss handler and pmap layer that + * manipulates page table contents. + */ + .data + .align 5 +GLOBAL(tlb0_miss_locks) + .space RES_GRANULE * MAXCPU +#endif diff --git a/sys/powerpc/booke/vm_machdep.c b/sys/powerpc/booke/vm_machdep.c index e8fff023f3de..2ad0d213d8eb 100644 --- a/sys/powerpc/booke/vm_machdep.c +++ b/sys/powerpc/booke/vm_machdep.c @@ -180,7 +180,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) p1 = td1->td_proc; pcb = (struct pcb *)((td2->td_kstack + - td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x2fU); + td2->td_kstack_pages * PAGE_SIZE - sizeof(struct pcb)) & ~0x3fU); td2->td_pcb = pcb; /* Copy the pcb */ @@ -403,7 +403,7 @@ cpu_thread_alloc(struct thread *td) struct pcb *pcb; pcb = (struct pcb *)((td->td_kstack + td->td_kstack_pages * PAGE_SIZE - - sizeof(struct pcb)) & ~0x2fU); + sizeof(struct pcb)) & ~0x3fU); td->td_pcb = pcb; td->td_frame = (struct trapframe *)pcb - 1; } @@ -469,7 +469,8 @@ cpu_set_upcall_kse(struct thread *td, void (*entry)(void *), void *arg, tf = td->td_frame; /* align stack and alloc space for frame ptr and saved LR */ - sp = ((uint32_t)stack->ss_sp + stack->ss_size - 2 * sizeof(u_int32_t)) & ~0x1f; + sp = ((uint32_t)stack->ss_sp + stack->ss_size - + 2 * sizeof(u_int32_t)) & ~0x3f; bzero(tf, sizeof(struct trapframe)); tf->fixreg[1] = (register_t)sp; diff --git a/sys/powerpc/include/mutex.h b/sys/powerpc/include/mutex.h index 0b7fe2633e26..b6f80fbddd15 100644 --- a/sys/powerpc/include/mutex.h +++ b/sys/powerpc/include/mutex.h @@ -32,6 +32,7 @@ #ifndef _MACHINE_MUTEX_H_ #define _MACHINE_MUTEX_H_ +#if 0 #ifdef LOCORE /* @@ -62,4 +63,5 @@ #endif /* !LOCORE */ +#endif #endif /* __MACHINE_MUTEX_H */ diff --git a/sys/powerpc/include/pcpu.h b/sys/powerpc/include/pcpu.h index a0a3e517d5ed..51422daac70b 100644 --- a/sys/powerpc/include/pcpu.h +++ b/sys/powerpc/include/pcpu.h @@ -31,6 +31,7 @@ #define _MACHINE_PCPU_H_ #include +#include struct pmap; #define CPUSAVE_LEN 8 @@ -61,6 +62,7 @@ struct pmap; register_t pc_booke_mchksave[CPUSAVE_LEN]; \ register_t pc_booke_tlbsave[BOOKE_TLBSAVE_LEN]; \ register_t pc_booke_tlb_level; \ + uint32_t *pc_booke_tlb_lock; \ int pc_tid_next; /* Definitions for register offsets within the exception tmp save areas */ diff --git a/sys/powerpc/include/spr.h b/sys/powerpc/include/spr.h index 098c78c352db..870e989bfd42 100644 --- a/sys/powerpc/include/spr.h +++ b/sys/powerpc/include/spr.h @@ -667,6 +667,9 @@ #define L1CSR1_ICFI 0x00000002 /* Instruction Cache Flash Invalidate */ #define L1CSR1_ICE 0x00000001 /* Instruction Cache Enable */ +#define SPR_BUCSR 0x3F5 /* ..8 Branch Unit Control and Status Register */ +#define BUCSR_BPEN 0x00000001 /* Branch Prediction Enable */ + #endif /* #elif defined(E500) */ #endif /* !_POWERPC_SPR_H_ */ diff --git a/sys/powerpc/mpc85xx/ocpbus.h b/sys/powerpc/mpc85xx/ocpbus.h index 2c6380471cb0..f33f5479eb62 100644 --- a/sys/powerpc/mpc85xx/ocpbus.h +++ b/sys/powerpc/mpc85xx/ocpbus.h @@ -31,7 +31,18 @@ #define _MACHINE_OCP85XX_H_ /* - * Local access registers. + * Configuration control and status registers + */ +#define OCP85XX_CCSRBAR (CCSRBAR_VA + 0x0) +#define OCP85XX_BPTR (CCSRBAR_VA + 0x20) + +/* + * E500 Coherency Module registers + */ +#define OCP85XX_EEBPCR (CCSRBAR_VA + 0x1010) + +/* + * Local access registers */ #define OCP85XX_LAWBAR(n) (CCSRBAR_VA + 0xc08 + 0x20 * (n)) #define OCP85XX_LAWSR(n) (CCSRBAR_VA + 0xc10 + 0x20 * (n)) @@ -46,7 +57,12 @@ #define OCP85XX_TGTIF_RAM2 22 /* - * Power-On Reset configuration. + * L2 cache registers + */ +#define OCP85XX_L2CTL (CCSRBAR_VA + 0x20000) + +/* + * Power-On Reset configuration */ #define OCP85XX_PORDEVSR (CCSRBAR_VA + 0xe000c) #define OCP85XX_PORDEVSR2 (CCSRBAR_VA + 0xe0014) @@ -61,7 +77,7 @@ */ #define OCP85XX_I2C0_OFF 0x03000 #define OCP85XX_I2C1_OFF 0x03100 -#define OCP85XX_I2C_SIZE 0x15 +#define OCP85XX_I2C_SIZE 0x16 #define OCP85XX_UART0_OFF 0x04500 #define OCP85XX_UART1_OFF 0x04600 #define OCP85XX_UART_SIZE 0x10 diff --git a/sys/powerpc/powerpc/genassym.c b/sys/powerpc/powerpc/genassym.c index ebdddd49365f..ad262d4e010b 100644 --- a/sys/powerpc/powerpc/genassym.c +++ b/sys/powerpc/powerpc/genassym.c @@ -67,6 +67,7 @@ ASSYM(PC_BOOKE_CRITSAVE, offsetof(struct pcpu, pc_booke_critsave)); ASSYM(PC_BOOKE_MCHKSAVE, offsetof(struct pcpu, pc_booke_mchksave)); ASSYM(PC_BOOKE_TLBSAVE, offsetof(struct pcpu, pc_booke_tlbsave)); ASSYM(PC_BOOKE_TLB_LEVEL, offsetof(struct pcpu, pc_booke_tlb_level)); +ASSYM(PC_BOOKE_TLB_LOCK, offsetof(struct pcpu, pc_booke_tlb_lock)); #endif ASSYM(CPUSAVE_R28, CPUSAVE_R28*4); diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c index 0dbbced06cdd..986259f550a3 100644 --- a/sys/powerpc/powerpc/mp_machdep.c +++ b/sys/powerpc/powerpc/mp_machdep.c @@ -249,6 +249,8 @@ powerpc_ipi_handler(void *arg) uint32_t ipimask; int msg; + CTR2(KTR_SMP, "%s: MSR 0x%08x", __func__, mfmsr()); + ipimask = atomic_readandclear_32(&(pcpup->pc_ipimask)); if (ipimask == 0) return (FILTER_STRAY); @@ -257,14 +259,18 @@ powerpc_ipi_handler(void *arg) ipi_msg_cnt[msg]++; switch (msg) { case IPI_AST: + CTR1(KTR_SMP, "%s: IPI_AST", __func__); break; case IPI_PREEMPT: + CTR1(KTR_SMP, "%s: IPI_PREEMPT", __func__); sched_preempt(curthread); break; case IPI_RENDEZVOUS: + CTR1(KTR_SMP, "%s: IPI_RENDEZVOUS", __func__); smp_rendezvous_action(); break; case IPI_STOP: + CTR1(KTR_SMP, "%s: IPI_STOP (stop)", __func__); self = PCPU_GET(cpumask); savectx(PCPU_GET(curpcb)); atomic_set_int(&stopped_cpus, self); @@ -272,6 +278,7 @@ powerpc_ipi_handler(void *arg) cpu_spinwait(); atomic_clear_int(&started_cpus, self); atomic_clear_int(&stopped_cpus, self); + CTR1(KTR_SMP, "%s: IPI_STOP (restart)", __func__); break; } } @@ -283,8 +290,13 @@ static void ipi_send(struct pcpu *pc, int ipi) { + CTR4(KTR_SMP, "%s: pc=%p, targetcpu=%d, IPI=%d", __func__, + pc, pc->pc_cpuid, ipi); + atomic_set_32(&pc->pc_ipimask, (1 << ipi)); PIC_IPI(pic, pc->pc_cpuid); + + CTR1(KTR_SMP, "%s: sent", __func__); } /* Send an IPI to a set of cpus. */ diff --git a/sys/powerpc/powerpc/openpic.c b/sys/powerpc/powerpc/openpic.c index 89b9ec099aac..963768d5ecad 100644 --- a/sys/powerpc/powerpc/openpic.c +++ b/sys/powerpc/powerpc/openpic.c @@ -206,6 +206,8 @@ openpic_dispatch(device_t dev, struct trapframe *tf) struct openpic_softc *sc; u_int cpuid, vector; + CTR1(KTR_INTR, "%s: got interrupt", __func__); + cpuid = PCPU_GET(cpuid); sc = device_get_softc(dev); From 5a065915b0697dc18f74c3a0726af98577900662 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Thu, 21 May 2009 12:05:15 +0000 Subject: [PATCH 370/544] Improve style(9), clean up. --- sys/powerpc/booke/clock.c | 16 +++++++-------- sys/powerpc/booke/locore.S | 2 -- sys/powerpc/booke/vm_machdep.c | 10 +++------- sys/powerpc/powerpc/busdma_machdep.c | 30 ++++++++++++---------------- 4 files changed, 23 insertions(+), 35 deletions(-) diff --git a/sys/powerpc/booke/clock.c b/sys/powerpc/booke/clock.c index 63f9f3ae7119..1d9043ebbed9 100644 --- a/sys/powerpc/booke/clock.c +++ b/sys/powerpc/booke/clock.c @@ -79,14 +79,14 @@ __FBSDID("$FreeBSD$"); /* * Initially we assume a processor with a bus frequency of 12.5 MHz. */ -u_int tickspending; -u_long ns_per_tick = 80; -static u_long ticks_per_sec = 12500000; -static long ticks_per_intr; +u_int tickspending; +u_long ns_per_tick = 80; +static u_long ticks_per_sec = 12500000; +static long ticks_per_intr; #define DIFF19041970 2082844800 -static timecounter_get_t decr_get_timecount; +static timecounter_get_t decr_get_timecount; static struct timecounter decr_timecounter = { decr_get_timecount, /* get_timecount */ @@ -122,7 +122,6 @@ decr_intr(struct trapframe *frame) statclock(TRAPF_USERMODE(frame)); if (profprocs != 0) profclock(TRAPF_USERMODE(frame), TRAPF_PC(frame)); - } void @@ -181,14 +180,13 @@ decr_tc_init(void) tc_init(&decr_timecounter); } - static unsigned decr_get_timecount(struct timecounter *tc) { quad_t tb; tb = mftb(); - return tb; + return (tb); } /* @@ -207,7 +205,7 @@ DELAY(int n) } start = mftb(); - end = start + (u_quad_t)ticks_per_sec / ( USECS_IN_SEC / n); + end = start + (u_quad_t)ticks_per_sec / (USECS_IN_SEC / n); do { now = mftb(); } while (now < end || (now > start && end < start)); diff --git a/sys/powerpc/booke/locore.S b/sys/powerpc/booke/locore.S index a14e26cb892d..86dff0088494 100644 --- a/sys/powerpc/booke/locore.S +++ b/sys/powerpc/booke/locore.S @@ -334,9 +334,7 @@ kernload_ap: lis %r3, KERNBASE@h ori %r3, %r3, KERNBASE@l /* EPN = KERNBASE */ -#if SMP ori %r3, %r3, MAS2_M@l /* WIMGE = 0b00100 */ -#endif mtspr SPR_MAS2, %r3 isync diff --git a/sys/powerpc/booke/vm_machdep.c b/sys/powerpc/booke/vm_machdep.c index 2ad0d213d8eb..178b863de546 100644 --- a/sys/powerpc/booke/vm_machdep.c +++ b/sys/powerpc/booke/vm_machdep.c @@ -14,8 +14,6 @@ * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES @@ -226,10 +224,7 @@ cpu_fork(struct thread *td1, struct proc *p2, struct thread *td2, int flags) * This is needed to make kernel threads stay in kernel mode. */ void -cpu_set_fork_handler(td, func, arg) - struct thread *td; - void (*func)(void *); - void *arg; +cpu_set_fork_handler(struct thread *td, void (*func)(void *), void *arg) { struct callframe *cf; @@ -331,7 +326,7 @@ sf_buf_alloc(struct vm_page *m, int flags) } /* - * Detatch mapped page and release resources back to the system. + * Detach mapped page and release resources back to the system. * * Remove a reference from the given sf_buf, adding it to the free * list when its reference count reaches zero. A freed sf_buf still, @@ -341,6 +336,7 @@ sf_buf_alloc(struct vm_page *m, int flags) void sf_buf_free(struct sf_buf *sf) { + mtx_lock(&sf_buf_lock); sf->ref_count--; if (sf->ref_count == 0) { diff --git a/sys/powerpc/powerpc/busdma_machdep.c b/sys/powerpc/powerpc/busdma_machdep.c index 5f4ad44c37bd..f12de3d4690d 100644 --- a/sys/powerpc/powerpc/busdma_machdep.c +++ b/sys/powerpc/powerpc/busdma_machdep.c @@ -31,7 +31,7 @@ __FBSDID("$FreeBSD$"); /* - * MacPPC bus dma support routines + * Bus dma support routines */ #include @@ -124,11 +124,10 @@ dflt_lock(void *arg, bus_dma_lock_op_t op) */ int bus_dma_tag_create(bus_dma_tag_t parent, bus_size_t alignment, - bus_size_t boundary, bus_addr_t lowaddr, - bus_addr_t highaddr, bus_dma_filter_t *filter, - void *filterarg, bus_size_t maxsize, int nsegments, - bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, - void *lockfuncarg, bus_dma_tag_t *dmat) + bus_size_t boundary, bus_addr_t lowaddr, bus_addr_t highaddr, + bus_dma_filter_t *filter, void *filterarg, bus_size_t maxsize, + int nsegments, bus_size_t maxsegsz, int flags, bus_dma_lock_t *lockfunc, + void *lockfuncarg, bus_dma_tag_t *dmat) { bus_dma_tag_t newtag; int error = 0; @@ -251,7 +250,7 @@ bus_dmamap_destroy(bus_dma_tag_t dmat, bus_dmamap_t map) */ int bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, - bus_dmamap_t *mapp) + bus_dmamap_t *mapp) { int mflags; @@ -319,9 +318,8 @@ bus_dmamem_free(bus_dma_tag_t dmat, void *vaddr, bus_dmamap_t map) */ static int bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[], - void *buf, bus_size_t buflen, struct thread *td, - int flags, vm_offset_t *lastaddrp, int *segp, - int first) + void *buf, bus_size_t buflen, struct thread *td, int flags, + vm_offset_t *lastaddrp, int *segp, int first) { bus_size_t sgsize; bus_addr_t curaddr, lastaddr, baddr, bmask; @@ -405,8 +403,8 @@ bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[], */ int bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, - bus_size_t buflen, bus_dmamap_callback_t *callback, - void *callback_arg, int flags) + bus_size_t buflen, bus_dmamap_callback_t *callback, + void *callback_arg, int flags) { #ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT bus_dma_segment_t dm_segments[dmat->nsegments]; @@ -437,8 +435,7 @@ bus_dmamap_load(bus_dma_tag_t dmat, bus_dmamap_t map, void *buf, */ int bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags) + bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { #ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT bus_dma_segment_t dm_segments[dmat->nsegments]; @@ -480,7 +477,7 @@ bus_dmamap_load_mbuf(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, int bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, - bus_dma_segment_t *segs, int *nsegs, int flags) + bus_dma_segment_t *segs, int *nsegs, int flags) { int error = 0; @@ -514,8 +511,7 @@ bus_dmamap_load_mbuf_sg(bus_dma_tag_t dmat, bus_dmamap_t map, struct mbuf *m0, */ int bus_dmamap_load_uio(bus_dma_tag_t dmat, bus_dmamap_t map, struct uio *uio, - bus_dmamap_callback2_t *callback, void *callback_arg, - int flags) + bus_dmamap_callback2_t *callback, void *callback_arg, int flags) { vm_offset_t lastaddr; #ifdef __CC_SUPPORTS_DYNAMIC_ARRAY_INIT From 46990862ab1b1af1e8137c5fc2c00ad554bcbd5b Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 21 May 2009 12:36:40 +0000 Subject: [PATCH 371/544] Largely revert the earlier change to use a single CCB for the RAID recovery thread. Multiple RAID events in quick succession can cause an additional bus rescan to be scheduled before an earlier scan has completed. In this case the driver was attempting to use the same CCB storage for two requests. PR: kern/130330 Reviewed by: Riccardo Torrini riccardo.torrini | esaote com MFC after: 1 week --- sys/dev/mpt/mpt_raid.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/sys/dev/mpt/mpt_raid.c b/sys/dev/mpt/mpt_raid.c index 0d5e03a730aa..6b7eb7b46c46 100644 --- a/sys/dev/mpt/mpt_raid.c +++ b/sys/dev/mpt/mpt_raid.c @@ -658,19 +658,19 @@ mpt_terminate_raid_thread(struct mpt_softc *mpt) static void mpt_cam_rescan_callback(struct cam_periph *periph, union ccb *ccb) { + xpt_free_path(ccb->ccb_h.path); + xpt_free_ccb(ccb); } static void mpt_raid_thread(void *arg) { struct mpt_softc *mpt; - union ccb *ccb; int firstrun; mpt = (struct mpt_softc *)arg; firstrun = 1; - ccb = xpt_alloc_ccb(); MPT_LOCK(mpt); while (mpt->shutdwn_raid == 0) { @@ -698,15 +698,21 @@ mpt_raid_thread(void *arg) } if (mpt->raid_rescan != 0) { + union ccb *ccb; struct cam_path *path; int error; mpt->raid_rescan = 0; + MPT_UNLOCK(mpt); + ccb = xpt_alloc_ccb(); + + MPT_LOCK(mpt); error = xpt_create_path(&path, xpt_periph, cam_sim_path(mpt->phydisk_sim), CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD); if (error != CAM_REQ_CMP) { + xpt_free_ccb(ccb); mpt_prt(mpt, "Unable to rescan RAID Bus!\n"); } else { xpt_setup_ccb(&ccb->ccb_h, path, 5); @@ -719,7 +725,6 @@ mpt_raid_thread(void *arg) } } } - xpt_free_ccb(ccb); mpt->raid_thread = NULL; wakeup(&mpt->raid_thread); MPT_UNLOCK(mpt); From 9995e57b01361165d05b6f5478fd28b7100ce432 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Thu, 21 May 2009 13:22:07 +0000 Subject: [PATCH 372/544] Move the M_WAITOK flag in notify() into an M_NOWAIT one in order to match the behaviour alredy present with the further malloc() call in devctl_notify(). This fixes a bug in the CAM layer where the camisr handler finished to call camperiphfree() (and subsequently destroy_dev() resulting in a new dev notify) while the xpt lock is held. PR: kern/130330 Tested by: Riccardo Torrini --- sys/kern/kern_conf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_conf.c b/sys/kern/kern_conf.c index 61488e9b01fe..284f4829155d 100644 --- a/sys/kern/kern_conf.c +++ b/sys/kern/kern_conf.c @@ -491,7 +491,9 @@ notify(struct cdev *dev, const char *ev) if (cold) return; namelen = strlen(dev->si_name); - data = malloc(namelen + sizeof(prefix), M_TEMP, M_WAITOK); + data = malloc(namelen + sizeof(prefix), M_TEMP, M_NOWAIT); + if (data == NULL) + return; memcpy(data, prefix, sizeof(prefix) - 1); memcpy(data + sizeof(prefix) - 1, dev->si_name, namelen + 1); devctl_notify("DEVFS", "CDEV", ev, data); From e6b089446b73b984fb2966792858123ba8fb6032 Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 21 May 2009 13:39:46 +0000 Subject: [PATCH 373/544] Attempt to clarify some confusing wording regarding atomic_load() and atomic_store(). --- share/man/man9/atomic.9 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/share/man/man9/atomic.9 b/share/man/man9/atomic.9 index 70ee2ab78ed5..0bc567c4b9bf 100644 --- a/share/man/man9/atomic.9 +++ b/share/man/man9/atomic.9 @@ -225,7 +225,7 @@ return (*addr) .Pp The .Fn atomic_load -functions always have acquire semantics. +functions are only provided with acquire memory barriers. .Bl -hang .It Fn atomic_readandclear addr .Bd -literal -compact @@ -263,7 +263,7 @@ not have any variants with memory barriers at this time. .Pp The .Fn atomic_store -functions always have release semantics. +functions are only provided with release memory barriers. .Pp The type .Dq Li 64 From 3cf138bb795dde1df81fc72115f8aec00ff080ec Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Thu, 21 May 2009 14:43:12 +0000 Subject: [PATCH 374/544] Modified the attach and detach routines to handle bringing ports up and down more cleanly. This addresses a problem where if we have the link flap during boot the driver would lock up the system. Reviewed by: jhb MFC after: 1 week --- sys/dev/cxgb/cxgb_main.c | 233 ++++++++++++++++++++++++--------------- 1 file changed, 147 insertions(+), 86 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 3108688c823e..9639037a95cd 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -392,6 +392,31 @@ upgrade_fw(adapter_t *sc) return (status); } +/* + * The cxgb_controller_attach function is responsible for the initial + * bringup of the device. Its responsibilities include: + * + * 1. Determine if the device supports MSI or MSI-X. + * 2. Allocate bus resources so that we can access the Base Address Register + * 3. Create and initialize mutexes for the controller and its control + * logic such as SGE and MDIO. + * 4. Call hardware specific setup routine for the adapter as a whole. + * 5. Allocate the BAR for doing MSI-X. + * 6. Setup the line interrupt iff MSI-X is not supported. + * 7. Create the driver's taskq. + * 8. Start the task queue threads. + * 9. Update the firmware if required. + * 10. Create a child device for each MAC (port) + * 11. Initialize T3 private state. + * 12. Trigger the LED + * 13. Setup offload iff supported. + * 14. Reset/restart the tick callout. + * 15. Attach sysctls + * + * NOTE: Any modification or deviation from this list MUST be reflected in + * the above comment. Failure to do so will result in problems on various + * error conditions including link flapping. + */ static int cxgb_controller_attach(device_t dev) { @@ -635,6 +660,11 @@ cxgb_controller_attach(device_t dev) return (error); } +/* + * The cxgb_controlller_detach routine is called with the device is + * unloaded from the system. + */ + static int cxgb_controller_detach(device_t dev) { @@ -647,6 +677,24 @@ cxgb_controller_detach(device_t dev) return (0); } +/* + * The cxgb_free() is called by the cxgb_controller_detach() routine + * to tear down the structures that were built up in + * cxgb_controller_attach(), and should be the final piece of work + * done when fullly unloading the driver. + * + * + * 1. Shutting down the threads started by the cxgb_controller_attach() + * routine. + * 2. Stopping the lower level device and all callouts (cxgb_down_locked()). + * 3. Detaching all of the port devices created during the + * cxgb_controller_attach() routine. + * 4. Removing the device children created via cxgb_controller_attach(). + * 5. Releaseing PCI resources associated with the device. + * 6. Turning off the offload support, iff it was turned on. + * 7. Destroying the mutexes created in cxgb_controller_attach(). + * + */ static void cxgb_free(struct adapter *sc) { @@ -655,14 +703,27 @@ cxgb_free(struct adapter *sc) ADAPTER_LOCK(sc); sc->flags |= CXGB_SHUTDOWN; ADAPTER_UNLOCK(sc); - cxgb_pcpu_shutdown_threads(sc); - ADAPTER_LOCK(sc); -/* - * drops the lock - */ + cxgb_pcpu_shutdown_threads(sc); + + ADAPTER_LOCK(sc); cxgb_down_locked(sc); + ADAPTER_UNLOCK(sc); + t3_sge_deinit_sw(sc); + /* + * Wait for last callout + */ + + DELAY(hz*100); + + bus_generic_detach(sc->dev); + + for (i = 0; i < (sc)->params.nports; i++) { + if (device_delete_child(sc->dev, sc->portdev[i]) != 0) + device_printf(sc->dev, "failed to delete child port\n"); + } + #ifdef MSI_SUPPORTED if (sc->flags & (USING_MSI | USING_MSIX)) { device_printf(sc->dev, "releasing msi message(s)\n"); @@ -676,19 +737,6 @@ cxgb_free(struct adapter *sc) sc->msix_regs_res); } - t3_sge_deinit_sw(sc); - /* - * Wait for last callout - */ - - DELAY(hz*100); - - for (i = 0; i < (sc)->params.nports; ++i) { - if (sc->portdev[i] != NULL) - device_delete_child(sc->dev, sc->portdev[i]); - } - - bus_generic_detach(sc->dev); if (sc->tq != NULL) { taskqueue_free(sc->tq); sc->tq = NULL; @@ -957,6 +1005,7 @@ cxgb_port_attach(device_t dev) } ether_ifattach(ifp, p->hw_addr); + #ifdef IFNET_MULTIQUEUE ifp->if_transmit = cxgb_pcpu_transmit; #endif @@ -1022,38 +1071,104 @@ cxgb_port_attach(device_t dev) TASK_INIT(&p->link_fault_task, 0, cxgb_link_fault, p); + /* If it's MSI or INTx, allocate a single interrupt for everything */ + if ((sc->flags & USING_MSIX) == 0) { + if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, + &sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { + device_printf(sc->dev, "Cannot allocate interrupt rid=%d\n", + sc->irq_rid); + err = EINVAL; + goto out; + } + device_printf(sc->dev, "allocated irq_res=%p\n", sc->irq_res); + + if (bus_setup_intr(sc->dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET, +#ifdef INTR_FILTERS + NULL, +#endif + sc->cxgb_intr, sc, &sc->intr_tag)) { + device_printf(sc->dev, "Cannot set up interrupt\n"); + err = EINVAL; + goto irq_err; + } + } else { + cxgb_setup_msix(sc, sc->msi_count); + } + #if defined(LINK_ATTACH) cxgb_link_start(p); t3_link_changed(sc, p->port_id); #endif - return (0); +out: + return (err); +irq_err: + CH_ERR(sc, "request_irq failed, err %d\n", err); + goto out; } +/* + * cxgb_port_detach() is called via the device_detach methods when + * cxgb_free() calls the bus_generic_detach. It is responsible for + * removing the device from the view of the kernel, i.e. from all + * interfaces lists etc. This routine is only called when the driver is + * being unloaded, not when the link goes down. + * + */ static int cxgb_port_detach(device_t dev) { struct port_info *p; + struct adapter *sc; p = device_get_softc(dev); + sc = p->adapter; + + if (p->port_cdev != NULL) + destroy_dev(p->port_cdev); + + ether_ifdetach(p->ifp); + printf("waiting for callout to stop ..."); + printf("done\n"); PORT_LOCK(p); if (p->ifp->if_drv_flags & IFF_DRV_RUNNING) cxgb_stop_locked(p); PORT_UNLOCK(p); - ether_ifdetach(p->ifp); - printf("waiting for callout to stop ..."); - DELAY(1000000); - printf("done\n"); + if (sc->intr_tag != NULL) { + bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag); + sc->intr_tag = NULL; + } + if (sc->irq_res != NULL) { + device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n", + sc->irq_rid, sc->irq_res); + bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid, + sc->irq_res); + sc->irq_res = NULL; + } + + if (sc->flags & USING_MSIX) + cxgb_teardown_msix(sc); + + callout_drain(&sc->cxgb_tick_ch); + callout_drain(&sc->sge_timer_ch); + + if (sc->tq != NULL) { + printf("draining slow intr\n"); + + taskqueue_drain(sc->tq, &sc->slow_intr_task); + printf("draining ext intr\n"); + taskqueue_drain(sc->tq, &sc->ext_intr_task); + printf("draining tick task\n"); + taskqueue_drain(sc->tq, &sc->tick_task); + } + /* * the lock may be acquired in ifdetach */ PORT_LOCK_DEINIT(p); if_free(p->ifp); - if (p->port_cdev != NULL) - destroy_dev(p->port_cdev); - return (0); } @@ -1705,30 +1820,6 @@ cxgb_up(struct adapter *sc) t3_intr_clear(sc); - /* If it's MSI or INTx, allocate a single interrupt for everything */ - if ((sc->flags & USING_MSIX) == 0) { - if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, - &sc->irq_rid, RF_SHAREABLE | RF_ACTIVE)) == NULL) { - device_printf(sc->dev, "Cannot allocate interrupt rid=%d\n", - sc->irq_rid); - err = EINVAL; - goto out; - } - device_printf(sc->dev, "allocated irq_res=%p\n", sc->irq_res); - - if (bus_setup_intr(sc->dev, sc->irq_res, INTR_MPSAFE|INTR_TYPE_NET, -#ifdef INTR_FILTERS - NULL, -#endif - sc->cxgb_intr, sc, &sc->intr_tag)) { - device_printf(sc->dev, "Cannot set up interrupt\n"); - err = EINVAL; - goto irq_err; - } - } else { - cxgb_setup_msix(sc, sc->msi_count); - } - t3_sge_start(sc); t3_intr_enable(sc); @@ -1749,9 +1840,6 @@ cxgb_up(struct adapter *sc) } out: return (err); -irq_err: - CH_ERR(sc, "request_irq failed, err %d\n", err); - goto out; } @@ -1765,36 +1853,8 @@ cxgb_down_locked(struct adapter *sc) t3_sge_stop(sc); t3_intr_disable(sc); - if (sc->intr_tag != NULL) { - bus_teardown_intr(sc->dev, sc->irq_res, sc->intr_tag); - sc->intr_tag = NULL; - } - if (sc->irq_res != NULL) { - device_printf(sc->dev, "de-allocating interrupt irq_rid=%d irq_res=%p\n", - sc->irq_rid, sc->irq_res); - bus_release_resource(sc->dev, SYS_RES_IRQ, sc->irq_rid, - sc->irq_res); - sc->irq_res = NULL; - } - - if (sc->flags & USING_MSIX) - cxgb_teardown_msix(sc); - callout_stop(&sc->cxgb_tick_ch); callout_stop(&sc->sge_timer_ch); - callout_drain(&sc->cxgb_tick_ch); - callout_drain(&sc->sge_timer_ch); - - if (sc->tq != NULL) { - printf("draining slow intr\n"); - - taskqueue_drain(sc->tq, &sc->slow_intr_task); - printf("draining ext intr\n"); - taskqueue_drain(sc->tq, &sc->ext_intr_task); - printf("draining tick task\n"); - taskqueue_drain(sc->tq, &sc->tick_task); - } - ADAPTER_UNLOCK(sc); } static int @@ -1861,8 +1921,9 @@ offload_close(struct t3cdev *tdev) ADAPTER_LOCK(adapter); if (!adapter->open_device_map) cxgb_down_locked(adapter); - else - ADAPTER_UNLOCK(adapter); + + ADAPTER_UNLOCK(adapter); + return (0); } @@ -1957,10 +2018,10 @@ cxgb_stop_locked(struct port_info *pi) ADAPTER_LOCK(pi->adapter); clrbit(&pi->adapter->open_device_map, pi->port_id); - if (pi->adapter->open_device_map == 0) { + if (pi->adapter->open_device_map == 0) cxgb_down_locked(pi->adapter); - } else - ADAPTER_UNLOCK(pi->adapter); + + ADAPTER_UNLOCK(pi->adapter); #if !defined(LINK_ATTACH) DELAY(100); From bac9ff34461a766a0bdb7f7fcb1ccdf6c2baf6be Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 21 May 2009 14:52:36 +0000 Subject: [PATCH 375/544] Fix the comment at line 3711 to be consistent with the change applied for r192537. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index aa0e72543da0..37ba36e3c5b5 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3706,7 +3706,7 @@ nfsrv_nextclientindex(void) return (client_index); /* - * In practice, we'll never get here, but the reboot is here, + * In practice we'll never get here, but the panic is here * just for fun. (client_index will not wrap around on any real server) */ panic("nfsv4 server out of clientids"); From 0bbdea7776fe3cd085426874cd768cf0dd0f2a00 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Thu, 21 May 2009 15:08:03 +0000 Subject: [PATCH 376/544] Integrate three changes from Chelsio. 1) Add a sysctl that will say what type of PHYs exist on the card. 2) Fix a bug that occurs when an AEL 2005 PHY resets without a transciever in the card. 3) Unify the PHY link detection code. Obtained from: Navdeep Parhar MFC after: 10 days --- sys/dev/cxgb/common/cxgb_ael1002.c | 5 +- sys/dev/cxgb/common/cxgb_common.h | 1 - sys/dev/cxgb/common/cxgb_t3_hw.c | 214 ++++++++++++++++++----------- sys/dev/cxgb/cxgb_adapter.h | 14 +- sys/dev/cxgb/cxgb_main.c | 121 ++++------------ sys/dev/cxgb/cxgb_sge.c | 5 + 6 files changed, 177 insertions(+), 183 deletions(-) diff --git a/sys/dev/cxgb/common/cxgb_ael1002.c b/sys/dev/cxgb/common/cxgb_ael1002.c index 3bc67e2ab9a5..c92abda4c364 100644 --- a/sys/dev/cxgb/common/cxgb_ael1002.c +++ b/sys/dev/cxgb/common/cxgb_ael1002.c @@ -1156,6 +1156,7 @@ static int get_module_type(struct cphy *phy) v = ael_i2c_rd(phy, MODULE_DEV_ADDR, 131); if (v < 0) return v; + v &= 0xf0; if (v == 0x10) return phy_modtype_lrm; if (v == 0x40) @@ -1245,7 +1246,9 @@ static int ael2005_reset(struct cphy *phy, int wait) return err; phy->modtype = (u8)err; - if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) + if (err == phy_modtype_none || err == phy_modtype_unknown) + err = 0; + else if (err == phy_modtype_twinax || err == phy_modtype_twinax_long) err = ael2005_setup_twinax_edc(phy, err); else err = ael2005_setup_sr_edc(phy); diff --git a/sys/dev/cxgb/common/cxgb_common.h b/sys/dev/cxgb/common/cxgb_common.h index e0d94b8fc78b..09e78407307c 100644 --- a/sys/dev/cxgb/common/cxgb_common.h +++ b/sys/dev/cxgb/common/cxgb_common.h @@ -701,7 +701,6 @@ int t3_slow_intr_handler(adapter_t *adapter); int t3_phy_intr_handler(adapter_t *adapter); void t3_link_changed(adapter_t *adapter, int port_id); -void t3_link_fault(adapter_t *adapter, int port_id); int t3_link_start(struct cphy *phy, struct cmac *mac, struct link_config *lc); const struct adapter_info *t3_get_adapter_info(unsigned int board_id); int t3_seeprom_read(adapter_t *adapter, u32 addr, u32 *data); diff --git a/sys/dev/cxgb/common/cxgb_t3_hw.c b/sys/dev/cxgb/common/cxgb_t3_hw.c index 5d734dd42986..5d6711e46870 100644 --- a/sys/dev/cxgb/common/cxgb_t3_hw.c +++ b/sys/dev/cxgb/common/cxgb_t3_hw.c @@ -1285,6 +1285,49 @@ static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg, t3_write_reg(mac->adapter, A_XGM_RX_HASH_LOW, rx_hash_low); } +static int t3_detect_link_fault(adapter_t *adapter, int port_id) +{ + struct port_info *pi = adap2pinfo(adapter, port_id); + struct cmac *mac = &pi->mac; + uint32_t rx_cfg, rx_hash_high, rx_hash_low; + int link_fault; + + /* stop rx */ + t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); + + /* clear status and make sure intr is enabled */ + (void) t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + t3_xgm_intr_enable(adapter, port_id); + + /* restart rx */ + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN); + t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); + + link_fault = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + return (link_fault & F_LINKFAULTCHANGE ? 1 : 0); +} + +static void t3_clear_faults(adapter_t *adapter, int port_id) +{ + struct port_info *pi = adap2pinfo(adapter, port_id); + struct cmac *mac = &pi->mac; + + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, + F_ENDROPPKT, 0); + t3_mac_enable(mac, MAC_DIRECTION_TX | MAC_DIRECTION_RX); + t3_set_reg_field(adapter, A_XGM_STAT_CTRL + mac->offset, F_CLRSTATS, 1); + + if (adapter->params.nports <= 2) { + t3_xgm_intr_disable(adapter, pi->port_id); + t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); + t3_write_reg(adapter, A_XGM_INT_CAUSE + mac->offset, F_XGM_INT); + t3_set_reg_field(adapter, A_XGM_INT_ENABLE + mac->offset, + F_XGM_INT, F_XGM_INT); + t3_xgm_intr_enable(adapter, pi->port_id); + } +} + /** * t3_link_changed - handle interface link changes * @adapter: the adapter @@ -1296,34 +1339,47 @@ static void t3_open_rx_traffic(struct cmac *mac, u32 rx_cfg, */ void t3_link_changed(adapter_t *adapter, int port_id) { - int link_ok, speed, duplex, fc; + int link_ok, speed, duplex, fc, link_fault, link_change; struct port_info *pi = adap2pinfo(adapter, port_id); struct cphy *phy = &pi->phy; struct cmac *mac = &pi->mac; struct link_config *lc = &pi->link_config; - int force_link_down = 0; + + link_ok = lc->link_ok; + speed = lc->speed; + duplex = lc->duplex; + fc = lc->fc; + link_fault = 0; phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); - if (!lc->link_ok && link_ok && adapter->params.nports <= 2) { - u32 rx_cfg, rx_hash_high, rx_hash_low; - u32 status; + /* + * Check for link faults if any of these is true: + * a) A link fault is suspected, and PHY says link ok + * b) PHY link transitioned from down -> up + */ + if (adapter->params.nports <= 2 && + ((pi->link_fault && link_ok) || (!lc->link_ok && link_ok))) { - t3_xgm_intr_enable(adapter, port_id); - t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); - t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); - t3_mac_enable(mac, MAC_DIRECTION_RX); + link_fault = t3_detect_link_fault(adapter, port_id); + if (link_fault) { + if (pi->link_fault != LF_YES) { + mac->stats.link_faults++; + pi->link_fault = LF_YES; + } - status = t3_read_reg(adapter, A_XGM_INT_STATUS + mac->offset); - if (status & F_LINKFAULTCHANGE) { - mac->stats.link_faults++; - force_link_down = 1; - } - t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); + /* Don't report link up or any other change */ + link_ok = 0; + speed = lc->speed; + duplex = lc->duplex; + fc = lc->fc; + } else { + /* clear faults here if this was a false alarm. */ + if (pi->link_fault == LF_MAYBE && + link_ok && lc->link_ok) + t3_clear_faults(adapter, port_id); - if (force_link_down) { - t3_os_link_fault_handler(adapter, port_id); - return; + pi->link_fault = LF_NO; } } @@ -1336,77 +1392,67 @@ void t3_link_changed(adapter_t *adapter, int port_id) duplex == lc->duplex && fc == lc->fc) return; /* nothing changed */ - if (link_ok != lc->link_ok && adapter->params.rev > 0 && - uses_xaui(adapter)) { - if (link_ok) - t3b_pcs_reset(mac); - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, - link_ok ? F_TXACTENABLE | F_RXEN : 0); - } + link_change = link_ok != lc->link_ok; lc->link_ok = (unsigned char)link_ok; lc->speed = speed < 0 ? SPEED_INVALID : speed; lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; - if (link_ok && speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { - /* Set MAC speed, duplex, and flow control to match PHY. */ - t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); - lc->fc = (unsigned char)fc; + if (link_ok) { + + /* down -> up, or up -> up with changed settings */ + + if (link_change && adapter->params.rev > 0 && + uses_xaui(adapter)) { + t3b_pcs_reset(mac); + t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, + F_TXACTENABLE | F_RXEN); + } + + if (speed >= 0 && lc->autoneg == AUTONEG_ENABLE) { + /* Set MAC settings to match PHY. */ + t3_mac_set_speed_duplex_fc(mac, speed, duplex, fc); + lc->fc = (unsigned char)fc; + } + + t3_clear_faults(adapter, port_id); + + } else { + + /* up -> down */ + + if (adapter->params.rev > 0 && uses_xaui(adapter)) { + t3_write_reg(adapter, + A_XGM_XAUI_ACT_CTRL + mac->offset, 0); + } + + t3_xgm_intr_disable(adapter, pi->port_id); + if (adapter->params.nports <= 2) { + t3_set_reg_field(adapter, + A_XGM_INT_ENABLE + mac->offset, + F_XGM_INT, 0); + } + + if (!link_fault) { + if (is_10G(adapter)) + pi->phy.ops->power_down(&pi->phy, 1); + t3_mac_disable(mac, MAC_DIRECTION_RX); + t3_link_start(phy, mac, lc); + } + + /* + * Make sure Tx FIFO continues to drain, even as rxen is left + * high to help detect and indicate remote faults. + */ + t3_set_reg_field(adapter, A_XGM_TXFIFO_CFG + mac->offset, 0, + F_ENDROPPKT); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); + t3_write_reg(adapter, A_XGM_TX_CTRL + mac->offset, F_TXEN); + t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, F_RXEN); } t3_os_link_changed(adapter, port_id, link_ok, speed, duplex, fc); } -void t3_link_fault(adapter_t *adapter, int port_id) -{ - struct port_info *pi = adap2pinfo(adapter, port_id); - struct cmac *mac = &pi->mac; - struct cphy *phy = &pi->phy; - struct link_config *lc = &pi->link_config; - int link_ok, speed, duplex, fc, link_fault; - u32 rx_cfg, rx_hash_high, rx_hash_low; - - if (!pi->link_fault) - return; /* nothing to do */ - - t3_gate_rx_traffic(mac, &rx_cfg, &rx_hash_high, &rx_hash_low); - - if (adapter->params.rev > 0 && uses_xaui(adapter)) - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, 0); - - t3_write_reg(adapter, A_XGM_RX_CTRL + mac->offset, 0); - t3_mac_enable(mac, MAC_DIRECTION_RX); - - t3_open_rx_traffic(mac, rx_cfg, rx_hash_high, rx_hash_low); - - link_fault = t3_read_reg(adapter, - A_XGM_INT_STATUS + mac->offset); - link_fault &= F_LINKFAULTCHANGE; - - phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc); - - if (link_fault) { - lc->link_ok = 0; - lc->speed = SPEED_INVALID; - lc->duplex = DUPLEX_INVALID; - - t3_os_link_fault(adapter, port_id, 0); - - /* Account link faults only when the phy reports a link up */ - if (link_ok) - mac->stats.link_faults++; - } else { - if (link_ok) - t3_write_reg(adapter, A_XGM_XAUI_ACT_CTRL + mac->offset, - F_TXACTENABLE | F_RXEN); - - pi->link_fault = 0; - lc->link_ok = (unsigned char)link_ok; - lc->speed = speed < 0 ? SPEED_INVALID : speed; - lc->duplex = duplex < 0 ? DUPLEX_INVALID : duplex; - t3_os_link_fault(adapter, port_id, link_ok); - } -} - /** * t3_link_start - apply link configuration to MAC/PHY * @phy: the PHY to setup @@ -1901,10 +1947,12 @@ static void mc7_intr_handler(struct mc7 *mc7) static int mac_intr_handler(adapter_t *adap, unsigned int idx) { u32 cause; + struct port_info *pi; struct cmac *mac; idx = idx == 0 ? 0 : adapter_info(adap)->nports0; /* MAC idx -> port */ - mac = &adap2pinfo(adap, idx)->mac; + pi = adap2pinfo(adap, idx); + mac = &pi->mac; /* * We mask out interrupt causes for which we're not taking interrupts. @@ -1937,9 +1985,9 @@ static int mac_intr_handler(adapter_t *adap, unsigned int idx) t3_set_reg_field(adap, A_XGM_INT_ENABLE + mac->offset, F_XGM_INT, 0); - mac->stats.link_faults++; - t3_os_link_fault_handler(adap, idx); + /* link fault suspected */ + pi->link_fault = LF_MAYBE; } t3_write_reg(adap, A_XGM_INT_CAUSE + mac->offset, cause); diff --git a/sys/dev/cxgb/cxgb_adapter.h b/sys/dev/cxgb/cxgb_adapter.h index d8dcb12c2bbe..930c97351a27 100644 --- a/sys/dev/cxgb/cxgb_adapter.h +++ b/sys/dev/cxgb/cxgb_adapter.h @@ -100,6 +100,12 @@ extern int cxgb_debug; #define SX_DESTROY sx_destroy #endif +enum { + LF_NO = 0, + LF_MAYBE, + LF_YES +}; + struct port_info { struct adapter *adapter; struct ifnet *ifp; @@ -123,7 +129,6 @@ struct port_info { uint8_t hw_addr[ETHER_ADDR_LEN]; struct task timer_reclaim_task; - struct task link_fault_task; struct cdev *port_cdev; #define PORT_LOCK_NAME_LEN 32 @@ -393,6 +398,7 @@ struct adapter { device_t portdev[MAX_NPORTS]; struct t3cdev tdev; char fw_version[64]; + char port_types[MAX_NPORTS + 1]; uint32_t open_device_map; uint32_t registered_device_map; #ifdef USE_SX @@ -435,6 +441,7 @@ struct t3_rx_mode { #define ADAPTER_LOCK_INIT(adap, name) SX_INIT(&(adap)->lock, name) #define ADAPTER_LOCK_DEINIT(adap) SX_DESTROY(&(adap)->lock) #define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) sx_assert(&(adap)->lock, SA_UNLOCKED) +#define ADAPTER_LOCK_ASSERT_OWNED(adap) sx_assert(&(adap)->lock, SA_LOCKED) #else #define PORT_LOCK(port) mtx_lock(&(port)->lock); #define PORT_UNLOCK(port) mtx_unlock(&(port)->lock); @@ -446,7 +453,8 @@ struct t3_rx_mode { #define ADAPTER_UNLOCK(adap) mtx_unlock(&(adap)->lock); #define ADAPTER_LOCK_INIT(adap, name) mtx_init(&(adap)->lock, name, 0, MTX_DEF) #define ADAPTER_LOCK_DEINIT(adap) mtx_destroy(&(adap)->lock) -#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MO_NOTOWNED) +#define ADAPTER_LOCK_ASSERT_NOTOWNED(adap) mtx_assert(&(adap)->lock, MA_NOTOWNED) +#define ADAPTER_LOCK_ASSERT_OWNED(adap) mtx_assert(&(adap)->lock, MA_OWNED) #endif @@ -530,8 +538,6 @@ int t3_os_pci_restore_state(struct adapter *adapter); void t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, int duplex, int fc); void t3_os_phymod_changed(struct adapter *adap, int port_id); -void t3_os_link_fault(adapter_t *adapter, int port_id, int state); -void t3_os_link_fault_handler(adapter_t *adapter, int port_id); void t3_sge_err_intr_handler(adapter_t *adapter); int t3_offload_tx(struct t3cdev *, struct mbuf *); void t3_os_ext_intr_handler(adapter_t *adapter); diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 9639037a95cd..e51002559563 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -115,7 +115,7 @@ static int offload_open(struct port_info *pi); static void touch_bars(device_t dev); static int offload_close(struct t3cdev *tdev); static void cxgb_link_start(struct port_info *p); -static void cxgb_link_fault(void *arg, int ncount); +int t3_detect_link_fault(adapter_t *adapter, int port_id); static device_method_t cxgb_controller_methods[] = { DEVMETHOD(device_probe, cxgb_controller_probe), @@ -650,6 +650,10 @@ cxgb_controller_attach(device_t dev) sc->params.vpd.ec, sc->params.vpd.sn); device_set_desc_copy(dev, buf); + snprintf(&sc->port_types[0], sizeof(sc->port_types), "%x%x%x%x", + sc->params.vpd.port_type[0], sc->params.vpd.port_type[1], + sc->params.vpd.port_type[2], sc->params.vpd.port_type[3]); + device_printf(sc->dev, "Firmware Version %s\n", &sc->fw_version[0]); callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_add_attach_sysctls(sc); @@ -1069,8 +1073,6 @@ cxgb_port_attach(device_t dev) bcopy(IF_LLADDR(p->ifp), p->hw_addr, ETHER_ADDR_LEN); t3_sge_init_port(p); - TASK_INIT(&p->link_fault_task, 0, cxgb_link_fault, p); - /* If it's MSI or INTx, allocate a single interrupt for everything */ if ((sc->flags & USING_MSIX) == 0) { if ((sc->irq_res = bus_alloc_resource_any(sc->dev, SYS_RES_IRQ, @@ -1257,32 +1259,6 @@ t3_os_pci_restore_state(struct adapter *sc) return (0); } -void t3_os_link_fault(struct adapter *adap, int port_id, int state) -{ - struct port_info *pi = &adap->port[port_id]; - - if (!state) { - if_link_state_change(pi->ifp, LINK_STATE_DOWN); - return; - } - - if (adap->params.nports <= 2) { - struct cmac *mac = &pi->mac; - - /* Clear local faults */ - t3_xgm_intr_disable(adap, port_id); - t3_read_reg(adap, A_XGM_INT_STATUS + pi->mac.offset); - t3_write_reg(adap, A_XGM_INT_CAUSE + pi->mac.offset, F_XGM_INT); - - t3_set_reg_field(adap, A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, F_XGM_INT); - t3_xgm_intr_enable(adap, pi->port_id); - t3_mac_enable(mac, MAC_DIRECTION_TX); - } - - if_link_state_change(pi->ifp, LINK_STATE_UP); -} - /** * t3_os_link_changed - handle link status changes * @adapter: the adapter associated with the link change @@ -1301,48 +1277,12 @@ t3_os_link_changed(adapter_t *adapter, int port_id, int link_status, int speed, int duplex, int fc) { struct port_info *pi = &adapter->port[port_id]; - struct cmac *mac = &adapter->port[port_id].mac; if (link_status) { - DELAY(10); - t3_mac_enable(mac, MAC_DIRECTION_RX | MAC_DIRECTION_TX); - /* Clear errors created by MAC enable */ - t3_set_reg_field(adapter, A_XGM_STAT_CTRL + pi->mac.offset, - F_CLRSTATS, 1); - - if (adapter->params.nports <= 2) { - /* Clear local faults */ - t3_xgm_intr_disable(adapter, pi->port_id); - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - t3_write_reg(adapter, A_XGM_INT_CAUSE + pi->mac.offset, - F_XGM_INT); - - t3_set_reg_field(adapter, - A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, F_XGM_INT); - t3_xgm_intr_enable(adapter, pi->port_id); - } - + pi->ifp->if_baudrate = IF_Mbps(speed); if_link_state_change(pi->ifp, LINK_STATE_UP); - } else { - t3_xgm_intr_disable(adapter, pi->port_id); - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - if (adapter->params.nports <= 2) { - t3_set_reg_field(adapter, - A_XGM_INT_ENABLE + pi->mac.offset, - F_XGM_INT, 0); - } - - /* PR 5666. We shouldn't power down 1G phys */ - if (is_10G(adapter)) - pi->phy.ops->power_down(&pi->phy, 1); - - t3_read_reg(adapter, A_XGM_INT_STATUS + pi->mac.offset); - t3_mac_disable(mac, MAC_DIRECTION_RX); - t3_link_start(&pi->phy, mac, &pi->link_config); - + } else if_link_state_change(pi->ifp, LINK_STATE_DOWN); - } } /** @@ -1395,22 +1335,6 @@ t3_os_ext_intr_handler(adapter_t *sc) ADAPTER_UNLOCK(sc); } -static void -cxgb_link_fault(void *arg, int ncount) -{ - struct port_info *pi = arg; - - t3_link_fault(pi->adapter, pi->port_id); -} - -void t3_os_link_fault_handler(struct adapter *sc, int port_id) -{ - struct port_info *pi = &sc->port[port_id]; - - pi->link_fault = 1; - taskqueue_enqueue(sc->tq, &pi->link_fault_task); -} - void t3_os_set_hw_addr(adapter_t *adapter, int port_idx, u8 hw_addr[]) { @@ -1966,15 +1890,16 @@ cxgb_init_locked(struct port_info *p) log(LOG_WARNING, "Could not initialize offload capabilities\n"); } + + device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id); + t3_port_intr_enable(sc, p->port_id); + #if !defined(LINK_ATTACH) cxgb_link_start(p); t3_link_changed(sc, p->port_id); #endif ifp->if_baudrate = IF_Mbps(p->link_config.speed); - device_printf(sc->dev, "enabling interrupts on port=%d\n", p->port_id); - t3_port_intr_enable(sc, p->port_id); - callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_sge_reset_adapter(sc); @@ -2338,12 +2263,23 @@ check_link_status(adapter_t *sc) { int i; + /* For synchronized access to open_device_map */ + ADAPTER_LOCK_ASSERT_OWNED(sc); + for (i = 0; i < (sc)->params.nports; ++i) { struct port_info *p = &sc->port[i]; + struct link_config *lc = &p->link_config; - if (!(p->phy.caps & SUPPORTED_IRQ)) + if (!isset(&sc->open_device_map, p->port_id)) { + /* + * port is down, report link down too. Note + * that we do this for IRQ based PHYs too. + */ + lc->link_ok = 0; + t3_os_link_changed(sc, i, lc->link_ok, lc->speed, + lc->duplex, lc->fc); + } else if (p->link_fault || !(p->phy.caps & SUPPORTED_IRQ)) t3_link_changed(sc, i); - p->ifp->if_baudrate = IF_Mbps(p->link_config.speed); } } @@ -2410,12 +2346,12 @@ cxgb_tick_handler(void *arg, int count) int i; uint32_t cause, reset; - if(sc->flags & CXGB_SHUTDOWN) + if(sc->flags & CXGB_SHUTDOWN || !(sc->flags & FULL_INIT_DONE)) return; ADAPTER_LOCK(sc); - if (p->linkpoll_period) - check_link_status(sc); + + check_link_status(sc); sc->check_task_cnt++; @@ -2457,9 +2393,6 @@ cxgb_tick_handler(void *arg, int count) t3_mac_update_stats(mac); PORT_UNLOCK(pi); - if (pi->link_fault) - taskqueue_enqueue(sc->tq, &pi->link_fault_task); - ifp->if_opackets = mstats->tx_frames_64 + mstats->tx_frames_65_127 + diff --git a/sys/dev/cxgb/cxgb_sge.c b/sys/dev/cxgb/cxgb_sge.c index 47f36fd5e1cd..f0a3694cb5c7 100644 --- a/sys/dev/cxgb/cxgb_sge.c +++ b/sys/dev/cxgb/cxgb_sge.c @@ -3349,6 +3349,10 @@ t3_add_attach_sysctls(adapter_t *sc) "hw_revision", CTLFLAG_RD, &sc->params.rev, 0, "chip model"); + SYSCTL_ADD_STRING(ctx, children, OID_AUTO, + "port_types", + CTLFLAG_RD, &sc->port_types, + 0, "type of ports"); SYSCTL_ADD_INT(ctx, children, OID_AUTO, "enable_debug", CTLFLAG_RW, &cxgb_debug, @@ -3680,6 +3684,7 @@ t3_add_configured_sysctls(adapter_t *sc) CXGB_SYSCTL_ADD_ULONG(xaui_pcs_align_change); CXGB_SYSCTL_ADD_ULONG(num_toggled); CXGB_SYSCTL_ADD_ULONG(num_resets); + CXGB_SYSCTL_ADD_ULONG(link_faults); #undef CXGB_SYSCTL_ADD_ULONG } } From fedda42340cd272bb1d9601a0f797cdb29a49fc2 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 21 May 2009 15:30:29 +0000 Subject: [PATCH 377/544] o remove bpf tap call missed in r192468 o correct rssi taken from rx descriptor; need dbm --- sys/dev/iwi/if_iwi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index dcfde7e14d02..a551448c6907 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -1274,7 +1274,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame)); - rssi = frame->signal; + rssi = frame->rssi_dbm; nf = -95; if (ieee80211_radiotap_active(ic)) { struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap; @@ -1960,8 +1960,6 @@ iwi_start_locked(struct ifnet *ifp) break; } - BPF_MTAP(ifp, m); - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; if (iwi_tx_start(ifp, m, ni, ac) != 0) { ieee80211_free_node(ni); From 07f8bbea053d809b36d9011aea85b71e3313487c Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 21 May 2009 15:30:59 +0000 Subject: [PATCH 378/544] rssi/nf data are now dbm, tag them accordingly --- sys/dev/iwi/if_iwivar.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index 1acb6c3e69a6..7a11d888bcfc 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -42,8 +42,8 @@ struct iwi_rx_radiotap_header { ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_RATE) | \ (1 << IEEE80211_RADIOTAP_CHANNEL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \ - (1 << IEEE80211_RADIOTAP_DB_ANTNOISE) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \ + (1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \ (1 << IEEE80211_RADIOTAP_ANTENNA)) struct iwi_tx_radiotap_header { From d422da9a0a969d4a1b82327fb10d63214e59cabc Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 21 May 2009 16:18:45 +0000 Subject: [PATCH 379/544] Only use the ABI compat shim for vfs.bufspace if the old buffer is smaller than a long. PR: amd64/134786 Submitted by: Emil Mikulic emikulic| gmail MFC after: 3 days --- sys/kern/vfs_bio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 16df88959ee5..a3c3e97823a8 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -293,7 +293,7 @@ sysctl_bufspace(SYSCTL_HANDLER_ARGS) long lvalue; int ivalue; - if (sizeof(int) == sizeof(long) || req->oldlen == sizeof(long)) + if (sizeof(int) == sizeof(long) || req->oldlen >= sizeof(long)) return (sysctl_handle_long(oidp, arg1, arg2, req)); lvalue = *(long *)arg1; if (lvalue > INT_MAX) From 770c15f60f023900ca40d1d91ee89ba3b08df29a Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 21 May 2009 16:19:54 +0000 Subject: [PATCH 380/544] Add a new sysctl: kern.tty_inq_flush_secure. When enabled all TTY input queue buffers are zeroed when flushing or closing the TTY. Because TTY input queues are also used to store filled in passwords, this may be an interesting switch to enable for security minded people. --- sys/kern/tty_inq.c | 22 ++++++++-------------- 1 file changed, 8 insertions(+), 14 deletions(-) diff --git a/sys/kern/tty_inq.c b/sys/kern/tty_inq.c index 60a13de4e0e1..0ef407935056 100644 --- a/sys/kern/tty_inq.c +++ b/sys/kern/tty_inq.c @@ -68,6 +68,9 @@ SYSCTL_ULONG(_kern, OID_AUTO, tty_inq_nfast, CTLFLAG_RD, static unsigned long ttyinq_nslow = 0; SYSCTL_ULONG(_kern, OID_AUTO, tty_inq_nslow, CTLFLAG_RD, &ttyinq_nslow, 0, "Buffered reads to userspace on input"); +static int ttyinq_flush_secure = 0; +SYSCTL_INT(_kern, OID_AUTO, tty_inq_flush_secure, CTLFLAG_RW, + &ttyinq_flush_secure, 0, "Zero buffers while flushing"); #define TTYINQ_QUOTESIZE (TTYINQ_DATASIZE / BMSIZE) #define BMSIZE 32 @@ -376,28 +379,19 @@ ttyinq_findchar(struct ttyinq *ti, const char *breakc, size_t maxlen, void ttyinq_flush(struct ttyinq *ti) { + struct ttyinq_block *tib = ti->ti_lastblock; ti->ti_begin = 0; ti->ti_linestart = 0; ti->ti_reprint = 0; ti->ti_end = 0; -} -#if 0 -void -ttyinq_flush_safe(struct ttyinq *ti) -{ - struct ttyinq_block *tib; - - ttyinq_flush(ti); - - /* Zero all data in the input queue to make it more safe */ - TAILQ_FOREACH(tib, &ti->ti_list, tib_list) { - bzero(&tib->tib_quotes, sizeof tib->tib_quotes); - bzero(&tib->tib_data, sizeof tib->tib_data); + /* Zero all data in the input queue to get rid of passwords. */ + if (ttyinq_flush_secure) { + for (tib = ti->ti_firstblock; tib != NULL; tib = tib->tib_next) + bzero(&tib->tib_data, sizeof tib->tib_data); } } -#endif int ttyinq_peekchar(struct ttyinq *ti, char *c, int *quote) From 46bd01cb3371ebf86ff3686647abd7220c198808 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Thu, 21 May 2009 16:27:47 +0000 Subject: [PATCH 381/544] Modify src/etc/mtree/BSD.include.dist and src/include/Makefile so that the .h files in src/sys/fs/nfs will be installed under /usr/include/fs/nfs. This will allow the following utilities to build, once additions and changes for the experimental nfs subsystem are committed: usr.sbin/mountd - Once modified to add support for the experimental nfs subsystem. ur.sbin/nfsstat - Once modified to add support for the experimental nfs subsystem. usr.sbin/nfscbd - The client side callback daemon for NFSv4. usr.sbin/nfsuserd - The NFSv4 user/group name<->uid/gid mapping daemon. usr.sbin/nfsdumpstate - The NFSv4 utility for dumping open/lock state. usr.sbin/nfsrevoke - The sysadmin command for revoking NFSv4 state. Approved by: kib (mentor) --- etc/mtree/BSD.include.dist | 2 ++ include/Makefile | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 6358071e02b1..5b953b59dd7d 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -136,6 +136,8 @@ .. msdosfs .. + nfs + .. ntfs .. nullfs diff --git a/include/Makefile b/include/Makefile index 6e116c4b40a8..150a030f929b 100644 --- a/include/Makefile +++ b/include/Makefile @@ -43,7 +43,7 @@ LSUBDIRS= cam/scsi \ dev/ic dev/iicbus ${_dev_ieee488} dev/lmc dev/ofw \ dev/pbio ${_dev_powermac_nvram} dev/ppbus dev/smbus \ dev/speaker dev/usb dev/utopia dev/vkbd dev/wi \ - fs/devfs fs/fdescfs fs/fifofs fs/msdosfs fs/ntfs fs/nullfs \ + fs/devfs fs/fdescfs fs/fifofs fs/msdosfs fs/nfs fs/ntfs fs/nullfs \ ${_fs_nwfs} fs/portalfs fs/procfs fs/smbfs fs/udf fs/unionfs \ geom/cache geom/concat geom/eli geom/gate geom/journal geom/label \ geom/mirror geom/multipath geom/nop \ From 52f542a8e499110296a92389a6469c081321835f Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Thu, 21 May 2009 16:48:06 +0000 Subject: [PATCH 382/544] Enable secure TTY input buffer flushing by default. I'm leaving the sysctl there. If people really notice a slowdown, they can revert to the old behaviour. Discussed with: kib --- sys/kern/tty_inq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/tty_inq.c b/sys/kern/tty_inq.c index 0ef407935056..c618a0ad1a5d 100644 --- a/sys/kern/tty_inq.c +++ b/sys/kern/tty_inq.c @@ -68,7 +68,7 @@ SYSCTL_ULONG(_kern, OID_AUTO, tty_inq_nfast, CTLFLAG_RD, static unsigned long ttyinq_nslow = 0; SYSCTL_ULONG(_kern, OID_AUTO, tty_inq_nslow, CTLFLAG_RD, &ttyinq_nslow, 0, "Buffered reads to userspace on input"); -static int ttyinq_flush_secure = 0; +static int ttyinq_flush_secure = 1; SYSCTL_INT(_kern, OID_AUTO, tty_inq_flush_secure, CTLFLAG_RW, &ttyinq_flush_secure, 0, "Zero buffers while flushing"); From 0ed39d3ec48b552102d2f0a906cd599c70a184a1 Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Thu, 21 May 2009 17:01:38 +0000 Subject: [PATCH 383/544] Pullup svn source to p4 top of tree: * Fix LOR in MLDv2 query input path. * Strip embedded KAME scope IDs for on-wire IPv6 address comparisons. --- sys/netinet6/mld6.c | 50 +++++++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 15 deletions(-) diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index 42046971e078..c24ceba2fe8d 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -629,8 +629,8 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, #endif IN6_MULTI_LOCK(); - IF_ADDR_LOCK(ifp); MLD_LOCK(); + IF_ADDR_LOCK(ifp); mli = MLD_IFINFO(ifp); KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp)); @@ -661,12 +661,12 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, /* * MLDv1 General Query. * If this was not sent to the all-nodes group, ignore it. - * - * XXX Do we need to check for a scope ID in the destination - * address on input and strip it? */ - if (IN6_ARE_ADDR_EQUAL(&ip6->ip6_dst, - &in6addr_linklocal_allnodes)) { + struct in6_addr dst; + + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes)) { /* * For each reporting group joined on this * interface, kick the report timer. @@ -685,8 +685,8 @@ mld_v1_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, } } - MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); + MLD_UNLOCK(); IN6_MULTI_UNLOCK(); return (0); @@ -807,8 +807,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, return (EMSGSIZE); IN6_MULTI_LOCK(); - IF_ADDR_LOCK(ifp); MLD_LOCK(); + IF_ADDR_LOCK(ifp); mli = MLD_IFINFO(ifp); KASSERT(mli != NULL, ("%s: no mld_ifinfo for ifp %p", __func__, ifp)); @@ -819,17 +819,25 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, mli->mli_qi = qqi; mli->mli_qri = maxdelay; - CTR4(KTR_MLD, "%s: qrv %d qi %d qri %d", __func__, qrv, qqi, + CTR4(KTR_MLD, "%s: qrv %d qi %d maxdelay %d", __func__, qrv, qqi, maxdelay); if (IN6_IS_ADDR_UNSPECIFIED(&mld->mld_addr)) { /* * MLDv2 General Query. + * * Schedule a current-state report on this ifp for * all groups, possibly containing source lists. + * + * Strip scope ID embedded by ip6_input(). We do not need + * to do this for the MLD payload. */ - if (!IN6_ARE_ADDR_EQUAL(&in6addr_linklocal_allnodes, - &ip6->ip6_dst) || nsrc > 0) { + struct in6_addr dst; + + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (!IN6_ARE_ADDR_EQUAL(&dst, &in6addr_linklocal_allnodes) || + nsrc > 0) { /* * General Queries SHOULD be directed to ff02::1. * A general query with a source list has undefined @@ -885,8 +893,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, } out_locked: - MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); + MLD_UNLOCK(); IN6_MULTI_UNLOCK(); return (0); @@ -1016,15 +1024,19 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6, { struct in6_ifaddr *ia; struct in6_multi *inm; + struct in6_addr src, dst; #ifdef KTR char ip6tbuf[INET6_ADDRSTRLEN]; #endif if (ifp->if_flags & IFF_LOOPBACK) return (0); + if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr)) + return (EINVAL); - if (!IN6_IS_ADDR_MULTICAST(&mld->mld_addr) || - !IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &ip6->ip6_dst)) + dst = ip6->ip6_dst; + in6_clearscope(&dst); + if (!IN6_ARE_ADDR_EQUAL(&mld->mld_addr, &dst)) return (EINVAL); /* @@ -1032,16 +1044,23 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6, * leave requires knowing that we are the only member of a * group. Assume we used the link-local address if available, * otherwise look for ::. + * + * XXX Note that scope ID comparison is needed for the address + * returned by in6ifa_ifpforlinklocal(), but SHOULD NOT be + * performed for the on-wire address. */ ia = in6ifa_ifpforlinklocal(ifp, IN6_IFF_NOTREADY|IN6_IFF_ANYCAST); + src = ip6->ip6_src; + in6_clearscope(&src); if ((ia && IN6_ARE_ADDR_EQUAL(&ip6->ip6_src, IA6_IN6(ia))) || - (ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src))) + (ia == NULL && IN6_IS_ADDR_UNSPECIFIED(&src))) return (0); CTR3(KTR_MLD, "process v1 report %s on ifp %p(%s)", ip6_sprintf(ip6tbuf, &mld->mld_addr), ifp, ifp->if_xname); IN6_MULTI_LOCK(); + MLD_LOCK(); IF_ADDR_LOCK(ifp); /* @@ -1090,6 +1109,7 @@ mld_v1_input_report(struct ifnet *ifp, const struct ip6_hdr *ip6, } out_locked: + MLD_UNLOCK(); IF_ADDR_UNLOCK(ifp); IN6_MULTI_UNLOCK(); From c54c1f7c08e26ef706ab475fde2118d1f21ea798 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:16:35 +0000 Subject: [PATCH 384/544] Fix libusb20_dev_get_device_desc and defunt xref. Submitted by: Hans Petter Selasky --- lib/libusb/libusb.3 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/libusb/libusb.3 b/lib/libusb/libusb.3 index 60979d5e25f4..1ab432e9e66b 100644 --- a/lib/libusb/libusb.3 +++ b/lib/libusb/libusb.3 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 5, 2009 +.Dd May 21, 2009 .Dt LIBUSB 3 .Os .Sh NAME @@ -148,8 +148,8 @@ USB access library (libusb -lusb) .Fn libusb20_dev_get_power_mode "struct libusb20_device *pdev" .Ft int .Fn libusb20_dev_set_alt_index "struct libusb20_device *pdev" "uint8_t iface_index" "uint8_t alt_index" -.Ft int -.Fn libusb20_dev_get_device_desc "struct libusb20_device *pdev" "uint8_t iface_indexr", "char *buf" "uint8_t len" +.Ft struct LIBUSB20_DEVICE_DESC_DECODED * +.Fn libusb20_dev_get_device_desc "struct libusb20_device *pdev" .Ft struct libusb20_config * .Fn libusb20_dev_alloc_config "struct libusb20_device *pdev" "uint8_t config_index" .Ft struct libusb20_device * @@ -945,7 +945,7 @@ These functions are compliant with LibUSB version 0.1.12. . /dev/usb .Sh SEE ALSO -.Xr usb2_core 4 , +.Xr usb 4 , .Xr usbconfig 8 . . From b47fd404524036034ac68b48d85e8f6f5c42fff3 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:26:20 +0000 Subject: [PATCH 385/544] Update usb(4) to match reality, remove section on permissions. Delete usb2_core.4. Submitted by: Hans Petter Selasky --- share/man/man4/usb.4 | 881 +++++++++++++++++++++++++------------ share/man/man4/usb2_core.4 | 635 -------------------------- 2 files changed, 594 insertions(+), 922 deletions(-) delete mode 100644 share/man/man4/usb2_core.4 diff --git a/share/man/man4/usb.4 b/share/man/man4/usb.4 index 665ab57fb0a6..4fcfd964e879 100644 --- a/share/man/man4/usb.4 +++ b/share/man/man4/usb.4 @@ -25,9 +25,32 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF .\" THE POSSIBILITY OF SUCH DAMAGE. .\" +.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" .\" $FreeBSD$ .\" -.Dd November 22, 2006 +.Dd May 20, 2009 .Dt USB 4 .Os .Sh NAME @@ -47,22 +70,29 @@ module at boot time, place the following line in .Bd -literal -offset indent usb_load="YES" .Ed -.Pp -.In dev/usb/usb.h -.In dev/usb/usbhid.h +.Sh USERLAND PROGRAMMING +USB functions can be accessed from userland through the libusb library. +See +.Xr libusb 3 +for more information. .Sh DESCRIPTION .Fx provides machine-independent bus support and drivers for .Tn USB -devices. +devices in host and device side mode. .Pp The .Nm -driver has three layers: the controller, the bus, and the -device layer. +driver has three layers: +.Bl -tag +.It USB Controller (Bus) +.It USB Device +.It USB Driver +.El +.Pp The controller attaches to a physical bus -(like -.Xr pci 4 ) . +like +.Xr pci 4 . The .Tn USB bus attaches to the controller, and the root hub attaches @@ -79,14 +109,20 @@ root hub. .Sh INTRODUCTION TO USB The .Tn USB -is a 12 Mb/s serial bus (1.5 Mb/s for low speed devices). +is a system where external devices can be connected to a PC. +The most common USB speeds are: +.Bl -tag +.It Low Speed (1.5MBit/sec) +.It Full Speed (12MBit/sec) +.It High Speed (480MBit/sec) +.El +.Pp Each .Tn USB -has a host controller that is the master of the bus; -all other devices on the bus only speak when spoken to. +has a USB controller that is the master of the bus. +The physical communication is simplex which means the host controller only communicates with one USB device at a time. .Pp -There can be up to 127 devices (apart from the host controller) -on a bus, each with its own address. +There can be up to 127 devices connected to an USB HUB tree. The addresses are assigned dynamically by the host when each device is attached to the bus. .Pp @@ -116,286 +152,558 @@ A device may operate in different configurations. Depending on the configuration, the device may present different sets of endpoints and interfaces. -.\" .Pp -.\" Each device located on a hub has several -.\" .Xr config 8 -.\" locators: -.\" .Bl -tag -compact -width xxxxxx -.\" .It Cd port -.\" this is the number of the port on the closest upstream hub. -.\" .It Cd configuration -.\" this is the configuration the device must be in for this driver to attach. -.\" This locator does not set the configuration; it is iterated by the bus -.\" enumeration. -.\" .It Cd interface -.\" this is the interface number within a device that an interface driver -.\" attaches to. -.\" .It Cd vendor -.\" this is the 16 bit vendor id of the device. -.\" .It Cd product -.\" this is the 16 bit product id of the device. -.\" .It Cd release -.\" this is the 16 bit release (revision) number of the device. -.\" .El -.\" The first locator can be used to pin down a particular device -.\" according to its physical position in the device tree. -.\" The last three locators can be used to pin down a particular -.\" device according to what device it actually is. .Pp The bus enumeration of the .Tn USB bus proceeds in several steps: .Bl -enum .It -Any device specific driver can attach to the device. +Any interface specific driver can attach to the device. .It -If none is found, any device class specific driver can attach. -.It -If none is found, all configurations are iterated over. -For each configuration, all the interfaces are iterated over, and interface -drivers can attach. -If any interface driver attached in a certain -configuration, the iteration over configurations is stopped. -.It -If still no drivers have been found, the generic -.Tn USB -driver can attach. +If none is found, generic interface class drivers can attach. .El -.Sh USB CONTROLLER INTERFACE -Use the following to get access to the -.Tn USB -specific structures and defines. +.Sh USB KERNEL PROGRAMMING +Here is a list of commonly used functions: .Pp -The -.Pa /dev/usb Ns Ar N -can be opened and a few operations can be performed on it. -The -.Xr poll 2 -system call will say that I/O is possible on the controller device when a -.Tn USB -device has been connected or disconnected to the bus. +. +.Ft "usb2_error_t" +.Fo "usb2_transfer_setup" +.Fa "udev" +.Fa "ifaces" +.Fa "pxfer" +.Fa "setup_start" +.Fa "n_setup" +.Fa "priv_sc" +.Fa "priv_mtx" +.Fc +. .Pp -The following -.Xr ioctl 2 -commands are supported on the controller device: -.Bl -tag -width xxxxxx -.It Dv USB_DISCOVER -This command will cause a complete bus discovery to be initiated. -If any devices attached or detached from the bus they will be -processed during this command. -This is the only way that new devices are found on the bus. -.It Dv USB_DEVICEINFO Vt "struct usb_device_info" -This command can be used to retrieve some information about a device -on the bus. +. +.Ft "void" +.Fo "usb2_transfer_unsetup" +.Fa "pxfer" +.Fa "n_setup" +.Fc +. +.Pp +. +.Ft "void" +.Fo "usb2_transfer_start" +.Fa "xfer" +.Fc +. +.Pp +. +.Ft "void" +.Fo "usb2_transfer_stop" +.Fa "xfer" +.Fc +. +.Pp +. +.Ft "void" +.Fo "usb2_transfer_drain" +.Fa "xfer" +.Fc +. +. +.Sh DESCRIPTION The -.Va udi_addr -field should be filled before the call and the other fields will -be filled by information about the device on that address. -Should no such device exist, an error is reported. -.Bd -literal -#define USB_MAX_DEVNAMES 4 -#define USB_MAX_DEVNAMELEN 16 -struct usb_device_info { - u_int8_t udi_bus; - u_int8_t udi_addr; /* device address */ - usb_event_cookie_t udi_cookie; - char udi_product[USB_MAX_STRING_LEN]; - char udi_vendor[USB_MAX_STRING_LEN]; - char udi_release[8]; - u_int16_t udi_productNo; - u_int16_t udi_vendorNo; - u_int16_t udi_releaseNo; - u_int8_t udi_class; - u_int8_t udi_subclass; - u_int8_t udi_protocol; - u_int8_t udi_config; - u_int8_t udi_speed; -#define USB_SPEED_LOW 1 -#define USB_SPEED_FULL 2 -#define USB_SPEED_HIGH 3 - int udi_power;/* power consumption in mA, 0 if selfpowered */ - int udi_nports; - char udi_devnames[USB_MAX_DEVNAMES][USB_MAX_DEVNAMELEN]; - u_int8_t udi_ports[16];/* hub only: addresses of devices on ports */ -#define USB_PORT_ENABLED 0xff -#define USB_PORT_SUSPENDED 0xfe -#define USB_PORT_POWERED 0xfd -#define USB_PORT_DISABLED 0xfc -}; +.Nm +module implements the core functionality of the USB standard and many +helper functions to make USB device driver programming easier and more +safe. +. +The +.Nm +module supports both USB Host and USB Device side mode! +. +.Sh USB TRANSFER MANAGEMENT FUNCTIONS +The USB standard defines four types of USB transfers. +. +Control transfers, Bulk transfers, Interrupt transfers and Isochronous +transfers. +. +All the transfer types are managed using the following five functions: +. +.Pp +. +.Fn usb2_transfer_setup +This function will allocate memory for and initialise an array of USB +transfers and all required DMA memory. +. +This function can sleep or block waiting for resources to become +available. +.Fa udev +is a pointer to "struct usb2_device". +.Fa ifaces +is an array of interface index numbers to use. See "if_index". +.Fa pxfer +is a pointer to an array of USB transfer pointers that are initialized +to NULL, and then pointed to allocated USB transfers. +.Fa setup_start +is a pointer to an array of USB config structures. +.Fa n_setup +is a number telling the USB system how many USB transfers should be +setup. +.Fa priv_sc +is the private softc pointer, which will be used to initialize +"xfer->priv_sc". +.Fa priv_mtx +is the private mutex protecting the transfer structure and the +softc. This pointer is used to initialize "xfer->priv_mtx". +This function returns +zero upon success. A non-zero return value indicates failure. +. +.Pp +. +.Fn usb2_transfer_unsetup +This function will release the given USB transfers and all allocated +resources associated with these USB transfers. +.Fa pxfer +is a pointer to an array of USB transfer pointers, that may be NULL, +that should be freed by the USB system. +.Fa n_setup +is a number telling the USB system how many USB transfers should be +unsetup. +. +This function can sleep waiting for USB transfers to complete. +. +This function is NULL safe with regard to the USB transfer structure +pointer. +. +It is not allowed to call this function from the USB transfer +callback. +. +.Pp +. +.Fn usb2_transfer_start +This function will start the USB transfer pointed to by +.Fa xfer, +if not already started. +. +This function is always non-blocking and must be called with the +so-called private USB mutex locked. +. +This function is NULL safe with regard to the USB transfer structure +pointer. +. +.Pp +. +.Fn usb2_transfer_stop +This function will stop the USB transfer pointed to by +.Fa xfer, +if not already stopped. +. +This function is always non-blocking and must be called with the +so-called private USB mutex locked. +. +This function can return before the USB callback has been called. +. +This function is NULL safe with regard to the USB transfer structure +pointer. +. +If the transfer was in progress, the callback will called with +"USB_ST_ERROR" and "xfer->error = USB_ERR_CANCELLED". +. +.Pp +. +.Fn usb2_transfer_drain +This function will stop an USB transfer, if not already stopped and +wait for any additional USB hardware operations to complete. +. +Buffers that are loaded into DMA using "usb2_set_frame_data()" can +safely be freed after that this function has returned. +. +This function can block the caller and will not return before the USB +callback has been called. +. +This function is NULL safe with regard to the USB transfer structure +pointer. +. +.Sh USB TRANSFER CALLBACK +. +The USB callback has three states. +. +USB_ST_SETUP, USB_ST_TRANSFERRED and USB_ST_ERROR. USB_ST_SETUP is the +initial state. +. +After the callback has been called with this state it will always be +called back at a later stage in one of the other two states. +. +In the USB_ST_ERROR state the "error" field of the USB transfer +structure is set to the error cause. +. +The USB callback should not restart the USB transfer in case the error +cause is USB_ERR_CANCELLED. +. +The USB callback is protected from recursion. +. +That means one can start and stop whatever transfer from the callback +of another transfer one desires. +. +Also the transfer that is currently called back. +. +Recursion is handled like this that when the callback that wants to +recurse returns it is called one more time. +. +. +.Pp +. +.Fn usb2_start_hardware +This function should only be called from within the USB callback and +is used to start the USB hardware. +. +Typical parameters that should be set in the USB transfer structure +before this function is called are "frlengths[]", "nframes" and +"frbuffers[]". +. +An USB transfer can have multiple frames consisting of one or more USB +packets making up an I/O vector for all USB transfer types. +. +After the USB transfer is complete "frlengths[]" is updated to the +actual USB transfer length for the given frame. +.Bd -literal -offset indent +void +usb2_default_callback(struct usb2_xfer *xfer) +{ + switch (USB_GET_STATE(xfer)) { + case USB_ST_SETUP: + /* + * Setup xfer->frlengths[], xfer->nframes + * and write data to xfer->frbuffers[], if any + */ + usb2_start_hardware(xfer); + break; + + case USB_ST_TRANSFERRED: + /* + * Read data from xfer->frbuffers[], if any. + * "xfer->frlengths[]" should now have been + * updated to the actual length. + */ + break; + + default: /* Error */ + /* + * Print error message and clear stall + * for example. + */ + break; + } + /* + * Here it is safe to do something without the private + * USB mutex locked. + */ + return; +} .Ed -.Pp -.Va udi_bus -and -.Va udi_addr -contain the topological information for the device. -.Va udi_devnames -contains the device names of the connected drivers. -For example, the -third -.Tn USB -Zip drive connected will be -.Li umass2 . -The -.Va udi_product , udi_vendor -and -.Va udi_release -fields contain self-explanatory descriptions of the device. -.Va udi_productNo , udi_vendorNo , udi_releaseNo , udi_class , udi_subclass -and -.Va udi_protocol -contain the corresponding values from the device descriptors. -The -.Va udi_config -field shows the current configuration of the device. -.Pp -.Va udi_speed -indicates whether the device is at low speed -.Pq Dv USB_SPEED_LOW , -full speed -.Pq Dv USB_SPEED_FULL -or high speed -.Pq Dv USB_SPEED_HIGH . -The -.Va udi_power -field shows the power consumption in milli-amps drawn at 5 volts, -or zero if the device is self powered. -.Pp -If the device is a hub, the -.Va udi_nports -field is non-zero, and the -.Va udi_ports -field contains the addresses of the connected devices. -If no device is connected to a port, one of the -.Dv USB_PORT_* -values indicates its status. -.It Dv USB_DEVICESTATS Vt "struct usb_device_stats" -This command retrieves statistics about the controller. -.Bd -literal -struct usb_device_stats { - u_long uds_requests[4]; -}; +. +.Sh USB CONTROL TRANSFERS +An USB control transfer has three parts. +. +First the SETUP packet, then DATA packet(s) and then a STATUS +packet. +. +The SETUP packet is always pointed to by "xfer->frbuffers[0]" and the +length is stored in "xfer->frlengths[0]" also if there should not be +sent any SETUP packet! If an USB control transfer has no DATA stage, +then "xfer->nframes" should be set to 1. +. +Else the default value is "xfer->nframes" equal to 2. +. +.Bd -literal -offset indent + +Example1: SETUP + STATUS + xfer->nframes = 1; + xfer->frlenghts[0] = 8; + usb2_start_hardware(xfer); + +Example2: SETUP + DATA + STATUS + xfer->nframes = 2; + xfer->frlenghts[0] = 8; + xfer->frlenghts[1] = 1; + usb2_start_hardware(xfer); + +Example3: SETUP + DATA + STATUS - split +1st callback: + xfer->nframes = 1; + xfer->frlenghts[0] = 8; + usb2_start_hardware(xfer); + +2nd callback: + /* IMPORTANT: frbuffers[0] must still point at the setup packet! */ + xfer->nframes = 2; + xfer->frlenghts[0] = 0; + xfer->frlenghts[1] = 1; + usb2_start_hardware(xfer); + +Example4: SETUP + STATUS - split +1st callback: + xfer->nframes = 1; + xfer->frlenghts[0] = 8; + xfer->flags.manual_status = 1; + usb2_start_hardware(xfer); + +2nd callback: + xfer->nframes = 1; + xfer->frlenghts[0] = 0; + xfer->flags.manual_status = 0; + usb2_start_hardware(xfer); + .Ed +.Sh USB TRANSFER CONFIG +To simply the search for endpoints the +.Nm +module defines a USB config structure where it is possible to specify +the characteristics of the wanted endpoint. +.Bd -literal -offset indent + +struct usb2_config { + bufsize, + callback + direction, + endpoint, + frames, + index flags, + interval, + timeout, + type, +}; + +.Ed +. .Pp -The -.Va udi_requests -field is indexed by the transfer kind, i.e.\& -.Dv UE_* , -and indicates how many transfers of each kind that has been completed -by the controller. -.It Dv USB_REQUEST Vt "struct usb_ctl_request" -This command can be used to execute arbitrary requests on the control pipe. -This is -.Em DANGEROUS -and should be used with great care since it -can destroy the bus integrity. +.Fa type +field selects the USB pipe type. +. +Valid values are: UE_INTERRUPT, UE_CONTROL, UE_BULK, +UE_ISOCHRONOUS. +. +The special value UE_BULK_INTR will select BULK and INTERRUPT pipes. +. +This field is mandatory. +. +.Pp +.Fa endpoint +field selects the USB endpoint number. +. +A value of 0xFF, "-1" or "UE_ADDR_ANY" will select the first matching +endpoint. +. +This field is mandatory. +. +.Pp +.Fa direction +field selects the USB endpoint direction. +. +A value of "UE_DIR_ANY" will select the first matching endpoint. +. +Else valid values are: "UE_DIR_IN" and "UE_DIR_OUT". +. +"UE_DIR_IN" and "UE_DIR_OUT" can be binary OR'ed by "UE_DIR_SID" which +means that the direction will be swapped in case of +USB_MODE_DEVICE. +. +Note that "UE_DIR_IN" refers to the data transfer direction of the +"IN" tokens and "UE_DIR_OUT" refers to the data transfer direction of +the "OUT" tokens. +. +This field is mandatory. +. +.Pp +.Fa interval +field selects the interrupt interval. +. +The value of this field is given in milliseconds and is independent of +device speed. +. +Depending on the endpoint type, this field has different meaning: +.Bl -tag +.It UE_INTERRUPT +"0" use the default interrupt interval based on endpoint descriptor. +"Else" use the given value for polling rate. +.It UE_ISOCHRONOUS +"0" use default. "Else" the value is ignored. +.It UE_BULK +.It UE_CONTROL +"0" no transfer pre-delay. "Else" a delay as given by this field in +milliseconds is inserted before the hardware is started when +"usb2_start_hardware()" is called. +.Pp +NOTE: The transfer timeout, if any, is started after that the +pre-delay has elapsed! +.El +. +.Pp +.Fa timeout +field, if non-zero, will set the transfer timeout in milliseconds. If +the "timeout" field is zero and the transfer type is ISOCHRONOUS a +timeout of 250ms will be used. +. +.Pp +.Fa frames +field sets the maximum number of frames. If zero is specified it will +yield the following results: +.Bl -tag +.It UE_BULK +xfer->nframes = 1; +.It UE_INTERRUPT +xfer->nframes = 1; +.It UE_CONTROL +xfer->nframes = 2; +.It UE_ISOCHRONOUS +Not allowed. Will cause an error. +.El +. +.Pp +.Fa ep_index +field allows you to give a number, in case more endpoints match the +description, that selects which matching "ep_index" should be used. +. +.Pp +.Fa if_index +field allows you to select which of the interface numbers in the +"ifaces" array parameter passed to "usb2_transfer_setup" that should +be used when setting up the given USB transfer. +. +.Pp +.Fa flags +field has type "struct usb2_xfer_flags" and allows one to set initial +flags an USB transfer. Valid flags are: +.Bl -tag +.It force_short_xfer +This flag forces the last transmitted USB packet to be short. A short +packet has a length of less than "xfer->max_packet_size", which +derives from "wMaxPacketSize". This flag can be changed during +operation. +.It short_xfer_ok +This flag allows the received transfer length, "xfer->actlen" to be +less than "xfer->sumlen" upon completion of a transfer. This flag can +be changed during operation. +.It short_frames_ok +This flag allows the reception of multiple short USB frames. This flag +only has effect for BULK and INTERRUPT endpoints and if the number of +frames received is greater than 1. This flag can be changed during +operation. +.It pipe_bof +This flag causes a failing USB transfer to remain first in the PIPE +queue except in the case of "xfer->error" equal to +"USB_ERR_CANCELLED". No other USB transfers in the affected PIPE queue +will be started until either: +.Bl -tag +.It 1 +The failing USB transfer is stopped using "usb2_transfer_stop()". +.It 2 +The failing USB transfer performs a successful transfer. +.El +The purpose of this flag is to avoid races when multiple transfers are +queued for execution on an USB endpoint, and the first executing +transfer fails leading to the need for clearing of stall for +example. +. +In this case this flag is used to prevent the following USB transfers +from being executed at the same time the clear-stall command is +executed on the USB control endpoint. +. +This flag can be changed during operation. +.Pp +"BOF" is short for "Block On Failure" +.Pp +NOTE: This flag should be set on all BULK and INTERRUPT USB transfers +which use an endpoint that can be shared between userland and kernel. +. +. +.It proxy_buffer +Setting this flag will cause that the total buffer size will be +rounded up to the nearest atomic hardware transfer size. +. +The maximum data length of any USB transfer is always stored in the +"xfer->max_data_length". +. +For control transfers the USB kernel will allocate additional space +for the 8-bytes of SETUP header. +. +These 8-bytes are not counted by the "xfer->max_data_length" +variable. +. +This flag can not be changed during operation. +. +. +.It ext_buffer +Setting this flag will cause that no data buffer will be +allocated. +. +Instead the USB client must supply a data buffer. +. +This flag can not be changed during operation. +. +. +.It manual_status +Setting this flag prevents an USB STATUS stage to be appended to the +end of the USB control transfer. +. +If no control data is transferred this flag must be cleared. +. +Else an error will be returned to the USB callback. +. +This flag is mostly useful for the USB device side. +. +This flag can be changed during operation. +. +. +.It no_pipe_ok +Setting this flag causes the USB_ERR_NO_PIPE error to be ignored. This +flag can not be changed during operation. +. +. +.It stall_pipe +.Bl -tag +.It Device Side Mode +Setting this flag will cause STALL pids to be sent to the endpoint +belonging to this transfer before the transfer is started. +. +The transfer is started at the moment the host issues a clear-stall +command on the STALL'ed endpoint. +. +This flag can be changed during operation. +.It Host Side Mode +Setting this flag will cause a clear-stall control request to be +executed on the endpoint before the USB transfer is started. .El .Pp -The include file -.In dev/usb/usb.h -contains definitions for the types used by the various -.Xr ioctl 2 -calls. -The naming convention of the fields for the various -.Tn USB -descriptors exactly follows the naming in the -.Tn USB -specification. -Byte sized fields can be accessed directly, but word (16 bit) -sized fields must be access by the -.Fn UGETW field -and -.Fn USETW field value -macros to handle byte order and alignment properly. +If this flag is changed outside the USB callback function you have to +use the "usb2_transfer_set_stall()" and "usb2_transfer_clear_stall()" +functions! This flag is automatically cleared after that the stall or +clear stall has been executed. +. +.El .Pp -The include file -.In dev/usb/usbhid.h -similarly contains the definitions for -Human Interface Devices -.Pq Tn HID . -.Sh USB EVENT INTERFACE -All -.Tn USB -events are reported via the -.Pa /dev/usb -device. -This device can be opened for reading and each -.Xr read 2 -will yield an event record (if something has happened). +.Fa bufsize +field sets the total buffer size in bytes. +. +If this field is zero, "wMaxPacketSize" will be used, multiplied by +the "frames" field if the transfer type is ISOCHRONOUS. +. +This is useful for setting up interrupt pipes. +. +This field is mandatory. +.Pp +NOTE: For control transfers "bufsize" includes the length of the +request structure. +. +.Pp +.Fa callback +pointer sets the USB callback. This field is mandatory. +. +. +.Sh USB LINUX COMPAT LAYER The -.Xr poll 2 -system call can be used to determine if an event record is available -for reading. -.Pp -The event record has the following definition: -.Bd -literal -struct usb_event { - int ue_type; -#define USB_EVENT_CTRLR_ATTACH 1 -#define USB_EVENT_CTRLR_DETACH 2 -#define USB_EVENT_DEVICE_ATTACH 3 -#define USB_EVENT_DEVICE_DETACH 4 -#define USB_EVENT_DRIVER_ATTACH 5 -#define USB_EVENT_DRIVER_DETACH 6 - struct timespec ue_time; - union { - struct { - int ue_bus; - } ue_ctrlr; - struct usb_device_info ue_device; - struct { - usb_event_cookie_t ue_cookie; - char ue_devname[16]; - } ue_driver; - } u; -}; -.Ed -The -.Va ue_type -field identifies the type of event that is described. -The possible events are attach/detach of a host controller, -a device, or a device driver. -The union contains information -pertinent to the different types of events. -Macros, -.Fn USB_EVENT_IS_ATTACH "ue_type" -and -.Fn USB_EVENT_IS_DETACH "ue_type" -can be used to determine if an event was an -.Dq attach -or a -.Dq detach -request. -.Pp -The -.Va ue_bus -contains the number of the -.Tn USB -bus for host controller events. -.Pp -The -.Va ue_device -record contains information about the device in a device event event. -.Pp -The -.Va ue_cookie -is an opaque value that uniquely determines which -device a device driver has been attached to (i.e., it equals -the cookie value in the device that the driver attached to). -.Pp -The -.Va ue_devname -contains the name of the device (driver) as seen in, e.g., -kernel messages. -.Pp -Note that there is a separation between device and device -driver events. -A device event is generated when a physical -.Tn USB -device is attached or detached. -A single -.Tn USB -device may -have zero, one, or many device drivers associated with it. +.Nm +module supports the Linux USB API. +. +. +. .Sh SEE ALSO The .Tn USB @@ -403,6 +711,7 @@ specifications can be found at: .Pp .D1 Pa http://www.usb.org/developers/docs/ .Pp +.Xr libusb 3 , .Xr aue 4 , .Xr axe 4 , .Xr cue 4 , @@ -413,7 +722,6 @@ specifications can be found at: .Xr rue 4 , .Xr ucom 4 , .Xr udav 4 , -.Xr ugen 4 , .Xr uhci 4 , .Xr uhid 4 , .Xr ukbd 4 , @@ -423,17 +731,16 @@ specifications can be found at: .Xr uplcom 4 , .Xr urio 4 , .Xr uvscom 4 , -.Xr usbdevs 8 +.Xr usbconfig 8 +.Sh STANDARDS +The +.Nm +module complies with the USB 2.0 standard. .Sh HISTORY The .Nm -driver first appeared in -.Fx 3.0 . -.Sh AUTHORS -The +module has been inspired by the NetBSD USB stack initially written by +Lennart Augustsson. The .Nm -driver was written by -.An Lennart Augustsson Aq augustss@carlstedt.se -for the -.Nx -project. +module was written by +.An Hans Petter Selasky Aq hselasky@freebsd.org . diff --git a/share/man/man4/usb2_core.4 b/share/man/man4/usb2_core.4 deleted file mode 100644 index 6600a802d157..000000000000 --- a/share/man/man4/usb2_core.4 +++ /dev/null @@ -1,635 +0,0 @@ -.\" $FreeBSD$ -.\" -.\" Copyright (c) 2008 Hans Petter Selasky. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.Dd February 17, 2009 -.Dt USB2_CORE 4 -.Os -. -.Sh NAME -. -. -.Nm usb2_core -. -.Nd "USB core functions" -. -. -.Sh SYNOPSIS -To compile this module into the kernel, place the following line in -your kernel configuration file: -.Bd -ragged -offset indent -.Cd "device usb2_core" -.Ed -.Pp -To load the module at boot time, place the following line in -.Xr loader.conf 5 : -.Bd -literal -offset indent -usb2_core_load="YES" -.Ed -. -.Pp -Here is a list of commonly used functions: -.Pp -. -.Ft "usb2_error_t" -.Fo "usb2_transfer_setup" -.Fa "udev" -.Fa "ifaces" -.Fa "pxfer" -.Fa "setup_start" -.Fa "n_setup" -.Fa "priv_sc" -.Fa "priv_mtx" -.Fc -. -.Ft "void" -.Fo "usb2_transfer_unsetup" -.Fa "pxfer" -.Fa "n_setup" -.Fc -. -.Ft "void" -.Fo "usb2_transfer_start" -.Fa "xfer" -.Fc -. -.Ft "void" -.Fo "usb2_transfer_stop" -.Fa "xfer" -.Fc -. -.Ft "void" -.Fo "usb2_transfer_drain" -.Fa "xfer" -.Fc -. -. -.Sh DESCRIPTION -The -.Nm -module implements the core functionality of the USB standard and many -helper functions to make USB device driver programming easier and more -safe. -. -The -.Nm -module supports both USB Host and USB Device side mode! -. -.Sh USB TRANSFER MANAGEMENT FUNCTIONS -The USB standard defines four types of USB transfers. -. -Control transfers, Bulk transfers, Interrupt transfers and Isochronous -transfers. -. -All the transfer types are managed using the following five functions: -. -.Pp -. -.Fn usb2_transfer_setup -This function will allocate memory for and initialise an array of USB -transfers and all required DMA memory. -. -This function can sleep or block waiting for resources to become -available. -.Fa udev -is a pointer to "struct usb2_device". -.Fa ifaces -is an array of interface index numbers to use. See "if_index". -.Fa pxfer -is a pointer to an array of USB transfer pointers that are initialized -to NULL, and then pointed to allocated USB transfers. -.Fa setup_start -is a pointer to an array of USB config structures. -.Fa n_setup -is a number telling the USB system how many USB transfers should be -setup. -.Fa priv_sc -is the private softc pointer, which will be used to initialize -"xfer->priv_sc". -.Fa priv_mtx -is the private mutex protecting the transfer structure and the -softc. This pointer is used to initialize "xfer->priv_mtx". -This function returns -zero upon success. A non-zero return value indicates failure. -. -.Pp -. -.Fn usb2_transfer_unsetup -This function will release the given USB transfers and all allocated -resources associated with these USB transfers. -.Fa pxfer -is a pointer to an array of USB transfer pointers, that may be NULL, -that should be freed by the USB system. -.Fa n_setup -is a number telling the USB system how many USB transfers should be -unsetup. -. -This function can sleep waiting for USB transfers to complete. -. -This function is NULL safe with regard to the USB transfer structure -pointer. -. -It is not allowed to call this function from the USB transfer -callback. -. -.Pp -. -.Fn usb2_transfer_start -This function will start the USB transfer pointed to by -.Fa xfer, -if not already started. -. -This function is always non-blocking and must be called with the -so-called private USB mutex locked. -. -This function is NULL safe with regard to the USB transfer structure -pointer. -. -.Pp -. -.Fn usb2_transfer_stop -This function will stop the USB transfer pointed to by -.Fa xfer, -if not already stopped. -. -This function is always non-blocking and must be called with the -so-called private USB mutex locked. -. -This function can return before the USB callback has been called. -. -This function is NULL safe with regard to the USB transfer structure -pointer. -. -If the transfer was in progress, the callback will called with -"USB_ST_ERROR" and "xfer->error = USB_ERR_CANCELLED". -. -.Pp -. -.Fn usb2_transfer_drain -This function will stop an USB transfer, if not already stopped and -wait for any additional USB hardware operations to complete. -. -Buffers that are loaded into DMA using "usb2_set_frame_data()" can -safely be freed after that this function has returned. -. -This function can block the caller and will not return before the USB -callback has been called. -. -This function is NULL safe with regard to the USB transfer structure -pointer. -. -.Sh USB TRANSFER CALLBACK -. -The USB callback has three states. -. -USB_ST_SETUP, USB_ST_TRANSFERRED and USB_ST_ERROR. USB_ST_SETUP is the -initial state. -. -After the callback has been called with this state it will always be -called back at a later stage in one of the other two states. -. -In the USB_ST_ERROR state the "error" field of the USB transfer -structure is set to the error cause. -. -The USB callback should not restart the USB transfer in case the error -cause is USB_ERR_CANCELLED. -. -The USB callback is protected from recursion. -. -That means one can start and stop whatever transfer from the callback -of another transfer one desires. -. -Also the transfer that is currently called back. -. -Recursion is handled like this that when the callback that wants to -recurse returns it is called one more time. -. -. -.Pp -. -.Fn usb2_start_hardware -This function should only be called from within the USB callback and -is used to start the USB hardware. -. -Typical parameters that should be set in the USB transfer structure -before this function is called are "frlengths[]", "nframes" and -"frbuffers[]". -. -An USB transfer can have multiple frames consisting of one or more USB -packets making up an I/O vector for all USB transfer types. -. -After the USB transfer is complete "frlengths[]" is updated to the -actual USB transfer length for the given frame. -.Bd -literal -offset indent -void -usb2_default_callback(struct usb2_xfer *xfer) -{ - switch (USB_GET_STATE(xfer)) { - case USB_ST_SETUP: - /* - * Setup xfer->frlengths[], xfer->nframes - * and write data to xfer->frbuffers[], if any - */ - usb2_start_hardware(xfer); - break; - - case USB_ST_TRANSFERRED: - /* - * Read data from xfer->frbuffers[], if any. - * "xfer->frlengths[]" should now have been - * updated to the actual length. - */ - break; - - default: /* Error */ - /* - * Print error message and clear stall - * for example. - */ - break; - } - /* - * Here it is safe to do something without the private - * USB mutex locked. - */ - return; -} -.Ed -. -.Sh USB CONTROL TRANSFERS -An USB control transfer has three parts. -. -First the SETUP packet, then DATA packet(s) and then a STATUS -packet. -. -The SETUP packet is always pointed to by "xfer->frbuffers[0]" and the -length is stored in "xfer->frlengths[0]" also if there should not be -sent any SETUP packet! If an USB control transfer has no DATA stage, -then "xfer->nframes" should be set to 1. -. -Else the default value is "xfer->nframes" equal to 2. -. -.Bd -literal -offset indent - -Example1: SETUP + STATUS - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - usb2_start_hardware(xfer); - -Example2: SETUP + DATA + STATUS - xfer->nframes = 2; - xfer->frlenghts[0] = 8; - xfer->frlenghts[1] = 1; - usb2_start_hardware(xfer); - -Example3: SETUP + DATA + STATUS - split -1st callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - usb2_start_hardware(xfer); - -2nd callback: - /* IMPORTANT: frbuffers[0] must still point at the setup packet! */ - xfer->nframes = 2; - xfer->frlenghts[0] = 0; - xfer->frlenghts[1] = 1; - usb2_start_hardware(xfer); - -Example4: SETUP + STATUS - split -1st callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - xfer->flags.manual_status = 1; - usb2_start_hardware(xfer); - -2nd callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 0; - xfer->flags.manual_status = 0; - usb2_start_hardware(xfer); - -.Ed -.Sh USB TRANSFER CONFIG -To simply the search for endpoints the -.Nm -module defines a USB config structure where it is possible to specify -the characteristics of the wanted endpoint. -.Bd -literal -offset indent - -struct usb2_config { - bufsize, - callback - direction, - endpoint, - frames, - index flags, - interval, - timeout, - type, -}; - -.Ed -. -.Pp -.Fa type -field selects the USB pipe type. -. -Valid values are: UE_INTERRUPT, UE_CONTROL, UE_BULK, -UE_ISOCHRONOUS. -. -The special value UE_BULK_INTR will select BULK and INTERRUPT pipes. -. -This field is mandatory. -. -.Pp -.Fa endpoint -field selects the USB endpoint number. -. -A value of 0xFF, "-1" or "UE_ADDR_ANY" will select the first matching -endpoint. -. -This field is mandatory. -. -.Pp -.Fa direction -field selects the USB endpoint direction. -. -A value of "UE_DIR_ANY" will select the first matching endpoint. -. -Else valid values are: "UE_DIR_IN" and "UE_DIR_OUT". -. -"UE_DIR_IN" and "UE_DIR_OUT" can be binary OR'ed by "UE_DIR_SID" which -means that the direction will be swapped in case of -USB_MODE_DEVICE. -. -Note that "UE_DIR_IN" refers to the data transfer direction of the -"IN" tokens and "UE_DIR_OUT" refers to the data transfer direction of -the "OUT" tokens. -. -This field is mandatory. -. -.Pp -.Fa interval -field selects the interrupt interval. -. -The value of this field is given in milliseconds and is independent of -device speed. -. -Depending on the endpoint type, this field has different meaning: -.Bl -tag -.It UE_INTERRUPT -"0" use the default interrupt interval based on endpoint descriptor. -"Else" use the given value for polling rate. -.It UE_ISOCHRONOUS -"0" use default. "Else" the value is ignored. -.It UE_BULK -.It UE_CONTROL -"0" no transfer pre-delay. "Else" a delay as given by this field in -milliseconds is inserted before the hardware is started when -"usb2_start_hardware()" is called. -.Pp -NOTE: The transfer timeout, if any, is started after that the -pre-delay has elapsed! -.El -. -.Pp -.Fa timeout -field, if non-zero, will set the transfer timeout in milliseconds. If -the "timeout" field is zero and the transfer type is ISOCHRONOUS a -timeout of 250ms will be used. -. -.Pp -.Fa frames -field sets the maximum number of frames. If zero is specified it will -yield the following results: -.Bl -tag -.It UE_BULK -xfer->nframes = 1; -.It UE_INTERRUPT -xfer->nframes = 1; -.It UE_CONTROL -xfer->nframes = 2; -.It UE_ISOCHRONOUS -Not allowed. Will cause an error. -.El -. -.Pp -.Fa ep_index -field allows you to give a number, in case more endpoints match the -description, that selects which matching "ep_index" should be used. -. -.Pp -.Fa if_index -field allows you to select which of the interface numbers in the -"ifaces" array parameter passed to "usb2_transfer_setup" that should -be used when setting up the given USB transfer. -. -.Pp -.Fa flags -field has type "struct usb2_xfer_flags" and allows one to set initial -flags an USB transfer. Valid flags are: -.Bl -tag -.It force_short_xfer -This flag forces the last transmitted USB packet to be short. A short -packet has a length of less than "xfer->max_packet_size", which -derives from "wMaxPacketSize". This flag can be changed during -operation. -.It short_xfer_ok -This flag allows the received transfer length, "xfer->actlen" to be -less than "xfer->sumlen" upon completion of a transfer. This flag can -be changed during operation. -.It short_frames_ok -This flag allows the reception of multiple short USB frames. This flag -only has effect for BULK and INTERRUPT endpoints and if the number of -frames received is greater than 1. This flag can be changed during -operation. -.It pipe_bof -This flag causes a failing USB transfer to remain first in the PIPE -queue except in the case of "xfer->error" equal to -"USB_ERR_CANCELLED". No other USB transfers in the affected PIPE queue -will be started until either: -.Bl -tag -.It 1 -The failing USB transfer is stopped using "usb2_transfer_stop()". -.It 2 -The failing USB transfer performs a successful transfer. -.El -The purpose of this flag is to avoid races when multiple transfers are -queued for execution on an USB endpoint, and the first executing -transfer fails leading to the need for clearing of stall for -example. -. -In this case this flag is used to prevent the following USB transfers -from being executed at the same time the clear-stall command is -executed on the USB control endpoint. -. -This flag can be changed during operation. -.Pp -"BOF" is short for "Block On Failure" -.Pp -NOTE: This flag should be set on all BULK and INTERRUPT USB transfers -which use an endpoint that can be shared between userland and kernel. -. -. -.It proxy_buffer -Setting this flag will cause that the total buffer size will be -rounded up to the nearest atomic hardware transfer size. -. -The maximum data length of any USB transfer is always stored in the -"xfer->max_data_length". -. -For control transfers the USB kernel will allocate additional space -for the 8-bytes of SETUP header. -. -These 8-bytes are not counted by the "xfer->max_data_length" -variable. -. -This flag can not be changed during operation. -. -. -.It ext_buffer -Setting this flag will cause that no data buffer will be -allocated. -. -Instead the USB client must supply a data buffer. -. -This flag can not be changed during operation. -. -. -.It manual_status -Setting this flag prevents an USB STATUS stage to be appended to the -end of the USB control transfer. -. -If no control data is transferred this flag must be cleared. -. -Else an error will be returned to the USB callback. -. -This flag is mostly useful for the USB device side. -. -This flag can be changed during operation. -. -. -.It no_pipe_ok -Setting this flag causes the USB_ERR_NO_PIPE error to be ignored. This -flag can not be changed during operation. -. -. -.It stall_pipe -.Bl -tag -.It Device Side Mode -Setting this flag will cause STALL pids to be sent to the endpoint -belonging to this transfer before the transfer is started. -. -The transfer is started at the moment the host issues a clear-stall -command on the STALL'ed endpoint. -. -This flag can be changed during operation. -.It Host Side Mode -Setting this flag will cause a clear-stall control request to be -executed on the endpoint before the USB transfer is started. -.El -.Pp -If this flag is changed outside the USB callback function you have to -use the "usb2_transfer_set_stall()" and "usb2_transfer_clear_stall()" -functions ! -. -.El -.Pp -.Fa bufsize -field sets the total buffer size in bytes. -. -If this field is zero, "wMaxPacketSize" will be used, multiplied by -the "frames" field if the transfer type is ISOCHRONOUS. -. -This is useful for setting up interrupt pipes. -. -This field is mandatory. -.Pp -NOTE: For control transfers "bufsize" includes the length of the -request structure. -. -.Pp -.Fa callback -pointer sets the USB callback. This field is mandatory. -. -. -.Sh USB LINUX COMPAT LAYER -The -.Nm -module supports the Linux USB API. -. -. -. -. -.Sh USB SECURITY MODEL -. -. -The -.Nm -module implements fine grained read and write access based on username -and group. -. -Access is granted at four levels: -. -.Bl -tag -.It Level 4 - USB interface -USB interfaces can be given individual access rights. -.It Level 3 - USB device -USB devices can be given individual access rights. -.It Level 2 - USB BUS -USB busses can be given individual access rights. -.It Level 1 - USB -USB as a whole can be given individual access rights. -.El -.Pp -The -.Nm -module will search for access rights starting at level 4 continuing -downwards to USB at level 1. -. -For critical applications you should be aware that the outgoing serial -BUS traffic will be broadcasted to all USB devices. -. -For absolute security USB devices that require different access rights -should not be placed on the same USB BUS or controller. -. -If connected to the same USB bus, it is possible that a USB device can -sniff and intercept the communication of another USB device. -. -Using USB HUBs will not solve this problem. -.Sh SEE ALSO -.Xr usb2_controller 4 -.Xr usbconfig 8 -.Sh STANDARDS -The -.Nm -module complies with the USB 2.0 standard. -.Sh HISTORY -The -.Nm -module has been inspired by the NetBSD USB stack initially written by -Lennart Augustsson. The -.Nm -module was written by -.An Hans Petter Selasky Aq hselasky@freebsd.org . From 476183df94c2e19b878e00d91122cdf771a72b34 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:39:21 +0000 Subject: [PATCH 386/544] Improve device mode (gadget) stall handling. Some hardware easily comes out of sync with regard to whether the current or the next control transfer should be stalled, if a stall command is always issued before receiving the SETUP packet. After this patch the stall command will only be issued when a transfer should actually be stalled. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/at91dci.c | 3 ++- sys/dev/usb/controller/at91dci.h | 1 + sys/dev/usb/controller/atmegadci.c | 3 ++- sys/dev/usb/controller/atmegadci.h | 1 + sys/dev/usb/controller/musb_otg.c | 3 ++- sys/dev/usb/controller/musb_otg.h | 1 + sys/dev/usb/controller/uss820dci.c | 12 +++++++----- sys/dev/usb/controller/uss820dci.h | 2 ++ sys/dev/usb/usb_core.h | 1 + sys/dev/usb/usb_transfer.c | 8 ++++++-- 10 files changed, 25 insertions(+), 10 deletions(-) diff --git a/sys/dev/usb/controller/at91dci.c b/sys/dev/usb/controller/at91dci.c index e65fc37ec4f0..63a589af0e54 100644 --- a/sys/dev/usb/controller/at91dci.c +++ b/sys/dev/usb/controller/at91dci.c @@ -848,7 +848,7 @@ at91dci_setup_standard_chain_sub(struct at91dci_std_temp *temp) td->remainder = temp->len; td->fifo_bank = 0; td->error = 0; - td->did_stall = 0; + td->did_stall = temp->did_stall; td->short_pkt = temp->short_pkt; td->alt_next = temp->setup_alt_next; } @@ -879,6 +879,7 @@ at91dci_setup_standard_chain(struct usb2_xfer *xfer) temp.td_next = xfer->td_start[0]; temp.offset = 0; temp.setup_alt_next = xfer->flags_int.short_frames_ok; + temp.did_stall = !xfer->flags_int.control_stall; sc = AT9100_DCI_BUS2SC(xfer->xroot->bus); ep_no = (xfer->endpoint & UE_ADDR); diff --git a/sys/dev/usb/controller/at91dci.h b/sys/dev/usb/controller/at91dci.h index 0271fb9b8c8e..87cbc87e2408 100644 --- a/sys/dev/usb/controller/at91dci.h +++ b/sys/dev/usb/controller/at91dci.h @@ -169,6 +169,7 @@ struct at91dci_std_temp { * short_pkt = 1: transfer should not be short terminated */ uint8_t setup_alt_next; + uint8_t did_stall; }; struct at91dci_config_desc { diff --git a/sys/dev/usb/controller/atmegadci.c b/sys/dev/usb/controller/atmegadci.c index a4b1274fc649..df1fe781672f 100644 --- a/sys/dev/usb/controller/atmegadci.c +++ b/sys/dev/usb/controller/atmegadci.c @@ -751,7 +751,7 @@ atmegadci_setup_standard_chain_sub(struct atmegadci_std_temp *temp) td->offset = temp->offset; td->remainder = temp->len; td->error = 0; - td->did_stall = 0; + td->did_stall = temp->did_stall; td->short_pkt = temp->short_pkt; td->alt_next = temp->setup_alt_next; } @@ -782,6 +782,7 @@ atmegadci_setup_standard_chain(struct usb2_xfer *xfer) temp.td_next = xfer->td_start[0]; temp.offset = 0; temp.setup_alt_next = xfer->flags_int.short_frames_ok; + temp.did_stall = !xfer->flags_int.control_stall; sc = ATMEGA_BUS2SC(xfer->xroot->bus); ep_no = (xfer->endpoint & UE_ADDR); diff --git a/sys/dev/usb/controller/atmegadci.h b/sys/dev/usb/controller/atmegadci.h index cd4b4f13a4e7..8f5a538d5678 100644 --- a/sys/dev/usb/controller/atmegadci.h +++ b/sys/dev/usb/controller/atmegadci.h @@ -222,6 +222,7 @@ struct atmegadci_std_temp { * short_pkt = 1: transfer should not be short terminated */ uint8_t setup_alt_next; + uint8_t did_stall; }; struct atmegadci_config_desc { diff --git a/sys/dev/usb/controller/musb_otg.c b/sys/dev/usb/controller/musb_otg.c index 39b7612a07b9..6b867d5750c8 100644 --- a/sys/dev/usb/controller/musb_otg.c +++ b/sys/dev/usb/controller/musb_otg.c @@ -1099,7 +1099,7 @@ musbotg_setup_standard_chain_sub(struct musbotg_std_temp *temp) td->offset = temp->offset; td->remainder = temp->len; td->error = 0; - td->did_stall = 0; + td->did_stall = temp->did_stall; td->short_pkt = temp->short_pkt; td->alt_next = temp->setup_alt_next; } @@ -1129,6 +1129,7 @@ musbotg_setup_standard_chain(struct usb2_xfer *xfer) temp.td_next = xfer->td_start[0]; temp.offset = 0; temp.setup_alt_next = xfer->flags_int.short_frames_ok; + temp.did_stall = !xfer->flags_int.control_stall; sc = MUSBOTG_BUS2SC(xfer->xroot->bus); ep_no = (xfer->endpoint & UE_ADDR); diff --git a/sys/dev/usb/controller/musb_otg.h b/sys/dev/usb/controller/musb_otg.h index 2dd2ce317be2..f68792198d94 100644 --- a/sys/dev/usb/controller/musb_otg.h +++ b/sys/dev/usb/controller/musb_otg.h @@ -332,6 +332,7 @@ struct musbotg_std_temp { * short_pkt = 1: transfer should not be short terminated */ uint8_t setup_alt_next; + uint8_t did_stall; }; struct musbotg_config_desc { diff --git a/sys/dev/usb/controller/uss820dci.c b/sys/dev/usb/controller/uss820dci.c index 5a857d0d819f..05389c4f91f6 100644 --- a/sys/dev/usb/controller/uss820dci.c +++ b/sys/dev/usb/controller/uss820dci.c @@ -410,10 +410,10 @@ uss820dci_data_rx(struct uss820dci_td *td) /* read out EPCON register */ /* enable RX input */ - if (!td->did_stall) { + if (!td->did_enable) { uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc), USS820_EPCON, 0xFF, USS820_EPCON_RXIE); - td->did_stall = 1; + td->did_enable = 1; } return (1); /* not complete */ } @@ -573,10 +573,10 @@ uss820dci_data_tx(struct uss820dci_td *td) * Enable TX output, which must happen after that we have written * data into the FIFO. This is undocumented. */ - if (!td->did_stall) { + if (!td->did_enable) { uss820dci_update_shared_1(USS820_DCI_PC2SC(td->pc), USS820_EPCON, 0xFF, USS820_EPCON_TXOE); - td->did_stall = 1; + td->did_enable = 1; } /* check remainder */ if (td->remainder == 0) { @@ -813,7 +813,8 @@ uss820dci_setup_standard_chain_sub(struct uss820_std_temp *temp) td->offset = temp->offset; td->remainder = temp->len; td->error = 0; - td->did_stall = 0; + td->did_enable = 0; + td->did_stall = temp->did_stall; td->short_pkt = temp->short_pkt; td->alt_next = temp->setup_alt_next; } @@ -843,6 +844,7 @@ uss820dci_setup_standard_chain(struct usb2_xfer *xfer) temp.td_next = xfer->td_start[0]; temp.offset = 0; temp.setup_alt_next = xfer->flags_int.short_frames_ok; + temp.did_stall = !xfer->flags_int.control_stall; sc = USS820_DCI_BUS2SC(xfer->xroot->bus); ep_no = (xfer->endpoint & UE_ADDR); diff --git a/sys/dev/usb/controller/uss820dci.h b/sys/dev/usb/controller/uss820dci.h index 24e3ce20a061..08bbb6a463d4 100644 --- a/sys/dev/usb/controller/uss820dci.h +++ b/sys/dev/usb/controller/uss820dci.h @@ -280,6 +280,7 @@ struct uss820dci_td { uint8_t short_pkt:1; uint8_t support_multi_buffer:1; uint8_t did_stall:1; + uint8_t did_enable:1; }; struct uss820_std_temp { @@ -296,6 +297,7 @@ struct uss820_std_temp { * short_pkt = 1: transfer should not be short terminated */ uint8_t setup_alt_next; + uint8_t did_stall; }; struct uss820dci_config_desc { diff --git a/sys/dev/usb/usb_core.h b/sys/dev/usb/usb_core.h index eec357d3f908..5c4fde81d7c6 100644 --- a/sys/dev/usb/usb_core.h +++ b/sys/dev/usb/usb_core.h @@ -371,6 +371,7 @@ struct usb2_xfer_flags_int { uint8_t control_hdr:1; /* set if control header should be * sent */ uint8_t control_act:1; /* set if control transfer is active */ + uint8_t control_stall:1; /* set if control transfer should be stalled */ uint8_t short_frames_ok:1; /* filtered version */ uint8_t short_xfer_ok:1; /* filtered version */ diff --git a/sys/dev/usb/usb_transfer.c b/sys/dev/usb/usb_transfer.c index 1dd444b815fc..304edd5d28bf 100644 --- a/sys/dev/usb/usb_transfer.c +++ b/sys/dev/usb/usb_transfer.c @@ -1225,9 +1225,13 @@ usb2_start_hardware_sub(struct usb2_xfer *xfer) usb2_frlength_t len; /* Check for control endpoint stall */ - if (xfer->flags.stall_pipe) { - /* no longer active */ + if (xfer->flags.stall_pipe && xfer->flags_int.control_act) { + /* the control transfer is no longer active */ + xfer->flags_int.control_stall = 1; xfer->flags_int.control_act = 0; + } else { + /* don't stall control transfer by default */ + xfer->flags_int.control_stall = 0; } /* Check for invalid number of frames */ From 55e76c210e73b5d87066203c1016fd2eff64c988 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:42:32 +0000 Subject: [PATCH 387/544] Add a driver for the AVR32 series USB Device Controller. Not hooked up as FreeBSD does not yet support this platform but it makes it easier to stay in sync. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/avr32dci.c | 2065 +++++++++++++++++++++++++++++ sys/dev/usb/controller/avr32dci.h | 254 ++++ 2 files changed, 2319 insertions(+) create mode 100644 sys/dev/usb/controller/avr32dci.c create mode 100644 sys/dev/usb/controller/avr32dci.h diff --git a/sys/dev/usb/controller/avr32dci.c b/sys/dev/usb/controller/avr32dci.c new file mode 100644 index 000000000000..1836589aa906 --- /dev/null +++ b/sys/dev/usb/controller/avr32dci.c @@ -0,0 +1,2065 @@ +#include +__FBSDID("$FreeBSD$"); + +/*- + * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * This file contains the driver for the AVR32 series USB Device + * Controller + */ + +/* + * NOTE: When the chip detects BUS-reset it will also reset the + * endpoints, Function-address and more. + */ + +#include +#include +#include + +#define USB_DEBUG_VAR avr32dci_debug + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define AVR32_BUS2SC(bus) \ + ((struct avr32dci_softc *)(((uint8_t *)(bus)) - \ + ((uint8_t *)&(((struct avr32dci_softc *)0)->sc_bus)))) + +#define AVR32_PC2SC(pc) \ + AVR32_BUS2SC(USB_DMATAG_TO_XROOT((pc)->tag_parent)->bus) + +#if USB_DEBUG +static int avr32dci_debug = 0; + +SYSCTL_NODE(_hw_usb, OID_AUTO, avr32dci, CTLFLAG_RW, 0, "USB AVR32 DCI"); +SYSCTL_INT(_hw_usb_avr32dci, OID_AUTO, debug, CTLFLAG_RW, + &avr32dci_debug, 0, "AVR32 DCI debug level"); +#endif + +#define AVR32_INTR_ENDPT 1 + +/* prototypes */ + +struct usb2_bus_methods avr32dci_bus_methods; +struct usb2_pipe_methods avr32dci_device_non_isoc_methods; +struct usb2_pipe_methods avr32dci_device_isoc_fs_methods; + +static avr32dci_cmd_t avr32dci_setup_rx; +static avr32dci_cmd_t avr32dci_data_rx; +static avr32dci_cmd_t avr32dci_data_tx; +static avr32dci_cmd_t avr32dci_data_tx_sync; +static void avr32dci_device_done(struct usb2_xfer *, usb2_error_t); +static void avr32dci_do_poll(struct usb2_bus *); +static void avr32dci_standard_done(struct usb2_xfer *); +static void avr32dci_root_intr(struct avr32dci_softc *sc); + +/* + * Here is a list of what the chip supports: + */ +static const struct usb2_hw_ep_profile + avr32dci_ep_profile[4] = { + + [0] = { + .max_in_frame_size = 64, + .max_out_frame_size = 64, + .is_simplex = 1, + .support_control = 1, + }, + + [1] = { + .max_in_frame_size = 512, + .max_out_frame_size = 512, + .is_simplex = 1, + .support_bulk = 1, + .support_interrupt = 1, + .support_isochronous = 1, + .support_in = 1, + .support_out = 1, + }, + + [2] = { + .max_in_frame_size = 64, + .max_out_frame_size = 64, + .is_simplex = 1, + .support_bulk = 1, + .support_interrupt = 1, + .support_in = 1, + .support_out = 1, + }, + + [3] = { + .max_in_frame_size = 1024, + .max_out_frame_size = 1024, + .is_simplex = 1, + .support_bulk = 1, + .support_interrupt = 1, + .support_isochronous = 1, + .support_in = 1, + .support_out = 1, + }, +}; + +static void +avr32dci_get_hw_ep_profile(struct usb2_device *udev, + const struct usb2_hw_ep_profile **ppf, uint8_t ep_addr) +{ + if (ep_addr == 0) + *ppf = avr32dci_ep_profile; + else if (ep_addr < 3) + *ppf = avr32dci_ep_profile + 1; + else if (ep_addr < 5) + *ppf = avr32dci_ep_profile + 2; + else if (ep_addr < 7) + *ppf = avr32dci_ep_profile + 3; + else + *ppf = NULL; +} + +static void +avr32dci_mod_ctrl(struct avr32dci_softc *sc, uint32_t set, uint32_t clear) +{ + uint32_t temp; + + temp = AVR32_READ_4(sc, AVR32_CTRL); + temp |= set; + temp &= ~clear; + AVR32_WRITE_4(sc, AVR32_CTRL, temp); +} + +static void +avr32dci_mod_ien(struct avr32dci_softc *sc, uint32_t set, uint32_t clear) +{ + uint32_t temp; + + temp = AVR32_READ_4(sc, AVR32_IEN); + temp |= set; + temp &= ~clear; + AVR32_WRITE_4(sc, AVR32_IEN, temp); +} + +static void +avr32dci_clocks_on(struct avr32dci_softc *sc) +{ + if (sc->sc_flags.clocks_off && + sc->sc_flags.port_powered) { + + DPRINTFN(5, "\n"); + + /* turn on clocks */ + (sc->sc_clocks_on) (&sc->sc_bus); + + avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_EN_USBA, 0); + + sc->sc_flags.clocks_off = 0; + } +} + +static void +avr32dci_clocks_off(struct avr32dci_softc *sc) +{ + if (!sc->sc_flags.clocks_off) { + + DPRINTFN(5, "\n"); + + avr32dci_mod_ctrl(sc, 0, AVR32_CTRL_DEV_EN_USBA); + + /* turn clocks off */ + (sc->sc_clocks_off) (&sc->sc_bus); + + sc->sc_flags.clocks_off = 1; + } +} + +static void +avr32dci_pull_up(struct avr32dci_softc *sc) +{ + /* pullup D+, if possible */ + + if (!sc->sc_flags.d_pulled_up && + sc->sc_flags.port_powered) { + sc->sc_flags.d_pulled_up = 1; + avr32dci_mod_ctrl(sc, 0, AVR32_CTRL_DEV_DETACH); + } +} + +static void +avr32dci_pull_down(struct avr32dci_softc *sc) +{ + /* pulldown D+, if possible */ + + if (sc->sc_flags.d_pulled_up) { + sc->sc_flags.d_pulled_up = 0; + avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_DETACH, 0); + } +} + +static void +avr32dci_wakeup_peer(struct avr32dci_softc *sc) +{ + if (!sc->sc_flags.status_suspend) { + return; + } + avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_REWAKEUP, 0); + + /* wait 8 milliseconds */ + /* Wait for reset to complete. */ + usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 125); + + /* hardware should have cleared RMWKUP bit */ +} + +static void +avr32dci_set_address(struct avr32dci_softc *sc, uint8_t addr) +{ + DPRINTFN(5, "addr=%d\n", addr); + + avr32dci_mod_ctrl(sc, AVR32_UDADDR_ADDEN | addr, 0); +} + +static uint8_t +avr32dci_setup_rx(struct avr32dci_td *td) +{ + struct avr32dci_softc *sc; + struct usb2_device_request req; + uint16_t count; + uint32_t temp; + + /* get pointer to softc */ + sc = AVR32_PC2SC(td->pc); + + /* check endpoint status */ + temp = AVR32_READ_4(sc, AVR32_EPTSTA(td->ep_no)); + + DPRINTFN(5, "EPTSTA(%u)=0x%08x\n", td->ep_no, temp); + + if (!(temp & AVR32_EPTSTA_RX_SETUP)) { + goto not_complete; + } + /* clear did stall */ + td->did_stall = 0; + /* get the packet byte count */ + count = AVR32_EPTSTA_BYTE_COUNT(temp); + + /* verify data length */ + if (count != td->remainder) { + DPRINTFN(0, "Invalid SETUP packet " + "length, %d bytes\n", count); + goto not_complete; + } + if (count != sizeof(req)) { + DPRINTFN(0, "Unsupported SETUP packet " + "length, %d bytes\n", count); + goto not_complete; + } + /* receive data */ + memcpy(&req, sc->physdata, sizeof(req)); + + /* copy data into real buffer */ + usb2_copy_in(td->pc, 0, &req, sizeof(req)); + + td->offset = sizeof(req); + td->remainder = 0; + + /* sneak peek the set address */ + if ((req.bmRequestType == UT_WRITE_DEVICE) && + (req.bRequest == UR_SET_ADDRESS)) { + sc->sc_dv_addr = req.wValue[0] & 0x7F; + /* must write address before ZLP */ + avr32dci_mod_ctrl(sc, 0, AVR32_CTRL_DEV_FADDR_EN | + AVR32_CTRL_DEV_ADDR); + avr32dci_mod_ctrl(sc, sc->sc_dv_addr, 0); + } else { + sc->sc_dv_addr = 0xFF; + } + + /* clear SETUP packet interrupt */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(td->ep_no), AVR32_EPTSTA_RX_SETUP); + return (0); /* complete */ + +not_complete: + if (temp & AVR32_EPTSTA_RX_SETUP) { + /* clear SETUP packet interrupt */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(td->ep_no), AVR32_EPTSTA_RX_SETUP); + } + /* abort any ongoing transfer */ + if (!td->did_stall) { + DPRINTFN(5, "stalling\n"); + AVR32_WRITE_4(sc, AVR32_EPTSETSTA(td->ep_no), + AVR32_EPTSTA_FRCESTALL); + td->did_stall = 1; + } + return (1); /* not complete */ +} + +static uint8_t +avr32dci_data_rx(struct avr32dci_td *td) +{ + struct avr32dci_softc *sc; + struct usb2_page_search buf_res; + uint16_t count; + uint32_t temp; + uint8_t to; + uint8_t got_short; + + to = 4; /* don't loop forever! */ + got_short = 0; + + /* get pointer to softc */ + sc = AVR32_PC2SC(td->pc); + +repeat: + /* check if any of the FIFO banks have data */ + /* check endpoint status */ + temp = AVR32_READ_4(sc, AVR32_EPTSTA(td->ep_no)); + + DPRINTFN(5, "EPTSTA(%u)=0x%08x\n", td->ep_no, temp); + + if (temp & AVR32_EPTSTA_RX_SETUP) { + if (td->remainder == 0) { + /* + * We are actually complete and have + * received the next SETUP + */ + DPRINTFN(5, "faking complete\n"); + return (0); /* complete */ + } + /* + * USB Host Aborted the transfer. + */ + td->error = 1; + return (0); /* complete */ + } + /* check status */ + if (!(temp & AVR32_EPTSTA_RX_BK_RDY)) { + /* no data */ + goto not_complete; + } + /* get the packet byte count */ + count = AVR32_EPTSTA_BYTE_COUNT(temp); + + /* verify the packet byte count */ + if (count != td->max_packet_size) { + if (count < td->max_packet_size) { + /* we have a short packet */ + td->short_pkt = 1; + got_short = 1; + } else { + /* invalid USB packet */ + td->error = 1; + return (0); /* we are complete */ + } + } + /* verify the packet byte count */ + if (count > td->remainder) { + /* invalid USB packet */ + td->error = 1; + return (0); /* we are complete */ + } + while (count > 0) { + usb2_get_page(td->pc, td->offset, &buf_res); + + /* get correct length */ + if (buf_res.length > count) { + buf_res.length = count; + } + /* receive data */ + bcopy(sc->physdata + + (AVR32_EPTSTA_CURRENT_BANK(temp) << td->bank_shift) + + (td->ep_no << 16) + (td->offset % td->max_packet_size), + buf_res.buffer, buf_res.length) + /* update counters */ + count -= buf_res.length; + td->offset += buf_res.length; + td->remainder -= buf_res.length; + } + + /* clear OUT packet interrupt */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(td->ep_no), AVR32_EPTSTA_RX_BK_RDY); + + /* check if we are complete */ + if ((td->remainder == 0) || got_short) { + if (td->short_pkt) { + /* we are complete */ + return (0); + } + /* else need to receive a zero length packet */ + } + if (--to) { + goto repeat; + } +not_complete: + return (1); /* not complete */ +} + +static uint8_t +avr32dci_data_tx(struct avr32dci_td *td) +{ + struct avr32dci_softc *sc; + struct usb2_page_search buf_res; + uint16_t count; + uint8_t to; + uint32_t temp; + + to = 4; /* don't loop forever! */ + + /* get pointer to softc */ + sc = AVR32_PC2SC(td->pc); + +repeat: + + /* check endpoint status */ + temp = AVR32_READ_4(sc, AVR32_EPTSTA(td->ep_no)); + + DPRINTFN(5, "EPTSTA(%u)=0x%08x\n", td->ep_no, temp); + + if (temp & AVR32_EPTSTA_RX_SETUP) { + /* + * The current transfer was aborted + * by the USB Host + */ + td->error = 1; + return (0); /* complete */ + } + if (temp & AVR32_EPTSTA_TX_PK_RDY) { + /* cannot write any data - all banks are busy */ + goto not_complete; + } + count = td->max_packet_size; + if (td->remainder < count) { + /* we have a short packet */ + td->short_pkt = 1; + count = td->remainder; + } + while (count > 0) { + + usb2_get_page(td->pc, td->offset, &buf_res); + + /* get correct length */ + if (buf_res.length > count) { + buf_res.length = count; + } + /* transmit data */ + bcopy(buf_res.buffer, sc->physdata + + (AVR32_EPTSTA_CURRENT_BANK(temp) << td->bank_shift) + + (td->ep_no << 16) + (td->offset % td->max_packet_size), + buf_res.length) + /* update counters */ + count -= buf_res.length; + td->offset += buf_res.length; + td->remainder -= buf_res.length; + } + + /* allocate FIFO bank */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(td->ep_no), AVR32_EPTSTA_TX_BK_RDY); + + /* check remainder */ + if (td->remainder == 0) { + if (td->short_pkt) { + return (0); /* complete */ + } + /* else we need to transmit a short packet */ + } + if (--to) { + goto repeat; + } +not_complete: + return (1); /* not complete */ +} + +static uint8_t +avr32dci_data_tx_sync(struct avr32dci_td *td) +{ + struct avr32dci_softc *sc; + uint32_t temp; + + /* get pointer to softc */ + sc = AVR32_PC2SC(td->pc); + + /* check endpoint status */ + temp = AVR32_READ_4(sc, AVR32_EPTSTA(td->ep_no)); + + DPRINTFN(5, "EPTSTA(%u)=0x%08x\n", td->ep_no, temp); + + if (temp & AVR32_EPTSTA_RX_SETUP) { + DPRINTFN(5, "faking complete\n"); + /* Race condition */ + return (0); /* complete */ + } + /* + * The control endpoint has only got one bank, so if that bank + * is free the packet has been transferred! + */ + if (AVR32_EPTSTA_BUSY_BANK_STA(temp) != 0) { + /* cannot write any data - a bank is busy */ + goto not_complete; + } + if (sc->sc_dv_addr != 0xFF) { + /* set new address */ + avr32dci_set_address(sc, sc->sc_dv_addr); + } + return (0); /* complete */ + +not_complete: + return (1); /* not complete */ +} + +static uint8_t +avr32dci_xfer_do_fifo(struct usb2_xfer *xfer) +{ + struct avr32dci_td *td; + + DPRINTFN(9, "\n"); + + td = xfer->td_transfer_cache; + while (1) { + if ((td->func) (td)) { + /* operation in progress */ + break; + } + if (((void *)td) == xfer->td_transfer_last) { + goto done; + } + if (td->error) { + goto done; + } else if (td->remainder > 0) { + /* + * We had a short transfer. If there is no alternate + * next, stop processing ! + */ + if (!td->alt_next) { + goto done; + } + } + /* + * Fetch the next transfer descriptor and transfer + * some flags to the next transfer descriptor + */ + td = td->obj_next; + xfer->td_transfer_cache = td; + } + return (1); /* not complete */ + +done: + /* compute all actual lengths */ + + avr32dci_standard_done(xfer); + return (0); /* complete */ +} + +static void +avr32dci_interrupt_poll(struct avr32dci_softc *sc) +{ + struct usb2_xfer *xfer; + +repeat: + TAILQ_FOREACH(xfer, &sc->sc_bus.intr_q.head, wait_entry) { + if (!avr32dci_xfer_do_fifo(xfer)) { + /* queue has been modified */ + goto repeat; + } + } +} + +void +avr32dci_vbus_interrupt(struct avr32dci_softc *sc, uint8_t is_on) +{ + DPRINTFN(5, "vbus = %u\n", is_on); + + if (is_on) { + if (!sc->sc_flags.status_vbus) { + sc->sc_flags.status_vbus = 1; + + /* complete root HUB interrupt endpoint */ + + avr32dci_root_intr(sc); + } + } else { + if (sc->sc_flags.status_vbus) { + sc->sc_flags.status_vbus = 0; + sc->sc_flags.status_bus_reset = 0; + sc->sc_flags.status_suspend = 0; + sc->sc_flags.change_suspend = 0; + sc->sc_flags.change_connect = 1; + + /* complete root HUB interrupt endpoint */ + + avr32dci_root_intr(sc); + } + } +} + +void +avr32dci_interrupt(struct avr32dci_softc *sc) +{ + uint32_t status; + + USB_BUS_LOCK(&sc->sc_bus); + + /* read interrupt status */ + status = AVR32_READ_4(sc, AVR32_INTSTA); + + /* clear all set interrupts */ + AVR32_WRITE_4(sc, AVR32_CLRINT, status); + + DPRINTFN(14, "INTSTA=0x%08x\n", status); + + /* check for any bus state change interrupts */ + if (status & AVR32_INT_ENDRESET) { + + DPRINTFN(5, "end of reset\n"); + + /* set correct state */ + sc->sc_flags.status_bus_reset = 1; + sc->sc_flags.status_suspend = 0; + sc->sc_flags.change_suspend = 0; + sc->sc_flags.change_connect = 1; + + /* disable resume interrupt */ + avr32dci_mod_ien(sc, AVR32_INT_DET_SUSPD | + AVR32_INT_ENDRESET, AVR32_INT_WAKE_UP); + + /* complete root HUB interrupt endpoint */ + avr32dci_root_intr(sc); + } + /* + * If resume and suspend is set at the same time we interpret + * that like RESUME. Resume is set when there is at least 3 + * milliseconds of inactivity on the USB BUS. + */ + if (status & AVR32_INT_WAKE_UP) { + + DPRINTFN(5, "resume interrupt\n"); + + if (sc->sc_flags.status_suspend) { + /* update status bits */ + sc->sc_flags.status_suspend = 0; + sc->sc_flags.change_suspend = 1; + + /* disable resume interrupt */ + avr32dci_mod_ien(sc, AVR32_INT_DET_SUSPD | + AVR32_INT_ENDRESET, AVR32_INT_WAKE_UP); + + /* complete root HUB interrupt endpoint */ + avr32dci_root_intr(sc); + } + } else if (status & AVR32_INT_DET_SUSPD) { + + DPRINTFN(5, "suspend interrupt\n"); + + if (!sc->sc_flags.status_suspend) { + /* update status bits */ + sc->sc_flags.status_suspend = 1; + sc->sc_flags.change_suspend = 1; + + /* disable suspend interrupt */ + avr32dci_mod_ien(sc, AVR32_INT_WAKE_UP | + AVR32_INT_ENDRESET, AVR32_INT_DET_SUSPD); + + /* complete root HUB interrupt endpoint */ + avr32dci_root_intr(sc); + } + } + /* check for any endpoint interrupts */ + if (status & -AVR32_INT_EPT_INT(0)) { + + DPRINTFN(5, "real endpoint interrupt\n"); + + avr32dci_interrupt_poll(sc); + } + USB_BUS_UNLOCK(&sc->sc_bus); +} + +static void +avr32dci_setup_standard_chain_sub(struct avr32dci_std_temp *temp) +{ + struct avr32dci_td *td; + + /* get current Transfer Descriptor */ + td = temp->td_next; + temp->td = td; + + /* prepare for next TD */ + temp->td_next = td->obj_next; + + /* fill out the Transfer Descriptor */ + td->func = temp->func; + td->pc = temp->pc; + td->offset = temp->offset; + td->remainder = temp->len; + td->error = 0; + td->did_stall = temp->did_stall; + td->short_pkt = temp->short_pkt; + td->alt_next = temp->setup_alt_next; +} + +static void +avr32dci_setup_standard_chain(struct usb2_xfer *xfer) +{ + struct avr32dci_std_temp temp; + struct avr32dci_softc *sc; + struct avr32dci_td *td; + uint32_t x; + uint8_t ep_no; + uint8_t need_sync; + + DPRINTFN(9, "addr=%d endpt=%d sumlen=%d speed=%d\n", + xfer->address, UE_GET_ADDR(xfer->endpoint), + xfer->sumlen, usb2_get_speed(xfer->xroot->udev)); + + temp.max_frame_size = xfer->max_frame_size; + + td = xfer->td_start[0]; + xfer->td_transfer_first = td; + xfer->td_transfer_cache = td; + + /* setup temp */ + + temp.td = NULL; + temp.td_next = xfer->td_start[0]; + temp.offset = 0; + temp.setup_alt_next = xfer->flags_int.short_frames_ok; + temp.did_stall = !xfer->flags_int.control_stall; + + sc = AVR32_BUS2SC(xfer->xroot->bus); + ep_no = (xfer->endpoint & UE_ADDR); + + /* check if we should prepend a setup message */ + + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_hdr) { + + temp.func = &avr32dci_setup_rx; + temp.len = xfer->frlengths[0]; + temp.pc = xfer->frbuffers + 0; + temp.short_pkt = temp.len ? 1 : 0; + /* check for last frame */ + if (xfer->nframes == 1) { + /* no STATUS stage yet, SETUP is last */ + if (xfer->flags_int.control_act) + temp.setup_alt_next = 0; + } + avr32dci_setup_standard_chain_sub(&temp); + } + x = 1; + } else { + x = 0; + } + + if (x != xfer->nframes) { + if (xfer->endpoint & UE_DIR_IN) { + temp.func = &avr32dci_data_tx; + need_sync = 1; + } else { + temp.func = &avr32dci_data_rx; + need_sync = 0; + } + + /* setup "pc" pointer */ + temp.pc = xfer->frbuffers + x; + } else { + need_sync = 0; + } + while (x != xfer->nframes) { + + /* DATA0 / DATA1 message */ + + temp.len = xfer->frlengths[x]; + + x++; + + if (x == xfer->nframes) { + if (xfer->flags_int.control_xfr) { + if (xfer->flags_int.control_act) { + temp.setup_alt_next = 0; + } + } else { + temp.setup_alt_next = 0; + } + } + if (temp.len == 0) { + + /* make sure that we send an USB packet */ + + temp.short_pkt = 0; + + } else { + + /* regular data transfer */ + + temp.short_pkt = (xfer->flags.force_short_xfer) ? 0 : 1; + } + + avr32dci_setup_standard_chain_sub(&temp); + + if (xfer->flags_int.isochronous_xfr) { + temp.offset += temp.len; + } else { + /* get next Page Cache pointer */ + temp.pc = xfer->frbuffers + x; + } + } + + if (xfer->flags_int.control_xfr) { + + /* always setup a valid "pc" pointer for status and sync */ + temp.pc = xfer->frbuffers + 0; + temp.len = 0; + temp.short_pkt = 0; + temp.setup_alt_next = 0; + + /* check if we need to sync */ + if (need_sync) { + /* we need a SYNC point after TX */ + temp.func = &avr32dci_data_tx_sync; + avr32dci_setup_standard_chain_sub(&temp); + } + /* check if we should append a status stage */ + if (!xfer->flags_int.control_act) { + + /* + * Send a DATA1 message and invert the current + * endpoint direction. + */ + if (xfer->endpoint & UE_DIR_IN) { + temp.func = &avr32dci_data_rx; + need_sync = 0; + } else { + temp.func = &avr32dci_data_tx; + need_sync = 1; + } + + avr32dci_setup_standard_chain_sub(&temp); + if (need_sync) { + /* we need a SYNC point after TX */ + temp.func = &avr32dci_data_tx_sync; + avr32dci_setup_standard_chain_sub(&temp); + } + } + } + /* must have at least one frame! */ + td = temp.td; + xfer->td_transfer_last = td; +} + +static void +avr32dci_timeout(void *arg) +{ + struct usb2_xfer *xfer = arg; + + DPRINTF("xfer=%p\n", xfer); + + USB_BUS_LOCK_ASSERT(xfer->xroot->bus, MA_OWNED); + + /* transfer is transferred */ + avr32dci_device_done(xfer, USB_ERR_TIMEOUT); +} + +static void +avr32dci_start_standard_chain(struct usb2_xfer *xfer) +{ + DPRINTFN(9, "\n"); + + /* poll one time - will turn on interrupts */ + if (avr32dci_xfer_do_fifo(xfer)) { + uint8_t ep_no = xfer->endpoint & UE_ADDR_MASK; + + avr32dci_mod_ien(sc, AVR32_INT_EPT_INT(ep_no), 0); + + /* put transfer on interrupt queue */ + usb2_transfer_enqueue(&xfer->xroot->bus->intr_q, xfer); + + /* start timeout, if any */ + if (xfer->timeout != 0) { + usb2_transfer_timeout_ms(xfer, + &avr32dci_timeout, xfer->timeout); + } + } +} + +static void +avr32dci_root_intr(struct avr32dci_softc *sc) +{ + DPRINTFN(9, "\n"); + + USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); + + /* set port bit */ + sc->sc_hub_idata[0] = 0x02; /* we only have one port */ + + uhub_root_intr(&sc->sc_bus, sc->sc_hub_idata, + sizeof(sc->sc_hub_idata)); +} + +static usb2_error_t +avr32dci_standard_done_sub(struct usb2_xfer *xfer) +{ + struct avr32dci_td *td; + uint32_t len; + uint8_t error; + + DPRINTFN(9, "\n"); + + td = xfer->td_transfer_cache; + + do { + len = td->remainder; + + if (xfer->aframes != xfer->nframes) { + /* + * Verify the length and subtract + * the remainder from "frlengths[]": + */ + if (len > xfer->frlengths[xfer->aframes]) { + td->error = 1; + } else { + xfer->frlengths[xfer->aframes] -= len; + } + } + /* Check for transfer error */ + if (td->error) { + /* the transfer is finished */ + error = 1; + td = NULL; + break; + } + /* Check for short transfer */ + if (len > 0) { + if (xfer->flags_int.short_frames_ok) { + /* follow alt next */ + if (td->alt_next) { + td = td->obj_next; + } else { + td = NULL; + } + } else { + /* the transfer is finished */ + td = NULL; + } + error = 0; + break; + } + td = td->obj_next; + + /* this USB frame is complete */ + error = 0; + break; + + } while (0); + + /* update transfer cache */ + + xfer->td_transfer_cache = td; + + return (error ? + USB_ERR_STALLED : USB_ERR_NORMAL_COMPLETION); +} + +static void +avr32dci_standard_done(struct usb2_xfer *xfer) +{ + usb2_error_t err = 0; + + DPRINTFN(13, "xfer=%p pipe=%p transfer done\n", + xfer, xfer->pipe); + + /* reset scanner */ + + xfer->td_transfer_cache = xfer->td_transfer_first; + + if (xfer->flags_int.control_xfr) { + + if (xfer->flags_int.control_hdr) { + + err = avr32dci_standard_done_sub(xfer); + } + xfer->aframes = 1; + + if (xfer->td_transfer_cache == NULL) { + goto done; + } + } + while (xfer->aframes != xfer->nframes) { + + err = avr32dci_standard_done_sub(xfer); + xfer->aframes++; + + if (xfer->td_transfer_cache == NULL) { + goto done; + } + } + + if (xfer->flags_int.control_xfr && + !xfer->flags_int.control_act) { + + err = avr32dci_standard_done_sub(xfer); + } +done: + avr32dci_device_done(xfer, err); +} + +/*------------------------------------------------------------------------* + * avr32dci_device_done + * + * NOTE: this function can be called more than one time on the + * same USB transfer! + *------------------------------------------------------------------------*/ +static void +avr32dci_device_done(struct usb2_xfer *xfer, usb2_error_t error) +{ + struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus); + uint8_t ep_no; + + USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); + + DPRINTFN(9, "xfer=%p, pipe=%p, error=%d\n", + xfer, xfer->pipe, error); + + if (xfer->flags_int.usb_mode == USB_MODE_DEVICE) { + ep_no = (xfer->endpoint & UE_ADDR); + + /* disable endpoint interrupt */ + avr32dci_mod_ien(sc, 0, AVR32_INT_EPT_INT(ep_no)); + + DPRINTFN(15, "disabled interrupts!\n"); + } + /* dequeue transfer and start next transfer */ + usb2_transfer_done(xfer, error); +} + +static void +avr32dci_set_stall(struct usb2_device *udev, struct usb2_xfer *xfer, + struct usb2_pipe *pipe) +{ + struct avr32dci_softc *sc; + uint8_t ep_no; + + USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); + + DPRINTFN(5, "pipe=%p\n", pipe); + + if (xfer) { + /* cancel any ongoing transfers */ + avr32dci_device_done(xfer, USB_ERR_STALLED); + } + sc = AVR32_BUS2SC(udev->bus); + /* get endpoint number */ + ep_no = (pipe->edesc->bEndpointAddress & UE_ADDR); + /* set stall */ + AVR32_WRITE_4(sc, AVR32_EPTSETSTA(ep_no), AVR32_EPTSTA_FRCESTALL); +} + +static void +avr32dci_clear_stall_sub(struct avr32dci_softc *sc, uint8_t ep_no, + uint8_t ep_type, uint8_t ep_dir) +{ + const struct usb2_hw_ep_profile *pf; + uint32_t temp; + uint32_t epsize; + uint8_t n; + + if (ep_type == UE_CONTROL) { + /* clearing stall is not needed */ + return; + } + /* set endpoint reset */ + AVR32_WRITE_4(sc, AVR32_EPTRST, AVR32_EPTRST_MASK(ep_no)); + + /* set stall */ + AVR32_WRITE_4(sc, AVR32_EPTSETSTA(ep_no), AVR32_EPTSTA_FRCESTALL); + + /* reset data toggle */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(ep_no), AVR32_EPTSTA_TOGGLESQ); + + /* clear stall */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(ep_no), AVR32_EPTSTA_FRCESTALL); + + if (ep_type == UE_BULK) { + temp = AVR32_EPTCFG_TYPE_BULK; + } else if (ep_type == UE_INTERRUPT) { + temp = AVR32_EPTCFG_TYPE_INTR; + } else { + temp = AVR32_EPTCFG_TYPE_ISOC | + AVR32_EPTCFG_NB_TRANS(1); + } + if (ep_dir & UE_DIR_IN) { + temp |= AVR32_EPTCFG_EPDIR_IN; + } + avr32dci_get_hw_ep_profile(NULL, &pf, ep_no); + + /* compute endpoint size (use maximum) */ + epsize = pf->max_in_frame_size | pf->max_out_frame_size; + n = 0; + while ((epsize /= 2)) + n++; + temp |= AVR32_EPTCFG_EPSIZE(n); + + /* use the maximum number of banks supported */ + if (ep_no < 1) + temp |= AVR32_EPTCFG_NBANK(1); + else if (ep_no < 3) + temp |= AVR32_EPTCFG_NBANK(2); + else + temp |= AVR32_EPTCFG_NBANK(3); + + AVR32_WRITE_4(sc, AVR32_EPTCFG(ep_no), temp); + + temp = AVR32_READ_4(sc, AVR32_EPTCFG(ep_no)); + + if (!(temp & AVR32_EPTCFG_EPT_MAPD)) { + DPRINTFN(0, "Chip rejected configuration\n"); + } else { + AVR32_WRITE_4(sc, AVR32_EPTCTLENB(ep_no), + AVR32_EPTCTL_EPT_ENABL); + } +} + +static void +avr32dci_clear_stall(struct usb2_device *udev, struct usb2_pipe *pipe) +{ + struct avr32dci_softc *sc; + struct usb2_endpoint_descriptor *ed; + + DPRINTFN(5, "pipe=%p\n", pipe); + + USB_BUS_LOCK_ASSERT(udev->bus, MA_OWNED); + + /* check mode */ + if (udev->flags.usb_mode != USB_MODE_DEVICE) { + /* not supported */ + return; + } + /* get softc */ + sc = AVR32_BUS2SC(udev->bus); + + /* get endpoint descriptor */ + ed = pipe->edesc; + + /* reset endpoint */ + avr32dci_clear_stall_sub(sc, + (ed->bEndpointAddress & UE_ADDR), + (ed->bmAttributes & UE_XFERTYPE), + (ed->bEndpointAddress & (UE_DIR_IN | UE_DIR_OUT))); +} + +usb2_error_t +avr32dci_init(struct avr32dci_softc *sc) +{ + uint8_t n; + + DPRINTF("start\n"); + + /* set up the bus structure */ + sc->sc_bus.usbrev = USB_REV_1_1; + sc->sc_bus.methods = &avr32dci_bus_methods; + + USB_BUS_LOCK(&sc->sc_bus); + + /* make sure USB is enabled */ + avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_EN_USBA, 0); + + /* turn on clocks */ + (sc->sc_clocks_on) (&sc->sc_bus); + + /* make sure device is re-enumerated */ + avr32dci_mod_ctrl(sc, AVR32_CTRL_DEV_DETACH, 0); + + /* wait a little for things to stabilise */ + usb2_pause_mtx(&sc->sc_bus.bus_mtx, hz / 20); + + /* disable interrupts */ + avr32dci_mod_ien(sc, 0, 0xFFFFFFFF); + + /* enable interrupts */ + avr32dci_mod_ien(sc, AVR32_INT_DET_SUSPD | + AVR32_INT_ENDRESET, 0); + + /* reset all endpoints */ +/**INDENT** Warning@1207: Extra ) */ + AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1)); + + /* disable all endpoints */ + for (n = 0; n != AVR32_EP_MAX; n++) { + /* disable endpoint */ + AVR32_WRITE_4(sc, AVR32_EPTCTLDIS(n), AVR32_EPTCTL_EPT_ENABL); + } + + /* turn off clocks */ + + avr32dci_clocks_off(sc); + + USB_BUS_UNLOCK(&sc->sc_bus); + + /* catch any lost interrupts */ + + avr32dci_do_poll(&sc->sc_bus); + + return (0); /* success */ +} + +void +avr32dci_uninit(struct avr32dci_softc *sc) +{ + uint8_t n; + + USB_BUS_LOCK(&sc->sc_bus); + + /* turn on clocks */ + (sc->sc_clocks_on) (&sc->sc_bus); + + /* disable interrupts */ + avr32dci_mod_ien(sc, 0, 0xFFFFFFFF); + + /* reset all endpoints */ +/**INDENT** Warning@1242: Extra ) */ + AVR32_WRITE_4(sc, AVR32_EPTRST, (1 << AVR32_EP_MAX) - 1)); + + /* disable all endpoints */ + for (n = 0; n != AVR32_EP_MAX; n++) { + /* disable endpoint */ + AVR32_WRITE_4(sc, AVR32_EPTCTLDIS(n), AVR32_EPTCTL_EPT_ENABL); + } + + sc->sc_flags.port_powered = 0; + sc->sc_flags.status_vbus = 0; + sc->sc_flags.status_bus_reset = 0; + sc->sc_flags.status_suspend = 0; + sc->sc_flags.change_suspend = 0; + sc->sc_flags.change_connect = 1; + + avr32dci_pull_down(sc); + avr32dci_clocks_off(sc); + + USB_BUS_UNLOCK(&sc->sc_bus); +} + +void +avr32dci_suspend(struct avr32dci_softc *sc) +{ + return; +} + +void +avr32dci_resume(struct avr32dci_softc *sc) +{ + return; +} + +static void +avr32dci_do_poll(struct usb2_bus *bus) +{ + struct avr32dci_softc *sc = AVR32_BUS2SC(bus); + + USB_BUS_LOCK(&sc->sc_bus); + avr32dci_interrupt_poll(sc); + USB_BUS_UNLOCK(&sc->sc_bus); +} + +/*------------------------------------------------------------------------* + * at91dci bulk support + * at91dci control support + * at91dci interrupt support + *------------------------------------------------------------------------*/ +static void +avr32dci_device_non_isoc_open(struct usb2_xfer *xfer) +{ + return; +} + +static void +avr32dci_device_non_isoc_close(struct usb2_xfer *xfer) +{ + avr32dci_device_done(xfer, USB_ERR_CANCELLED); +} + +static void +avr32dci_device_non_isoc_enter(struct usb2_xfer *xfer) +{ + return; +} + +static void +avr32dci_device_non_isoc_start(struct usb2_xfer *xfer) +{ + /* setup TDs */ + avr32dci_setup_standard_chain(xfer); + avr32dci_start_standard_chain(xfer); +} + +struct usb2_pipe_methods avr32dci_device_non_isoc_methods = +{ + .open = avr32dci_device_non_isoc_open, + .close = avr32dci_device_non_isoc_close, + .enter = avr32dci_device_non_isoc_enter, + .start = avr32dci_device_non_isoc_start, +}; + +/*------------------------------------------------------------------------* + * at91dci full speed isochronous support + *------------------------------------------------------------------------*/ +static void +avr32dci_device_isoc_fs_open(struct usb2_xfer *xfer) +{ + return; +} + +static void +avr32dci_device_isoc_fs_close(struct usb2_xfer *xfer) +{ + avr32dci_device_done(xfer, USB_ERR_CANCELLED); +} + +static void +avr32dci_device_isoc_fs_enter(struct usb2_xfer *xfer) +{ + struct avr32dci_softc *sc = AVR32_BUS2SC(xfer->xroot->bus); + uint32_t temp; + uint32_t nframes; + uint8_t ep_no; + + DPRINTFN(6, "xfer=%p next=%d nframes=%d\n", + xfer, xfer->pipe->isoc_next, xfer->nframes); + + /* get the current frame index */ + ep_no = xfer->endpoint & UE_ADDR_MASK; + nframes = (AVR32_READ_4(sc, AVR32_FNUM) / 8); + + nframes &= AVR32_FRAME_MASK; + + /* + * check if the frame index is within the window where the frames + * will be inserted + */ + temp = (nframes - xfer->pipe->isoc_next) & AVR32_FRAME_MASK; + + if ((xfer->pipe->is_synced == 0) || + (temp < xfer->nframes)) { + /* + * If there is data underflow or the pipe queue is + * empty we schedule the transfer a few frames ahead + * of the current frame position. Else two isochronous + * transfers might overlap. + */ + xfer->pipe->isoc_next = (nframes + 3) & AVR32_FRAME_MASK; + xfer->pipe->is_synced = 1; + DPRINTFN(3, "start next=%d\n", xfer->pipe->isoc_next); + } + /* + * compute how many milliseconds the insertion is ahead of the + * current frame position: + */ + temp = (xfer->pipe->isoc_next - nframes) & AVR32_FRAME_MASK; + + /* + * pre-compute when the isochronous transfer will be finished: + */ + xfer->isoc_time_complete = + usb2_isoc_time_expand(&sc->sc_bus, nframes) + temp + + xfer->nframes; + + /* compute frame number for next insertion */ + xfer->pipe->isoc_next += xfer->nframes; + + /* setup TDs */ + avr32dci_setup_standard_chain(xfer); +} + +static void +avr32dci_device_isoc_fs_start(struct usb2_xfer *xfer) +{ + /* start TD chain */ + avr32dci_start_standard_chain(xfer); +} + +struct usb2_pipe_methods avr32dci_device_isoc_fs_methods = +{ + .open = avr32dci_device_isoc_fs_open, + .close = avr32dci_device_isoc_fs_close, + .enter = avr32dci_device_isoc_fs_enter, + .start = avr32dci_device_isoc_fs_start, +}; + +/*------------------------------------------------------------------------* + * at91dci root control support + *------------------------------------------------------------------------* + * Simulate a hardware HUB by handling all the necessary requests. + *------------------------------------------------------------------------*/ + +static const struct usb2_device_descriptor avr32dci_devd = { + .bLength = sizeof(struct usb2_device_descriptor), + .bDescriptorType = UDESC_DEVICE, + .bcdUSB = {0x00, 0x02}, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_HSHUBSTT, + .bMaxPacketSize = 64, + .bcdDevice = {0x00, 0x01}, + .iManufacturer = 1, + .iProduct = 2, + .bNumConfigurations = 1, +}; + +static const struct usb2_device_qualifier avr32dci_odevd = { + .bLength = sizeof(struct usb2_device_qualifier), + .bDescriptorType = UDESC_DEVICE_QUALIFIER, + .bcdUSB = {0x00, 0x02}, + .bDeviceClass = UDCLASS_HUB, + .bDeviceSubClass = UDSUBCLASS_HUB, + .bDeviceProtocol = UDPROTO_FSHUB, + .bMaxPacketSize0 = 0, + .bNumConfigurations = 0, +}; + +static const struct avr32dci_config_desc avr32dci_confd = { + .confd = { + .bLength = sizeof(struct usb2_config_descriptor), + .bDescriptorType = UDESC_CONFIG, + .wTotalLength[0] = sizeof(avr32dci_confd), + .bNumInterface = 1, + .bConfigurationValue = 1, + .iConfiguration = 0, + .bmAttributes = UC_SELF_POWERED, + .bMaxPower = 0, + }, + .ifcd = { + .bLength = sizeof(struct usb2_interface_descriptor), + .bDescriptorType = UDESC_INTERFACE, + .bNumEndpoints = 1, + .bInterfaceClass = UICLASS_HUB, + .bInterfaceSubClass = UISUBCLASS_HUB, + .bInterfaceProtocol = UIPROTO_HSHUBSTT, + }, + .endpd = { + .bLength = sizeof(struct usb2_endpoint_descriptor), + .bDescriptorType = UDESC_ENDPOINT, + .bEndpointAddress = (UE_DIR_IN | AVR32_INTR_ENDPT), + .bmAttributes = UE_INTERRUPT, + .wMaxPacketSize[0] = 8, + .bInterval = 255, + }, +}; + +static const struct usb2_hub_descriptor_min avr32dci_hubd = { + .bDescLength = sizeof(avr32dci_hubd), + .bDescriptorType = UDESC_HUB, + .bNbrPorts = 1, + .wHubCharacteristics[0] = + (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) & 0xFF, + .wHubCharacteristics[1] = + (UHD_PWR_NO_SWITCH | UHD_OC_INDIVIDUAL) >> 8, + .bPwrOn2PwrGood = 50, + .bHubContrCurrent = 0, + .DeviceRemovable = {0}, /* port is removable */ +}; + +#define STRING_LANG \ + 0x09, 0x04, /* American English */ + +#define STRING_VENDOR \ + 'A', 0, 'V', 0, 'R', 0, '3', 0, '2', 0 + +#define STRING_PRODUCT \ + 'D', 0, 'C', 0, 'I', 0, ' ', 0, 'R', 0, \ + 'o', 0, 'o', 0, 't', 0, ' ', 0, 'H', 0, \ + 'U', 0, 'B', 0, + +USB_MAKE_STRING_DESC(STRING_LANG, avr32dci_langtab); +USB_MAKE_STRING_DESC(STRING_VENDOR, avr32dci_vendor); +USB_MAKE_STRING_DESC(STRING_PRODUCT, avr32dci_product); + +static usb2_error_t +avr32dci_roothub_exec(struct usb2_device *udev, + struct usb2_device_request *req, const void **pptr, uint16_t *plength) +{ + struct avr32dci_softc *sc = AVR32_BUS2SC(udev->bus); + const void *ptr; + uint16_t len; + uint16_t value; + uint16_t index; + uint32_t temp; + usb2_error_t err; + + USB_BUS_LOCK_ASSERT(&sc->sc_bus, MA_OWNED); + + /* buffer reset */ + ptr = (const void *)&sc->sc_hub_temp; + len = 0; + err = 0; + + value = UGETW(req->wValue); + index = UGETW(req->wIndex); + + /* demultiplex the control request */ + + switch (req->bmRequestType) { + case UT_READ_DEVICE: + switch (req->bRequest) { + case UR_GET_DESCRIPTOR: + goto tr_handle_get_descriptor; + case UR_GET_CONFIG: + goto tr_handle_get_config; + case UR_GET_STATUS: + goto tr_handle_get_status; + default: + goto tr_stalled; + } + break; + + case UT_WRITE_DEVICE: + switch (req->bRequest) { + case UR_SET_ADDRESS: + goto tr_handle_set_address; + case UR_SET_CONFIG: + goto tr_handle_set_config; + case UR_CLEAR_FEATURE: + goto tr_valid; /* nop */ + case UR_SET_DESCRIPTOR: + goto tr_valid; /* nop */ + case UR_SET_FEATURE: + default: + goto tr_stalled; + } + break; + + case UT_WRITE_ENDPOINT: + switch (req->bRequest) { + case UR_CLEAR_FEATURE: + switch (UGETW(req->wValue)) { + case UF_ENDPOINT_HALT: + goto tr_handle_clear_halt; + case UF_DEVICE_REMOTE_WAKEUP: + goto tr_handle_clear_wakeup; + default: + goto tr_stalled; + } + break; + case UR_SET_FEATURE: + switch (UGETW(req->wValue)) { + case UF_ENDPOINT_HALT: + goto tr_handle_set_halt; + case UF_DEVICE_REMOTE_WAKEUP: + goto tr_handle_set_wakeup; + default: + goto tr_stalled; + } + break; + case UR_SYNCH_FRAME: + goto tr_valid; /* nop */ + default: + goto tr_stalled; + } + break; + + case UT_READ_ENDPOINT: + switch (req->bRequest) { + case UR_GET_STATUS: + goto tr_handle_get_ep_status; + default: + goto tr_stalled; + } + break; + + case UT_WRITE_INTERFACE: + switch (req->bRequest) { + case UR_SET_INTERFACE: + goto tr_handle_set_interface; + case UR_CLEAR_FEATURE: + goto tr_valid; /* nop */ + case UR_SET_FEATURE: + default: + goto tr_stalled; + } + break; + + case UT_READ_INTERFACE: + switch (req->bRequest) { + case UR_GET_INTERFACE: + goto tr_handle_get_interface; + case UR_GET_STATUS: + goto tr_handle_get_iface_status; + default: + goto tr_stalled; + } + break; + + case UT_WRITE_CLASS_INTERFACE: + case UT_WRITE_VENDOR_INTERFACE: + /* XXX forward */ + break; + + case UT_READ_CLASS_INTERFACE: + case UT_READ_VENDOR_INTERFACE: + /* XXX forward */ + break; + + case UT_WRITE_CLASS_DEVICE: + switch (req->bRequest) { + case UR_CLEAR_FEATURE: + goto tr_valid; + case UR_SET_DESCRIPTOR: + case UR_SET_FEATURE: + break; + default: + goto tr_stalled; + } + break; + + case UT_WRITE_CLASS_OTHER: + switch (req->bRequest) { + case UR_CLEAR_FEATURE: + goto tr_handle_clear_port_feature; + case UR_SET_FEATURE: + goto tr_handle_set_port_feature; + case UR_CLEAR_TT_BUFFER: + case UR_RESET_TT: + case UR_STOP_TT: + goto tr_valid; + + default: + goto tr_stalled; + } + break; + + case UT_READ_CLASS_OTHER: + switch (req->bRequest) { + case UR_GET_TT_STATE: + goto tr_handle_get_tt_state; + case UR_GET_STATUS: + goto tr_handle_get_port_status; + default: + goto tr_stalled; + } + break; + + case UT_READ_CLASS_DEVICE: + switch (req->bRequest) { + case UR_GET_DESCRIPTOR: + goto tr_handle_get_class_descriptor; + case UR_GET_STATUS: + goto tr_handle_get_class_status; + + default: + goto tr_stalled; + } + break; + default: + goto tr_stalled; + } + goto tr_valid; + +tr_handle_get_descriptor: + switch (value >> 8) { + case UDESC_DEVICE: + if (value & 0xff) { + goto tr_stalled; + } + len = sizeof(avr32dci_devd); + ptr = (const void *)&avr32dci_devd; + goto tr_valid; + case UDESC_CONFIG: + if (value & 0xff) { + goto tr_stalled; + } + len = sizeof(avr32dci_confd); + ptr = (const void *)&avr32dci_confd; + goto tr_valid; + case UDESC_STRING: + switch (value & 0xff) { + case 0: /* Language table */ + len = sizeof(avr32dci_langtab); + ptr = (const void *)&avr32dci_langtab; + goto tr_valid; + + case 1: /* Vendor */ + len = sizeof(avr32dci_vendor); + ptr = (const void *)&avr32dci_vendor; + goto tr_valid; + + case 2: /* Product */ + len = sizeof(avr32dci_product); + ptr = (const void *)&avr32dci_product; + goto tr_valid; + default: + break; + } + break; + default: + goto tr_stalled; + } + goto tr_stalled; + +tr_handle_get_config: + len = 1; + sc->sc_hub_temp.wValue[0] = sc->sc_conf; + goto tr_valid; + +tr_handle_get_status: + len = 2; + USETW(sc->sc_hub_temp.wValue, UDS_SELF_POWERED); + goto tr_valid; + +tr_handle_set_address: + if (value & 0xFF00) { + goto tr_stalled; + } + sc->sc_rt_addr = value; + goto tr_valid; + +tr_handle_set_config: + if (value >= 2) { + goto tr_stalled; + } + sc->sc_conf = value; + goto tr_valid; + +tr_handle_get_interface: + len = 1; + sc->sc_hub_temp.wValue[0] = 0; + goto tr_valid; + +tr_handle_get_tt_state: +tr_handle_get_class_status: +tr_handle_get_iface_status: +tr_handle_get_ep_status: + len = 2; + USETW(sc->sc_hub_temp.wValue, 0); + goto tr_valid; + +tr_handle_set_halt: +tr_handle_set_interface: +tr_handle_set_wakeup: +tr_handle_clear_wakeup: +tr_handle_clear_halt: + goto tr_valid; + +tr_handle_clear_port_feature: + if (index != 1) { + goto tr_stalled; + } + DPRINTFN(9, "UR_CLEAR_PORT_FEATURE on port %d\n", index); + + switch (value) { + case UHF_PORT_SUSPEND: + avr32dci_wakeup_peer(sc); + break; + + case UHF_PORT_ENABLE: + sc->sc_flags.port_enabled = 0; + break; + + case UHF_PORT_TEST: + case UHF_PORT_INDICATOR: + case UHF_C_PORT_ENABLE: + case UHF_C_PORT_OVER_CURRENT: + case UHF_C_PORT_RESET: + /* nops */ + break; + case UHF_PORT_POWER: + sc->sc_flags.port_powered = 0; + avr32dci_pull_down(sc); + avr32dci_clocks_off(sc); + break; + case UHF_C_PORT_CONNECTION: + /* clear connect change flag */ + sc->sc_flags.change_connect = 0; + + if (!sc->sc_flags.status_bus_reset) { + /* we are not connected */ + break; + } + /* configure the control endpoint */ + /* set endpoint reset */ + AVR32_WRITE_4(sc, AVR32_EPTRST, AVR32_EPTRST_MASK(0)); + + /* set stall */ + AVR32_WRITE_4(sc, AVR32_EPTSETSTA(0), AVR32_EPTSTA_FRCESTALL); + + /* reset data toggle */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(0), AVR32_EPTSTA_TOGGLESQ); + + /* clear stall */ + AVR32_WRITE_4(sc, AVR32_EPTCLRSTA(0), AVR32_EPTSTA_FRCESTALL); + + /* configure */ + AVR32_WRITE_4(sc, AVR32_EPTCFG(0), AVR32_EPTCFG_TYPE_CONTROL | + AVR32_EPTCFG_NBANK(1) | AVR32_EPTCFG_EPSIZE(6)); + + temp = AVR32_READ_4(sc, AVR32_EPTCFG(0)); + + if (!(temp & AVR32_EPTCFG_EPT_MAPD)) { + DPRINTFN(0, "Chip rejected configuration\n"); + } else { + AVR32_WRITE_4(sc, AVR32_EPTCTLENB(0), + AVR32_EPTCTL_EPT_ENABL); + } + break; + case UHF_C_PORT_SUSPEND: + sc->sc_flags.change_suspend = 0; + break; + default: + err = USB_ERR_IOERROR; + goto done; + } + goto tr_valid; + +tr_handle_set_port_feature: + if (index != 1) { + goto tr_stalled; + } + DPRINTFN(9, "UR_SET_PORT_FEATURE\n"); + + switch (value) { + case UHF_PORT_ENABLE: + sc->sc_flags.port_enabled = 1; + break; + case UHF_PORT_SUSPEND: + case UHF_PORT_RESET: + case UHF_PORT_TEST: + case UHF_PORT_INDICATOR: + /* nops */ + break; + case UHF_PORT_POWER: + sc->sc_flags.port_powered = 1; + break; + default: + err = USB_ERR_IOERROR; + goto done; + } + goto tr_valid; + +tr_handle_get_port_status: + + DPRINTFN(9, "UR_GET_PORT_STATUS\n"); + + if (index != 1) { + goto tr_stalled; + } + if (sc->sc_flags.status_vbus) { + avr32dci_clocks_on(sc); + avr32dci_pull_up(sc); + } else { + avr32dci_pull_down(sc); + avr32dci_clocks_off(sc); + } + + /* Select Device Side Mode */ + + value = UPS_PORT_MODE_DEVICE; + + /* Check for High Speed */ + if (AVR32_READ_4(sc, AVR32_INTSTA) & AVR32_INT_SPEED) + value |= UPS_HIGH_SPEED; + + if (sc->sc_flags.port_powered) { + value |= UPS_PORT_POWER; + } + if (sc->sc_flags.port_enabled) { + value |= UPS_PORT_ENABLED; + } + if (sc->sc_flags.status_vbus && + sc->sc_flags.status_bus_reset) { + value |= UPS_CURRENT_CONNECT_STATUS; + } + if (sc->sc_flags.status_suspend) { + value |= UPS_SUSPEND; + } + USETW(sc->sc_hub_temp.ps.wPortStatus, value); + + value = 0; + + if (sc->sc_flags.change_connect) { + value |= UPS_C_CONNECT_STATUS; + } + if (sc->sc_flags.change_suspend) { + value |= UPS_C_SUSPEND; + } + USETW(sc->sc_hub_temp.ps.wPortChange, value); + len = sizeof(sc->sc_hub_temp.ps); + goto tr_valid; + +tr_handle_get_class_descriptor: + if (value & 0xFF) { + goto tr_stalled; + } + ptr = (const void *)&avr32dci_hubd; + len = sizeof(avr32dci_hubd); + goto tr_valid; + +tr_stalled: + err = USB_ERR_STALLED; +tr_valid: +done: + *plength = len; + *pptr = ptr; + return (err); +} + +static void +avr32dci_xfer_setup(struct usb2_setup_params *parm) +{ + const struct usb2_hw_ep_profile *pf; + struct avr32dci_softc *sc; + struct usb2_xfer *xfer; + void *last_obj; + uint32_t ntd; + uint32_t n; + uint8_t ep_no; + + sc = AVR32_BUS2SC(parm->udev->bus); + xfer = parm->curr_xfer; + + /* + * NOTE: This driver does not use any of the parameters that + * are computed from the following values. Just set some + * reasonable dummies: + */ + parm->hc_max_packet_size = 0x400; + parm->hc_max_packet_count = 1; + parm->hc_max_frame_size = 0x400; + + usb2_transfer_setup_sub(parm); + + /* + * compute maximum number of TDs + */ + if ((xfer->pipe->edesc->bmAttributes & UE_XFERTYPE) == UE_CONTROL) { + + ntd = xfer->nframes + 1 /* STATUS */ + 1 /* SYNC 1 */ + + 1 /* SYNC 2 */ ; + } else { + + ntd = xfer->nframes + 1 /* SYNC */ ; + } + + /* + * check if "usb2_transfer_setup_sub" set an error + */ + if (parm->err) + return; + + /* + * allocate transfer descriptors + */ + last_obj = NULL; + + /* + * get profile stuff + */ + ep_no = xfer->endpoint & UE_ADDR; + avr32dci_get_hw_ep_profile(parm->udev, &pf, ep_no); + + if (pf == NULL) { + /* should not happen */ + parm->err = USB_ERR_INVAL; + return; + } + /* align data */ + parm->size[0] += ((-parm->size[0]) & (USB_HOST_ALIGN - 1)); + + for (n = 0; n != ntd; n++) { + + struct avr32dci_td *td; + + if (parm->buf) { + uint32_t temp; + + td = USB_ADD_BYTES(parm->buf, parm->size[0]); + + /* init TD */ + td->max_packet_size = xfer->max_packet_size; + td->ep_no = ep_no; + temp = pf->max_in_frame_size | pf->max_out_frame_size; + td->bank_shift = 0; + while ((temp /= 2)) + td->bank_shift++; + if (pf->support_multi_buffer) { + td->support_multi_buffer = 1; + } + td->obj_next = last_obj; + + last_obj = td; + } + parm->size[0] += sizeof(*td); + } + + xfer->td_start[0] = last_obj; +} + +static void +avr32dci_xfer_unsetup(struct usb2_xfer *xfer) +{ + return; +} + +static void +avr32dci_pipe_init(struct usb2_device *udev, struct usb2_endpoint_descriptor *edesc, + struct usb2_pipe *pipe) +{ + struct avr32dci_softc *sc = AVR32_BUS2SC(udev->bus); + + DPRINTFN(2, "pipe=%p, addr=%d, endpt=%d, mode=%d (%d,%d)\n", + pipe, udev->address, + edesc->bEndpointAddress, udev->flags.usb_mode, + sc->sc_rt_addr, udev->device_index); + + if (udev->device_index != sc->sc_rt_addr) { + + if (udev->flags.usb_mode != USB_MODE_DEVICE) { + /* not supported */ + return; + } + if ((udev->speed != USB_SPEED_FULL) && + (udev->speed != USB_SPEED_HIGH)) { + /* not supported */ + return; + } + if ((edesc->bmAttributes & UE_XFERTYPE) == UE_ISOCHRONOUS) + pipe->methods = &avr32dci_device_isoc_fs_methods; + else + pipe->methods = &avr32dci_device_non_isoc_methods; + } +} + +struct usb2_bus_methods avr32dci_bus_methods = +{ + .pipe_init = &avr32dci_pipe_init, + .xfer_setup = &avr32dci_xfer_setup, + .xfer_unsetup = &avr32dci_xfer_unsetup, + .get_hw_ep_profile = &avr32dci_get_hw_ep_profile, + .set_stall = &avr32dci_set_stall, + .clear_stall = &avr32dci_clear_stall, + .roothub_exec = &avr32dci_roothub_exec, +}; diff --git a/sys/dev/usb/controller/avr32dci.h b/sys/dev/usb/controller/avr32dci.h new file mode 100644 index 000000000000..6a9895f2fff5 --- /dev/null +++ b/sys/dev/usb/controller/avr32dci.h @@ -0,0 +1,254 @@ +/* $FreeBSD$ */ +/*- + * Copyright (c) 2009 Hans Petter Selasky. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef _AVR32DCI_H_ +#define _AVR32DCI_H_ + +#define AVR32_MAX_DEVICES (USB_MIN_DEVICES + 1) + +/* Register definitions */ + +#define AVR32_CTRL 0x00 /* Control */ +#define AVR32_CTRL_DEV_ADDR 0x7F +#define AVR32_CTRL_DEV_FADDR_EN 0x80 +#define AVR32_CTRL_DEV_EN_USBA 0x100 +#define AVR32_CTRL_DEV_DETACH 0x200 +#define AVR32_CTRL_DEV_REWAKEUP 0x400 + +#define AVR32_FNUM 0x04 /* Frame Number */ +#define AVR32_FNUM_MASK 0x3FFF +#define AVR32_FRAME_MASK 0x7FF + +/* 0x08 - 0x0C Reserved */ +#define AVR32_IEN 0x10 /* Interrupt Enable */ +#define AVR32_INTSTA 0x14 /* Interrupt Status */ +#define AVR32_CLRINT 0x18 /* Clear Interrupt */ + +#define AVR32_INT_SPEED 0x00000001 /* set if High Speed else Full Speed */ +#define AVR32_INT_DET_SUSPD 0x00000002 +#define AVR32_INT_MICRO_SOF 0x00000004 +#define AVR32_INT_INT_SOF 0x00000008 +#define AVR32_INT_ENDRESET 0x00000010 +#define AVR32_INT_WAKE_UP 0x00000020 +#define AVR32_INT_ENDOFRSM 0x00000040 +#define AVR32_INT_UPSTR_RES 0x00000080 +#define AVR32_INT_EPT_INT(n) (0x00000100 << (n)) +#define AVR32_INT_DMA_INT(n) (0x01000000 << (n)) + +#define AVR32_EPTRST 0x1C /* Endpoints Reset */ +#define AVR32_EPTRST_MASK(n) (0x00000001 << (n)) + +/* 0x20 - 0xCC Reserved */ +#define AVR32_TSTSOFCNT 0xD0 /* Test SOF Counter */ +#define AVR32_TSTCNTA 0xD4 /* Test A Counter */ +#define AVR32_TSTCNTB 0xD8 /* Test B Counter */ +#define AVR32_TSTMODEREG 0xDC /* Test Mode */ +#define AVR32_TST 0xE0 /* Test */ +#define AVR32_TST_NORMAL 0x00000000 +#define AVR32_TST_HS_ONLY 0x00000002 +#define AVR32_TST_FS_ONLY 0x00000003 + +/* 0xE4 - 0xE8 Reserved */ +#define AVR32_IPPADDRSIZE 0xEC /* PADDRSIZE */ +#define AVR32_IPNAME1 0xF0 /* Name1 */ +#define AVR32_IPNAME2 0xF4 /* Name2 */ +#define AVR32_IPFEATURES 0xF8 /* Features */ +#define AVR32_IPFEATURES_NEP(x) (((x) & 0xF) ? ((x) & 0xF) : 0x10) + +#define AVR32_IPVERSION 0xFC /* IP Version */ + +#define _A(base,n) ((base) + (0x20*(n))) +#define AVR32_EPTCFG(n) _A(0x100, n) /* Endpoint Configuration */ +#define AVR32_EPTCFG_EPSIZE(n) ((n)-3) /* power of two */ +#define AVR32_EPTCFG_EPDIR_OUT 0x00000000 +#define AVR32_EPTCFG_EPDIR_IN 0x00000008 +#define AVR32_EPTCFG_TYPE_CTRL 0x00000000 +#define AVR32_EPTCFG_TYPE_ISOC 0x00000100 +#define AVR32_EPTCFG_TYPE_BULK 0x00000200 +#define AVR32_EPTCFG_TYPE_INTR 0x00000300 +#define AVR32_EPTCFG_NBANK(n) (0x00000400*(n)) +#define AVR32_EPTCFG_NB_TRANS(n) (0x00001000*(n)) +#define AVR32_EPTCFG_EPT_MAPD 0x80000000 + +#define AVR32_EPTCTLENB(n) _A(0x104, n) /* Endpoint Control Enable */ +#define AVR32_EPTCTLDIS(n) _A(0x108, n) /* Endpoint Control Disable */ +#define AVR32_EPTCTL(n) _A(0x10C, n) /* Endpoint Control */ +#define AVR32_EPTCTL_EPT_ENABL 0x00000001 +#define AVR32_EPTCTL_AUTO_VALID 0x00000002 +#define AVR32_EPTCTL_INTDIS_DMA 0x00000008 +#define AVR32_EPTCTL_NYET_DIS 0x00000010 +#define AVR32_EPTCTL_DATAX_RX 0x00000040 +#define AVR32_EPTCTL_MDATA_RX 0x00000080 +#define AVR32_EPTCTL_ERR_OVFLW 0x00000100 +#define AVR32_EPTCTL_RX_BK_RDY 0x00000200 +#define AVR32_EPTCTL_TX_COMPLT 0x00000400 +#define AVR32_EPTCTL_TX_PK_RDY 0x00000800 +#define AVR32_EPTCTL_RX_SETUP 0x00001000 +#define AVR32_EPTCTL_STALL_SNT 0x00002000 +#define AVR32_EPTCTL_NAK_IN 0x00004000 +#define AVR32_EPTCTL_NAK_OUT 0x00008000 +#define AVR32_EPTCTL_BUSY_BANK 0x00040000 +#define AVR32_EPTCTL_SHORT_PCKT 0x80000000 + +/* 0x110 Reserved */ +#define AVR32_EPTSETSTA(n) _A(0x114, n) /* Endpoint Set Status */ +#define AVR32_EPTCLRSTA(n) _A(0x118, n) /* Endpoint Clear Status */ +#define AVR32_EPTSTA(n) _A(0x11C, n) /* Endpoint Status */ +#define AVR32_EPTSTA_FRCESTALL 0x00000020 +#define AVR32_EPTSTA_TOGGLESQ_STA(x) (((x) & 0xC0) >> 6) +#define AVR32_EPTSTA_TOGGLESQ 0x00000040 +#define AVR32_EPTSTA_ERR_OVFLW 0x00000100 +#define AVR32_EPTSTA_RX_BK_RDY 0x00000200 +#define AVR32_EPTSTA_TX_COMPLT 0x00000400 +#define AVR32_EPTSTA_TX_PK_RDY 0x00000800 +#define AVR32_EPTSTA_RX_SETUP 0x00001000 +#define AVR32_EPTSTA_STALL_SNT 0x00002000 +#define AVR32_EPTSTA_NAK_IN 0x00004000 +#define AVR32_EPTSTA_NAK_OUT 0x00008000 +#define AVR32_EPTSTA_CURRENT_BANK(x) (((x) & 0x00030000) >> 16) +#define AVR32_EPTSTA_BUSY_BANK_STA(x) (((x) & 0x000C0000) >> 18) +#define AVR32_EPTSTA_BYTE_COUNT(x) (((x) & 0x7FF00000) >> 20) +#define AVR32_EPTSTA_SHRT_PCKT 0x80000000 + +/* 0x300 - 0x30C Reserved */ +#define AVR32_DMANXTDSC 0x310 /* DMA Next Descriptor Address */ +#define AVR32_DMAADDRESS 0x314 /* DMA Channel Address */ + +#define AVR32_READ_4(sc, reg) \ + bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg) + +#define AVR32_WRITE_4(sc, reg, data) \ + bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data) + +#define AVR32_WRITE_MULTI_4(sc, reg, ptr, len) \ + bus_space_write_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len) + +#define AVR32_READ_MULTI_4(sc, reg, ptr, len) \ + bus_space_read_multi_4((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, ptr, len) + +/* + * Maximum number of endpoints supported: + */ +#define AVR32_EP_MAX 7 + +struct avr32dci_td; + +typedef uint8_t (avr32dci_cmd_t)(struct avr32dci_td *td); +typedef void (avr32dci_clocks_t)(struct usb2_bus *); + +struct avr32dci_td { + struct avr32dci_td *obj_next; + avr32dci_cmd_t *func; + struct usb2_page_cache *pc; + uint32_t offset; + uint32_t remainder; + uint16_t max_packet_size; + uint8_t error:1; + uint8_t alt_next:1; + uint8_t short_pkt:1; + uint8_t support_multi_buffer:1; + uint8_t did_stall:1; + uint8_t ep_no:3; +}; + +struct avr32dci_std_temp { + avr32dci_cmd_t *func; + struct usb2_page_cache *pc; + struct avr32dci_td *td; + struct avr32dci_td *td_next; + uint32_t len; + uint32_t offset; + uint16_t max_frame_size; + uint8_t bank_shift; + uint8_t short_pkt; + /* + * short_pkt = 0: transfer should be short terminated + * short_pkt = 1: transfer should not be short terminated + */ + uint8_t setup_alt_next; + uint8_t did_stall; +}; + +struct avr32dci_config_desc { + struct usb2_config_descriptor confd; + struct usb2_interface_descriptor ifcd; + struct usb2_endpoint_descriptor endpd; +} __packed; + +union avr32dci_hub_temp { + uWord wValue; + struct usb2_port_status ps; +}; + +struct avr32dci_flags { + uint8_t change_connect:1; + uint8_t change_suspend:1; + uint8_t status_suspend:1; /* set if suspended */ + uint8_t status_vbus:1; /* set if present */ + uint8_t status_bus_reset:1; /* set if reset complete */ + uint8_t remote_wakeup:1; + uint8_t self_powered:1; + uint8_t clocks_off:1; + uint8_t port_powered:1; + uint8_t port_enabled:1; + uint8_t d_pulled_up:1; +}; + +struct avr32dci_softc { + struct usb2_bus sc_bus; + union avr32dci_hub_temp sc_hub_temp; + + /* must be set by by the bus interface layer */ + avr32dci_clocks_t *sc_clocks_on; + avr32dci_clocks_t *sc_clocks_off; + + struct usb2_device *sc_devices[AVR32_MAX_DEVICES]; + struct resource *sc_irq_res; + void *sc_intr_hdl; + struct resource *sc_io_res; + bus_space_tag_t sc_io_tag; + bus_space_handle_t sc_io_hdl; + uint8_t *physdata; + + uint8_t sc_rt_addr; /* root hub address */ + uint8_t sc_dv_addr; /* device address */ + uint8_t sc_conf; /* root hub config */ + + uint8_t sc_hub_idata[1]; + + struct avr32dci_flags sc_flags; +}; + +/* prototypes */ + +usb2_error_t avr32dci_init(struct avr32dci_softc *sc); +void avr32dci_uninit(struct avr32dci_softc *sc); +void avr32dci_suspend(struct avr32dci_softc *sc); +void avr32dci_resume(struct avr32dci_softc *sc); +void avr32dci_interrupt(struct avr32dci_softc *sc); +void avr32dci_vbus_interrupt(struct avr32dci_softc *sc, uint8_t is_on); + +#endif /* _AVR32DCI_H_ */ From 1d70ff1cf6bbdbf43e0fbe8d7ae5c23940ea3aae Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:43:35 +0000 Subject: [PATCH 388/544] Fix a failure to report failure on stalled status stage for control transactions. Submitted by: Hans Petter Selasky --- sys/dev/usb/controller/ehci.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/sys/dev/usb/controller/ehci.c b/sys/dev/usb/controller/ehci.c index 6156cb8a906c..c3b7ba4ca5bc 100644 --- a/sys/dev/usb/controller/ehci.c +++ b/sys/dev/usb/controller/ehci.c @@ -1156,13 +1156,6 @@ ehci_non_isoc_done_sub(struct usb2_xfer *xfer) } /* Check for last transfer */ if (((void *)td) == xfer->td_transfer_last) { - if (len == 0) { - /* - * Halt is ok if descriptor is last, - * and complete: - */ - status &= ~EHCI_QTD_HALTED; - } td = NULL; break; } From 774651eee782a13bdc34d7fb28cac07436dcaf12 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:45:37 +0000 Subject: [PATCH 389/544] Use the correct usb config number on attach. Reported by: Greg Rivers Submitted by: Hans Petter Selasky --- sys/dev/usb/serial/umct.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/usb/serial/umct.c b/sys/dev/usb/serial/umct.c index 2b3faac8eef3..b72943b92638 100644 --- a/sys/dev/usb/serial/umct.c +++ b/sys/dev/usb/serial/umct.c @@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$"); #define UMCT_INTR_INTERVAL 100 #define UMCT_IFACE_INDEX 0 -#define UMCT_CONFIG_INDEX 1 +#define UMCT_CONFIG_INDEX 0 enum { UMCT_BULK_DT_WR, From df05202dd560ca1e2f60cda5d2365875513f5e71 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:47:27 +0000 Subject: [PATCH 390/544] Add Sharp WILLCOM03 ipaq and Option GTHSDPA 3g device ids. Submitted by: Hans Petter Selasky --- sys/dev/usb/serial/u3g.c | 1 + sys/dev/usb/serial/uipaq.c | 4 +++- sys/dev/usb/usbdevs | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sys/dev/usb/serial/u3g.c b/sys/dev/usb/serial/u3g.c index 02c2bb57592d..72a406a8e333 100644 --- a/sys/dev/usb/serial/u3g.c +++ b/sys/dev/usb/serial/u3g.c @@ -163,6 +163,7 @@ static const struct usb2_device_id u3g_devs[] = { U3G_DEV(OPTION, GT3GQUAD, 0), U3G_DEV(OPTION, GT3GPLUS, 0), U3G_DEV(OPTION, GTMAX36, 0), + U3G_DEV(OPTION, GTHSDPA, 0), U3G_DEV(OPTION, GTMAXHSUPA, 0), U3G_DEV(OPTION, VODAFONEMC3G, 0), /* OEM: Qualcomm, Inc. */ diff --git a/sys/dev/usb/serial/uipaq.c b/sys/dev/usb/serial/uipaq.c index 353570ac9711..97480475a5b6 100644 --- a/sys/dev/usb/serial/uipaq.c +++ b/sys/dev/usb/serial/uipaq.c @@ -996,8 +996,10 @@ static const struct usb2_device_id uipaq_devs[] = { {USB_VPI(USB_VENDOR_SHARP, 0x9121, 0)}, /* SHARP S01SH USB Modem */ {USB_VPI(USB_VENDOR_SHARP, 0x9151, 0)}, -/**/ + /**/ {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WZERO3ES, 0)}, + /**/ + {USB_VPI(USB_VENDOR_SHARP, USB_PRODUCT_SHARP_WILLCOM03, 0)}, /* Symbol USB Sync */ {USB_VPI(USB_VENDOR_SYMBOL, 0x2000, 0)}, /* Symbol USB Sync 0x2001 */ diff --git a/sys/dev/usb/usbdevs b/sys/dev/usb/usbdevs index a626a1df1d65..183a77d4b555 100644 --- a/sys/dev/usb/usbdevs +++ b/sys/dev/usb/usbdevs @@ -1914,6 +1914,7 @@ product OPTION GT3GQUAD 0x6300 GlobeTrotter 3G QUAD datacard product OPTION GT3GPLUS 0x6600 GlobeTrotter 3G+ datacard product OPTION GTICON322 0xd033 GlobeTrotter Icon322 storage product OPTION GTMAX36 0x6701 GlobeTrotter Max 3.6 Modem +product OPTION GTHSDPA 0x6971 GlobeTrotter HSDPA product OPTION GTMAXHSUPA 0x7001 GlobeTrotter HSUPA /* OQO */ @@ -2134,6 +2135,7 @@ product SHARP SL5600 0x8006 Zaurus SL-5600 PDA product SHARP SLC700 0x8007 Zaurus SL-C700 PDA product SHARP SLC750 0x9031 Zaurus SL-C750 PDA product SHARP WZERO3ES 0x9123 W-ZERO3 ES Smartphone +product SHARP WILLCOM03 0x9242 WILLCOM03 /* Shuttle Technology products */ product SHUTTLE EUSB 0x0001 E-USB Bridge From a688f49162d762c330684e01a6e503ff9b4d4ea8 Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:48:41 +0000 Subject: [PATCH 391/544] Remove README.TXT as the info is in usb(4). --- sys/dev/usb/README.TXT | 411 ----------------------------------------- 1 file changed, 411 deletions(-) delete mode 100644 sys/dev/usb/README.TXT diff --git a/sys/dev/usb/README.TXT b/sys/dev/usb/README.TXT deleted file mode 100644 index d24770c24068..000000000000 --- a/sys/dev/usb/README.TXT +++ /dev/null @@ -1,411 +0,0 @@ - -$FreeBSD$ - -DESCRIPTION OF THE NEW USB API - -The new USB 2.0 API consists of 5 functions. All transfer types are -managed using these functions. There is no longer need for separate -functions to setup INTERRUPT- and ISOCHRONOUS- transfers. - -+--------------------------------------------------------------+ -| | -| "usb2_transfer_setup" - This function will allocate all | -| necessary DMA memory and might | -| sleep! | -| | -| "usb2_transfer_unsetup" - This function will stop the USB | -| transfer, if it is currently | -| active, release all DMA | -| memory and might sleep! | -| | -| "usb2_transfer_start" - This function will start an USB | -| transfer, if not already started.| -| This function is always | -| non-blocking. ** | -| | -| "usb2_transfer_stop" - This function will stop an USB | -| transfer, if not already stopped.| -| The callback function will be | -| called before this function | -| returns. This function is always | -| non-blocking. ** | -| | -| "usb2_transfer_drain" - This function will stop an USB | -| transfer, if not already stopped | -| and wait for any additional | -| DMA load operations to complete. | -| Buffers that are loaded into DMA | -| using "usb2_set_frame_data" can | -| safely be freed after that | -| this function has returned. This | -| function can block the caller. | -| | -| ** These functions must be called with the private driver's | -| lock locked. | -| | -| NOTE: These USB API functions are NULL safe, with regard | -| to the USB transfer structure pointer. | -+--------------------------------------------------------------+ - -Reference: /sys/dev/usb/usb_transfer.c - -/* - * A simple USB callback state-machine: - * - * +->-----------------------+ - * | | - * +-<-+-------[tr_setup]--------+-<-+-<-[start/restart] - * | | - * | | - * | | - * +------>-[tr_transferred]---------+ - * | | - * +--------->-[tr_error]------------+ - */ - -void -usb2_default_callback(struct usb2_xfer *xfer) -{ - /* - * NOTE: it is not allowed to return - * before "USB_CHECK_STATUS()", - * even if the system is tearing down! - */ - switch (USB_GET_STATE(xfer)) { - case USB_ST_SETUP: - /* - * Setup xfer->frlengths[], xfer->nframes - * and write data to xfer->frbuffers[], if any - */ - - /**/ - usb2_start_hardware(xfer); - return; - - case USB_ST_TRANSFERRED: - /* - * Read data from xfer->frbuffers[], if any. - * "xfer->frlengths[]" should now have been - * updated to the actual length. - */ - return; - - default: /* Error */ - /* print error message and clear stall for example */ - return; - } -} - -=== Notes for USB control transfers === - -An USB control transfer has three parts. First the SETUP packet, then -DATA packet(s) and then a STATUS packet. The SETUP packet is always -pointed to by "xfer->frbuffers[0]" and the length is stored in -"xfer->frlengths[0]" also if there should not be sent any SETUP -packet! If an USB control transfer has no DATA stage, then -"xfer->nframes" should be set to 1. Else the default value is -"xfer->nframes" equal to 2. - -Example1: SETUP + STATUS - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - usb2_start_hardware(xfer); - -Example2: SETUP + DATA + STATUS - xfer->nframes = 2; - xfer->frlenghts[0] = 8; - xfer->frlenghts[1] = 1; - usb2_start_hardware(xfer); - -Example3: SETUP + DATA + STATUS - split -1st callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - usb2_start_hardware(xfer); - -2nd callback: - /* IMPORTANT: frbuffer[0] must still point at the setup packet! */ - xfer->nframes = 2; - xfer->frlenghts[0] = 0; - xfer->frlenghts[1] = 1; - usb2_start_hardware(xfer); - -Example4: SETUP + STATUS - split -1st callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 8; - xfer->flags.manual_status = 1; - usb2_start_hardware(xfer); - -2nd callback: - xfer->nframes = 1; - xfer->frlenghts[0] = 0; - xfer->flags.manual_status = 0; - usb2_start_hardware(xfer); - - -=== General USB transfer notes === - - 1) Something that one should be aware of is that all USB callbacks support -recursation. That means one can start/stop whatever transfer from the callback -of another transfer one desires. Also the transfer that is currently called -back. Recursion is handled like this that when the callback that wants to -recurse returns it is called one more time. - - 2) After that the "usb2_start_hardware()" function has been called in -the callback one can always depend on that "tr_error" or "tr_transferred" -will get jumped afterwards. Always! - - 3) Sleeping functions can only be called from the attach routine of the -driver. Else one should not use sleeping functions unless one has to. It is -very difficult with sleep, because one has to think that the device might have -detached when the thread returns from sleep. - - 4) Polling. - - use_polling - This flag can be used with any callback and will cause the - "usb2_transfer_start()" function to wait using "DELAY()", - without exiting any mutexes, until the transfer is finished or - has timed out. This flag can be changed during operation. - - NOTE: If polling is used the "timeout" field should be non-zero! - NOTE: USB_ERR_CANCELLED is returned in case of timeout - instead of USB_ERR_TIMEOUT! - - - -USB device driver examples: - -/sys/dev/usb/net/if_axe.c -/sys/dev/usb/net/if_aue.c - -QUICK REFERENCE -=============== - - -/*------------------------------------------------------------------------* - * usb2_error_t - * usb2_transfer_setup(udev, ifaces, pxfer, setup_start, - * n_setup, priv_sc, priv_mtx) - *------------------------------------------------------------------------*/ - -- "udev" is a pointer to "struct usb2_device". - -- "ifaces" array of interface index numbers to use. See "if_index". - -- "pxfer" is a pointer to an array of USB transfer pointers that are - initialized to NULL, and then pointed to allocated USB transfers. - -- "setup_start" is a pointer to an array of USB config structures. - -- "n_setup" is a number telling the USB system how many USB transfers - should be setup. - -- "priv_sc" is the private softc pointer, which will be used to - initialize "xfer->priv_sc". - -- "priv_mtx" is the private mutex protecting the transfer structure and - the softc. This pointer is used to initialize "xfer->priv_mtx". - -/*------------------------------------------------------------------------* - * void - * usb2_transfer_unsetup(pxfer, n_setup) - *------------------------------------------------------------------------*/ - -- "pxfer" is a pointer to an array of USB transfer pointers, that may - be NULL, that should be freed by the USB system. - -- "n_setup" is a number telling the USB system how many USB transfers - should be unsetup - -NOTE: This function can sleep, waiting for active mutexes to become unlocked! -NOTE: It is not allowed to call "usb2_transfer_unsetup" from the callback - of a USB transfer. - -/*------------------------------------------------------------------------* - * void - * usb2_transfer_start(xfer) - *------------------------------------------------------------------------*/ - -- "xfer" is pointer to a USB transfer that should be started - -NOTE: this function must be called with "priv_mtx" locked - -/*------------------------------------------------------------------------* - * void - * usb2_transfer_stop(xfer) - *------------------------------------------------------------------------*/ - -- "xfer" is a pointer to a USB transfer that should be stopped - -NOTE: this function must be called with "priv_mtx" locked - -NOTE: if the transfer was in progress, the callback will called with - "xfer->error=USB_ERR_CANCELLED", before this function returns - -/*------------------------------------------------------------------------* - * struct usb2_config { - * type, endpoint, direction, interval, timeout, frames, index - * flags, bufsize, callback - * }; - *------------------------------------------------------------------------*/ - -- The "type" field selects the USB pipe type. Valid values are: - UE_INTERRUPT, UE_CONTROL, UE_BULK, UE_ISOCHRONOUS. The special - value UE_BULK_INTR will select BULK and INTERRUPT pipes. - This field is mandatory. - -- The "endpoint" field selects the USB endpoint number. A value of - 0xFF, "-1" or "UE_ADDR_ANY" will select the first matching endpoint. - This field is mandatory. - -- The "direction" field selects the USB endpoint direction. A value of - "UE_DIR_ANY" will select the first matching endpoint. Else valid - values are: "UE_DIR_IN" and "UE_DIR_OUT". "UE_DIR_IN" and - "UE_DIR_OUT" can be binary ORed by "UE_DIR_SID" which means that the - direction will be swapped in case of USB_MODE_DEVICE. Note that - "UE_DIR_IN" refers to the data transfer direction of the "IN" tokens - and "UE_DIR_OUT" refers to the data transfer direction of the "OUT" - tokens. This field is mandatory. - -- The "interval" field selects the interrupt interval. The value of this - field is given in milliseconds and is independent of device speed. Depending - on the endpoint type, this field has different meaning: - - UE_INTERRUPT) - "0" use the default interrupt interval based on endpoint descriptor. - "Else" use the given value for polling rate. - - UE_ISOCHRONOUS) - "0" use default. - "Else" the value is ignored. - - UE_BULK) - UE_CONTROL) - "0" no transfer pre-delay. - "Else" a delay as given by this field in milliseconds is - inserted before the hardware is started when - "usb2_start_hardware()" is called. - NOTE: The transfer timeout, if any, is started after that - the pre-delay has elapsed! - -- The "timeout" field, if non-zero, will set the transfer timeout in - milliseconds. If the "timeout" field is zero and the transfer type - is ISOCHRONOUS a timeout of 250ms will be used. - -- The "frames" field sets the maximum number of frames. If zero is - specified it will yield the following results: - - UE_BULK) - UE_INTERRUPT) - xfer->nframes = 1; - - UE_CONTROL) - xfer->nframes = 2; - - UE_ISOCHRONOUS) - Not allowed. Will cause an error. - -- The "ep_index" field allows you to give a number, in case more - endpoints match the description, that selects which matching - "ep_index" should be used. - -- The "if_index" field allows you to select which of the interface - numbers in the "ifaces" array parameter passed to "usb2_transfer_setup" - that should be used when setting up the given USB transfer. - -- The "flags" field has type "struct usb2_xfer_flags" and allows one - to set initial flags an USB transfer. Valid flags are: - - force_short_xfer - This flag forces the last transmitted USB packet to be short. - A short packet has a length of less than "xfer->max_packet_size", - which derives from "wMaxPacketSize". This flag can be changed - during operation. - - short_xfer_ok - This flag allows the received transfer length, "xfer->actlen" - to be less than "xfer->sumlen" upon completion of a transfer. - This flag can be changed during operation. - - pipe_bof - This flag causes a failing USB transfer to remain first - in the PIPE queue except in the case of "xfer->error" equal - to "USB_ERR_CANCELLED". No other USB transfers in the affected - PIPE queue will be started until either: - - 1) The failing USB transfer is stopped using "usb2_transfer_stop()". - 2) The failing USB transfer performs a successful transfer. - - The purpose of this flag is to avoid races when multiple - transfers are queued for execution on an USB endpoint, and the - first executing transfer fails leading to the need for - clearing of stall for example. In this case this flag is used - to prevent the following USB transfers from being executed at - the same time the clear-stall command is executed on the USB - control endpoint. This flag can be changed during operation. - - "BOF" is short for "Block On Failure" - - NOTE: This flag should be set on all BULK and INTERRUPT - USB transfers which use an endpoint that can be shared - between userland and kernel. - - proxy_buffer - Setting this flag will cause that the total buffer size will - be rounded up to the nearest atomic hardware transfer - size. The maximum data length of any USB transfer is always - stored in the "xfer->max_data_length". For control transfers - the USB kernel will allocate additional space for the 8-bytes - of SETUP header. These 8-bytes are not counted by the - "xfer->max_data_length" variable. This flag can not be changed - during operation. - - ext_buffer - Setting this flag will cause that no data buffer will be - allocated. Instead the USB client must supply a data buffer. - This flag can not be changed during operation. - - manual_status - Setting this flag prevents an USB STATUS stage to be appended - to the end of the USB control transfer. If no control data is - transferred this flag must be cleared. Else an error will be - returned to the USB callback. This flag is mostly useful for - the USB device side. This flag can be changed during - operation. - - no_pipe_ok - Setting this flag causes the USB_ERR_NO_PIPE error to be - ignored. This flag can not be changed during operation. - - stall_pipe - Setting this flag will cause STALL pids to be sent to the - endpoint belonging to this transfer before the transfer is - started. The transfer is started at the moment the host issues - a clear-stall command on the STALL'ed endpoint. This flag can - be changed during operation. This flag does only have effect - in USB device side mode except for control endpoints. This - flag is cleared when the stall command has been executed. This - flag can only be changed outside the callback function by - using the functions "usb2_transfer_set_stall()" and - "usb2_transfer_clear_stall()" ! - -- The "bufsize" field sets the total buffer size in bytes. If - this field is zero, "wMaxPacketSize" will be used, multiplied by the - "frames" field if the transfer type is ISOCHRONOUS. This is useful for - setting up interrupt pipes. This field is mandatory. - - NOTE: For control transfers "bufsize" includes - the length of the request structure. - -- The "callback" pointer sets the USB callback. This field is mandatory. - -MUTEX NOTE: -=========== - -When you create a mutex using "mtx_init()", don't forget to call -"mtx_destroy()" at detach, else you can get "freed memory accessed" -panics. - ---HPS From fe45987e99869efae556e67759eaca768b05770f Mon Sep 17 00:00:00 2001 From: Andrew Thompson Date: Thu, 21 May 2009 17:55:18 +0000 Subject: [PATCH 392/544] Don't clear last usage when a new HID item is found, it improves parsing of Apple keyboard HID descriptors. Submitted by: Hans Petter Selasky --- sys/dev/usb/usb_hid.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/sys/dev/usb/usb_hid.c b/sys/dev/usb/usb_hid.c index cfec2096c669..52efa6777908 100644 --- a/sys/dev/usb/usb_hid.c +++ b/sys/dev/usb/usb_hid.c @@ -296,9 +296,6 @@ hid_get_item(struct hid_data *s, struct hid_item *h) } else { s->ncount = 1; } - /* set default usage */ - /* use the undefined HID PAGE */ - s->usage_last = 0; goto top; case 9: /* Output */ From 62aa21ae8616f869a460d76d2e24f714195b8fd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Thu, 21 May 2009 17:56:00 +0000 Subject: [PATCH 393/544] When man pages are formatted in UTF-8, .Fl is encoded as U+2212 "MINUS SIGN" instead of U+002D "HYPHEN-MINUS". This is unfortunate for two reasons: 1) this is not the character which is actually used on the command line, and 2) it makes it impossible to search a man page for a specific command-line option. This patch fixes this, but there are other unresolved issues, such as confusion between -, \- and hy: while the latter is always (and only) used for hyphenation, both - and \- are used for negation and subtraction, and \- is used for command-line options and sometimes also for parenthesis. IMHO, the correct Unicode characters are: - hyphenation: either U+2010 or U+00AD, most likely the former (the latter is the so-called soft hyphen, used to indicate a point at which a text processor is allowed to hyphenate a word) - negation and subtraction: U+2212 - parenthesis: in English, U+2214, with spaces suppressed before and after; in some others (such as Norwegian), U+2213 with spaces retained. - command-line options: U+002D, because that is what is actually used on the command line. However, fixing this would require extensive modifications to (at least) the doc and man macro sets... MFC after: 1 week --- contrib/groff/font/devutf8/R.proto | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/groff/font/devutf8/R.proto b/contrib/groff/font/devutf8/R.proto index ac0828fe4926..3e69500db51a 100644 --- a/contrib/groff/font/devutf8/R.proto +++ b/contrib/groff/font/devutf8/R.proto @@ -726,7 +726,7 @@ st 24 0 0x220B product 24 0 0x220F coproduct 24 0 0x2210 sum 24 0 0x2211 -\- 24 0 0x2212 +\- 24 0 0x002D mi " -+ 24 0 0x2213 ** 24 0 0x2217 From 05e5bb311b0c63ec8112fbbabd90ee19fe35bc31 Mon Sep 17 00:00:00 2001 From: Bruce M Simpson Date: Thu, 21 May 2009 18:05:17 +0000 Subject: [PATCH 394/544] Pullup from p4 tip: * Fix MLDv2 general query timer (fallout from automated refactoring). * Refactor MLDv1 timer. MLDv2 query processing is now working. --- sys/netinet6/mld6.c | 37 +++++++++++++++---------------------- 1 file changed, 15 insertions(+), 22 deletions(-) diff --git a/sys/netinet6/mld6.c b/sys/netinet6/mld6.c index c24ceba2fe8d..1eeeba14ec0e 100644 --- a/sys/netinet6/mld6.c +++ b/sys/netinet6/mld6.c @@ -855,8 +855,8 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, * not schedule any other reports. * Otherwise, reset the interface timer. */ - if (mli->mli_v1_timer == 0 || mli->mli_v2_timer >= timer) { - mli->mli_v1_timer = MLD_RANDOM_DELAY(timer); + if (mli->mli_v2_timer == 0 || mli->mli_v2_timer >= timer) { + mli->mli_v2_timer = MLD_RANDOM_DELAY(timer); V_interface_timers_running6 = 1; } } else { @@ -888,7 +888,7 @@ mld_v2_input_query(struct ifnet *ifp, const struct ip6_hdr *ip6, * Otherwise, prepare to respond to the * group-specific or group-and-source query. */ - if (mli->mli_v1_timer == 0 || mli->mli_v2_timer >= timer) + if (mli->mli_v2_timer == 0 || mli->mli_v2_timer >= timer) mld_v2_process_group_query(inm, mli, timer, m, off); } @@ -1498,6 +1498,7 @@ mld_v2_process_group_timers(struct mld_ifinfo *mli, static void mld_set_version(struct mld_ifinfo *mli, const int version) { + int old_version_timer; MLD_LOCK_ASSERT(); @@ -1505,24 +1506,18 @@ mld_set_version(struct mld_ifinfo *mli, const int version) version, mli->mli_ifp, mli->mli_ifp->if_xname); if (version == MLD_VERSION_1) { - int old_version_timer; /* * Compute the "Older Version Querier Present" timer as per * Section 9.12. */ old_version_timer = mli->mli_rv * mli->mli_qi + mli->mli_qri; old_version_timer *= PR_SLOWHZ; - - if (version == MLD_VERSION_1) { - mli->mli_v1_timer = old_version_timer; - } + mli->mli_v1_timer = old_version_timer; } - if (mli->mli_v1_timer > 0) { - if (mli->mli_version != MLD_VERSION_1) { - mli->mli_version = MLD_VERSION_1; - mld_v2_cancel_link_timers(mli); - } + if (mli->mli_v1_timer > 0 && mli->mli_version != MLD_VERSION_1) { + mli->mli_version = MLD_VERSION_1; + mld_v2_cancel_link_timers(mli); } } @@ -1648,17 +1643,15 @@ mld_v1_process_querier_timers(struct mld_ifinfo *mli) MLD_LOCK_ASSERT(); - if (mli->mli_v1_timer == 0) { + if (mli->mli_v1_timer == 0 && mli->mli_version != MLD_VERSION_2) { /* - * MLDv1 Querier Present timers expired; revert to MLDv2. + * MLDv1 Querier Present timer expired; revert to MLDv2. */ - if (mli->mli_version != MLD_VERSION_2) { - CTR5(KTR_MLD, - "%s: transition from v%d -> v%d on %p(%s)", - __func__, mli->mli_version, MLD_VERSION_2, - mli->mli_ifp, mli->mli_ifp->if_xname); - mli->mli_version = MLD_VERSION_2; - } + CTR5(KTR_MLD, + "%s: transition from v%d -> v%d on %p(%s)", + __func__, mli->mli_version, MLD_VERSION_2, + mli->mli_ifp, mli->mli_ifp->if_xname); + mli->mli_version = MLD_VERSION_2; } } From dacc4a46c26d295f372ca5967d7b7a306ae56ffc Mon Sep 17 00:00:00 2001 From: TAKATSU Tomonari Date: Thu, 21 May 2009 21:21:22 +0000 Subject: [PATCH 395/544] Add myself to the list of ports committers. Approved by: maho (mentor) --- share/misc/committers-ports.dot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/misc/committers-ports.dot b/share/misc/committers-ports.dot index 229f06316be1..978ae3db06de 100644 --- a/share/misc/committers-ports.dot +++ b/share/misc/committers-ports.dot @@ -144,6 +144,7 @@ stefan [label="Stefan Walter\nstefan@FreeBSD.org\n2006/05/07"] tabthorpe [label="Thomas Abthorpe\ntabthorpe@FreeBSD.org\n2007/08/20"] tdb [label="Tim Bishop\ntdb@FreeBSD.org\n2005/11/30"] timur [label="Timur Bakeyev\ntimur@FreeBSD.org\n2007/06/07"] +tota [label="TAKATSU Tomonari\ntota@FreeBSD.org\n2009/03/30"] trasz [label="Edward Tomasz Napierala\ntrasz@FreeBSD.org\n2007/04/12"] trhodes [label="Tom Rhodes\ntrhodes@FreeBSD.org\n2004/07/06"] thierry [label="Thierry Thomas\nthierry@FreeBSD.org\n2004/03/15"] @@ -257,6 +258,8 @@ leeym -> clsung lioux -> pat +maho -> tota + marcus -> ahze marcus -> bland marcus -> eik From 4f6e13686bebcb6c99d713763e5a3fc3a8e3d960 Mon Sep 17 00:00:00 2001 From: Xin LI Date: Thu, 21 May 2009 23:00:20 +0000 Subject: [PATCH 396/544] Use calloc(). --- usr.sbin/iostat/iostat.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/usr.sbin/iostat/iostat.c b/usr.sbin/iostat/iostat.c index 40d78ab80930..65a0386a92a0 100644 --- a/usr.sbin/iostat/iostat.c +++ b/usr.sbin/iostat/iostat.c @@ -311,16 +311,13 @@ main(int argc, char **argv) } } - cur.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); + cur.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); if (cur.dinfo == NULL) - err(1, "malloc failed"); + err(1, "calloc failed"); - last.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo)); + last.dinfo = (struct devinfo *)calloc(1, sizeof(struct devinfo)); if (last.dinfo == NULL) - err(1, "malloc failed"); - - bzero(cur.dinfo, sizeof(struct devinfo)); - bzero(last.dinfo, sizeof(struct devinfo)); + err(1, "calloc failed"); /* * Grab all the devices. We don't look to see if the list has From f0295f76db0919aed94dcedfe399ac0010fe6124 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Thu, 21 May 2009 23:19:49 +0000 Subject: [PATCH 397/544] update for r192468 (monitor mode changes) Submitted by: jkim --- sys/modules/wlan/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/modules/wlan/Makefile b/sys/modules/wlan/Makefile index edb2218d41ec..bc39c29fc9a2 100644 --- a/sys/modules/wlan/Makefile +++ b/sys/modules/wlan/Makefile @@ -7,7 +7,7 @@ SRCS= ieee80211.c ieee80211_crypto.c ieee80211_crypto_none.c ieee80211_dfs.c \ ieee80211_freebsd.c ieee80211_input.c ieee80211_ioctl.c \ ieee80211_node.c ieee80211_output.c ieee80211_phy.c ieee80211_power.c \ ieee80211_proto.c ieee80211_scan.c ieee80211_scan_sta.c \ - ieee80211_regdomain.c ieee80211_ht.c \ + ieee80211_radiotap.c ieee80211_regdomain.c ieee80211_ht.c \ ieee80211_adhoc.c ieee80211_hostap.c ieee80211_monitor.c \ ieee80211_sta.c ieee80211_wds.c ieee80211_ddb.c SRCS+= bus_if.h device_if.h opt_inet.h opt_ipx.h opt_wlan.h opt_ddb.h \ From 92f7f12bca2bb7f39cf721940d84a85c7addb24c Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 01:15:07 +0000 Subject: [PATCH 398/544] Fix the experimental nfs server so that it depends on the nlm, since it now calls nlm_acquire_next_sysid(). Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdport.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index b48682e98bd2..f1a1aef3f762 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -3144,4 +3144,5 @@ DECLARE_MODULE(nfsd, nfsd_mod, SI_SUB_VFS, SI_ORDER_ANY); /* So that loader and kldload(2) can find us, wherever we are.. */ MODULE_VERSION(nfsd, 1); MODULE_DEPEND(nfsd, nfscommon, 1, 1, 1); +MODULE_DEPEND(nfsd, nfslockd, 1, 1, 1); From 9ce13065db7684fd495c4c97ca5f0058178633e2 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 May 2009 09:59:34 +0000 Subject: [PATCH 399/544] Add privileges for Capi4BSD to control: - controller reset/firmware loading. - controller level tracing and tracing of capi messages of applications running with different user credentials. Reviewed by: rwatson MFC after: 2 weeks --- sys/sys/priv.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sys/sys/priv.h b/sys/sys/priv.h index 43354067b287..ac6075bcd0db 100644 --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -457,10 +457,16 @@ #define PRIV_CPUCTL_WRMSR 640 /* Write model-specific register. */ #define PRIV_CPUCTL_UPDATE 641 /* Update cpu microcode. */ +/* + * Capi4BSD privileges. + */ +#define PRIV_C4B_RESET_CTLR 650 /* Load firmware, reset controller. */ +#define PRIV_C4B_TRACE 651 /* Unrestricted CAPI message tracing. */ + /* * Track end of privilege list. */ -#define _PRIV_HIGHEST 642 +#define _PRIV_HIGHEST 652 /* * Validate that a named privilege is known by the privilege system. Invalid From 86ce6a83d16fdedede88990ffe1d85ad83d8e7c8 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 22 May 2009 12:35:12 +0000 Subject: [PATCH 400/544] Remove the unmaintained University of Michigan NFSv4 client from 8.x prior to 8.0-RELEASE. Rick Macklem's new and more feature-rich NFSv234 client and server are replacing it. Discussed with: rmacklem --- etc/rc.d/idmapd | 18 - sbin/Makefile | 1 - sbin/idmapd/Makefile | 11 - sbin/idmapd/idmapd.8 | 63 - sbin/idmapd/idmapd.c | 418 ----- sbin/mount_nfs/Makefile | 4 +- sbin/mount_nfs/mount_nfs.8 | 7 +- sbin/mount_nfs/mount_nfs.c | 255 +-- sys/Makefile | 2 +- sys/conf/files | 9 - sys/conf/options | 1 - sys/fs/nfs/nfs_commonkrpc.c | 1 - sys/fs/nfs/nfsport.h | 1 - sys/modules/nfs4client/Makefile | 36 - sys/modules/nfsclient/Makefile | 12 +- sys/nfs4client/nfs4.h | 260 --- sys/nfs4client/nfs4_dev.c | 456 ----- sys/nfs4client/nfs4_dev.h | 65 - sys/nfs4client/nfs4_idmap.c | 509 ------ sys/nfs4client/nfs4_idmap.h | 64 - sys/nfs4client/nfs4_socket.c | 348 ---- sys/nfs4client/nfs4_subs.c | 1367 -------------- sys/nfs4client/nfs4_vfs.h | 34 - sys/nfs4client/nfs4_vfs_subs.c | 125 -- sys/nfs4client/nfs4_vfsops.c | 886 ---------- sys/nfs4client/nfs4_vn.h | 33 - sys/nfs4client/nfs4_vn_subs.c | 225 --- sys/nfs4client/nfs4_vnops.c | 2931 ------------------------------- sys/nfs4client/nfs4m_subs.h | 498 ------ sys/nfsclient/bootp_subr.c | 2 - sys/nfsclient/krpc_subr.c | 2 - sys/nfsclient/nfs.h | 12 - sys/nfsclient/nfs_bio.c | 21 +- sys/nfsclient/nfs_diskless.c | 1 - sys/nfsclient/nfs_krpc.c | 7 - sys/nfsclient/nfs_lock.c | 2 - sys/nfsclient/nfs_nfsiod.c | 2 - sys/nfsclient/nfs_node.c | 13 +- sys/nfsclient/nfs_socket.c | 8 - sys/nfsclient/nfs_subs.c | 2 - sys/nfsclient/nfs_vfsops.c | 1 - sys/nfsclient/nfs_vnops.c | 2 - sys/nfsclient/nfsm_subs.h | 11 - sys/nfsclient/nfsmount.h | 1 - sys/nfsclient/nfsnode.h | 7 - sys/nlm/nlm_advlock.c | 2 +- sys/rpc/rpcclnt.c | 2114 ---------------------- sys/rpc/rpcclnt.h | 354 ---- 48 files changed, 19 insertions(+), 11185 deletions(-) delete mode 100755 etc/rc.d/idmapd delete mode 100644 sbin/idmapd/Makefile delete mode 100644 sbin/idmapd/idmapd.8 delete mode 100644 sbin/idmapd/idmapd.c delete mode 100644 sys/modules/nfs4client/Makefile delete mode 100644 sys/nfs4client/nfs4.h delete mode 100644 sys/nfs4client/nfs4_dev.c delete mode 100644 sys/nfs4client/nfs4_dev.h delete mode 100644 sys/nfs4client/nfs4_idmap.c delete mode 100644 sys/nfs4client/nfs4_idmap.h delete mode 100644 sys/nfs4client/nfs4_socket.c delete mode 100644 sys/nfs4client/nfs4_subs.c delete mode 100644 sys/nfs4client/nfs4_vfs.h delete mode 100644 sys/nfs4client/nfs4_vfs_subs.c delete mode 100644 sys/nfs4client/nfs4_vfsops.c delete mode 100644 sys/nfs4client/nfs4_vn.h delete mode 100644 sys/nfs4client/nfs4_vn_subs.c delete mode 100644 sys/nfs4client/nfs4_vnops.c delete mode 100644 sys/nfs4client/nfs4m_subs.h delete mode 100644 sys/rpc/rpcclnt.c delete mode 100644 sys/rpc/rpcclnt.h diff --git a/etc/rc.d/idmapd b/etc/rc.d/idmapd deleted file mode 100755 index 4c90fd4d04c6..000000000000 --- a/etc/rc.d/idmapd +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: idmapd -# REQUIRE: rpcbind -# KEYWORD: nojail shutdown - -. /etc/rc.subr - -name="idmapd" - -load_rc_config $name -rcvar="idmapd_enable" -command="${idmapd:-/sbin/${name}}" -eval ${name}_flags=\"${idmapd_flags}\" -run_rc_command "$1" diff --git a/sbin/Makefile b/sbin/Makefile index 649f4a225a06..8ece390460d0 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -36,7 +36,6 @@ SUBDIR= adjkerntz \ ggate \ growfs \ gvinum \ - idmapd \ ifconfig \ init \ ${_ipf} \ diff --git a/sbin/idmapd/Makefile b/sbin/idmapd/Makefile deleted file mode 100644 index 8206e0d9bb81..000000000000 --- a/sbin/idmapd/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# @(#)Makefile 8.2 (Berkeley) 3/27/94 -# -# $FreeBSD$ - -PROG= idmapd -MAN= idmapd.8 - -CFLAGS+= -DNFS -I${.CURDIR}/../../sys -WARNS?= 2 - -.include diff --git a/sbin/idmapd/idmapd.8 b/sbin/idmapd/idmapd.8 deleted file mode 100644 index 1fb62168c6eb..000000000000 --- a/sbin/idmapd/idmapd.8 +++ /dev/null @@ -1,63 +0,0 @@ -.\" copyright (c) 2003 -.\" the regents of the university of michigan -.\" all rights reserved -.\" -.\" permission is granted to use, copy, create derivative works and redistribute -.\" this software and such derivative works for any purpose, so long as the name -.\" of the university of michigan is not used in any advertising or publicity -.\" pertaining to the use or distribution of this software without specific, -.\" written prior authorization. if the above copyright notice or any other -.\" identification of the university of michigan is included in any copy of any -.\" portion of this software, then the disclaimer below must also be included. -.\" -.\" this software is provided as is, without representation from the university -.\" of michigan as to its fitness for any purpose, and without warranty by the -.\" university of michigan of any kind, either express or implied, including -.\" without limitation the implied warranties of merchantability and fitness for -.\" a particular purpose. the regents of the university of michigan shall not be -.\" liable for any damages, including special, indirect, incidental, or -.\" consequential damages, with respect to any claim arising out of or in -.\" connection with the use of the software, even if it has been or is hereafter -.\" advised of the possibility of such damages. -.\" -.\" $FreeBSD$ -.\" -.Dd October 15, 2006 -.Dt IDMAPD 8 -.Os -.Sh NAME -.Nm idmapd -.Nd name/UID mapper for NFSv4 -.Sh SYNOPSIS -.Nm -.Op Fl v -.Op Fl d Ar domainname -.Sh DESCRIPTION -The -.Nm -daemon normally runs in the background and services UID/GID-to-name and -name-to-UID/GID mapping -requests from the NFSv4 client kernel threads. -.Pp -The options are: -.Bl -tag -width indent -.It Fl d -Set the domain part of the name string to the specified string. -.It Fl v -Be verbose, and do not run in the background. -.El -.Sh FILES -.Bl -tag -width ".Pa /etc/master.passwd" -compact -.It Pa /etc/pwd.db -The insecure password database file. -.It Pa /etc/spwd.db -The secure password database file. -.It Pa /etc/master.passwd -The current password file. -.It Pa /etc/passwd -A Version 7 format password file. -.El -.Sh SEE ALSO -.Xr getpwnam 3 , -.Xr getpwuid 3 , -.Xr mount_nfs4 8 diff --git a/sbin/idmapd/idmapd.c b/sbin/idmapd/idmapd.c deleted file mode 100644 index fa3a082d3ddb..000000000000 --- a/sbin/idmapd/idmapd.c +++ /dev/null @@ -1,418 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: idmapd.c,v 1.5 2003/11/05 14:58:58 rees Exp $ */ - -/* - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/* XXX ignores the domain of received names. */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#define DEV_PATH "/dev/nfs4" - -#define DOMAIN "@FreeBSD.org" -#define BADUSER "nobody" -#define BADGROUP "nogroup" -#define BADUID 65534 -#define BADGID 65533 - -struct idmap_e { - struct nfs4dev_msg msg; - TAILQ_ENTRY(idmap_e) next; -}; - -int fd, verbose; -char *domain = DOMAIN; - -TAILQ_HEAD(, idmap_e) upcall_q; - -#define add_idmap_e(E) do { \ - assert(E != NULL); \ - TAILQ_INSERT_TAIL(&upcall_q, E, next); \ -} while(0) - -#define remove_idmap_e(E) do { \ - assert(E != NULL && !TAILQ_EMPTY(&upcall_q)); \ - E = TAILQ_FIRST(&upcall_q); \ - TAILQ_REMOVE(&upcall_q, E, next); \ -} while(0) - -#define get_idmap_e(E) do { \ - if ((E = (struct idmap_e *) malloc(sizeof(struct idmap_e))) == NULL) {\ - fprintf(stderr, "get_idmap_e(): error in malloc\n");\ - } } while(0) - -#define put_idmap_e(E) free(E) - -/* from marius */ -int -validateascii(char *string, u_int32_t len) -{ - int i; - - for (i = 0; i < len; i++) { - if (string[i] == '\0') - break; - if (string[i] & 0x80) - return (-1); - } - - if (string[i] != '\0') - return (-1); - return (i + 1); -} - -char * -idmap_prune_domain(struct idmap_msg * m) -{ - size_t i; - size_t len; - char * ret = NULL; - - if (m == NULL) - return NULL; - - len = m->id_namelen; - - if (validateascii(m->id_name, len) < 0) { - fprintf(stderr, "msg has invalid ascii\n"); - return NULL; - } - - for (i=0; i < len && m->id_name[i] != '@' ; i++); - - ret = (char *)malloc(i+1); - if (ret == NULL) - return NULL; - - bcopy(m->id_name, ret, i); - ret[i] = '\0'; - - return ret; -} - -int -idmap_add_domain(struct idmap_msg * m, char * name) -{ - size_t len, nlen; - - if (m == NULL || name == NULL) - return -1; - - len = strlen(name); - - nlen = len + strlen(domain); - - if (nlen > IDMAP_MAXNAMELEN) - return -1; - - bcopy(name, &m->id_name[0], len); - bcopy(domain, &m->id_name[len], strlen(domain)); - - m->id_name[nlen] = '\0'; - m->id_namelen = nlen; - - return 0; -} - -int -idmap_name(struct idmap_msg * m, char *name) -{ - if (m == NULL || name == NULL || m->id_namelen != 0) - return -1; - - if (idmap_add_domain(m, name)) - return -1; - - return 0; -} - -int -idmap_id(struct idmap_msg * m, ident_t id) -{ - if (m == NULL || m->id_namelen == 0) { - fprintf(stderr, "idmap_id: bad msg\n"); - return -1; - } - - switch(m->id_type) { - case IDMAP_TYPE_UID: - m->id_id.uid = id.uid; - break; - case IDMAP_TYPE_GID: - m->id_id.gid = id.gid; - break; - default: - return -1; - break; - }; - - return 0; -} - -int -idmap_service(struct idmap_e * e) -{ - struct idmap_msg * m; - struct passwd * pwd; - struct group * grp; - ident_t id; - char * name; - - if (e == NULL) { - fprintf(stderr, "bad entry\n"); - return -1; - } - - if (e->msg.msg_vers != NFS4DEV_VERSION) { - fprintf(stderr, "kernel/userland version mismatch! %d/%d\n", - e->msg.msg_vers, NFS4DEV_VERSION); - return -1; - } - - if (e->msg.msg_type != NFS4DEV_TYPE_IDMAP) { - fprintf(stderr, "bad type!\n"); - return -1; - } - - if (e->msg.msg_len != sizeof(struct idmap_msg)) { - fprintf(stderr, "bad message length: %zu/%zu\n", e->msg.msg_len, - sizeof(struct idmap_msg)); - return -1; - } - - if (verbose) - printf("servicing msg xid: %x\n", e->msg.msg_xid); - - - m = (struct idmap_msg *)e->msg.msg_data; - - if (m->id_namelen != 0 && m->id_namelen != strlen(m->id_name)) { - fprintf(stderr, "bad name length in idmap_msg\n"); - return -1; - } - - switch (m->id_type) { - case IDMAP_TYPE_UID: - if (m->id_namelen == 0) { - /* id to name */ - pwd = getpwuid(m->id_id.uid); - - if (pwd == NULL) { - fprintf(stderr, "unknown uid %d!\n", - (uint32_t)m->id_id.uid); - name = BADUSER; - } else - name = pwd->pw_name; - - if (idmap_name(m, name)) - return -1; - - } else { - /* name to id */ - name = idmap_prune_domain(m); - if (name == NULL) - return -1; - - pwd = getpwnam(name); - - if (pwd == NULL) { - fprintf(stderr, "unknown username %s!\n", name); - - id.uid = (uid_t)BADUID; - } else - id.uid = pwd->pw_uid; - - free(name); - - if (idmap_id(m, id)) - return -1; - } - break; - case IDMAP_TYPE_GID: - if (m->id_namelen == 0) { - /* id to name */ - grp = getgrgid(m->id_id.gid); - - if (grp == NULL) { - fprintf(stderr, "unknown gid %d!\n", - (uint32_t)m->id_id.gid); - name = BADGROUP; - } else - name = grp->gr_name; - - if (idmap_name(m, name)) - return -1; - } else { - /* name to id */ - name = idmap_prune_domain(m); - if (name == NULL) - return -1; - - grp = getgrnam(name); - - if (grp == NULL) { - fprintf(stderr, "unknown groupname %s!\n", name); - - id.gid = (gid_t)BADGID; - } else - id.gid = grp->gr_gid; - - free(name); - - if (idmap_id(m, id)) - return -1; - } - break; - default: - fprintf(stderr, "bad idmap type: %d\n", m->id_type); - return -1; - break; - } - - return 0; -} - -int -main(int argc, char ** argv) -{ - int error = 0; - struct idmap_e * entry; - fd_set read_fds, write_fds; - int maxfd; - int ret, ch; - - while ((ch = getopt(argc, argv, "d:v")) != -1) { - switch (ch) { - case 'd': - domain = optarg; - break; - case 'v': - verbose = 1; - break; - default: - fprintf(stderr, "usage: %s [-v] [-d domain]\n", argv[0]); - exit(1); - break; - } - } - - - TAILQ_INIT(&upcall_q); - - fd = open(DEV_PATH, O_RDWR, S_IRUSR | S_IWUSR); - - if (fd < 0) { - perror(DEV_PATH); - exit(1); - } - - if (!verbose) - daemon(0,0); - - maxfd = fd; - for (;;) { - struct timeval timo = {1, 0}; - do { - FD_ZERO(&read_fds); - FD_ZERO(&write_fds); - - FD_SET(fd, &read_fds); - FD_SET(fd, &write_fds); - - ret = select(maxfd+1, &read_fds, &write_fds, NULL, &timo); - } while (ret < 0 && errno == EINTR); - - if (ret <= 0) { - if (ret != 0) - perror("select"); - continue; - } - - - if (FD_ISSET(fd, &read_fds)) { - for (;;) { - get_idmap_e(entry); - - error = ioctl(fd, NFS4DEVIOCGET, &entry->msg); - - if (error == -1) { - if (errno != EAGAIN) - perror("get ioctl:"); - put_idmap_e(entry); - break; - } - - switch (entry->msg.msg_type ) { - case NFS4DEV_TYPE_IDMAP: - if (idmap_service(entry)) - entry->msg.msg_error = EIO; - break; - default: - fprintf(stderr, "unknown nfs4dev_msg type\n"); - entry->msg.msg_error = EIO; - break; - } - - add_idmap_e(entry); - } - } - - if (FD_ISSET(fd, &write_fds)) { - while (!TAILQ_EMPTY(&upcall_q)) { - remove_idmap_e(entry); - - error = ioctl(fd, NFS4DEVIOCPUT, &entry->msg); - - if (error == -1) { - if (errno != EAGAIN) - perror("put ioctl"); - break; - } - put_idmap_e(entry); - } - } - } - - /* never reached */ - exit(1); -} diff --git a/sbin/mount_nfs/Makefile b/sbin/mount_nfs/Makefile index 4f7efeadd2b1..960f97c59c1d 100644 --- a/sbin/mount_nfs/Makefile +++ b/sbin/mount_nfs/Makefile @@ -5,15 +5,13 @@ PROG= mount_nfs SRCS= mount_nfs.c getmntopts.c mounttab.c MAN= mount_nfs.8 -MLINKS= mount_nfs.8 mount_nfs4.8 +MLINKS= mount_nfs.8 MOUNT= ${.CURDIR}/../mount UMNTALL= ${.CURDIR}/../../usr.sbin/rpc.umntall CFLAGS+= -DNFS -I${MOUNT} -I${UMNTALL} WARNS?= 3 -LINKS= ${BINDIR}/mount_nfs ${BINDIR}/mount_nfs4 - .PATH: ${MOUNT} ${UMNTALL} .include diff --git a/sbin/mount_nfs/mount_nfs.8 b/sbin/mount_nfs/mount_nfs.8 index c75a30dfd269..78a3b1967729 100644 --- a/sbin/mount_nfs/mount_nfs.8 +++ b/sbin/mount_nfs/mount_nfs.8 @@ -36,7 +36,7 @@ .Nd mount NFS file systems .Sh SYNOPSIS .Nm -.Op Fl 234bcdiLlNPsTU +.Op Fl 23bcdiLlNPsTU .Op Fl a Ar maxreadahead .Op Fl D Ar deadthresh .Op Fl g Ar maxgroups @@ -157,8 +157,6 @@ then version 2). Note that NFS version 2 has a file size limit of 2 gigabytes. .It Cm nfsv3 Use the NFS Version 3 protocol. -.It Cm nfsv4 -Use the NFS Version 4 protocol. .It Cm noconn For UDP mount points, do not do a .Xr connect 2 . @@ -303,9 +301,6 @@ Same as .It Fl 3 Same as .Fl o Cm nfsv3 -.It Fl 4 -Same as -.Fl o Cm nfsv4 .It Fl D Same as .Fl o Cm deadthresh diff --git a/sbin/mount_nfs/mount_nfs.c b/sbin/mount_nfs/mount_nfs.c index a2f5e89a3d6b..102c51d35a9d 100644 --- a/sbin/mount_nfs/mount_nfs.c +++ b/sbin/mount_nfs/mount_nfs.c @@ -1,27 +1,3 @@ -/* - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - /* * Copyright (c) 1992, 1993, 1994 * The Regents of the University of California. All rights reserved. @@ -140,7 +116,6 @@ enum mountmode { ANY, V2, V3, - V4 } mountmode = ANY; /* Return codes for nfs_tryproto. */ @@ -155,7 +130,6 @@ int fallback_mount(struct iovec *iov, int iovlen, int mntflags); int sec_name_to_num(char *sec); char *sec_num_to_name(int num); int getnfsargs(char *, struct iovec **iov, int *iovlen); -int getnfs4args(char *, struct iovec **iov, int *iovlen); /* void set_rpc_maxgrouplist(int); */ struct netconfig *getnetconf_cached(const char *netid); const char *netidbytype(int af, int sotype); @@ -164,8 +138,6 @@ int xdr_dir(XDR *, char *); int xdr_fh(XDR *, struct nfhret *); enum tryret nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr, struct iovec **iov, int *iovlen); -enum tryret nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec, - char **errstr); enum tryret returncode(enum clnt_stat stat, struct rpc_err *rpcerr); extern int getosreldate(void); @@ -190,15 +162,8 @@ main(int argc, char *argv[]) ++fstype; - if (strcmp(fstype, "nfs4") == 0) { - nfsproto = IPPROTO_TCP; - portspec = "2049"; - build_iovec(&iov, &iovlen, "tcp", NULL, 0); - mountmode = V4; - } - while ((c = getopt(argc, argv, - "234a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1) + "23a:bcdD:g:I:iLlNo:PR:r:sTt:w:x:U")) != -1) switch (c) { case '2': mountmode = V2; @@ -206,10 +171,6 @@ main(int argc, char *argv[]) case '3': mountmode = V3; break; - case '4': - mountmode = V4; - fstype = "nfs4"; - break; case 'a': printf("-a deprecated, use -o readhead=\n"); build_iovec(&iov, &iovlen, "readahead", optarg, (size_t)-1); @@ -301,10 +262,6 @@ main(int argc, char *argv[]) mountmode = V2; } else if (strcmp(opt, "nfsv3") == 0) { mountmode = V3; - } else if (strcmp(opt, "nfsv4") == 0) { - pass_flag_to_nmount=0; - mountmode = V4; - fstype = "nfs4"; } else if (strcmp(opt, "port") == 0) { pass_flag_to_nmount=0; asprintf(&portspec, "%d", @@ -406,13 +363,8 @@ main(int argc, char *argv[]) /* The default is to keep retrying forever. */ retrycnt = 0; - if (mountmode == V4) { - if (!getnfs4args(spec, &iov, &iovlen)) - exit(1); - } else { - if (!getnfsargs(spec, &iov, &iovlen)) - exit(1); - } + if (!getnfsargs(spec, &iov, &iovlen)) + exit(1); /* resolve the mountpoint with realpath(3) */ (void)checkpath(name, mntpath); @@ -814,129 +766,6 @@ getnfsargs(char *spec, struct iovec **iov, int *iovlen) return (1); } - -int -getnfs4args(char *spec, struct iovec **iov, int *iovlen) -{ - struct addrinfo hints, *ai_nfs, *ai; - enum tryret ret; - int ecode, speclen, remoteerr, sotype; - char *hostp, *delimp, *errstr; - size_t len; - static char nam[MNAMELEN + 1]; - - if (nfsproto == IPPROTO_TCP) - sotype = SOCK_STREAM; - else if (nfsproto == IPPROTO_UDP) - sotype = SOCK_DGRAM; - - - if ((delimp = strrchr(spec, ':')) != NULL) { - hostp = spec; - spec = delimp + 1; - } else if ((delimp = strrchr(spec, '@')) != NULL) { - warnx("path@server syntax is deprecated, use server:path"); - hostp = delimp + 1; - } else { - warnx("no : nfs-name"); - return (0); - } - *delimp = '\0'; - - /* - * If there has been a trailing slash at mounttime it seems - * that some mountd implementations fail to remove the mount - * entries from their mountlist while unmounting. - */ - for (speclen = strlen(spec); - speclen > 1 && spec[speclen - 1] == '/'; - speclen--) - spec[speclen - 1] = '\0'; - if (strlen(hostp) + strlen(spec) + 1 > MNAMELEN) { - warnx("%s:%s: %s", hostp, spec, strerror(ENAMETOOLONG)); - return (0); - } - /* Make both '@' and ':' notations equal */ - if (*hostp != '\0') { - len = strlen(hostp); - memmove(nam, hostp, len); - nam[len] = ':'; - memmove(nam + len + 1, spec, speclen); - nam[len + speclen + 1] = '\0'; - } - - /* - * Handle an internet host address. - */ - memset(&hints, 0, sizeof hints); - hints.ai_flags = AI_NUMERICHOST; - hints.ai_socktype = sotype; - if (getaddrinfo(hostp, portspec, &hints, &ai_nfs) != 0) { - hints.ai_flags = 0; - if ((ecode = getaddrinfo(hostp, portspec, &hints, &ai_nfs)) - != 0) { - if (portspec == NULL) - errx(1, "%s: %s", hostp, gai_strerror(ecode)); - else - errx(1, "%s:%s: %s", hostp, portspec, - gai_strerror(ecode)); - return (0); - } - } - - ret = TRYRET_LOCALERR; - for (;;) { - /* - * Try each entry returned by getaddrinfo(). Note the - * occurence of remote errors by setting `remoteerr'. - */ - remoteerr = 0; - for (ai = ai_nfs; ai != NULL; ai = ai->ai_next) { - if ((ai->ai_family == AF_INET6) && - (opflags & OF_NOINET6)) - continue; - if ((ai->ai_family == AF_INET) && - (opflags & OF_NOINET4)) - continue; - ret = nfs4_tryproto(ai, hostp, spec, &errstr); - if (ret == TRYRET_SUCCESS) - break; - if (ret != TRYRET_LOCALERR) - remoteerr = 1; - if ((opflags & ISBGRND) == 0) - fprintf(stderr, "%s\n", errstr); - } - if (ret == TRYRET_SUCCESS) - break; - - /* Exit if all errors were local. */ - if (!remoteerr) - exit(1); - - /* - * If retrycnt == 0, we are to keep retrying forever. - * Otherwise decrement it, and exit if it hits zero. - */ - if (retrycnt != 0 && --retrycnt == 0) - exit(1); - - if ((opflags & (BGRND | ISBGRND)) == BGRND) { - warnx("Cannot immediately mount %s:%s, backgrounding", - hostp, spec); - opflags |= ISBGRND; - if (daemon(0, 0) != 0) - err(1, "daemon"); - } - sleep(60); - } - freeaddrinfo(ai_nfs); - build_iovec(iov, iovlen, "hostname", nam, (size_t)-1); - /* Add mounted file system to PATH_MOUNTTAB */ - if (!add_mtab(hostp, spec)) - warnx("can't update %s for %s:%s", PATH_MOUNTTAB, hostp, spec); - return (1); -} - /* * Try to set up the NFS arguments according to the address * family, protocol (and possibly port) specified in `ai'. @@ -1142,82 +971,6 @@ nfs_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr, return (TRYRET_SUCCESS); } - -/* - * Try to set up the NFS arguments according to the address - * family, protocol (and possibly port) specified in `ai'. - * - * Returns TRYRET_SUCCESS if successful, or: - * TRYRET_TIMEOUT The server did not respond. - * TRYRET_REMOTEERR The server reported an error. - * TRYRET_LOCALERR Local failure. - * - * In all error cases, *errstr will be set to a statically-allocated string - * describing the error. - */ -enum tryret -nfs4_tryproto(struct addrinfo *ai, char *hostp, char *spec, char **errstr) -{ - static char errbuf[256]; - struct sockaddr_storage nfs_ss; - struct netbuf nfs_nb; - struct netconfig *nconf; - const char *netid; - int nfsvers, sotype; - - errbuf[0] = '\0'; - *errstr = errbuf; - - if (nfsproto == IPPROTO_TCP) - sotype = SOCK_STREAM; - else if (nfsproto == IPPROTO_UDP) - sotype = SOCK_DGRAM; - - if ((netid = netidbytype(ai->ai_family, sotype)) == NULL) { - snprintf(errbuf, sizeof errbuf, - "af %d sotype %d not supported", ai->ai_family, sotype); - return (TRYRET_LOCALERR); - } - if ((nconf = getnetconf_cached(netid)) == NULL) { - snprintf(errbuf, sizeof errbuf, "%s: %s", netid, nc_sperror()); - return (TRYRET_LOCALERR); - } - - nfsvers = 4; - - if (portspec != NULL && atoi(portspec) != 0) { - /* `ai' contains the complete nfsd sockaddr. */ - nfs_nb.buf = ai->ai_addr; - nfs_nb.len = nfs_nb.maxlen = ai->ai_addrlen; - } else { - /* Ask the remote rpcbind. */ - nfs_nb.buf = &nfs_ss; - nfs_nb.len = nfs_nb.maxlen = sizeof nfs_ss; - - if (!rpcb_getaddr(RPCPROG_NFS, nfsvers, nconf, &nfs_nb, - hostp)) { - snprintf(errbuf, sizeof errbuf, "[%s] %s:%s: %s", - netid, hostp, spec, - clnt_spcreateerror("RPCPROG_NFS")); - return (returncode(rpc_createerr.cf_stat, - &rpc_createerr.cf_error)); - } - } - - /* - * Store the filehandle and server address in nfsargsp, making - * sure to copy any locally allocated structures. - */ - addrlen = nfs_nb.len; - addr = malloc(addrlen); - - if (addr == NULL) - err(1, "malloc"); - bcopy(nfs_nb.buf, addr, addrlen); - - return (TRYRET_SUCCESS); -} - /* * Catagorise a RPC return status and error into an `enum tryret' * return code. @@ -1361,7 +1114,7 @@ void usage() { (void)fprintf(stderr, "%s\n%s\n%s\n%s\n", -"usage: mount_nfs [-234bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]", +"usage: mount_nfs [-23bcdiLlNPsTU] [-a maxreadahead] [-D deadthresh]", " [-g maxgroups] [-I readdirsize] [-o options] [-R retrycnt]", " [-r readsize] [-t timeout] [-w writesize] [-x retrans]", " rhost:path node"); diff --git a/sys/Makefile b/sys/Makefile index f41da817072d..cb5fd13164b4 100644 --- a/sys/Makefile +++ b/sys/Makefile @@ -11,7 +11,7 @@ SUBDIR= boot CSCOPEDIRS= boot bsm cam cddl compat conf contrib crypto ddb dev fs gdb \ geom gnu isa kern libkern modules net net80211 netatalk \ netgraph netinet netinet6 netipsec netipx netnatm netncp \ - netsmb nfs nfs4client nfsclient nfsserver nlm opencrypto \ + netsmb nfs nfsclient nfsserver nlm opencrypto \ pci rpc security sys ufs vm xdr ${CSCOPE_ARCHDIR} .if defined(ALL_ARCH) CSCOPE_ARCHDIR ?= amd64 arm i386 ia64 mips pc98 powerpc sparc64 sun4v diff --git a/sys/conf/files b/sys/conf/files index 33b4c6fd5da9..a3bd42f252bd 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2450,14 +2450,6 @@ netsmb/smb_subr.c optional netsmb netsmb/smb_trantcp.c optional netsmb netsmb/smb_usr.c optional netsmb nfs/nfs_common.c optional nfsclient | nfsserver -nfs4client/nfs4_dev.c optional nfsclient -nfs4client/nfs4_idmap.c optional nfsclient -nfs4client/nfs4_socket.c optional nfsclient -nfs4client/nfs4_subs.c optional nfsclient -nfs4client/nfs4_vfs_subs.c optional nfsclient -nfs4client/nfs4_vfsops.c optional nfsclient -nfs4client/nfs4_vn_subs.c optional nfsclient -nfs4client/nfs4_vnops.c optional nfsclient nfsclient/bootp_subr.c optional bootp nfsclient nfsclient/krpc_subr.c optional bootp nfsclient nfsclient/nfs_bio.c optional nfsclient @@ -2519,7 +2511,6 @@ rpc/rpc_generic.c optional krpc | nfslockd | nfsclient | nfsserver rpc/rpc_prot.c optional krpc | nfslockd | nfsclient | nfsserver rpc/rpcb_clnt.c optional krpc | nfslockd | nfsclient | nfsserver rpc/rpcb_prot.c optional krpc | nfslockd | nfsclient | nfsserver -rpc/rpcclnt.c optional nfsclient rpc/svc.c optional krpc | nfslockd | nfsserver rpc/svc_auth.c optional krpc | nfslockd | nfsserver rpc/svc_auth_unix.c optional krpc | nfslockd | nfsserver diff --git a/sys/conf/options b/sys/conf/options index 758190fd8408..cc06bd7f48fa 100644 --- a/sys/conf/options +++ b/sys/conf/options @@ -226,7 +226,6 @@ KGSSAPI_DEBUG opt_kgssapi.h # filesystems will be enabled - but look below. NFSCLIENT opt_nfs.h NFSSERVER opt_nfs.h -NFS4CLIENT opt_nfs.h # Use this option to compile both NFS client and server using the # legacy RPC implementation instead of the newer KRPC system (which diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 6e27e4d68384..4b37802454de 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -59,7 +59,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index 5be658799360..d452927d23d8 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -98,7 +98,6 @@ #include #include #include -#include #include /* diff --git a/sys/modules/nfs4client/Makefile b/sys/modules/nfs4client/Makefile deleted file mode 100644 index bdc272f5ff27..000000000000 --- a/sys/modules/nfs4client/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs4client \ - ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc -KMOD= nfs4client -SRCS= vnode_if.h \ - nfs_bio.c nfs_lock.c nfs_node.c nfs_nfsiod.c \ - nfs_common.c \ - opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h \ - nfs4_dev.c nfs4_idmap.c nfs4_socket.c nfs4_subs.c \ - nfs4_vfs_subs.c nfs4_vfsops.c nfs4_vn_subs.c nfs4_vnops.c -SRCS+= opt_inet6.h - -# USE THE RPCCLNT: -CFLAGS+= -DRPCCLNT_DEBUG -SRCS+= rpcclnt.c - -# USE THE NEW IDMAPPER -CFLAGS+= -DUSE_NEW_IDMAPPER - -.if !defined(KERNBUILDDIR) -NFS_INET?= 1 # 0/1 - requires INET to be configured in kernel -NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel - -.if ${NFS_INET} > 0 -opt_inet.h: - echo "#define INET 1" > ${.TARGET} -.endif - -.if ${NFS_INET6} > 0 -opt_inet6.h: - echo "#define INET6 1" > ${.TARGET} -.endif -.endif - -.include diff --git a/sys/modules/nfsclient/Makefile b/sys/modules/nfsclient/Makefile index a42050244aff..af02f6a98ae5 100644 --- a/sys/modules/nfsclient/Makefile +++ b/sys/modules/nfsclient/Makefile @@ -1,24 +1,14 @@ # $FreeBSD$ -.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs4client \ - ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc +.PATH: ${.CURDIR}/../../nfsclient ${.CURDIR}/../../nfs ${.CURDIR}/../../rpc KMOD= nfsclient SRCS= vnode_if.h \ nfs_bio.c nfs_lock.c nfs_node.c nfs_socket.c nfs_subs.c nfs_nfsiod.c \ nfs_vfsops.c nfs_vnops.c nfs_common.c nfs_krpc.c \ opt_inet.h opt_nfs.h opt_bootp.h opt_nfsroot.h -SRCS+= nfs4_dev.c nfs4_idmap.c nfs4_socket.c nfs4_subs.c \ - nfs4_vfs_subs.c nfs4_vfsops.c nfs4_vn_subs.c nfs4_vnops.c SRCS+= opt_inet6.h opt_kdtrace.h opt_kgssapi.h opt_route.h -# USE THE RPCCLNT: -CFLAGS+= -DRPCCLNT_DEBUG -SRCS+= rpcclnt.c - -# USE THE NEW IDMAPPER -CFLAGS+= -DUSE_NEW_IDMAPPER - .if !defined(KERNBUILDDIR) NFS_INET?= 1 # 0/1 - requires INET to be configured in kernel NFS_INET6?= 1 # 0/1 - requires INET6 to be configured in kernel diff --git a/sys/nfs4client/nfs4.h b/sys/nfs4client/nfs4.h deleted file mode 100644 index 4bcc6a7f3121..000000000000 --- a/sys/nfs4client/nfs4.h +++ /dev/null @@ -1,260 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4.h,v 1.25 2003/11/05 14:58:58 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef _NFS4CLIENT_NFS4_H -#define _NFS4CLIENT_NFS4_H - -#define NFS4_USE_RPCCLNT - -#define NFS4_MINOR_VERSION 0 -#define NFS_PORT 2049 -#define NFS4_DEF_FILE_IO_BUFFER_SIZE 4096 -#define NFS4_MAX_FILE_IO_BUFFER_SIZE 32768 -#define NFS4_DEF_MAXFILESIZE 0xffffffff -#define NFS4_SUPER_MAGIC 0xF00BA4 - -#define NFS4FS_SILLY_RENAME 1 -#define NFS4FS_STRICT_LOCKING 1 -#define NFS4FS_RETRY_OLD_STATEID 1 -#define NFS4FS_MIN_LEASE (1 * hz) -#define NFS4FS_DEFAULT_LEASE (30 * hz) -#define NFS4FS_MAX_LEASE (120 * hz) -#define NFS4FS_RETRY_MIN_DELAY (hz >> 4) -#define NFS4FS_RETRY_MAX_DELAY (hz << 3) -#define NFS4FS_SEMAPHORE_DELAY (hz >> 4) -#define NFS4FS_GRACE_DELAY (hz * 5) -#define NFS4FS_OLD_STATEID_DELAY (hz >> 3) -#define NFS4FS_OP_MAX 10 - - -#define NFS4_BUFSIZE 8192 -#define NFS4FS_MAX_IOV 10 -#define NFS4_SETCLIENTID_MAXTRIES 5 -#define NFS4_READDIR_MAXTRIES 5 -#define NFS4_MAXIO 4 -#define NFS4_MAX_REQUEST_SOFT 192 -#define NFS4_MAX_REQUEST_HARD 256 -#define NFS4_MAXCOMMIT 64 -#define NFS4_READ_DELAY (2 * HZ) -#define NFS4_WRITEBACK_DELAY (5 * HZ) -#define NFS4_WRITEBACK_LOCKDELAY (60 * HZ) -#define NFS4_COMMIT_DELAY (5 * HZ) -#define RPC_SLACK_SPACE 512 - - -struct nfs4_compound { - char *tag; - - int req_nops; - uint32_t *req_nopsp; - uint32_t *req_seqidp; - uint32_t *req_stateidp[NFS4_MAXIO]; - uint32_t req_nstateid; - - u_int seqidused; - - int rep_status; - int rep_nops; - - struct nfs4_fctx *fcp; - - struct vnode *curvp; - struct vnode *savevp; - - struct nfsmount *nmp; -}; - -struct nfs4_fdata { - struct nfsnode *fd_n; - pid_t fd_pid; -}; - -struct nfs4_oparg_putfh { - /* filled in by caller */ -/* struct dentry *dentry;*/ - - /* filled in by setup routine */ -/* nfs_opnum4 op;*/ - uint32_t fh_len; - nfsfh_t fh_val; - int nlookups; -}; - -struct nfs4_oparg_getattr { - struct vnode *vp; - nfsv4bitmap *bm; - struct nfsv4_fattr fa; -}; - -struct nfs4_oparg_getfh { - uint32_t fh_len; - nfsfh_t fh_val; - struct vnode *vp; -}; - -struct nfs4_oparg_lookup { - const char *name; - uint32_t namelen; - struct vnode *vp; -}; - -struct nfs4_oparg_setclientid { - struct nfsmount *np; - uint32_t namelen; - char *name; - char *cb_netid; - uint32_t cb_netidlen; - char *cb_univaddr; - uint32_t cb_univaddrlen; - uint32_t cb_prog; - - uint64_t clientid; - u_char verf[NFSX_V4VERF]; -}; - -struct nfs4_oparg_access { - uint32_t mode; - uint32_t rmode; - uint32_t supported; -}; - -struct nfs4_oparg_open { - uint32_t flags; - uint32_t rflags; - - nfsv4cltype ctype; - struct vattr *vap; - struct componentname *cnp; - - struct nfs4_fctx *fcp; - - char stateid[NFSX_V4STATEID]; -}; - -struct nfs4_oparg_read { - uint64_t off; - uint32_t maxcnt; - uint32_t eof; - uint32_t retlen; - struct uio *uiop; - struct nfs4_fctx *fcp; -}; - -struct nfs4_oparg_write { - uint64_t off; - uint32_t stable; - uint32_t cnt; - uint32_t retlen; - uint32_t committed; - struct uio *uiop; - u_char wverf[NFSX_V4VERF]; - struct nfs4_fctx *fcp; -}; - -struct nfs4_oparg_commit { - uint32_t len; - off_t start; - - u_char verf[NFSX_V4VERF]; -}; - -struct nfs4_oparg_readdir { - uint32_t cnt; - nfsv4bitmap *bm; - uint64_t cookie; - u_char verf[NFSX_V4VERF]; -}; - -struct nfs4_oparg_create { - nfstype type; - char *linktext; - char *name; - uint32_t namelen; - struct vattr *vap; -}; - -struct nfs4_oparg_rename { - const char *fname; - uint32_t fnamelen; - const char *tname; - uint32_t tnamelen; -}; - -struct nfs4_oparg_link { - const char *name; - uint32_t namelen; -}; - -/* - * Lockowner - */ -struct nfs4_lowner { - uint32_t lo_cnt; - uint32_t lo_seqid; - uint32_t lo_id; -}; - -#define NFS4_SEQIDMUTATINGERROR(err) \ -(((err) != NFSERR_STALE_CLIENTID) && \ - ((err) != NFSERR_BAD_SEQID) && \ - ((err) != NFSERR_STALE_STATEID) && \ - ((err) != NFSERR_BAD_STATEID)) - -/* Standard bitmasks */ -extern nfsv4bitmap nfsv4_fsinfobm; -extern nfsv4bitmap nfsv4_fsattrbm; -extern nfsv4bitmap nfsv4_getattrbm; -extern nfsv4bitmap nfsv4_readdirbm; - -vfs_init_t nfs4_init; -vfs_uninit_t nfs4_uninit; - -uint32_t nfs_v4fileid4_to_fileid(uint64_t); - -int nfs4_readrpc(struct vnode *, struct uio *, struct ucred *); -int nfs4_writerpc(struct vnode *, struct uio *, struct ucred *, int *, - int *); -int nfs4_commit(struct vnode *vp, u_quad_t offset, int cnt, - struct ucred *cred, struct thread *td); -int nfs4_readdirrpc(struct vnode *, struct uio *, struct ucred *); -int nfs4_readlinkrpc(struct vnode *, struct uio *, struct ucred *); -int nfs4_sigintr(struct nfsmount *, struct nfsreq *, struct thread *); -int nfs4_writebp(struct buf *, int, struct thread *); -int nfs4_request(struct vnode *, struct mbuf *, int, struct thread *, - struct ucred *, struct mbuf **, struct mbuf **, caddr_t *); -int nfs4_request_mnt(struct nfsmount *, struct mbuf *, int, struct thread *, - struct ucred *, struct mbuf **, struct mbuf **, caddr_t *); -int nfs4_connect(struct nfsmount *); -void nfs4_disconnect(struct nfsmount *); -void nfs4_safedisconnect(struct nfsmount *); -int nfs4_nmcancelreqs(struct nfsmount *); - -void nfs_v4initcompound(struct nfs4_compound *); -int nfs_v4postop(struct nfs4_compound *, int); -int nfs_v4handlestatus(int, struct nfs4_compound *); - -#endif /* _NFS4CLIENT_NFS4_H */ diff --git a/sys/nfs4client/nfs4_dev.c b/sys/nfs4client/nfs4_dev.c deleted file mode 100644 index fc1e4875d841..000000000000 --- a/sys/nfs4client/nfs4_dev.c +++ /dev/null @@ -1,456 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_dev.c,v 1.10 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef NFS4DEVVERBOSE -#define NFS4DEV_DEBUG(X...) printf(X) -#else -#define NFS4DEV_DEBUG(X...) -#endif - -#define NFS4DEV_NAME "nfs4" -#define CDEV_MINOR 1 - -MALLOC_DEFINE(M_NFS4DEV, "nfs4_dev", "NFS4 device"); - -struct nfs4dev_upcall { - /* request msg */ - struct nfs4dev_msg up_reqmsg; - size_t up_reqmsglen; - - /* reply (payload only) */ - caddr_t up_rep; - size_t * up_replen; - - int up_copied; /* non-zero when reply has been copied to - '*up_rep' */ - - int up_error; /* non-zero if an error occured */ - - TAILQ_ENTRY(nfs4dev_upcall) up_entry; -}; - - -#define nfs4dev_upcall_get(MP) (MP) = malloc(sizeof(struct nfs4dev_upcall), M_NFS4DEV, M_WAITOK | M_ZERO) - -#define nfs4dev_upcall_put(MP) free((MP), M_NFS4DEV) - -static int nfs4dev_nopen = 0; -static struct thread * nfs4dev_reader = NULL; -static struct cdev *nfs4device = 0; -static struct mtx nfs4dev_daemon_mtx; - -static int nfs4dev_xid = 0; -/* queue of pending upcalls */ -TAILQ_HEAD(, nfs4dev_upcall) nfs4dev_newq; -static struct mtx nfs4dev_newq_mtx; - -/* queue of upcalls waiting for replys */ -TAILQ_HEAD(, nfs4dev_upcall) nfs4dev_waitq; -static struct mtx nfs4dev_waitq_mtx; - -/* dev hooks */ -static d_open_t nfs4dev_open; -static d_close_t nfs4dev_close; -static d_ioctl_t nfs4dev_ioctl; -static d_poll_t nfs4dev_poll; - -static struct cdevsw nfs4dev_cdevsw = { -#if (__FreeBSD_version > 502102) - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, -#endif - .d_open = nfs4dev_open, - .d_close = nfs4dev_close, - .d_ioctl = nfs4dev_ioctl, - .d_poll = nfs4dev_poll, - .d_name = NFS4DEV_NAME, -}; - -static int nfs4dev_reply(caddr_t); -static int nfs4dev_request(caddr_t); - -/* Userland requests a new operation to service */ -static int -nfs4dev_request(caddr_t addr) -{ - struct nfs4dev_upcall * u; - struct nfs4dev_msg * m = (struct nfs4dev_msg *) addr; - - mtx_lock(&nfs4dev_newq_mtx); - - if (TAILQ_EMPTY(&nfs4dev_newq)) { - mtx_unlock(&nfs4dev_newq_mtx); - return EAGAIN; - } - - u = TAILQ_FIRST(&nfs4dev_newq); - TAILQ_REMOVE(&nfs4dev_newq, u, up_entry); - mtx_unlock(&nfs4dev_newq_mtx); - - bcopy(&u->up_reqmsg, m, sizeof(struct nfs4dev_msg)); - - mtx_lock(&nfs4dev_waitq_mtx); - TAILQ_INSERT_TAIL(&nfs4dev_waitq, u, up_entry); - mtx_unlock(&nfs4dev_waitq_mtx); - - return 0; -} - -static int -nfs4dev_reply(caddr_t addr) -{ - struct nfs4dev_upcall * u; - struct nfs4dev_msg * m = (struct nfs4dev_msg *) addr; - int error; - - if (m->msg_vers != NFS4DEV_VERSION) { - printf("nfs4dev version mismatch\n"); - return EINVAL; - } - - if (m->msg_type > NFS4DEV_MAX_TYPE) { - NFS4DEV_DEBUG("nfs4dev: unsupported message type\n"); - return EINVAL; - } - - if (m->msg_len < sizeof(*m) - NFS4DEV_MSG_MAX_DATALEN || - m->msg_len > NFS4DEV_MSG_MAX_DATALEN) { - NFS4DEV_DEBUG("bad message length\n"); - return EINVAL; - } - - /* match the reply with a request */ - mtx_lock(&nfs4dev_waitq_mtx); - TAILQ_FOREACH(u, &nfs4dev_waitq, up_entry) { - if (m->msg_xid == u->up_reqmsg.msg_xid) { - if (m->msg_type == u->up_reqmsg.msg_type) - goto found; - NFS4DEV_DEBUG("nfs4dev: op type mismatch!\n"); - break; - } - } - mtx_unlock(&nfs4dev_waitq_mtx); - - NFS4DEV_DEBUG("nfs4dev msg op: %d xid: %x not found.\n", - m->msg_type, m->msg_xid); - - error = EIO; - goto bad; - -found: - TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry); - mtx_unlock(&nfs4dev_waitq_mtx); - - if (m->msg_error) { - error = m->msg_error; - goto bad; - } - - if (m->msg_len > *u->up_replen) { - error = EFAULT; - goto bad; - } - - bcopy(m->msg_data, u->up_rep, m->msg_len); - *u->up_replen = m->msg_len; - - u->up_copied = m->msg_len; - wakeup(u); - - return 0; -bad: - if (u) { - u->up_error = error; - wakeup(u); - } - return error; -} - -void -nfs4dev_init(void) -{ - nfs4dev_xid = arc4random(); - TAILQ_INIT(&nfs4dev_newq); - TAILQ_INIT(&nfs4dev_waitq); - mtx_init(&nfs4dev_newq_mtx, "nfs4dev newq", NULL, MTX_DEF); - mtx_init(&nfs4dev_waitq_mtx, "nfs4dev waitq", NULL, MTX_DEF); - - mtx_init(&nfs4dev_daemon_mtx, "nfs4dev state", NULL, MTX_DEF); - - nfs4device = make_dev(&nfs4dev_cdevsw, CDEV_MINOR, (uid_t)0, (gid_t)0, - S_IRUSR | S_IWUSR, "nfs4"); -} - -void -nfs4dev_uninit(void) -{ - struct proc * dead = NULL; - - mtx_lock(&nfs4dev_daemon_mtx); - if (nfs4dev_nopen) { - if (nfs4dev_reader == NULL) { - NFS4DEV_DEBUG("nfs4dev uninit(): unregistered reader\n"); - } else { - dead = nfs4dev_reader->td_proc; - } - } - mtx_unlock(&nfs4dev_daemon_mtx); - - if (dead != NULL) { - NFS4DEV_DEBUG("nfs4dev_uninit(): you forgot to kill attached daemon (pid: %u)\n", - dead->p_pid); - PROC_LOCK(dead); - psignal(dead, SIGTERM); - PROC_UNLOCK(dead); - } - - /* XXX moot? */ - nfs4dev_purge(); - - mtx_destroy(&nfs4dev_newq_mtx); - mtx_destroy(&nfs4dev_waitq_mtx); - mtx_destroy(&nfs4dev_daemon_mtx); - - destroy_dev(nfs4device); -} - -/* device interface functions */ -static int -nfs4dev_open(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - if (dev != nfs4device) - return ENODEV; - - mtx_lock(&nfs4dev_daemon_mtx); - if (nfs4dev_nopen) { - mtx_unlock(&nfs4dev_daemon_mtx); - return EBUSY; - } - - nfs4dev_nopen++; - nfs4dev_reader = curthread; - mtx_unlock(&nfs4dev_daemon_mtx); - - return (0); -} - -static int -nfs4dev_close(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - struct nfs4dev_upcall * u; - - if (dev != nfs4device) - return ENODEV; - - mtx_lock(&nfs4dev_daemon_mtx); - if (!nfs4dev_nopen) { - mtx_unlock(&nfs4dev_daemon_mtx); - return ENOENT; - } - - nfs4dev_nopen--; - nfs4dev_reader = NULL; - mtx_unlock(&nfs4dev_daemon_mtx); - - mtx_lock(&nfs4dev_waitq_mtx); - - while (!TAILQ_EMPTY(&nfs4dev_waitq)) { - u = TAILQ_FIRST(&nfs4dev_waitq); - TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry); - u->up_error = EINTR; - wakeup(u); - } - - mtx_unlock(&nfs4dev_waitq_mtx); - - return 0; -} - -static int -nfs4dev_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int fflag, struct thread *td) -{ - int error; - - if (dev != nfs4device) - return ENODEV; - - if (data == NULL) - return EFAULT; - - if (nfs4dev_reader != curthread) - nfs4dev_reader = curthread; - - switch (cmd) { - case NFS4DEVIOCGET: - error = nfs4dev_request(data); - break; - case NFS4DEVIOCPUT: - error = nfs4dev_reply(data); - break; - default: - NFS4DEV_DEBUG("nfs4dev_ioctl: unkown ioctl cmd %d\n", (int)cmd); - error = EOPNOTSUPP; - break; - } - - return error; -} - -static int -nfs4dev_poll(struct cdev *dev, int events, struct thread *td) -{ - int revents; - - if (dev != nfs4device) - return EINVAL; - - mtx_lock(&nfs4dev_daemon_mtx); - if (nfs4dev_nopen == 0) { - mtx_unlock(&nfs4dev_daemon_mtx); - return 0; - } - mtx_unlock(&nfs4dev_daemon_mtx); - - revents = 0; - - /* check readable data */ - mtx_lock(&nfs4dev_newq_mtx); - if (!TAILQ_EMPTY(&nfs4dev_newq)) - revents |= POLLIN; - mtx_unlock(&nfs4dev_newq_mtx); - - mtx_lock(&nfs4dev_waitq_mtx); - if (!TAILQ_EMPTY(&nfs4dev_waitq)) - revents |= POLLOUT; - mtx_unlock(&nfs4dev_waitq_mtx); - - return revents; -} - -int -nfs4dev_call(uint32_t type, caddr_t req_data, size_t req_len, caddr_t rep_data, size_t * rep_lenp) -{ - struct nfs4dev_upcall * u; - int error = 0; - unsigned int xtmp; - - mtx_lock(&nfs4dev_daemon_mtx); - if (nfs4dev_nopen == 0) { - mtx_unlock(&nfs4dev_daemon_mtx); - return EINVAL; - } - mtx_unlock(&nfs4dev_daemon_mtx); - - if (type > NFS4DEV_MAX_TYPE) - return EOPNOTSUPP; - - NFS4DEV_DEBUG("upcall %d/%d:%d\n", type, req_len, *rep_lenp); - - nfs4dev_upcall_get(u); - - u->up_error = 0; - u->up_rep = rep_data; - u->up_replen = rep_lenp; - u->up_copied = 0; - - u->up_reqmsg.msg_vers = NFS4DEV_VERSION; - /* XXX efficient copying */ - bcopy(req_data, u->up_reqmsg.msg_data, req_len); - u->up_reqmsg.msg_len = req_len; - - mtx_lock(&nfs4dev_newq_mtx); - - /* get new XID */ - while ((xtmp = arc4random() % 256) == 0); - nfs4dev_xid += xtmp; - u->up_reqmsg.msg_xid = nfs4dev_xid; - - TAILQ_INSERT_TAIL(&nfs4dev_newq, u, up_entry); - mtx_unlock(&nfs4dev_newq_mtx); - - - NFS4DEV_DEBUG("nfs4dev op: %d xid: %x sleeping\n", u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid); - - do { - tsleep(u, PLOCK, "nfs4dev", 0); - } while (u->up_copied == 0 && u->up_error == 0); - - /* upcall now removed from the queue */ - - NFS4DEV_DEBUG("nfs4dev prog: %d xid: %x continues...\n", - u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid); - - if (u->up_error) { - error = u->up_error; - NFS4DEV_DEBUG("nfs4dev prog: %d xid: %x error: %d\n", - u->up_reqmsg.msg_type, u->up_reqmsg.msg_xid, u->up_error); - goto out; - } - -out: - nfs4dev_upcall_put(u); - return error; -} - -void -nfs4dev_purge(void) -{ - struct nfs4dev_upcall * u; - - mtx_lock(&nfs4dev_newq_mtx); - while (!TAILQ_EMPTY(&nfs4dev_newq)) { - u = TAILQ_FIRST(&nfs4dev_newq); - TAILQ_REMOVE(&nfs4dev_newq, u, up_entry); - u->up_error = EINTR; - wakeup(u); - } - mtx_unlock(&nfs4dev_newq_mtx); - - mtx_lock(&nfs4dev_waitq_mtx); - while (!TAILQ_EMPTY(&nfs4dev_waitq)) { - u = TAILQ_FIRST(&nfs4dev_waitq); - TAILQ_REMOVE(&nfs4dev_waitq, u, up_entry); - u->up_error = EINTR; - wakeup(u); - } - mtx_unlock(&nfs4dev_waitq_mtx); -} diff --git a/sys/nfs4client/nfs4_dev.h b/sys/nfs4client/nfs4_dev.h deleted file mode 100644 index be14ce2cdb33..000000000000 --- a/sys/nfs4client/nfs4_dev.h +++ /dev/null @@ -1,65 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_dev.h,v 1.3 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef _NFS3_DEV_H_ -#define _NFS4_DEV_H_ - -#include - - -/* type of upcall */ -#define NFS4DEV_TYPE_IDMAP 0 -#define NFS4DEV_TYPE_GSS 1 -#define NFS4DEV_MAX_TYPE 1 - -struct nfs4dev_msg { - unsigned int msg_vers; - unsigned int msg_type; - unsigned int msg_xid; - unsigned int msg_error; - - #define NFS4DEV_MSG_MAX_DATALEN 350 - size_t msg_len; - uint8_t msg_data[NFS4DEV_MSG_MAX_DATALEN]; -}; - -#define NFS4DEV_VERSION (0x3 << 16 | (int) sizeof(struct nfs4dev_msg)) - -/* ioctl commands */ -#define NFS4DEVIOCGET _IOR('A', 0x200, struct nfs4dev_msg) -#define NFS4DEVIOCPUT _IOW('A', 0x201, struct nfs4dev_msg) - -#ifdef _KERNEL -int nfs4dev_call(uint32_t type, caddr_t req_data, size_t req_len, caddr_t rep_datap, size_t * rep_lenp); - -void nfs4dev_purge(void); - -void nfs4dev_init(void); -void nfs4dev_uninit(void); -#endif - -#endif /* _NFS4_DEV_H_ */ diff --git a/sys/nfs4client/nfs4_idmap.c b/sys/nfs4client/nfs4_idmap.c deleted file mode 100644 index 5a02b47cebc9..000000000000 --- a/sys/nfs4client/nfs4_idmap.c +++ /dev/null @@ -1,509 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_idmap.c,v 1.4 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/* TODO: - * o validate ascii - * */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - - -#ifdef IDMAPVERBOSE -#define IDMAP_DEBUG(...) printf(__VA_ARGS__); -#else -#define IDMAP_DEBUG(...) -#endif - -#define IDMAP_HASH_SIZE 37 - -MALLOC_DEFINE(M_IDMAP, "idmap", "idmap"); - -#define idmap_entry_get(ID) (ID) = malloc(sizeof(struct idmap_entry), M_IDMAP, M_WAITOK | M_ZERO) -#define idmap_entry_put(ID) free((ID), M_IDMAP) - - - -struct idmap_entry { - struct idmap_msg id_info; - - TAILQ_ENTRY(idmap_entry) id_entry_id; - TAILQ_ENTRY(idmap_entry) id_entry_name; -}; - -struct idmap_hash { - TAILQ_HEAD(, idmap_entry) hash_name[IDMAP_HASH_SIZE]; - TAILQ_HEAD(, idmap_entry) hash_id[IDMAP_HASH_SIZE]; - - struct lock hash_lock; -}; - -#define IDMAP_RLOCK(lock) lockmgr(lock, LK_SHARED, NULL) -#define IDMAP_WLOCK(lock) lockmgr(lock, LK_EXCLUSIVE, NULL) -#define IDMAP_UNLOCK(lock) lockmgr(lock, LK_RELEASE, NULL) - - -static struct idmap_hash idmap_uid_hash; -static struct idmap_hash idmap_gid_hash; - -static struct idmap_entry * idmap_name_lookup(uint32_t, char *); -static struct idmap_entry * idmap_id_lookup(uint32_t, ident_t); -static int idmap_upcall_name(uint32_t, char *, struct idmap_entry **); -static int idmap_upcall_id(uint32_t , ident_t, struct idmap_entry ** ); -static int idmap_add(struct idmap_entry *); - -static int -idmap_upcall_name(uint32_t type, char * name, struct idmap_entry ** found) -{ - int error; - struct idmap_entry * e; - size_t len, siz; - - if (type > IDMAP_MAX_TYPE || type == 0) { - IDMAP_DEBUG("bad type %d\n", type); - return EINVAL; /* XXX */ - } - - if (name == NULL || (len = strlen(name)) == 0 || len > IDMAP_MAXNAMELEN) { - IDMAP_DEBUG("idmap_upcall_name: bad name\n"); - return EFAULT; /* XXX */ - } - - e = malloc(sizeof(struct idmap_entry), M_IDMAP, - M_WAITOK | M_ZERO); - - e->id_info.id_type = type; - bcopy(name, e->id_info.id_name, len); - e->id_info.id_namelen = len; - - - siz = sizeof(struct idmap_msg); - error = nfs4dev_call(NFS4DEV_TYPE_IDMAP, (caddr_t)&e->id_info, siz, - (caddr_t)&e->id_info, &siz); - - if (error) { - IDMAP_DEBUG("error %d in nfs4dev_upcall()\n", error); - *found = NULL; - return error; - } - - if (siz != sizeof(struct idmap_msg)) { - IDMAP_DEBUG("bad size of returned message\n"); - *found = NULL; - return EFAULT; - } - - *found = e; - return 0; -} - -static int -idmap_upcall_id(uint32_t type, ident_t id, struct idmap_entry ** found) -{ - int error; - struct idmap_entry * e; - size_t siz; - - if (type > IDMAP_MAX_TYPE) - panic("bad type"); /* XXX */ - - e = malloc(sizeof(struct idmap_entry), M_IDMAP, - M_WAITOK | M_ZERO); - - e->id_info.id_type = type; - e->id_info.id_namelen = 0; /* should already */ - e->id_info.id_id = id; - - siz = sizeof(struct idmap_msg); - error = nfs4dev_call(NFS4DEV_TYPE_IDMAP, (caddr_t)&e->id_info, siz, - (caddr_t)&e->id_info, &siz); - - if (error) { - IDMAP_DEBUG("error %d in nfs4dev_upcall()\n", error); - *found = NULL; - return error; - } - - if (siz != sizeof(struct idmap_msg)) { - IDMAP_DEBUG("bad size of returned message\n"); - *found = NULL; - return EFAULT; - } - - *found = e; - return 0; -} - -static void -idmap_hashf(struct idmap_entry *e, uint32_t * hval_id, uint32_t * hval_name) -{ - switch (e->id_info.id_type) { - case IDMAP_TYPE_UID: - *hval_id = e->id_info.id_id.uid % IDMAP_HASH_SIZE; - break; - case IDMAP_TYPE_GID: - *hval_id = e->id_info.id_id.gid % IDMAP_HASH_SIZE; - break; - default: - /* XXX yikes! */ - panic("hashf: bad type!"); - break; - } - - if (e->id_info.id_namelen == 0) - /* XXX */ panic("hashf: bad name"); - - *hval_name = fnv_32_str(e->id_info.id_name, FNV1_32_INIT) % IDMAP_HASH_SIZE; -} - -static int -idmap_add(struct idmap_entry * e) -{ - struct idmap_hash * hash; - uint32_t hval_id, hval_name; - - if (e->id_info.id_namelen == 0) { - printf("idmap_add: name of len 0\n"); - return EINVAL; - } - - switch (e->id_info.id_type) { - case IDMAP_TYPE_UID: - hash = &idmap_uid_hash; - break; - case IDMAP_TYPE_GID: - hash = &idmap_gid_hash; - break; - default: - /* XXX yikes */ - panic("idmap add: bad type!"); - break; - } - - idmap_hashf(e, &hval_id, &hval_name); - - IDMAP_WLOCK(&hash->hash_lock); - - TAILQ_INSERT_TAIL(&hash->hash_id[hval_id], e, id_entry_id); - TAILQ_INSERT_TAIL(&hash->hash_name[hval_name], e, id_entry_name); - - IDMAP_UNLOCK(&hash->hash_lock); - - return 0; -} - -static struct idmap_entry * -idmap_id_lookup(uint32_t type, ident_t id) -{ - struct idmap_hash * hash; - uint32_t hval; - struct idmap_entry * e; - - switch (type) { - case IDMAP_TYPE_UID: - hash = &idmap_uid_hash; - hval = id.uid % IDMAP_HASH_SIZE; - break; - case IDMAP_TYPE_GID: - hash = &idmap_gid_hash; - hval = id.gid % IDMAP_HASH_SIZE; - break; - default: - /* XXX yikes */ - panic("lookup: bad type!"); - break; - } - - - IDMAP_RLOCK(&hash->hash_lock); - - TAILQ_FOREACH(e, &hash->hash_id[hval], id_entry_name) { - if ((type == IDMAP_TYPE_UID && e->id_info.id_id.uid == id.uid)|| - (type == IDMAP_TYPE_GID && e->id_info.id_id.gid == id.gid)) { - IDMAP_UNLOCK(&hash->hash_lock); - return e; - } - } - - IDMAP_UNLOCK(&hash->hash_lock); - return NULL; -} - -static struct idmap_entry * -idmap_name_lookup(uint32_t type, char * name) -{ - struct idmap_hash * hash; - uint32_t hval; - struct idmap_entry * e; - size_t len; - - switch (type) { - case IDMAP_TYPE_UID: - hash = &idmap_uid_hash; - break; - case IDMAP_TYPE_GID: - hash = &idmap_gid_hash; - break; - default: - /* XXX yikes */ - panic("lookup: bad type!"); - break; - } - - len = strlen(name); - - if (len == 0 || len > IDMAP_MAXNAMELEN) { - IDMAP_DEBUG("bad name length %d\n", len); - return NULL; - } - - hval = fnv_32_str(name, FNV1_32_INIT) % IDMAP_HASH_SIZE; - - IDMAP_RLOCK(&hash->hash_lock); - - TAILQ_FOREACH(e, &hash->hash_name[hval], id_entry_name) { - if ((strlen(e->id_info.id_name) == strlen(name)) && strncmp(e->id_info.id_name, name, strlen(name)) == 0) { - IDMAP_UNLOCK(&hash->hash_lock); - return e; - } - } - - IDMAP_UNLOCK(&hash->hash_lock); - return NULL; -} - -void -idmap_init(void) -{ - unsigned int i; - - for (i=0; iid_info.id_name; - *len = e->id_info.id_namelen; - return 0; -} - -int -idmap_gid_to_name(gid_t gid, char ** name, size_t * len) -{ - struct idmap_entry * e; - int error = 0; - ident_t id; - - id.gid = gid; - - - if ((e = idmap_id_lookup(IDMAP_TYPE_GID, id)) == NULL) { - if ((error = idmap_upcall_id(IDMAP_TYPE_GID, id, &e))) { - IDMAP_DEBUG("error in upcall\n"); - return error; - } - - if (e == NULL) { - IDMAP_DEBUG("no error from upcall, but no data returned\n"); - return EFAULT; - } - - if (idmap_add(e) != 0) { - IDMAP_DEBUG("idmap_add failed\n"); - free(e, M_IDMAP); - } - } - - *name = e->id_info.id_name; - *len = e->id_info.id_namelen; - return 0; -} - -int -idmap_name_to_uid(char * name, size_t len, uid_t * id) -{ - struct idmap_entry * e; - int error = 0; - char * namestr; - - if (name == NULL ) - return EFAULT; - - if (len == 0 || len > IDMAP_MAXNAMELEN) { - IDMAP_DEBUG("idmap_name_to_uid: bad len\n"); - return EINVAL; - } - - /* XXX hack */ - namestr = malloc(len + 1, M_TEMP, M_WAITOK); - bcopy(name, namestr, len); - namestr[len] = '\0'; - - - if ((e = idmap_name_lookup(IDMAP_TYPE_UID, namestr)) == NULL) { - if ((error = idmap_upcall_name(IDMAP_TYPE_UID, namestr, &e))) { - free(namestr, M_TEMP); - return error; - } - - if (e == NULL) { - IDMAP_DEBUG("no error from upcall, but no data returned\n"); - free(namestr, M_TEMP); - return EFAULT; - } - - if (idmap_add(e) != 0) { - IDMAP_DEBUG("idmap_add failed\n"); - free(e, M_IDMAP); - } - } - - *id = e->id_info.id_id.uid; - free(namestr, M_TEMP); - return 0; -} - -int -idmap_name_to_gid(char * name, size_t len, gid_t * id) -{ - struct idmap_entry * e; - int error = 0; - - char * namestr; - - if (name == NULL ) - return EFAULT; - - if (len == 0 || len > IDMAP_MAXNAMELEN) { - IDMAP_DEBUG("idmap_name_to_uid: bad len\n"); - return EINVAL; - } - - /* XXX hack */ - namestr = malloc(len + 1, M_TEMP, M_WAITOK); - bcopy(name, namestr, len); - namestr[len] = '\0'; - - - if ((e = idmap_name_lookup(IDMAP_TYPE_GID, namestr)) == NULL) { - if ((error = idmap_upcall_name(IDMAP_TYPE_GID, namestr, &e)) != 0) { - IDMAP_DEBUG("error in upcall\n"); - free(namestr, M_TEMP); - return error; - } - - if (e == NULL) { - IDMAP_DEBUG("no error from upcall, but no data returned\n"); - free(namestr, M_TEMP); - return EFAULT; - } - - if (idmap_add(e) != 0) { - IDMAP_DEBUG("idmap_add failed\n"); - free(e, M_IDMAP); - } - } - - *id = e->id_info.id_id.gid; - free(namestr, M_TEMP); - return 0; -} diff --git a/sys/nfs4client/nfs4_idmap.h b/sys/nfs4client/nfs4_idmap.h deleted file mode 100644 index 0b09cf43444d..000000000000 --- a/sys/nfs4client/nfs4_idmap.h +++ /dev/null @@ -1,64 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_idmap.h,v 1.2 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef __NFS4_IDMAP_H__ -#define __NFS4_IDMAP_H__ - -#define IDMAP_TYPE_GID 1 -#define IDMAP_TYPE_UID 2 -#define IDMAP_MAX_TYPE 2 - -typedef union { - uid_t uid; - gid_t gid; -} ident_t; - -#define IDMAP_MAXNAMELEN 249 -struct idmap_msg { - uint32_t id_type; - ident_t id_id; - size_t id_namelen; - char id_name[IDMAP_MAXNAMELEN + 1]; -}; - - -#ifdef _KERNEL -MALLOC_DECLARE(M_IDMAP); - -void idmap_init(void); -void idmap_uninit(void); - -int idmap_gid_to_name(gid_t id, char ** name, size_t * len); -int idmap_uid_to_name(uid_t id, char ** name, size_t * len); - -int idmap_name_to_gid(char *, size_t len, gid_t *); -int idmap_name_to_uid(char *, size_t len, uid_t *); - -#endif /* _KERNEL */ - - -#endif /* __NFS4_GSS_H__ */ diff --git a/sys/nfs4client/nfs4_socket.c b/sys/nfs4client/nfs4_socket.c deleted file mode 100644 index c1fe15412962..000000000000 --- a/sys/nfs4client/nfs4_socket.c +++ /dev/null @@ -1,348 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs_socket.c,v 1.12 2003/11/05 14:59:01 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/*- - * Copyright (c) 1989, 1991, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Socket operations for use by nfs - */ - -#include "opt_inet6.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#ifdef NFS4_USE_RPCCLNT -#include -#include -#endif - -#ifdef NFS4_USE_RPCCLNT -static struct rpc_program nfs_program = { - NFS_PROG, NFS_VER4, "NFSv4" -}; -#endif - - -static struct { - short nfserr; - short syserr; -} nfs_errtbl[] = { - { NFS_OK, 0 }, - { NFSERR_PERM, EPERM }, - { NFSERR_NOENT, ENOENT }, - { NFSERR_IO, EIO }, - { NFSERR_NXIO, ENXIO }, - { NFSERR_ACCES, EACCES }, - { NFSERR_EXIST, EEXIST }, - { NFSERR_XDEV, EXDEV }, - { NFSERR_MLINK, EMLINK }, - { NFSERR_NODEV, ENODEV }, - { NFSERR_NOTDIR, ENOTDIR }, - { NFSERR_ISDIR, EISDIR }, - { NFSERR_INVAL, EINVAL }, - { NFSERR_FBIG, EFBIG }, - { NFSERR_NOSPC, ENOSPC }, - { NFSERR_ROFS, EROFS }, - { NFSERR_MLINK, EMLINK }, - { NFSERR_NAMETOL, ENAMETOOLONG }, - { NFSERR_NOTEMPTY, ENOTEMPTY }, - { NFSERR_NOTSUPP, EOPNOTSUPP }, -#ifdef EDQUOT - { NFSERR_DQUOT, EDQUOT }, -#endif - { NFSERR_STALE, ESTALE }, - { NFSERR_DENIED, EAGAIN }, - { NFSERR_SYMLINK, ELOOP }, - { NFSERR_BADXDR, EBADRPC }, - { NFSERR_WRONGSEC, EPERM }, - { -1, EIO } -}; - -static int -nfs4_nfserr_to_syserr(int nfserr) -{ - int i, syserr; - - /* XXX : not the optimal algorithm, but will do for now! */ - for (i = 0; nfs_errtbl[i].nfserr != -1; i++) { - if (nfs_errtbl[i].nfserr == nfserr) - break; - } -#ifdef NFS4_MAP_UNKNOWN_ERR - syserr = nfs_errtbl[i].syserr; -#else - if (nfs_errtbl[i].nfserr != -1) - syserr = nfs_errtbl[i].syserr; - else - syserr = nfserr; -#endif - return syserr; -} - -int -nfs4_connect(struct nfsmount *nmp) -{ - struct rpcclnt * rpc = &nmp->nm_rpcclnt; - struct rpc_auth * auth; - int flag = 0; - int error; - - /* XXX hack! */ -#ifdef __OpenBSD__ - struct proc * td = curproc; -#else - struct thread * td = curthread; -#endif - - auth = malloc(sizeof(struct rpc_auth), M_TEMP, M_WAITOK); - auth->auth_type = RPCAUTH_UNIX; - - /* translate nfs flags -> rpcclnt flags */ - if (nmp->nm_flag & NFSMNT_SOFT) - flag |= RPCCLNT_SOFT; - - if (nmp->nm_flag & NFSMNT_INT) - flag |= RPCCLNT_INT; - - if (nmp->nm_flag & NFSMNT_NOCONN) - flag |= RPCCLNT_NOCONN; - - if (nmp->nm_flag & NFSMNT_DUMBTIMR) - flag |= RPCCLNT_DUMBTIMR; - - /* rpc->rc_servername = nmp->nm_mountp->mnt_stat.f_mntfromname; */ - - error = rpcclnt_setup(rpc, &nfs_program, nmp->nm_nam, nmp->nm_sotype, - nmp->nm_soproto, auth, - /* XXX: check nmp->nm_flag to make sure these are set */ - (nmp->nm_rsize > nmp->nm_readdirsize) ? nmp->nm_rsize : nmp->nm_readdirsize, - nmp->nm_wsize, flag); - - /* set deadthresh, timeo, retry */ - rpc->rc_deadthresh = nmp->nm_deadthresh; - rpc->rc_timeo = nmp->nm_timeo; - rpc->rc_retry = nmp->nm_retry; - - - if (error) - return error; - - return rpcclnt_connect(rpc, td); -} - -/* - * NFS disconnect. Clean up and unlink. - */ -void -nfs4_disconnect(struct nfsmount *nmp) -{ - rpcclnt_disconnect(&nmp->nm_rpcclnt); -} - -void -nfs4_safedisconnect(struct nfsmount *nmp) -{ - rpcclnt_safedisconnect(&nmp->nm_rpcclnt); -} - -/* - * nfs_request - goes something like this - * - fill in request struct - * - links it into list - * - calls nfs_send() for first transmit - * - calls nfs_receive() to get reply - * - break down rpc header and return with nfs reply pointed to - * by mrep or error - * nb: always frees up mreq mbuf list - */ -/* XXX overloaded before */ -#define NQ_TRYLATERDEL 15 /* Initial try later delay (sec) */ - -int -nfs4_request(struct vnode *vp, struct mbuf *mrest, int procnum, - struct thread *td, struct ucred *cred, struct mbuf **mrp, - struct mbuf **mdp, caddr_t *dposp) -{ - int error; - - error = nfs4_request_mnt(VFSTONFS(vp->v_mount), mrest, procnum, - td, cred, mrp, mdp, dposp); - - /* - ** If the File Handle was stale, invalidate the - ** lookup cache, just in case. - **/ - if (error == ESTALE) - nfs_purgecache(vp); - - return (error); -} - - -int -nfs4_request_mnt(struct nfsmount *nmp, struct mbuf *mrest, int procnum, - struct thread *td, struct ucred *cred, struct mbuf **mrp, - struct mbuf **mdp, caddr_t *dposp) -{ - int error; - u_int32_t *tl; - struct rpcclnt * clnt = &nmp->nm_rpcclnt; - struct mbuf *md, *mrep; - caddr_t dpos; - struct rpc_reply reply; - - if ((error = rpcclnt_request(clnt, mrest, procnum, td, cred, - &reply)) != 0) { - goto out; - } - - /* XXX: don't free mrest if an error occured, to allow caller to retry*/ - m_freem(mrest); - mrep = reply.mrep; - md = reply.result_md; - dpos = reply.result_dpos; - - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - if (*tl != 0) { - error = fxdr_unsigned(int, *tl); -#if 0 - if ((nmp->nm_flag & NFSMNT_NFSV3) && - error == NFSERR_TRYLATER) { - m_freem(mrep); - error = 0; - waituntil = time_second + trylater_delay; - while (time_second < waituntil) - (void) tsleep(&fake_wchan, PSOCK, "nqnfstry", hz); - trylater_delay *= nfs_backoff[trylater_cnt]; - if (trylater_cnt < NFS_NBACKOFF - 1) - trylater_cnt++; - goto tryagain; - } -#endif - goto out; - } - - *mrp = mrep; - *mdp = md; - *dposp = dpos; - return (0); -nfsmout: -out: - m_freem(reply.mrep); - *mrp = NULL; - *mdp = NULL; - return (nfs4_nfserr_to_syserr(error)); -} - - -/* - * Mark all of an nfs mount's outstanding requests with R_SOFTTERM and - * wait for all requests to complete. This is used by forced unmounts - * to terminate any outstanding RPCs. - */ -int -nfs4_nmcancelreqs(nmp) - struct nfsmount *nmp; -{ - return rpcclnt_cancelreqs(&nmp->nm_rpcclnt); -} - -/* - * Test for a termination condition pending on the process. - * This is used for NFSMNT_INT mounts. - */ -int -nfs4_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td) -{ - if (rep != NULL) { - printf("nfs_sigintr: attempting to use nfsreq != NULL\n"); - return EINTR; - } - return rpcclnt_sigintr(&nmp->nm_rpcclnt, NULL, td); -} diff --git a/sys/nfs4client/nfs4_subs.c b/sys/nfs4client/nfs4_subs.c deleted file mode 100644 index 21c89c9e1a60..000000000000 --- a/sys/nfs4client/nfs4_subs.c +++ /dev/null @@ -1,1367 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_subs.c,v 1.52 2003/11/05 14:58:59 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#define NFSM_DISSECT(s) do { \ - tl = nfsm_dissect_xx((s), md, dpos); \ - if (tl == NULL) { \ - printf("NFSM_DISSECT error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \ - return (EBADRPC); \ - } \ -} while (0) - -#define NFSM_ADV(s) do { \ - t1 = nfsm_adv_xx((s), md, dpos); \ - if (t1 != 0) { \ - printf("NFSM_ADV error; allocation (%s/%d) (%s:%d)\n", #s, s, __FILE__, __LINE__); \ - return (EBADRPC); \ - } \ -} while (0) - -#define NFSM_MTOTIME(t) do { \ - NFSM_DISSECT(3 * NFSX_UNSIGNED); \ - (t).tv_sec = fxdr_hyper(tl); \ - tl += 2; \ - (t).tv_nsec = fxdr_unsigned(long, *tl++); \ -} while (0) - -static uint32_t __fsinfo_bm[2], __fsattr_bm[2], __getattr_bm[2], __readdir_bm[2]; - -nfsv4bitmap nfsv4_fsinfobm = { 2, __fsinfo_bm }; -nfsv4bitmap nfsv4_fsattrbm = { 2, __fsattr_bm }; -nfsv4bitmap nfsv4_getattrbm = { 2, __getattr_bm }; -nfsv4bitmap nfsv4_readdirbm = { 2, __readdir_bm }; - -/* Helper routines */ -int nfsm_v4build_attrs_xx(struct vattr *, struct mbuf **, caddr_t *); -int nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *, struct mbuf **, caddr_t *); - -void -nfsm_v4init(void) -{ - - /* Set up bitmasks */ - FA4_SET(FA4_FSID, __fsinfo_bm); - FA4_SET(FA4_MAXREAD, __fsinfo_bm); - FA4_SET(FA4_MAXWRITE, __fsinfo_bm); - FA4_SET(FA4_LEASE_TIME, __fsinfo_bm); - - FA4_SET(FA4_FSID, __fsattr_bm); - FA4_SET(FA4_FILES_FREE, __fsattr_bm); - FA4_SET(FA4_FILES_TOTAL, __fsattr_bm); - FA4_SET(FA4_SPACE_AVAIL, __fsattr_bm); - FA4_SET(FA4_SPACE_FREE, __fsattr_bm); - FA4_SET(FA4_SPACE_TOTAL, __fsattr_bm); - - FA4_SET(FA4_TYPE, __getattr_bm); - FA4_SET(FA4_FSID, __getattr_bm); - FA4_SET(FA4_SIZE, __getattr_bm); - FA4_SET(FA4_MODE, __getattr_bm); - FA4_SET(FA4_RAWDEV, __getattr_bm); - FA4_SET(FA4_NUMLINKS, __getattr_bm); - FA4_SET(FA4_OWNER, __getattr_bm); - FA4_SET(FA4_OWNER_GROUP, __getattr_bm); - FA4_SET(FA4_FILEID, __getattr_bm); - FA4_SET(FA4_TIME_ACCESS, __getattr_bm); - FA4_SET(FA4_TIME_CREATE, __getattr_bm); - FA4_SET(FA4_TIME_METADATA, __getattr_bm); - FA4_SET(FA4_TIME_MODIFY, __getattr_bm); - - FA4_SET(FA4_TYPE, __readdir_bm); - FA4_SET(FA4_FSID, __readdir_bm); - FA4_SET(FA4_FILEID, __readdir_bm); - FA4_SET(FA4_RDATTR_ERROR, __readdir_bm); -} - -/* - * Util - */ - -uint32_t -nfs_v4fileid4_to_fileid(uint64_t fid) -{ - return ((uint32_t)((fid >> 32) | fid)); -} - -void -nfs_v4initcompound(struct nfs4_compound *cp) -{ - bzero(cp, sizeof(*cp)); -} - -/* - * Build/dissect XDR buffer with a format string. - * - * u - unsigned - * h - hyper - * s - stringlength, string - * k - skip length (bytes) - * a - arraylength, componentlenght, array - * o - opaque fix length - * O - opaque var length in bytes - */ - -void -nfsm_buildf_xx(struct mbuf **mb, caddr_t *bpos, char *fmt, ...) -{ - uint32_t *tl, t1, len, uval; - uint64_t hval; - va_list args; - char *p, *which; - - va_start(args, fmt); - for (which = fmt; *which != '\0'; which++) - switch (*which) { - case 'u': /* Unsigned */ - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - uval = va_arg(args, uint32_t); - *tl++ = txdr_unsigned(uval); - break; - case 'h': /* Hyper */ - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - hval = va_arg(args, uint64_t); - txdr_hyper(hval, tl); - break; - case 'o': /* Fixed-length opaque */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - tl = nfsm_build_xx(nfsm_rndup(len), mb, bpos); - bcopy(p, tl, len); - break; - case 'O': /* Variable-length opaque */ - case 's': /* String */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - t1 = nfsm_strtom_xx(p, len, len, mb, bpos); - break; - case 'k': /* Skip */ - len = va_arg(args, uint32_t); - nfsm_build_xx(nfsm_rndup(len), mb, bpos); - break; - default: - panic("Invalid buildf string %s[%c]", fmt, *which); - break; - } - va_end(args); -} - -int -nfsm_dissectf_xx(struct mbuf **md, caddr_t *dpos, char *fmt, ...) -{ - uint32_t *tl, t1, len, *uval; - uint64_t *hval; - va_list args; - char *p, *which; - - va_start(args, fmt); - for (which = fmt; *which != '\0'; which++) - switch (*which) { - case 'u': /* Unsigned */ - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - uval = va_arg(args, uint32_t *); - *uval = fxdr_unsigned(uint32_t, *tl++); - break; - case 'h': /* Hyper */ - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - hval = va_arg(args, uint64_t *); - *hval = fxdr_hyper(tl); - break; - case 'o': /* Fixed-length opaque */ - len = va_arg(args, uint32_t); - p = va_arg(args, void *); - tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos); - if (tl == NULL) - return (EBADRPC); - bcopy(tl, p, len); - break; - case 'O': /* Variable-length opaque */ - case 's': /* String */ - len = va_arg(args, uint32_t); - p = va_arg(args, char *); - tl = nfsm_dissect_xx(nfsm_rndup(len), md, dpos); - if (tl == NULL) - return (EBADRPC); - bcopy(tl, p, len); - break; - case 'k': /* Skip bytes */ - len = va_arg(args, uint32_t); - t1 = nfsm_adv_xx(nfsm_rndup(len), md, dpos); - break; - default: - panic("Invalid dissectf string %s[%c]", fmt, *which); - break; - } - va_end(args); - - return (0); -} - -/* - * XXX - There are a few problems with the way the postops are places - * in the code. Ideally, they should be taken care of immediately, as - * to avoid uneceesary waits for mutexes, but then we would be - * introducing even more complexity by having to handle two separate - * cases. Also, since they are placed at the end of the vnops', there - * may be operations which sleep in between, further extending this - * wait. It is conceivable that there is a deadlock condition there, - * too. - * - * Also, for vnops that do multiple operations, it's inconvenient - * since on error, individual decoding will got nfsmout. - */ - -int -nfs_v4postop(struct nfs4_compound *cp, int status) -{ - struct nfs4_fctx *fcp = cp->fcp; - - /* - * XXX does the previous result need to be stores with the - * lockowner? ack, spec is unclear .. - */ - - if (fcp != NULL) - if (cp->seqidused < cp->rep_nops || - (cp->seqidused + 1 == cp->rep_nops && - NFS4_SEQIDMUTATINGERROR(status))) - fcp->lop->lo_seqid++; - - return (status); -} - -int -nfs_v4handlestatus(int status, struct nfs4_compound *cp) -{ - return (status); -} - -/* - * Initial setup of compound. - */ - -int -nfsm_v4build_compound_xx(struct nfs4_compound *cp, char *tag, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1, *tl, siz; - - /* Tag */ - siz = strlen(tag); - t1 = nfsm_rndup(siz) + NFSX_UNSIGNED; - if (t1 <= M_TRAILINGSPACE(*mb)) { - tl = nfsm_build_xx(t1, mb, bpos); - *tl++ = txdr_unsigned(siz); - *(tl + ((t1 >> 2) - 2)) = 0; - bcopy(tag, tl, siz); - } else { - t1 = nfsm_strtmbuf(mb, bpos, (const char *)tag, siz); - if (t1 != 0) - return (t1); - } - - /* Minor version and argarray*/ - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - *tl++ = txdr_unsigned(NFS4_MINOR_VERSION); - /* Save for backfill */ - cp->req_nopsp = tl; - *tl = txdr_unsigned(0); - - cp->curvp = NULL; - cp->savevp = NULL; - - return (0); -} - -/* - * XXX - * - backfill for stateid, and such - */ -int -nfsm_v4build_finalize_xx(struct nfs4_compound *cp, struct mbuf **mb, caddr_t *bpos) -{ - *cp->req_nopsp = txdr_unsigned(cp->req_nops); - - return (0); -} - -int -nfsm_v4build_putfh_xx(struct nfs4_compound *cp, struct vnode *vp, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1; - - /* Op */ - nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_PUTFH); - - /* FH */ - t1 = nfsm_fhtom_xx(vp, 1, mb, bpos); - if (t1 != 0) - return (t1); - - cp->req_nops++; - cp->curvp = vp; - - return (0); -} - -int -nfsm_v4build_putfh_nv_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uuo", - NFSV4OP_PUTFH, - gfh->fh_len, - gfh->fh_len, - &gfh->fh_val); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_simple_xx(struct nfs4_compound *cp, uint32_t op, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "u", op); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga, - struct mbuf **mb, caddr_t *bpos) -{ - int i; - - /* Op + bitmap length + bitmap */ - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_GETATTR, ga->bm->bmlen); - for (i = 0; i < ga->bm->bmlen; i++) - nfsm_buildf_xx(mb, bpos, "u", ga->bm->bmval[i]); - - ga->vp = cp->curvp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setattr_xx(struct nfs4_compound *cp, struct vattr *vap, - struct nfs4_fctx *fcp, struct mbuf **mb, caddr_t *bpos) -{ - int error; - static char zero_stateid[NFSX_V4STATEID]; - - nfsm_buildf_xx(mb, bpos, "uo", - NFSV4OP_SETATTR, - NFSX_V4STATEID, fcp ? fcp->stateid : zero_stateid); - error = nfsm_v4build_attrs_xx(vap, mb, bpos); - if (error == 0) - cp->req_nops++; - - return (error); -} - -int -nfsm_v4build_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "u", NFSV4OP_GETFH); - - gfh->vp = cp->curvp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_lookup_xx(struct nfs4_compound *cp, struct nfs4_oparg_lookup *l, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LOOKUP, l->namelen, l->name); - - cp->curvp = l->vp; - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setclientid_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos) -{ - struct timeval tv; - - microtime(&tv); - - nfsm_buildf_xx(mb, bpos, "uuusussu", - NFSV4OP_SETCLIENTID, - tv.tv_sec, tv.tv_usec, - sci->namelen, sci->name, - sci->cb_prog, - sci->cb_netidlen, sci->cb_netid, - sci->cb_univaddrlen, sci->cb_univaddr, - 0xCA11BACC); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_setclientid_confirm_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uho", - NFSV4OP_SETCLIENTID_CONFIRM, - sci->clientid, - sizeof(sci->verf), sci->verf); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **mb, caddr_t *bpos) -{ - int error = 0; - struct nfs4_lowner *lop = op->fcp->lop; - - nfsm_buildf_xx(mb, bpos, "uuuuhuu", - NFSV4OP_OPEN, - lop->lo_seqid, - op->flags & O_ACCMODE, - NFSV4OPENSHARE_DENY_NONE, - cp->nmp->nm_clientid, - 4, lop->lo_id); - - if (op->flags & O_CREAT) { - nfsm_buildf_xx(mb, bpos, "u", OTCREATE); - /* openflag4: mode */ - nfsm_buildf_xx(mb, bpos, "u", CMUNCHECKED); - /* openflag4: createattrs... */ - if (op->vap != NULL) { - if (op->flags & O_TRUNC) - op->vap->va_size = 0; - error = nfsm_v4build_attrs_xx(op->vap, mb, bpos); - if (error != 0) - return (error); - } else - nfsm_buildf_xx(mb, bpos, "uu", 0, 0); - } else - nfsm_buildf_xx(mb, bpos, "u", OTNOCREATE); - - nfsm_buildf_xx(mb, bpos, "us", op->ctype, - op->cnp->cn_namelen, op->cnp->cn_nameptr); - - cp->seqidused = cp->req_nops++; - cp->fcp = op->fcp; - - return (error); -} - -/* - * XXX - * - Wait on recovery - */ -int -nfsm_v4build_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uou", - NFSV4OP_OPEN_CONFIRM, - NFSX_V4STATEID, op->fcp->stateid, - op->fcp->lop->lo_seqid); - - cp->seqidused = cp->req_nops++; - cp->fcp = op->fcp; - - return (0); -} - -/* - * XXX - * - Wait on recovery - */ -int -nfsm_v4build_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp, - struct mbuf **mb, caddr_t *bpos) -{ - struct nfs4_lowner *lop = fcp->lop; - - nfsm_buildf_xx(mb, bpos, "uuo", - NFSV4OP_CLOSE, - lop->lo_seqid, - NFSX_V4STATEID, fcp->stateid); - - cp->seqidused = cp->req_nops++; - cp->fcp = fcp; - - return (0); -} - -int -nfsm_v4build_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_ACCESS, acc->mode); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uohu", - NFSV4OP_READ, - NFSX_V4STATEID, r->fcp->stateid, - r->off, - r->maxcnt); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uohuu", - NFSV4OP_WRITE, - NFSX_V4STATEID, w->fcp->stateid, - w->off, - w->stable, - w->cnt); - cp->req_nops++; - return (nfsm_uiotombuf(w->uiop, mb, w->cnt, bpos)); -} - -int -nfsm_v4build_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uhu", NFSV4OP_COMMIT, c->start, c->len); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_readdir_xx(struct nfs4_compound *cp, struct nfs4_oparg_readdir *r, - struct mbuf **mb, caddr_t *bpos) -{ - int i; - - nfsm_buildf_xx(mb, bpos, "uhouuu", - NFSV4OP_READDIR, - r->cookie, - sizeof(r->verf), r->verf, - r->cnt >> 4, /* meaningless "dircount" field */ - r->cnt, - r->bm->bmlen); - - for (i = 0; i < r->bm->bmlen; i++) - nfsm_buildf_xx(mb, bpos, "u", r->bm->bmval[i]); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_renew_xx(struct nfs4_compound *cp, uint64_t cid, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uh", NFSV4OP_RENEW, cid); - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c, - struct mbuf **mb, caddr_t *bpos) -{ - uint32_t t1; - - nfsm_buildf_xx(mb, bpos, "uu", NFSV4OP_CREATE, c->type); - - if (c->type == NFLNK) - /* XXX strlen */ - nfsm_buildf_xx(mb, bpos, "s", strlen(c->linktext), c->linktext); - else if (c->type == NFCHR || c->type == NFBLK) - nfsm_buildf_xx(mb, bpos, "uu", - major(c->vap->va_rdev), minor(c->vap->va_rdev)); - - /* Name */ - nfsm_buildf_xx(mb, bpos, "s", c->namelen, c->name); - - /* Attributes */ - t1 = nfsm_v4build_attrs_xx(c->vap, mb, bpos); - if (t1 != 0) - return (t1); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_rename_xx(struct nfs4_compound *cp, struct nfs4_oparg_rename *r, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "uss", NFSV4OP_RENAME, r->fnamelen, r->fname, - r->tnamelen, r->tname); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_link_xx(struct nfs4_compound *cp, struct nfs4_oparg_link *l, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_LINK, l->namelen, l->name); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_remove_xx(struct nfs4_compound *cp, const char *name, u_int namelen, - struct mbuf **mb, caddr_t *bpos) -{ - nfsm_buildf_xx(mb, bpos, "us", NFSV4OP_REMOVE, namelen, name); - - cp->req_nops++; - - return (0); -} - -int -nfsm_v4build_attrs_xx(struct vattr *vap, struct mbuf **mb, caddr_t *bpos) -{ - uint32_t *tl, *attrlenp, *bmvalp, len; - size_t siz; - - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - - *tl++ = txdr_unsigned(2); /* bitmap length */ - bmvalp = tl; - bzero(bmvalp, 8); - tl += 2; - attrlenp = tl; - - len = 0; - if (vap->va_size != VNOVAL) { - tl = nfsm_build_xx(2 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_SIZE, bmvalp); - txdr_hyper(vap->va_size, tl); tl += 2; - len += 2 * NFSX_UNSIGNED; - } - if (vap->va_mode != (u_short)VNOVAL) { - tl = nfsm_build_xx(NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_MODE, bmvalp); - *tl++ = txdr_unsigned(vap->va_mode); - len += NFSX_UNSIGNED; - } - if (vap->va_uid != VNOVAL) { - int error; - char *name; - error = idmap_uid_to_name(vap->va_uid, &name, &siz); - if (error || name == NULL || siz == 0) { - /* XXX */ - siz = sizeof("nobody") - 1; - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy("nobody", tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy(name, tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } - FA4_SET(FA4_OWNER, bmvalp); - } - if (vap->va_gid != VNOVAL) { - int error; - char *name; - error = idmap_gid_to_name(vap->va_gid, &name, &siz); - if (error || name == NULL || siz == 0) { - /* XXX */ - siz = sizeof("nogroup") - 1; - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy("nogroup", tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } else { - tl = nfsm_build_xx(NFSX_UNSIGNED + nfsm_rndup(siz), mb, - bpos); - *tl++ = txdr_unsigned(siz); - bcopy(name, tl, siz); - len += NFSX_UNSIGNED + nfsm_rndup(siz); - } - FA4_SET(FA4_OWNER_GROUP, bmvalp); - } - if (vap->va_atime.tv_sec != VNOVAL) { - uint64_t val = vap->va_atime.tv_sec; - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_TIME_ACCESS_SET, bmvalp); - *tl++ = txdr_unsigned(THCLIENTTIME); - txdr_hyper(val, tl); tl += 2; - *tl++ = txdr_unsigned(vap->va_atime.tv_nsec); - len += 4 * NFSX_UNSIGNED; - } - if (vap->va_mtime.tv_sec != VNOVAL) { - uint64_t val = vap->va_mtime.tv_sec; - tl = nfsm_build_xx(4 * NFSX_UNSIGNED, mb, bpos); - FA4_SET(FA4_TIME_MODIFY_SET, bmvalp); - *tl++ = txdr_unsigned(THCLIENTTIME); - txdr_hyper(val, tl); tl += 2; - *tl++ = txdr_unsigned(vap->va_mtime.tv_nsec); - len += 4 * NFSX_UNSIGNED; - } - - bmvalp[0] = txdr_unsigned(bmvalp[0]); - bmvalp[1] = txdr_unsigned(bmvalp[1]); - - *attrlenp = txdr_unsigned(len); - - return (0); -} - -int -nfsm_v4dissect_compound_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos) -{ - uint32_t taglen, t1, *tl; - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - - /* Reply status is handled by the RPC code */ - - taglen = fxdr_unsigned(uint32_t, *tl++); - t1 = nfsm_adv_xx(nfsm_rndup(taglen), md, dpos); - if (t1 != 0) - return (EBADRPC); - - tl = nfsm_dissect_xx(NFSX_UNSIGNED, md, dpos); - if (tl == NULL) - return (EBADRPC); - - cp->rep_nops = fxdr_unsigned(uint32_t, *tl++); - - return (0); -} - -int -nfsm_v4dissect_simple_xx(struct nfs4_compound *cp, uint32_t op, - uint32_t skipbytes, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, dop, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &dop, &status); - if (t1 != 0) - return (t1); - - if (dop != op || status != 0) - return (EBADRPC); - - if (skipbytes > 0) - NFSM_ADV(nfsm_rndup(skipbytes)); - - return (0); -} - -int -nfsm_v4dissect_getattr_xx(struct nfs4_compound *cp, struct nfs4_oparg_getattr *ga, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETATTR || - *tl++ != 0) - return (EBADRPC); - - return (nfsm_v4dissect_attrs_xx(&ga->fa, md, dpos)); -} - -int -nfsm_v4dissect_setattr_xx(struct nfs4_compound *cp, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, op, bmlen, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_SETATTR || status != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "u", &bmlen); - if (t1 != 0) - return (t1); - - return (nfsm_dissectf_xx(md, dpos, "k", bmlen << 2)); -} - -int -nfsm_v4dissect_getfh_xx(struct nfs4_compound *cp, struct nfs4_oparg_getfh *gfh, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, len, xdrlen; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_GETFH) - return (EBADRPC); - - if (*tl++ != 0) - return (EBADRPC); - - NFSM_DISSECT(NFSX_UNSIGNED); - len = fxdr_unsigned(uint32_t, *tl++); - if (len > NFSX_V4FH) - return (EBADRPC); - - /* XXX integrate this into nfs_mtofh()? */ - - gfh->fh_len = len; - xdrlen = nfsm_rndup(len); - - NFSM_DISSECT(xdrlen); - bcopy(tl, &gfh->fh_val, xdrlen); - - return (0); -} - -int -nfsm_v4dissect_setclientid_xx(struct nfs4_compound *cp, - struct nfs4_oparg_setclientid *sci, struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_SETCLIENTID) - return (EBADRPC); - - /* Handle NFS4ERR_CLID_INUSE specially */ - if (*tl++ != 0) - return (EBADRPC); - - NFSM_DISSECT(2 * NFSX_UNSIGNED); - sci->clientid = fxdr_hyper(tl); - - NFSM_DISSECT(nfsm_rndup(NFSX_V4VERF)); - bcopy(tl, sci->verf, NFSX_V4VERF); - - return (0); -} - -int -nfsm_v4dissect_close_xx(struct nfs4_compound *cp, struct nfs4_fctx *fcp, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, t1; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_CLOSE || - *tl++ != 0) - return (EBADRPC); - - /* Copy stateid */ - t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid); - if (t1 != 0) - return (t1); - - return (0); -} - -int -nfsm_v4dissect_access_xx(struct nfs4_compound *cp, struct nfs4_oparg_access *acc, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(4 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_ACCESS || - *tl++ != 0) - return (EBADRPC); - - acc->supported = fxdr_unsigned(uint32_t, *tl++); - acc->rmode = fxdr_unsigned(uint32_t, *tl++); - - return (0); -} - -int -nfsm_v4dissect_open_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl, t1, bmlen, delegtype = ODNONE; - int error = 0; - nfsv4changeinfo cinfo; - struct nfs4_fctx *fcp = op->fcp; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN || - *tl++ != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, fcp->stateid); - if (t1 != 0) - return (t1); - - error = nfsm_v4dissect_changeinfo_xx(&cinfo, md, dpos); - if (error != 0) - goto nfsmout; - - NFSM_DISSECT(2 * NFSX_UNSIGNED); - - op->rflags = fxdr_unsigned(uint32_t, *tl++); - bmlen = fxdr_unsigned(uint32_t, *tl++); - if (bmlen > 2) { - error = EBADRPC; - goto nfsmout; - } - - /* Skip */ - NFSM_ADV(nfsm_rndup(bmlen << 2)); - - NFSM_DISSECT(NFSX_UNSIGNED); - delegtype = fxdr_unsigned(uint32_t, *tl++); - switch (delegtype) { - case ODREAD: - case ODWRITE: - printf("nfs4: client delegation not yet supported\n"); - error = EOPNOTSUPP; - goto nfsmout; - break; - case ODNONE: - default: - break; - } - - nfsmout: - return (error); -} - -int -nfsm_v4dissect_open_confirm_xx(struct nfs4_compound *cp, struct nfs4_oparg_open *op, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - tl = nfsm_dissect_xx(2 * NFSX_UNSIGNED, md, dpos); - if (tl == NULL || fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_OPEN_CONFIRM || - *tl++ != 0) - return (EBADRPC); - - return nfsm_dissectf_xx(md, dpos, "o", NFSX_V4STATEID, op->fcp->stateid); -} - -int -nfsm_v4dissect_read_xx(struct nfs4_compound *cp, struct nfs4_oparg_read *r, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t op, status, t1; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_READ || status != 0) - return (EBADRPC); - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &r->eof, &r->retlen); - if (t1 != 0) - return (t1); - - return (nfsm_mbuftouio(md, r->uiop, r->retlen, dpos)); -} - -int -nfsm_v4dissect_write_xx(struct nfs4_compound *cp, struct nfs4_oparg_write *w, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t op, status, t1; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_WRITE || status != 0) - return (EBADRPC); - - return (nfsm_dissectf_xx(md, dpos, "uuo", &w->retlen, &w->committed, - NFSX_V4VERF, w->wverf)); -} - -int -nfsm_v4dissect_commit_xx(struct nfs4_compound *cp, struct nfs4_oparg_commit *c, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, op, status; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_COMMIT || status != 0) - return (EBADRPC); - - return (nfsm_dissectf_xx(md, dpos, "o", NFSX_V4VERF, c->verf)); -} - -int -nfsm_v4dissect_create_xx(struct nfs4_compound *cp, struct nfs4_oparg_create *c, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, op, status, bmlen; - nfsv4changeinfo ci; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_CREATE || status != 0) - return (EBADRPC); - - /* Just throw this away for now */ - t1 = nfsm_v4dissect_changeinfo_xx(&ci, md, dpos); - if (t1 != 0) - return (t1); - - /* Throw this away too */ - NFSM_DISSECT(NFSX_UNSIGNED); - bmlen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(bmlen * NFSX_UNSIGNED); - tl += bmlen; - - return 0; -} - -int -nfsm_v4dissect_readlink_xx(struct nfs4_compound *cp, struct uio *uiop, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, op, status, linklen; - - t1 = nfsm_dissectf_xx(md, dpos, "uu", &op, &status); - if (t1 != 0) - return (t1); - - if (op != NFSV4OP_READLINK || status != 0) - return (EBADRPC); - - /* Do this one manually for careful checking of sizes. */ - NFSM_DISSECT(NFSX_UNSIGNED); - linklen = fxdr_unsigned(uint32_t, *tl++); - if (linklen <= 0) - return (EBADRPC); - - return (nfsm_mbuftouio(md, uiop, MIN(linklen, uiop->uio_resid), dpos)); -} - -int -nfsm_v4dissect_changeinfo_xx(nfsv4changeinfo *ci, - struct mbuf **md, caddr_t *dpos) -{ - uint32_t *tl; - - NFSM_DISSECT(5 * NFSX_UNSIGNED); - - ci->ciatomic = fxdr_unsigned(uint32_t, *tl++); - ci->cibefore = fxdr_hyper(tl); tl += 2; - ci->ciafter = fxdr_hyper(tl); tl += 2; - - return (0); -} - -int -nfsm_v4dissect_attrs_xx(struct nfsv4_fattr *fa, struct mbuf **md, caddr_t *dpos) -{ - uint32_t t1, *tl, bmlen, bmval[2], attrlen, len = 0; - - /* Bitmap length + value */ - NFSM_DISSECT(NFSX_UNSIGNED); - - bmlen = fxdr_unsigned(uint32_t, *tl++); - if (bmlen > 2) - return (EBADRPC); - - if (bmlen == 0) - return (0); - - NFSM_DISSECT(nfsm_rndup(bmlen << 2) + NFSX_UNSIGNED); - - bmval[0] = bmlen > 0 ? fxdr_unsigned(uint32_t, *tl++) : 0; - bmval[1] = bmlen > 1 ? fxdr_unsigned(uint32_t, *tl++) : 0; - - /* Attribute length */ - attrlen = fxdr_unsigned(uint32_t, *tl++); - - /* - * XXX check for correct (<=) attributes mask return from - * server. need to pass this in. - */ - - if (FA4_ISSET(FA4_TYPE, bmval)) { - /* overflow check */ - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_type = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_TYPE; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_CHANGE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_changeid = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_CHANGEID; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SIZE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_size = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SIZE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FSID, bmval)) { - NFSM_DISSECT(4 * NFSX_UNSIGNED); - fa->fa4_fsid_major = fxdr_hyper(tl); tl += 2; - fa->fa4_fsid_minor = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SIZE; - len += 4 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_LEASE_TIME, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_lease_time = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_LEASE_TIME; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_RDATTR_ERROR, bmval)) { - /* ignore for now; we only ask for it so the compound won't fail */ - NFSM_DISSECT(NFSX_UNSIGNED); - tl++; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILEID, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_fileid = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FILEID; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILES_FREE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_ffree = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FFREE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_FILES_TOTAL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_ftotal = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_FTOTAL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXFILESIZE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxfilesize = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXFILESIZE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXNAME, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_maxname = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_MAXNAME; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXREAD, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxread = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXREAD; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_MAXWRITE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_maxwrite = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_MAXWRITE; - len += 2 * NFSX_UNSIGNED; - } - - if (FA4_ISSET(FA4_MODE, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_mode = fxdr_unsigned(mode_t, *tl++); - fa->fa4_valid |= FA4V_MODE; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_NUMLINKS, bmval)) { - NFSM_DISSECT(NFSX_UNSIGNED); - fa->fa4_nlink = fxdr_unsigned(nlink_t, *tl++); - fa->fa4_valid |= FA4V_NLINK; - len += NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_OWNER, bmval)) { - uint32_t ownerlen; - int error; - - NFSM_DISSECT(NFSX_UNSIGNED); - - ownerlen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(nfsm_rndup(ownerlen)); - error = idmap_name_to_uid((char *)tl, ownerlen, &fa->fa4_uid); - if (error) - fa->fa4_uid = -2; - fa->fa4_valid |= FA4V_UID; - len += NFSX_UNSIGNED + nfsm_rndup(ownerlen); - } - if (FA4_ISSET(FA4_OWNER_GROUP, bmval)) { - uint32_t ownergrouplen; - int error; - - NFSM_DISSECT(NFSX_UNSIGNED); - ownergrouplen = fxdr_unsigned(uint32_t, *tl++); - NFSM_DISSECT(nfsm_rndup(ownergrouplen)); - error = idmap_name_to_gid((char *)tl, ownergrouplen, &fa->fa4_gid); - if (error) - fa->fa4_gid = -2; - fa->fa4_valid |= FA4V_GID; - len += NFSX_UNSIGNED + nfsm_rndup(ownergrouplen); - } - if (FA4_ISSET(FA4_RAWDEV, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_rdev_major = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_rdev_minor = fxdr_unsigned(uint32_t, *tl++); - fa->fa4_valid |= FA4V_RDEV; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_AVAIL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_savail = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SAVAIL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_FREE, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_sfree = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_SFREE; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_TOTAL, bmval)) { - NFSM_DISSECT(2 * NFSX_UNSIGNED); - fa->fa4_stotal = fxdr_hyper(tl); - fa->fa4_valid |= FA4V_STOTAL; - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_SPACE_USED, bmval)) { - NFSM_ADV(2 * NFSX_UNSIGNED); - len += 2 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_ACCESS, bmval)) { - NFSM_MTOTIME(fa->fa4_atime); - fa->fa4_valid |= FA4V_ATIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_CREATE, bmval)) { - NFSM_MTOTIME(fa->fa4_btime); - fa->fa4_valid |= FA4V_BTIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_METADATA, bmval)) { - NFSM_MTOTIME(fa->fa4_ctime); - fa->fa4_valid |= FA4V_CTIME; - len += 3 * NFSX_UNSIGNED; - } - if (FA4_ISSET(FA4_TIME_MODIFY, bmval)) { - NFSM_MTOTIME(fa->fa4_mtime); - fa->fa4_valid |= FA4V_MTIME; - len += 3 * NFSX_UNSIGNED; - } - - if (len != attrlen) - return (EBADRPC); - - return (0); -} diff --git a/sys/nfs4client/nfs4_vfs.h b/sys/nfs4client/nfs4_vfs.h deleted file mode 100644 index 61999ac925b6..000000000000 --- a/sys/nfs4client/nfs4_vfs.h +++ /dev/null @@ -1,34 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_vfs.h,v 1.4 2003/11/05 14:59:00 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef _NFS4CLIENT_NFS4_VFS_H -#define _NFS4CLIENT_NFS4_VFS_H - -void nfs4_vfsop_fsinfo(struct nfsv4_fattr *, struct nfsmount *); -void nfs4_vfsop_statfs(struct nfsv4_fattr *, struct statfs *, struct mount *); - -#endif /* _NFS4CLIENT_NFS4_VFS_H */ diff --git a/sys/nfs4client/nfs4_vfs_subs.c b/sys/nfs4client/nfs4_vfs_subs.c deleted file mode 100644 index 6d667afa9fa0..000000000000 --- a/sys/nfs4client/nfs4_vfs_subs.c +++ /dev/null @@ -1,125 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_vfs_subs.c,v 1.5 2003/11/05 14:59:00 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* NFSv4 */ -#include -#include -#include - -#include - -void -nfs4_vfsop_fsinfo(struct nfsv4_fattr *fap, struct nfsmount *nmp) -{ - uint32_t max; - - if (fap->fa4_valid & FA4V_FSID) { - nmp->nm_fsid.val[0] = fap->fa4_fsid_major; - nmp->nm_fsid.val[1] = fap->fa4_fsid_minor; - } - if (fap->fa4_valid & FA4V_MAXREAD) { - max = fap->fa4_maxread; - if (max < nmp->nm_rsize) { - nmp->nm_rsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize == 0) - nmp->nm_rsize = max; - } - if (max < nmp->nm_readdirsize) { - nmp->nm_readdirsize = max & ~(NFS_DIRBLKSIZ - 1); - if (nmp->nm_readdirsize == 0) - nmp->nm_readdirsize = max; - } - } - if (fap->fa4_valid & FA4V_MAXWRITE) { - max = fap->fa4_maxwrite; - if (max < nmp->nm_wsize) { - nmp->nm_wsize = max & ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize == 0) - nmp->nm_wsize = max; - } - } - if (fap->fa4_valid & FA4V_LEASE_TIME) - nmp->nm_lease_time = fap->fa4_lease_time; - - /* nmp->nm_flag |= NFSMNT_GOTFSINFO; */ -} - -void -nfs4_vfsop_statfs(struct nfsv4_fattr *fap, struct statfs *sbp, struct mount *mp) -{ - struct nfsmount *nmp = VFSTONFS(mp); - - sbp->f_iosize = nfs_iosize(nmp); - sbp->f_bsize = NFS_FABLKSIZE; - - if (fap->fa4_valid & FA4V_FSID) { - sbp->f_fsid.val[0] = fap->fa4_fsid_major; - sbp->f_fsid.val[1] = fap->fa4_fsid_minor; - } - - sbp->f_ffree = fap->fa4_valid & FA4V_FFREE ? fap->fa4_ffree : 0; - /* sbp->f_ftotal = fa->fa4_valid & FA4_FTOTAL ? fa->fa4_ftotal : 0; */ - sbp->f_bavail = fap->fa4_valid & FA4V_SAVAIL ? - fap->fa4_savail / NFS_FABLKSIZE : 500000; - sbp->f_bfree = fap->fa4_valid & FA4V_SFREE ? - fap->fa4_sfree / NFS_FABLKSIZE : 500000; - sbp->f_blocks = fap->fa4_valid & FA4V_STOTAL ? - fap->fa4_stotal / NFS_FABLKSIZE : 1000000; -} diff --git a/sys/nfs4client/nfs4_vfsops.c b/sys/nfs4client/nfs4_vfsops.c deleted file mode 100644 index 808b63d9116a..000000000000 --- a/sys/nfs4client/nfs4_vfsops.c +++ /dev/null @@ -1,886 +0,0 @@ -/* $Id: nfs_vfsops.c,v 1.38 2003/11/05 14:59:01 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/*- - * Copyright (c) 1989, 1993, 1995 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_vfsops.c 8.12 (Berkeley) 5/20/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -#include "opt_bootp.h" -#include "opt_nfsroot.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -SYSCTL_NODE(_vfs, OID_AUTO, nfs4, CTLFLAG_RW, 0, "NFS4 filesystem"); -SYSCTL_STRUCT(_vfs_nfs4, NFS_NFSSTATS, nfsstats, CTLFLAG_RD, - &nfsstats, nfsstats, "S,nfsstats"); - -static void nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp); -static void nfs4_daemon(void *arg); -static int mountnfs(struct nfs_args *, struct mount *, - struct sockaddr *, char *, struct vnode **, - struct ucred *cred); -static int nfs4_do_setclientid(struct nfsmount *nmp, struct ucred *cred); -static vfs_mount_t nfs4_mount; -static vfs_cmount_t nfs4_cmount; -static vfs_unmount_t nfs4_unmount; -static vfs_root_t nfs4_root; -static vfs_statfs_t nfs4_statfs; -static vfs_sync_t nfs4_sync; - -static int fake_wchan; - -/* - * nfs vfs operations. - */ -static struct vfsops nfs4_vfsops = { - .vfs_init = nfs4_init, - .vfs_mount = nfs4_mount, - .vfs_cmount = nfs4_cmount, - .vfs_root = nfs4_root, - .vfs_statfs = nfs4_statfs, - .vfs_sync = nfs4_sync, - .vfs_uninit = nfs4_uninit, - .vfs_unmount = nfs4_unmount, -}; -VFS_SET(nfs4_vfsops, nfs4, VFCF_NETWORK); - -static struct nfs_rpcops nfs4_rpcops = { - nfs4_readrpc, - nfs4_writerpc, - nfs4_writebp, - nfs4_readlinkrpc, - nfs4_invaldir, - nfs4_commit, -}; - -/* So that loader and kldload(2) can find us, wherever we are.. */ -MODULE_VERSION(nfs4, 1); - -void nfsargs_ntoh(struct nfs_args *); - -int -nfs4_init(struct vfsconf *vfsp) -{ - - rpcclnt_init(); - nfs4dev_init(); - idmap_init(); - nfsm_v4init(); - - return (0); -} - -int -nfs4_uninit(struct vfsconf *vfsp) -{ - - rpcclnt_uninit(); - nfs4dev_uninit(); - idmap_uninit(); - - return (0); -} - -/* - * nfs statfs call - */ -static int -nfs4_statfs(struct mount *mp, struct statfs *sbp) -{ - struct vnode *vp; - struct thread *td; - struct nfs_statfs *sfp; - caddr_t bpos, dpos; - struct nfsmount *nmp = VFSTONFS(mp); - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfsnode *np; - struct nfs4_compound cp; - struct nfs4_oparg_getattr ga; - struct nfsv4_fattr *fap = &ga.fa; - - td = curthread; -#ifndef nolint - sfp = NULL; -#endif - error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE); - if (error) - return (error); - vp = NFSTOV(np); - nfsstats.rpccnt[NFSPROC_FSSTAT]++; - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, NFSX_FH(1)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - ga.bm = &nfsv4_fsattrbm; - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "statfs()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, td->td_ucred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_getattr(&cp, &ga); - - nfs4_vfsop_statfs(fap, sbp, mp); - -nfsmout: - error = nfs_v4postop(&cp, error); - - vput(vp); - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -static void -nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp) -{ - int s; - int adjsock; - int maxio; - - s = splnet(); - - /* - * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes - * no sense in that context. Also, set appropriate retransmit - * and soft timeout behavior. - */ - if (argp->sotype == SOCK_STREAM) { - nmp->nm_flag &= ~NFSMNT_NOCONN; - nmp->nm_flag |= NFSMNT_DUMBTIMR; - nmp->nm_timeo = NFS_MAXTIMEO; - nmp->nm_retry = NFS_RETRANS_TCP; - } - - nmp->nm_flag &= ~NFSMNT_RDIRPLUS; - - /* Re-bind if rsrvd port requested and wasn't on one */ - adjsock = !(nmp->nm_flag & NFSMNT_RESVPORT) - && (argp->flags & NFSMNT_RESVPORT); - /* Also re-bind if we're switching to/from a connected UDP socket */ - adjsock |= ((nmp->nm_flag & NFSMNT_NOCONN) != - (argp->flags & NFSMNT_NOCONN)); - - /* Update flags atomically. Don't change the lock bits. */ - nmp->nm_flag = argp->flags | nmp->nm_flag; - splx(s); - - if ((argp->flags & NFSMNT_TIMEO) && argp->timeo > 0) { - nmp->nm_timeo = (argp->timeo * NFS_HZ + 5) / 10; - if (nmp->nm_timeo < NFS_MINTIMEO) - nmp->nm_timeo = NFS_MINTIMEO; - else if (nmp->nm_timeo > NFS_MAXTIMEO) - nmp->nm_timeo = NFS_MAXTIMEO; - } - - if ((argp->flags & NFSMNT_RETRANS) && argp->retrans > 1) { - nmp->nm_retry = argp->retrans; - if (nmp->nm_retry > NFS_MAXREXMIT) - nmp->nm_retry = NFS_MAXREXMIT; - } - - if (argp->flags & NFSMNT_NFSV3) { - if (argp->sotype == SOCK_DGRAM) - maxio = NFS_MAXDGRAMDATA; - else - maxio = NFS_MAXDATA; - } else - maxio = NFS_V2MAXDATA; - - if ((argp->flags & NFSMNT_WSIZE) && argp->wsize > 0) { - nmp->nm_wsize = argp->wsize; - /* Round down to multiple of blocksize */ - nmp->nm_wsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_wsize <= 0) - nmp->nm_wsize = NFS_FABLKSIZE; - } - if (nmp->nm_wsize > maxio) - nmp->nm_wsize = maxio; - if (nmp->nm_wsize > MAXBSIZE) - nmp->nm_wsize = MAXBSIZE; - - if ((argp->flags & NFSMNT_RSIZE) && argp->rsize > 0) { - nmp->nm_rsize = argp->rsize; - /* Round down to multiple of blocksize */ - nmp->nm_rsize &= ~(NFS_FABLKSIZE - 1); - if (nmp->nm_rsize <= 0) - nmp->nm_rsize = NFS_FABLKSIZE; - } - if (nmp->nm_rsize > maxio) - nmp->nm_rsize = maxio; - if (nmp->nm_rsize > MAXBSIZE) - nmp->nm_rsize = MAXBSIZE; - - if ((argp->flags & NFSMNT_READDIRSIZE) && argp->readdirsize > 0) { - nmp->nm_readdirsize = argp->readdirsize; - } - if (nmp->nm_readdirsize > maxio) - nmp->nm_readdirsize = maxio; - if (nmp->nm_readdirsize > nmp->nm_rsize) - nmp->nm_readdirsize = nmp->nm_rsize; - - if ((argp->flags & NFSMNT_ACREGMIN) && argp->acregmin >= 0) - nmp->nm_acregmin = argp->acregmin; - else - nmp->nm_acregmin = NFS_MINATTRTIMO; - if ((argp->flags & NFSMNT_ACREGMAX) && argp->acregmax >= 0) - nmp->nm_acregmax = argp->acregmax; - else - nmp->nm_acregmax = NFS_MAXATTRTIMO; - if ((argp->flags & NFSMNT_ACDIRMIN) && argp->acdirmin >= 0) - nmp->nm_acdirmin = argp->acdirmin; - else - nmp->nm_acdirmin = NFS_MINDIRATTRTIMO; - if ((argp->flags & NFSMNT_ACDIRMAX) && argp->acdirmax >= 0) - nmp->nm_acdirmax = argp->acdirmax; - else - nmp->nm_acdirmax = NFS_MAXDIRATTRTIMO; - if (nmp->nm_acdirmin > nmp->nm_acdirmax) - nmp->nm_acdirmin = nmp->nm_acdirmax; - if (nmp->nm_acregmin > nmp->nm_acregmax) - nmp->nm_acregmin = nmp->nm_acregmax; - - if ((argp->flags & NFSMNT_MAXGRPS) && argp->maxgrouplist >= 0) { - if (argp->maxgrouplist <= NFS_MAXGRPS) - nmp->nm_numgrps = argp->maxgrouplist; - else - nmp->nm_numgrps = NFS_MAXGRPS; - } - if ((argp->flags & NFSMNT_READAHEAD) && argp->readahead >= 0) { - if (argp->readahead <= NFS_MAXRAHEAD) - nmp->nm_readahead = argp->readahead; - else - nmp->nm_readahead = NFS_MAXRAHEAD; - } - if ((argp->flags & NFSMNT_DEADTHRESH) && argp->deadthresh >= 0) { - if (argp->deadthresh <= NFS_MAXDEADTHRESH) - nmp->nm_deadthresh = argp->deadthresh; - else - nmp->nm_deadthresh = NFS_MAXDEADTHRESH; - } - - adjsock |= ((nmp->nm_sotype != argp->sotype) || - (nmp->nm_soproto != argp->proto)); - nmp->nm_sotype = argp->sotype; - nmp->nm_soproto = argp->proto; - - if (nmp->nm_rpcclnt.rc_so && adjsock) { - nfs_safedisconnect(nmp); - if (nmp->nm_sotype == SOCK_DGRAM) { - while (nfs4_connect(nmp)) { - printf("nfs4_decode_args: retrying connect\n"); - (void)tsleep(&fake_wchan, PSOCK, "nfscon", hz); - } - } - } -} - -/* - * VFS Operations. - * - * mount system call - * It seems a bit dumb to copyinstr() the host and path here and then - * bcopy() them in mountnfs(), but I wanted to detect errors before - * doing the sockargs() call because sockargs() allocates an mbuf and - * an error after that means that I have to release the mbuf. - */ -/* ARGSUSED */ -static int -nfs4_cmount(struct mntarg *ma, void *data, int flags) -{ - struct nfs_args args; - int error; - - error = copyin(data, &args, sizeof(struct nfs_args)); - if (error) - return (error); - ma = mount_arg(ma, "nfs_args", &args, sizeof args); - error = kernel_mount(ma, flags); - return (error); -} - -static int -nfs4_mount(struct mount *mp) -{ - int error; - struct nfs_args args; - struct sockaddr *nam; - struct vnode *vp; - char hst[MNAMELEN]; - size_t len; - - if (mp->mnt_flag & MNT_ROOTFS) { - printf("nfs4_mountroot not supported\n"); - return (EINVAL); - } - error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, sizeof args); - if (error) - return (error); - - if (args.version != NFS_ARGSVERSION) - return (EPROGMISMATCH); - if (mp->mnt_flag & MNT_UPDATE) { - struct nfsmount *nmp = VFSTONFS(mp); - - if (nmp == NULL) - return (EIO); - /* - * When doing an update, we can't change from or to - * v3, switch lockd strategies or change cookie translation - */ - args.flags = (args.flags & - ~(NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD)) | - (nmp->nm_flag & - (NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD)); - nfs4_decode_args(nmp, &args); - return (0); - } - - error = copyinstr(args.hostname, hst, MNAMELEN-1, &len); - if (error) - return (error); - bzero(&hst[len], MNAMELEN - len); - /* sockargs() call must be after above copyin() calls */ - error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen); - if (error) - return (error); - error = mountnfs(&args, mp, nam, hst, &vp, curthread->td_ucred); - return (error); -} - -/* - * renew should be done async - * should re-scan mount queue each time - */ -struct proc *nfs4_daemonproc; - -static int -nfs4_do_renew(struct nfsmount *nmp, struct ucred *cred) -{ - struct nfs4_compound cp; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - caddr_t bpos, dpos; - int error; - - mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, sizeof(uint64_t)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_do_renew()"); - nfsm_v4build_renew(&cp, nmp->nm_clientid); - nfsm_v4build_finalize(&cp); - - nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_renew(&cp); - nmp->nm_last_renewal = time_second; - return (0); - - nfsmout: - error = nfs_v4postop(&cp, error); - - /* XXX */ - if (mrep != NULL) - m_freem(mrep); - return (error); -} - -static void -nfs4_daemon(void *arg) -{ - struct mount *mp; - struct nfsmount *nmp; - int nmounts; - - while (1) { - nmounts = 0; - mtx_lock(&mountlist_mtx); - TAILQ_FOREACH(mp, &mountlist, mnt_list) { - if (strcmp(mp->mnt_vfc->vfc_name, "nfs4") != 0) - continue; - nmounts++; - nmp = VFSTONFS(mp); - if (time_second < nmp->nm_last_renewal + nmp->nm_lease_time - 4) - continue; - mtx_unlock(&mountlist_mtx); - mtx_lock(&Giant); - nfs4_do_renew(nmp, (struct ucred *) arg); - mtx_unlock(&Giant); - mtx_lock(&mountlist_mtx); - } - mtx_unlock(&mountlist_mtx); - - /* Must kill the daemon here, or module unload will cause a panic */ - if (nmounts == 0) { - mtx_lock(&Giant); - nfs4_daemonproc = NULL; - mtx_unlock(&Giant); - /*printf("nfsv4 renewd exiting\n");*/ - kproc_exit(0); - } - tsleep(&nfs4_daemonproc, PVFS, "nfs4", 2 * hz); - } -} - -/* - * Common code for mount and mountroot - */ -static int -mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, - char *hst, struct vnode **vpp, struct ucred *cred) -{ - struct nfsmount *nmp; - char *rpth, *cp1, *cp2; - int nlkup = 0, error; - struct nfs4_compound cp; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - caddr_t bpos, dpos; - struct nfs4_oparg_lookup lkup; - struct nfs4_oparg_getfh gfh; - struct nfs4_oparg_getattr ga; - struct thread *td = curthread; /* XXX */ - - if (mp->mnt_flag & MNT_UPDATE) { - nmp = VFSTONFS(mp); - /* update paths, file handles, etc, here XXX */ - free(nam, M_SONAME); - return (0); - } else { - nmp = uma_zalloc(nfsmount_zone, M_WAITOK); - bzero((caddr_t)nmp, sizeof (struct nfsmount)); - TAILQ_INIT(&nmp->nm_bufq); - mp->mnt_data = nmp; - } - - vfs_getnewfsid(mp); - nmp->nm_mountp = mp; - mtx_init(&nmp->nm_mtx, "NFS4mount lock", NULL, MTX_DEF); - - nmp->nm_maxfilesize = 0xffffffffLL; - nmp->nm_timeo = NFS_TIMEO; - nmp->nm_retry = NFS_RETRANS; - nmp->nm_wsize = NFS_WSIZE; - nmp->nm_rsize = NFS_RSIZE; - nmp->nm_readdirsize = NFS_READDIRSIZE; - nmp->nm_numgrps = NFS_MAXGRPS; - nmp->nm_readahead = NFS_DEFRAHEAD; - nmp->nm_deadthresh = NFS_MAXDEADTHRESH; - vfs_mountedfrom(mp, hst); - nmp->nm_nam = nam; - /* Set up the sockets and per-host congestion */ - nmp->nm_sotype = argp->sotype; - nmp->nm_soproto = argp->proto; - nmp->nm_rpcops = &nfs4_rpcops; - /* XXX */ - mp->mnt_stat.f_iosize = PAGE_SIZE; - - argp->flags |= (NFSMNT_NFSV3 | NFSMNT_NFSV4); - - nfs4_decode_args(nmp, argp); - - if ((error = nfs4_connect(nmp))) - goto bad; - - mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - ga.bm = &nfsv4_fsinfobm; - nfs_v4initcompound(&cp); - - /* Get remote path */ - rpth = hst; - strsep(&rpth, ":"); - - nfsm_v4build_compound(&cp, "mountnfs()"); - nfsm_v4build_putrootfh(&cp); - for (cp1 = rpth; cp1 && *cp1; cp1 = cp2) { - while (*cp1 == '/') - cp1++; - if (!*cp1) - break; - for (cp2 = cp1; *cp2 && *cp2 != '/'; cp2++) - ; - lkup.name = cp1; - lkup.namelen = cp2 - cp1; - nfsm_v4build_lookup(&cp, &lkup); - nlkup++; - } - nfsm_v4build_getfh(&cp, &gfh); - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_finalize(&cp); - - nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putrootfh(&cp); - while (nlkup--) - nfsm_v4dissect_lookup(&cp); - nfsm_v4dissect_getfh(&cp, &gfh); - nfsm_v4dissect_getattr(&cp, &ga); - - nfs4_vfsop_fsinfo(&ga.fa, nmp); - nmp->nm_state |= NFSSTA_GOTFSINFO; - - /* Copy root fh into nfsmount. */ - nmp->nm_fhsize = gfh.fh_len; - bcopy(&gfh.fh_val, nmp->nm_fh, nmp->nm_fhsize); - nmp->nm_last_renewal = time_second; - - if ((error = nfs4_do_setclientid(nmp, cred)) != 0) - goto nfsmout; - - /* Start renewd if it isn't already running */ - if (nfs4_daemonproc == NULL) - kproc_create(nfs4_daemon, crdup(cred), &nfs4_daemonproc, - (RFPROC|RFMEM), 0, "nfs4rd"); - - return (0); - nfsmout: - error = nfs_v4postop(&cp, error); - - /* XXX */ - if (mrep != NULL) - m_freem(mrep); -bad: - mtx_destroy(&nmp->nm_mtx); - nfs4_disconnect(nmp); - uma_zfree(nfsmount_zone, nmp); - free(nam, M_SONAME); - - return (error); -} - -/* - * unmount system call - */ -static int -nfs4_unmount(struct mount *mp, int mntflags) -{ - struct nfsmount *nmp; - int error, flags = 0; - - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - nmp = VFSTONFS(mp); - /* - * Goes something like this.. - * - Call vflush to clear out vnodes for this filesystem - * - Close the socket - * - Free up the data structures - */ - /* In the forced case, cancel any outstanding requests. */ - if (flags & FORCECLOSE) { - error = nfs_nmcancelreqs(nmp); - if (error) - return (error); - nfs4dev_purge(); - } - - error = vflush(mp, 0, flags, curthread); - if (error) - return (error); - - /* - * We are now committed to the unmount. - */ - nfs4_disconnect(nmp); - free(nmp->nm_nam, M_SONAME); - - /* XXX there's a race condition here for SMP */ - wakeup(&nfs4_daemonproc); - - mtx_destroy(&nmp->nm_mtx); - uma_zfree(nfsmount_zone, nmp); - return (0); -} - -/* - * Return root of a filesystem - */ -static int -nfs4_root(struct mount *mp, int flags, struct vnode **vpp) -{ - struct vnode *vp; - struct nfsmount *nmp; - struct nfsnode *np; - int error; - - nmp = VFSTONFS(mp); - error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, - LK_EXCLUSIVE); - if (error) - return (error); - vp = NFSTOV(np); - if (vp->v_type == VNON) - vp->v_type = VDIR; - vp->v_vflag |= VV_ROOT; - *vpp = vp; - - return (0); -} - -/* - * Flush out the buffer cache - */ -static int -nfs4_sync(struct mount *mp, int waitfor) -{ - struct vnode *vp, *mvp; - struct thread *td; - int error, allerror = 0; - - td = curthread; - - /* - * Force stale buffer cache information to be flushed. - */ - MNT_ILOCK(mp); -loop: - MNT_VNODE_FOREACH(vp, mp, mvp) { - VI_LOCK(vp); - MNT_IUNLOCK(mp); - /* XXX racy bv_cnt check. */ - if (VOP_ISLOCKED(vp) || vp->v_bufobj.bo_dirty.bv_cnt == 0 || - waitfor == MNT_LAZY) { - VI_UNLOCK(vp); - MNT_ILOCK(mp); - continue; - } - if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) { - MNT_ILOCK(mp); - MNT_VNODE_FOREACH_ABORT_ILOCKED(mp, mvp); - goto loop; - } - error = VOP_FSYNC(vp, waitfor, td); - if (error) - allerror = error; - VOP_UNLOCK(vp, 0); - vrele(vp); - - MNT_ILOCK(mp); - } - MNT_IUNLOCK(mp); - return (allerror); -} - -static int -nfs4_do_setclientid(struct nfsmount *nmp, struct ucred *cred) -{ - struct nfs4_oparg_setclientid scid; - struct nfs4_compound cp; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - caddr_t bpos, dpos; - struct route ro; - char *ipsrc = NULL, uaddr[24], name[24]; - int try = 0; - static unsigned long seq; - int error; - -#ifndef NFS4_USE_RPCCLNT - return (0); -#endif - if (nmp->nm_clientid) { - printf("nfs4_do_setclientid: already have clientid!\n"); - error = 0; - goto nfsmout; - } - - /* Try not to re-use clientids */ - if (seq == 0) - seq = time_second; - -#ifdef NFS4_USE_RPCCLNT - scid.cb_netid = (nmp->nm_rpcclnt.rc_sotype == SOCK_STREAM) ? "tcp" : "udp"; -#endif - scid.cb_netid = "tcp"; - scid.cb_netidlen = 3; - scid.cb_prog = 0x1234; /* XXX */ - - /* Do a route lookup to find our source address for talking to this server */ - bzero(&ro, sizeof ro); - -#ifdef NFS4_USE_RPCCLNT - ro.ro_dst = *nmp->nm_rpcclnt.rc_name; -#endif -/* XXX MRT NFS uses table 0 */ - in_rtalloc(&ro, 0); - if (ro.ro_rt == NULL) { - error = EHOSTUNREACH; - goto nfsmout; - } - ipsrc = inet_ntoa(IA_SIN(ifatoia(ro.ro_rt->rt_ifa))->sin_addr); - sprintf(uaddr, "%s.12.48", ipsrc); - scid.cb_univaddr = uaddr; - scid.cb_univaddrlen = strlen(uaddr); - RTFREE(ro.ro_rt); - - try_again: - sprintf(name, "%s-%d", ipsrc, (int) ((seq + try) % 1000000L)); - scid.namelen = strlen(name); - scid.name = name; - nfs_v4initcompound(&cp); - - mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_do_setclientid()"); - nfsm_v4build_setclientid(&cp, &scid); - nfsm_v4build_finalize(&cp); - - nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_setclientid(&cp, &scid); - nmp->nm_clientid = scid.clientid; - - error = nfs_v4postop(&cp, error); - - /* Confirm */ - m_freem(mrep); - mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, NFSX_FH(1)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_do_setclientid() (confirm)"); - nfsm_v4build_setclientid_confirm(&cp, &scid); - nfsm_v4build_finalize(&cp); - - nfsm_request_mnt(nmp, NFSV4PROC_COMPOUND, curthread, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_setclientid_confirm(&cp); - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep) - m_freem(mrep); - if (error == NFSERR_CLID_INUSE && (++try < NFS4_SETCLIENTID_MAXTRIES)) - goto try_again; - - return (error); -} diff --git a/sys/nfs4client/nfs4_vn.h b/sys/nfs4client/nfs4_vn.h deleted file mode 100644 index 2f5f7306187f..000000000000 --- a/sys/nfs4client/nfs4_vn.h +++ /dev/null @@ -1,33 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_vn.h,v 1.5 2003/11/05 14:59:00 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef _NFS4CLIENT_NFS4_VFS_H -#define _NFS4CLIENT_NFS4_VFS_H - -void nfs4_vnop_loadattrcache(struct vnode *, struct nfsv4_fattr *, struct vattr *); - -#endif /* _NFS4CLIENT_NFS4_VFS_H */ diff --git a/sys/nfs4client/nfs4_vn_subs.c b/sys/nfs4client/nfs4_vn_subs.c deleted file mode 100644 index 12095d015d8e..000000000000 --- a/sys/nfs4client/nfs4_vn_subs.c +++ /dev/null @@ -1,225 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4_vn_subs.c,v 1.9 2003/11/05 14:59:00 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -/* NFSv4 */ -#include -#include -#include - -#include - -void -nfs4_vnop_loadattrcache(struct vnode *vp, struct nfsv4_fattr *fap, - struct vattr *vaper) -{ - struct vattr *vap; - struct nfsnode *np; - int32_t rdev; - enum vtype vtyp; - u_short vmode; - struct timespec mtime; - struct timeval tv; - - microtime(&tv); - - vtyp = nv3tov_type[fap->fa4_type & 0x7]; - vmode = (fap->fa4_valid & FA4V_MODE) ? fap->fa4_mode : 0777; - rdev = (fap->fa4_valid & FA4V_RDEV) ? - makedev(fap->fa4_rdev_major, fap->fa4_rdev_minor) : 0; - if (fap->fa4_valid & FA4V_MTIME) - mtime = fap->fa4_mtime; - else - bzero(&mtime, sizeof mtime); - - /* - * If v_type == VNON it is a new node, so fill in the v_type, - * n_mtime fields. Check to see if it represents a special - * device, and if so, check for a possible alias. Once the - * correct vnode has been obtained, fill in the rest of the - * information. - */ - np = VTONFS(vp); - vap = &np->n_vattr; - if (vp->v_type != vtyp || np->n_mtime.tv_sec == 0) { - bzero(vap, sizeof *vap); - vp->v_type = vtyp; - np->n_mtime.tv_sec = mtime.tv_sec; - } - vap->va_type = vtyp; - vap->va_mode = (vmode & 07777); - vap->va_rdev = rdev; - vap->va_mtime = mtime; - vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0]; - if (fap->fa4_valid & FA4V_NLINK) - vap->va_nlink = fap->fa4_nlink; - if (fap->fa4_valid & FA4V_UID) - vap->va_uid = fap->fa4_uid; - if (fap->fa4_valid & FA4V_GID) - vap->va_gid = fap->fa4_gid; - vap->va_size = fap->fa4_size; - vap->va_blocksize = NFS_FABLKSIZE; - vap->va_bytes = fap->fa4_size; - if (fap->fa4_valid & FA4V_FILEID) - vap->va_fileid = nfs_v4fileid4_to_fileid(fap->fa4_fileid); - if (fap->fa4_valid & FA4V_ATIME) - vap->va_atime = fap->fa4_atime; - if (fap->fa4_valid & FA4V_BTIME) - vap->va_birthtime = fap->fa4_btime; - if (fap->fa4_valid & FA4V_CTIME) - vap->va_ctime = fap->fa4_ctime; - vap->va_flags = 0; - vap->va_filerev = 0; - /* XXX dontshrink flag? */ - if (vap->va_size != np->n_size) { - if (vap->va_type == VREG) { - if (np->n_flag & NMODIFIED) { - if (vap->va_size < np->n_size) - vap->va_size = np->n_size; - else - np->n_size = vap->va_size; - } else - np->n_size = vap->va_size; - vnode_pager_setsize(vp, np->n_size); - } else - np->n_size = vap->va_size; - } - np->n_attrstamp = tv.tv_sec; - if (vaper != NULL) { - bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap)); - if (np->n_flag & NCHG) { - if (np->n_flag & NACC) - vaper->va_atime = np->n_atim; - if (np->n_flag & NUPD) - vaper->va_mtime = np->n_mtim; - } - } -} - -static uint64_t nfs_nullcookie = 0; -/* - * This function finds the directory cookie that corresponds to the - * logical byte offset given. - */ -uint64_t * -nfs4_getcookie(struct nfsnode *np, off_t off, int add) -{ - struct nfsdmap *dp, *dp2; - int pos; - - pos = (uoff_t)off / NFS_DIRBLKSIZ; - if (pos == 0 || off < 0) { -#ifdef DIAGNOSTIC - if (add) - panic("nfs getcookie add at <= 0"); -#endif - return (&nfs_nullcookie); - } - pos--; - dp = LIST_FIRST(&np->n_cookies); - if (!dp) { - if (add) { - dp = malloc(sizeof (struct nfsdmap), - M_NFSDIROFF, M_WAITOK); - dp->ndm_eocookie = 0; - LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list); - } else - return (NULL); - } - while (pos >= NFSNUMCOOKIES) { - pos -= NFSNUMCOOKIES; - if (LIST_NEXT(dp, ndm_list)) { - if (!add && dp->ndm_eocookie < NFSNUMCOOKIES && - pos >= dp->ndm_eocookie) - return (NULL); - dp = LIST_NEXT(dp, ndm_list); - } else if (add) { - dp2 = malloc(sizeof (struct nfsdmap), - M_NFSDIROFF, M_WAITOK); - dp2->ndm_eocookie = 0; - LIST_INSERT_AFTER(dp, dp2, ndm_list); - dp = dp2; - } else - return (NULL); - } - if (pos >= dp->ndm_eocookie) { - if (add) - dp->ndm_eocookie = pos + 1; - else - return (NULL); - } - return (&dp->ndm4_cookies[pos]); -} - -/* - * Invalidate cached directory information, except for the actual directory - * blocks (which are invalidated separately). - * Done mainly to avoid the use of stale offset cookies. - */ -void -nfs4_invaldir(struct vnode *vp) -{ - struct nfsnode *np = VTONFS(vp); - - np->n_direofoffset = 0; - bzero(np->n4_cookieverf, NFSX_V4VERF); - if (LIST_FIRST(&np->n_cookies)) - LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0; -} diff --git a/sys/nfs4client/nfs4_vnops.c b/sys/nfs4client/nfs4_vnops.c deleted file mode 100644 index af85494a13ea..000000000000 --- a/sys/nfs4client/nfs4_vnops.c +++ /dev/null @@ -1,2931 +0,0 @@ -/* $Id: nfs_vnops.c,v 1.45 2003/11/05 14:59:02 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/* - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_vnops.c 8.16 (Berkeley) 5/27/95 - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * vnode op calls for Sun NFS version 2 and 3 - */ - -#include "opt_inet.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -/* NFSv4 */ -#include -#include - -/* Defs */ -#define TRUE 1 -#define FALSE 0 - -/* - * Ifdef for FreeBSD-current merged buffer cache. It is unfortunate that these - * calls are not in getblk() and brelse() so that they would not be necessary - * here. - */ -#ifndef B_VMIO -#define vfs_busy_pages(bp, f) -#endif - -static int nfs4_flush(struct vnode *, int, struct thread *, - int); -static int nfs4_setattrrpc(struct vnode *, struct vattr *, struct ucred *); -static int nfs4_closerpc(struct vnode *, struct ucred *, int); - -static vop_lookup_t nfs4_lookup; -static vop_create_t nfs4_create; -static vop_mknod_t nfs4_mknod; -static vop_open_t nfs4_open; -static vop_close_t nfs4_close; -static vop_access_t nfs4_access; -static vop_getattr_t nfs4_getattr; -static vop_setattr_t nfs4_setattr; -static vop_read_t nfs4_read; -static vop_fsync_t nfs4_fsync; -static vop_remove_t nfs4_remove; -static vop_link_t nfs4_link; -static vop_rename_t nfs4_rename; -static vop_mkdir_t nfs4_mkdir; -static vop_rmdir_t nfs4_rmdir; -static vop_symlink_t nfs4_symlink; -static vop_readdir_t nfs4_readdir; -static vop_strategy_t nfs4_strategy; -static int nfs4_lookitup(struct vnode *, const char *, int, - struct ucred *, struct thread *, struct nfsnode **); -static int nfs4_sillyrename(struct vnode *, struct vnode *, - struct componentname *); -static vop_readlink_t nfs4_readlink; -static vop_print_t nfs4_print; -static vop_advlock_t nfs4_advlock; -static vop_advlockasync_t nfs4_advlockasync; - -/* - * Global vfs data structures for nfs - */ -struct vop_vector nfs4_vnodeops = { - .vop_default = &default_vnodeops, - .vop_access = nfs4_access, - .vop_advlock = nfs4_advlock, - .vop_advlockasync = nfs4_advlockasync, - .vop_close = nfs4_close, - .vop_create = nfs4_create, - .vop_fsync = nfs4_fsync, - .vop_getattr = nfs4_getattr, - .vop_getpages = nfs_getpages, - .vop_putpages = nfs_putpages, - .vop_inactive = nfs_inactive, - .vop_link = nfs4_link, - .vop_lookup = nfs4_lookup, - .vop_mkdir = nfs4_mkdir, - .vop_mknod = nfs4_mknod, - .vop_open = nfs4_open, - .vop_print = nfs4_print, - .vop_read = nfs4_read, - .vop_readdir = nfs4_readdir, - .vop_readlink = nfs4_readlink, - .vop_reclaim = nfs_reclaim, - .vop_remove = nfs4_remove, - .vop_rename = nfs4_rename, - .vop_rmdir = nfs4_rmdir, - .vop_setattr = nfs4_setattr, - .vop_strategy = nfs4_strategy, - .vop_symlink = nfs4_symlink, - .vop_write = nfs_write, -}; - -static int nfs4_removerpc(struct vnode *dvp, const char *name, int namelen, - struct ucred *cred, struct thread *td); -static int nfs4_renamerpc(struct vnode *fdvp, const char *fnameptr, - int fnamelen, struct vnode *tdvp, - const char *tnameptr, int tnamelen, - struct ucred *cred, struct thread *td); -static int nfs4_renameit(struct vnode *sdvp, struct componentname *scnp, - struct sillyrename *sp); -static int nfs4_openrpc(struct vnode *, struct vnode **, - struct componentname *, int, struct vattr *); -static int nfs4_open_confirm(struct vnode *vp, struct nfs4_compound *cpp, - struct nfs4_oparg_open *openap, - struct nfs4_oparg_getfh *gfh, - struct ucred *cred, struct thread *td); -static int nfs4_createrpc(struct vnode *, struct vnode **, - struct componentname *, nfstype, - struct vattr *, char *); - -/* - * Global variables - */ -struct nfs4_lowner nfs4_masterlowner; - -#define DIRHDSIZ (sizeof (struct dirent) - (MAXNAMLEN + 1)) - -SYSCTL_DECL(_vfs_nfs4); - -static int nfs4_access_cache_timeout = NFS_MAXATTRTIMO; -SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_timeout, CTLFLAG_RW, - &nfs4_access_cache_timeout, 0, "NFS ACCESS cache timeout"); - -#if 0 -static int nfsv3_commit_on_close = 0; -SYSCTL_INT(_vfs_nfs4, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW, - &nfsv3_commit_on_close, 0, "write+commit on close, else only write"); - -SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_hits, CTLFLAG_RD, - &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count"); - -SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_misses, CTLFLAG_RD, - &nfsstats.accesscache_misses, 0, "NFS ACCESS cache miss count"); -#endif - -#define NFSV3ACCESS_ALL (NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY \ - | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE \ - | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP) -static int -nfs4_v3_access_otw(struct vnode *vp, int wmode, struct thread *td, - struct ucred *cred, uint32_t *retmode) -{ - const int v3 = 1; - u_int32_t *tl; - int error = 0, attrflag, i, lrupos; - - return (0); - - struct mbuf *mreq, *mrep = NULL, *md, *mb; - caddr_t bpos, dpos; - u_int32_t rmode; - struct nfsnode *np = VTONFS(vp); - - nfsstats.rpccnt[NFSPROC_ACCESS]++; - mreq = nfsm_reqhead(vp, NFSPROC_ACCESS, NFSX_FH(v3) + NFSX_UNSIGNED); - mb = mreq; - bpos = mtod(mb, caddr_t); - nfsm_fhtom(vp, v3); - tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED); - *tl = txdr_unsigned(wmode); - nfsm_request(vp, NFSPROC_ACCESS, td, cred); - nfsm_postop_attr(vp, attrflag); - if (!error) { - lrupos = 0; - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - rmode = fxdr_unsigned(u_int32_t, *tl); - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { - if (np->n_accesscache[i].uid == cred->cr_uid) { - np->n_accesscache[i].mode = rmode; - np->n_accesscache[i].stamp = time_second; - break; - } - if (i > 0 && np->n_accesscache[i].stamp < - np->n_accesscache[lrupos].stamp) - lrupos = i; - } - if (i == NFS_ACCESSCACHESIZE) { - np->n_accesscache[lrupos].uid = cred->cr_uid; - np->n_accesscache[lrupos].mode = rmode; - np->n_accesscache[lrupos].stamp = time_second; - } - if (retmode != NULL) - *retmode = rmode; - } - m_freem(mrep); -nfsmout: - return error; -} - -/* - * nfs access vnode op. - * For nfs version 2, just return ok. File accesses may fail later. - * For nfs version 3, use the access rpc to check accessibility. If file modes - * are changed on the server, accesses might still fail later. - */ -static int -nfs4_access(struct vop_access_args *ap) -{ - struct vnode *vp = ap->a_vp; - int error = 0, i, gotahit; - u_int32_t mode, rmode, wmode; - int v3 = NFS_ISV3(vp); /* v3 \in v4 */ - struct nfsnode *np = VTONFS(vp); - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - struct nfs4_oparg_access acc; - struct thread *td = ap->a_td; - struct ucred *cred = ap->a_cred; - - /* - * Disallow write attempts on filesystems mounted read-only; - * unless the file is a socket, fifo, or a block or character - * device resident on the filesystem. - */ - if ((ap->a_accmode & VWRITE) && (vp->v_mount->mnt_flag & MNT_RDONLY)) { - switch (vp->v_type) { - case VREG: - case VDIR: - case VLNK: - return (EROFS); - default: - break; - } - } - /* - * For nfs v3, check to see if we have done this recently, and if - * so return our cached result instead of making an ACCESS call. - * If not, do an access rpc, otherwise you are stuck emulating - * ufs_access() locally using the vattr. This may not be correct, - * since the server may apply other access criteria such as - * client uid-->server uid mapping that we do not know about. - */ - /* XXX Disable this for now; needs fixing of _access_otw() */ - if (0 && v3) { - if (ap->a_accmode & VREAD) - mode = NFSV3ACCESS_READ; - else - mode = 0; - if (vp->v_type != VDIR) { - if (ap->a_accmode & VWRITE) - mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND); - if (ap->a_accmode & VEXEC) - mode |= NFSV3ACCESS_EXECUTE; - } else { - if (ap->a_accmode & VWRITE) - mode |= (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND | - NFSV3ACCESS_DELETE); - if (ap->a_accmode & VEXEC) - mode |= NFSV3ACCESS_LOOKUP; - } - /* XXX safety belt, only make blanket request if caching */ - if (nfs4_access_cache_timeout > 0) { - wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY | - NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE | - NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP; - } else { - wmode = mode; - } - - /* - * Does our cached result allow us to give a definite yes to - * this request? - */ - gotahit = 0; - for (i = 0; i < NFS_ACCESSCACHESIZE; i++) { - if (ap->a_cred->cr_uid == np->n_accesscache[i].uid) { - if (time_second < (np->n_accesscache[i].stamp + - nfs4_access_cache_timeout) && - (np->n_accesscache[i].mode & mode) == mode) { - nfsstats.accesscache_hits++; - gotahit = 1; - } - break; - } - } - if (gotahit == 0) { - /* - * Either a no, or a don't know. Go to the wire. - */ - nfsstats.accesscache_misses++; - error = nfs4_v3_access_otw(vp, wmode, ap->a_td, - ap->a_cred, &rmode); - if (error == 0) { - if ((rmode & mode) != mode) - error = EACCES; - } - } - return (error); - } - - /* XXX use generic access code here? */ - mode = ap->a_accmode & VREAD ? NFSV4ACCESS_READ : 0; - if (vp->v_type == VDIR) { - if (ap->a_accmode & VWRITE) - mode |= NFSV4ACCESS_MODIFY | NFSV4ACCESS_EXTEND | NFSV4ACCESS_DELETE; - if (ap->a_accmode & VEXEC) - mode |= NFSV4ACCESS_LOOKUP; - } else { - if (ap->a_accmode & VWRITE) - mode |= NFSV4ACCESS_MODIFY | NFSV4ACCESS_EXTEND; - if (ap->a_accmode & VEXEC) - mode |= NFSV4ACCESS_EXECUTE; - } - - nfs_v4initcompound(&cp); - acc.mode = mode; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_access()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_access(&cp, &acc); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_access(&cp, &acc); - - if ((acc.rmode & mode) != mode) - error = EACCES; - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -static int -nfs4_openrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, - int flags, struct vattr *vap) -{ - struct vnode *vp = *vpp; - struct nfs4_oparg_getattr getattr; - struct nfs4_oparg_getfh getfh; - struct nfs4_oparg_open opena; - struct nfs4_compound cp; - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct ucred *cred = cnp->cn_cred; - struct thread *td = cnp->cn_thread; - struct nfs4_fctx xfc, *fcp; - struct nfsnode *np; - - if (vp == NULL) { - /* Create a new file */ - np = NULL; - fcp = &xfc; - bzero(fcp, sizeof(*fcp)); - } else { - np = VTONFS(vp); - fcp = flags & FWRITE ? &np->n_wfc : &np->n_rfc; - } - - /* - * Since we are currently only one lockowner; we only open the - * file once each for reading and writing. - */ - if (fcp->refcnt++ != 0) { - *vpp = vp; - /*printf("not opening %s\n", np->n_name != NULL ? np->n_name : "");*/ - return (0); - } - - fcp->lop = &nfs4_masterlowner; - fcp->np = np; - - nfs_v4initcompound(&cp); - cp.nmp = VFSTONFS(dvp->v_mount); - - opena.ctype = NCLNULL; - opena.flags = flags; - opena.vap = vap; - opena.fcp = fcp; /* For lockowner */ - opena.cnp = cnp; - - getattr.bm = &nfsv4_getattrbm; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_openrpc()"); - nfsm_v4build_putfh(&cp, dvp); - nfsm_v4build_open(&cp, &opena); - nfsm_v4build_getattr(&cp, &getattr); - nfsm_v4build_getfh(&cp, &getfh); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp != NULL ? vp : dvp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_open(&cp, &opena); - nfsm_v4dissect_getattr(&cp, &getattr); - nfsm_v4dissect_getfh(&cp, &getfh); - - error = nfs_v4postop(&cp, error); - - if (opena.rflags & NFSV4OPENRES_CONFIRM) { - error = nfs4_open_confirm(vp ? vp : dvp, &cp, &opena, &getfh, cred, td); - if (error != 0) - goto nfsmout; - } - - if (vp == NULL) { - /* New file */ - error = nfs_nget(dvp->v_mount, &getfh.fh_val, - getfh.fh_len, &np, LK_EXCLUSIVE); - if (error != 0) - goto nfsmout; - - vp = NFSTOV(np); - np->n_dvp = dvp; - np->n_namelen = cnp->cn_namelen; /* XXX memory leaks on these; track! */ - if (np->n_name != NULL) - free(np->n_name, M_NFSREQ); - np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK); - bcopy(cnp->cn_nameptr, np->n_name, np->n_namelen); - np->n_name[np->n_namelen] = '\0'; - if (flags & FWRITE) - np->n_wfc = *fcp; - else - np->n_rfc = *fcp; - - /*printf("opened new file %s\n", np->n_name);*/ - - nfs4_vnop_loadattrcache(vp, &getattr.fa, NULL); - *vpp = vp; - } else { - /*printf("openend \"old\" %s\n", np->n_name != NULL ? np->n_name : "");*/ - - if (flags & O_TRUNC && np->n_size != 0) { - struct vattr va; - - VATTR_NULL(&va); - va.va_size = 0; - error = nfs4_setattrrpc(vp, &va, cnp->cn_cred); - } - np->n_attrstamp = 0; - } - - nfsmout: - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -static int -nfs4_open_confirm(struct vnode *vp, struct nfs4_compound *cpp, - struct nfs4_oparg_open *openap, struct nfs4_oparg_getfh *gfh, - struct ucred *cred, struct thread *td) -{ - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - - nfs_v4initcompound(cpp); - cpp->nmp = VFSTONFS(vp->v_mount); - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(cpp, "nfs4_open_confirm()"); - nfsm_v4build_putfh_nv(cpp, gfh); - nfsm_v4build_open_confirm(cpp, openap); - nfsm_v4build_finalize(cpp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(cpp); - nfsm_v4dissect_putfh(cpp); - nfsm_v4dissect_open_confirm(cpp, openap); - - nfsmout: - error = nfs_v4postop(cpp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - - -/* - * nfs open vnode op - * Check to see if the type is ok - * and that deletion is not in progress. - * For paged in text files, you will need to flush the page cache - * if consistency is lost. - */ -/* ARGSUSED */ -static int -nfs4_open(struct vop_open_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - enum vtype vtype = vp->v_type; - int mode = ap->a_mode; - struct componentname cn; - - if (vtype != VREG) { - if (vtype != VDIR && vtype != VLNK) { -#ifdef DIAGNOSTIC - printf("open eacces vtyp=%d\n", vp->v_type); -#endif - return (EACCES); - } else - return (0); - } - - if (np->n_flag & NCREATED) { - np->n_flag &= ~NCREATED; - return (0); - } - - cn.cn_nameptr = np->n_name; - cn.cn_namelen = np->n_namelen; - cn.cn_cred = ap->a_cred; - cn.cn_thread = ap->a_td; - - return (nfs4_openrpc(np->n_dvp, &vp, &cn, mode, NULL)); -} - -static int -nfs4_closerpc(struct vnode *vp, struct ucred *cred, int flags) -{ - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct thread *td; - struct nfs4_fctx *fcp; - struct nfs4_compound cp; - struct nfsnode *np = VTONFS(vp); - - td = curthread; - fcp = flags & FWRITE ? &np->n_wfc : &np->n_rfc; - - nfs_v4initcompound(&cp); - - if (--fcp->refcnt != 0) - return (0); - - /*printf("closing %s\n", np->n_name != NULL ? np->n_name : "");*/ - - cp.fcp = fcp; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_closerpc()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_close(&cp, fcp); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_close(&cp, fcp); - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -/* - * nfs close vnode op - * play it safe for now (see comments in v2/v3 nfs_close regarding dirty buffers) - */ -/* ARGSUSED */ -static int -nfs4_close(struct vop_close_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - int error = 0; - - if (vp->v_type != VREG) - return (0); - - if (np->n_flag & NMODIFIED) { - error = nfs_vinvalbuf(vp, V_SAVE, ap->a_td, 1); - np->n_attrstamp = 0; - } - - error = nfs4_closerpc(vp, ap->a_cred, ap->a_fflag); - - if (!error && np->n_flag & NWRITEERR) { - np->n_flag &= ~NWRITEERR; - error = np->n_error; - } - return (error); -} - -/* - * nfs getattr call from vfs. - */ -static int -nfs4_getattr(struct vop_getattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_oparg_getattr ga; - struct nfs4_compound cp; - - /* - * Update local times for special files. - */ - if (np->n_flag & (NACC | NUPD)) - np->n_flag |= NCHG; - /* - * First look in the cache. - */ - if (nfs_getattrcache(vp, ap->a_vap) == 0) - return (0); - - nfsstats.rpccnt[NFSPROC_GETATTR]++; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, NFSX_FH(1)); - mb = mreq; - bpos = mtod(mb, caddr_t); - - ga.bm = &nfsv4_getattrbm; - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_getattr()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, curthread, ap->a_cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_getattr(&cp, &ga); - - nfs4_vnop_loadattrcache(vp, &ga.fa, ap->a_vap); - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - return (error); -} - -/* - * nfs setattr call. - */ -static int -nfs4_setattr(struct vop_setattr_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct vattr *vap = ap->a_vap; - struct thread *td = curthread; - int error = 0; - u_quad_t tsize; - -#ifndef nolint - tsize = (u_quad_t)0; -#endif - - /* - * Setting of flags is not supported. - */ - if (vap->va_flags != VNOVAL) - return (EOPNOTSUPP); - - /* - * Disallow write attempts if the filesystem is mounted read-only. - */ - if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL || - vap->va_gid != (gid_t)VNOVAL || vap->va_atime.tv_sec != VNOVAL || - vap->va_mtime.tv_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) && - (vp->v_mount->mnt_flag & MNT_RDONLY)) - return (EROFS); - if (vap->va_size != VNOVAL) { - switch (vp->v_type) { - case VDIR: - return (EISDIR); - case VCHR: - case VBLK: - case VSOCK: - case VFIFO: - if (vap->va_mtime.tv_sec == VNOVAL && - vap->va_atime.tv_sec == VNOVAL && - vap->va_mode == (mode_t)VNOVAL && - vap->va_uid == (uid_t)VNOVAL && - vap->va_gid == (gid_t)VNOVAL) - return (0); - vap->va_size = VNOVAL; - break; - default: - /* - * Disallow write attempts if the filesystem is - * mounted read-only. - */ - if (vp->v_mount->mnt_flag & MNT_RDONLY) - return (EROFS); - - /* - * We run vnode_pager_setsize() early (why?), - * we must set np->n_size now to avoid vinvalbuf - * V_SAVE races that might setsize a lower - * value. - */ - - tsize = np->n_size; - error = nfs_meta_setsize(vp, ap->a_cred, td, - vap->va_size); - - if (np->n_flag & NMODIFIED) { - if (vap->va_size == 0) - error = nfs_vinvalbuf(vp, 0, td, 1); - else - error = nfs_vinvalbuf(vp, V_SAVE, td, 1); - if (error) { - vnode_pager_setsize(vp, np->n_size); - return (error); - } - } - /* - * np->n_size has already been set to vap->va_size - * in nfs_meta_setsize(). We must set it again since - * nfs_loadattrcache() could be called through - * nfs_meta_setsize() and could modify np->n_size. - */ - np->n_vattr.va_size = np->n_size = vap->va_size; - }; - } else if ((vap->va_mtime.tv_sec != VNOVAL || - vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) && - vp->v_type == VREG && - (error = nfs_vinvalbuf(vp, V_SAVE, td, 1)) == EINTR) - return (error); - - if (vap->va_size != VNOVAL && np->n_wfc.refcnt == 0) { - /* Have to open the file before we can truncate it */ - struct componentname cn; - - cn.cn_nameptr = np->n_name; - cn.cn_namelen = np->n_namelen; - cn.cn_cred = ap->a_cred; - cn.cn_thread = td; - error = nfs4_openrpc(np->n_dvp, &vp, &cn, FWRITE, NULL); - if (error) - return error; - np->n_flag |= NTRUNCATE; - } - - error = nfs4_setattrrpc(vp, vap, ap->a_cred); - if (error && vap->va_size != VNOVAL) { - np->n_size = np->n_vattr.va_size = tsize; - vnode_pager_setsize(vp, np->n_size); - } - return (error); -} - -/* - * Do an nfs setattr rpc. - */ -static int -nfs4_setattrrpc(struct vnode *vp, struct vattr *vap, struct ucred *cred) -{ - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct thread *td; - struct nfs4_compound cp; - struct nfs4_oparg_getattr ga; - struct nfsnode *np = VTONFS(vp); - struct nfs4_fctx *fcp; - - td = curthread; - nfsstats.rpccnt[NFSPROC_SETATTR]++; - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - ga.bm = &nfsv4_getattrbm; - fcp = (vap->va_size != VNOVAL) ? &np->n_wfc : NULL; - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_setattrrpc"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_setattr(&cp, vap, fcp); - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_setattr(&cp); - nfsm_v4dissect_getattr(&cp, &ga); - - nfs4_vnop_loadattrcache(vp, &ga.fa, NULL); - - /* TODO: do the settatr and close in a single compound rpc */ - if (np->n_flag & NTRUNCATE) { - error = nfs4_closerpc(vp, cred, FWRITE); - np->n_flag &= ~NTRUNCATE; - } - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -/* - * nfs lookup call, one step at a time... - * First look in cache - * If not found, unlock the directory nfsnode and do the rpc - */ -static int -nfs4_lookup(struct vop_lookup_args *ap) -{ - struct componentname *cnp = ap->a_cnp; - struct vnode *dvp = ap->a_dvp; - struct vnode **vpp = ap->a_vpp; - int isdot, flags = cnp->cn_flags; - struct vnode *newvp; - struct nfsmount *nmp; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - long len; - nfsfh_t *fhp; - struct nfsnode *np; - int error = 0, fhsize; - struct thread *td = cnp->cn_thread; - struct nfs4_compound cp; - struct nfs4_oparg_getattr ga, dga; - struct nfs4_oparg_lookup l; - struct nfs4_oparg_getfh gfh; - - *vpp = NULLVP; - if ((flags & ISLASTCN) && (dvp->v_mount->mnt_flag & MNT_RDONLY) && - (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) - return (EROFS); - if (dvp->v_type != VDIR) - return (ENOTDIR); - nmp = VFSTONFS(dvp->v_mount); - np = VTONFS(dvp); - - isdot = cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.'; - - if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0) { - *vpp = NULLVP; - return (error); - } - if ((error = cache_lookup(dvp, vpp, cnp)) && error != ENOENT) { - struct vattr vattr; - - newvp = *vpp; - if (!VOP_GETATTR(newvp, &vattr, cnp->cn_cred) - && vattr.va_ctime.tv_sec == VTONFS(newvp)->n_ctime) { - nfsstats.lookupcache_hits++; - if (cnp->cn_nameiop != LOOKUP && - (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - return (0); - } - cache_purge(newvp); - if (newvp != dvp) - vput(newvp); - else - vrele(newvp); - } - - error = 0; - newvp = NULLVP; - nfsstats.lookupcache_misses++; - nfsstats.rpccnt[NFSPROC_LOOKUP]++; - - len = cnp->cn_namelen; - mreq = nfsm_reqhead(NULL, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - ga.bm = &nfsv4_getattrbm; - dga.bm = &nfsv4_getattrbm; - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_lookup()"); - nfsm_v4build_putfh(&cp, dvp); - nfsm_v4build_getattr(&cp, &dga); - if (flags & ISDOTDOT) - nfsm_v4build_lookupp(&cp); - else if (!isdot) { - l.name = cnp->cn_nameptr; - l.namelen = len; - nfsm_v4build_lookup(&cp, &l); - } - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_getfh(&cp, &gfh); - nfsm_v4build_finalize(&cp); - - nfsm_request(dvp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_getattr(&cp, &dga); - if (flags & ISDOTDOT) - nfsm_v4dissect_lookupp(&cp); - else if (!isdot) - nfsm_v4dissect_lookup(&cp); - nfsm_v4dissect_getattr(&cp, &ga); - nfsm_v4dissect_getfh(&cp, &gfh); - - nfs4_vnop_loadattrcache(dvp, &dga.fa, NULL); - fhp = &gfh.fh_val; - fhsize = gfh.fh_len; - - /* - * Handle RENAME case... - */ - if (cnp->cn_nameiop == RENAME && (flags & ISLASTCN)) { - if (NFS_CMPFH(np, fhp, fhsize)) - return (EISDIR); - - error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE); - if (error) - return (error); - - newvp = NFSTOV(np); - - nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL); - - *vpp = newvp; - cnp->cn_flags |= SAVENAME; - return (0); - } - - if (flags & ISDOTDOT) { - VOP_UNLOCK(dvp, 0); - - error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE); - vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY); - if (error) - return (error); - newvp = NFSTOV(np); - - nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL); - } else if (NFS_CMPFH(np, fhp, fhsize)) { - VREF(dvp); - newvp = dvp; - } else { - error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE); - if (error) - return (error); - newvp = NFSTOV(np); - - /* Fill in np used by open. */ - np->n_dvp = dvp; - np->n_namelen = cnp->cn_namelen; - if (np->n_name != NULL) - free(np->n_name, M_NFSREQ); - np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK); - bcopy(cnp->cn_nameptr, np->n_name, np->n_namelen); - np->n_name[np->n_namelen] = '\0'; - - nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL); - } - - if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - if ((cnp->cn_flags & MAKEENTRY) && - (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN))) { - np->n_ctime = np->n_vattr.va_ctime.tv_sec; - cache_enter(dvp, newvp, cnp); - } - *vpp = newvp; - m_freem(mrep); -nfsmout: - error = nfs_v4postop(&cp, error); - - if (error) { - if (newvp != NULLVP) { - vrele(newvp); - *vpp = NULLVP; - } - if ((cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME) && - (flags & ISLASTCN) && error == ENOENT) { - if (dvp->v_mount->mnt_flag & MNT_RDONLY) - error = EROFS; - else - error = EJUSTRETURN; - } - if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN)) - cnp->cn_flags |= SAVENAME; - } - - return (error); -} - -/* - * nfs read call. - * Just call nfs_bioread() to do the work. - */ -static int -nfs4_read(struct vop_read_args *ap) -{ - struct vnode *vp = ap->a_vp; - - switch (vp->v_type) { - case VREG: - return (nfs_bioread(vp, ap->a_uio, ap->a_ioflag, ap->a_cred)); - case VDIR: - return (EISDIR); - default: - return (EOPNOTSUPP); - } -} - -/* - * nfs readlink call - */ -static int -nfs4_readlink(struct vop_readlink_args *ap) -{ - struct vnode *vp = ap->a_vp; - - if (vp->v_type != VLNK) - return (EINVAL); - return (nfs_bioread(vp, ap->a_uio, 0, ap->a_cred)); -} - -/* - * Do a readlink rpc. - * Called by nfs_doio() from below the buffer cache. - */ -int -nfs4_readlinkrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - - nfsstats.rpccnt[NFSPROC_READLINK]++; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_readlinkrpc()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_readlink(&cp); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_readlink(&cp, uiop); - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - return (error); -} - -/* - * nfs read rpc call - * Ditto above - */ -int -nfs4_readrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfsmount *nmp; - int error = 0, len, tsiz; - struct nfs4_compound cp; - struct nfs4_oparg_read read; - struct nfsnode *np = VTONFS(vp); - - nmp = VFSTONFS(vp->v_mount); - tsiz = uiop->uio_resid; - if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) - return (EFBIG); - - if (tsiz == 0) - return (0); - - read.uiop = uiop; - read.fcp = np->n_rfc.refcnt > 0 ? &np->n_rfc : &np->n_wfc; - - while (tsiz > 0) { - nfsstats.rpccnt[NFSPROC_READ]++; - len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz; - - read.off = uiop->uio_offset; - read.maxcnt = len; - nfs_v4initcompound(&cp); - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_readrpc()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_read(&cp, &read); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred); - if (error != 0) { - error = nfs_v4postop(&cp, error); - goto nfsmout; - } - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_read(&cp, &read); - - if (read.eof || read.retlen == 0) - tsiz = 0; - else - tsiz -= read.retlen; - - error = nfs_v4postop(&cp, error); - - m_freem(mrep); - mrep = NULL; - } -nfsmout: - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -/* - * nfs write call - */ -int -nfs4_writerpc(struct vnode *vp, struct uio *uiop, struct ucred *cred, - int *iomode, int *must_commit) -{ - int32_t backup; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - int error = 0, len, tsiz, wccflag = 1, rlen; - struct nfs4_compound cp; - struct nfs4_oparg_write write; - nfsv4stablehow commit, committed = NSHFILESYNC; - caddr_t verf; - struct nfsnode *np = VTONFS(vp); - -#ifndef DIAGNOSTIC - if (uiop->uio_iovcnt != 1) - panic("nfs: writerpc iovcnt > 1"); -#endif - *must_commit = 0; - tsiz = uiop->uio_resid; - if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize) - return (EFBIG); - - if (tsiz == 0) - return (0); - - write.stable = (nfsv4stablehow)*iomode; - write.uiop = uiop; - write.fcp = &np->n_wfc; - - while (tsiz > 0) { - nfsstats.rpccnt[NFSPROC_WRITE]++; - len = (tsiz > nmp->nm_wsize) ? nmp->nm_wsize : tsiz; - - write.off = uiop->uio_offset; - write.cnt = len; - nfs_v4initcompound(&cp); - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_writerpc()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_write(&cp, &write); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred); - if (error != 0) { - error = nfs_v4postop(&cp, error); - goto nfsmout; - } - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_write(&cp, &write); - - rlen = write.retlen; - if (rlen == 0) { - error = NFSERR_IO; - break; - } else if (rlen < len) { - backup = len - rlen; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base - backup; - uiop->uio_iov->iov_len += backup; - uiop->uio_offset -= backup; - uiop->uio_resid += backup; - len = rlen; - } - - commit = write.committed; - - if (committed == NSHFILESYNC || - (committed = NSHDATASYNC && commit == NSHUNSTABLE)) - committed = commit; - - verf = (caddr_t)write.wverf; - - if ((nmp->nm_flag & NFSSTA_HASWRITEVERF) == 0) { - bcopy(verf, nmp->nm_verf, NFSX_V4VERF); - nmp->nm_flag |= NFSMNT_HASWRITEVERF; - } else if (bcmp(verf, nmp->nm_verf, NFSX_V4VERF)) { - *must_commit = 1; - bcopy(verf, nmp->nm_verf, NFSX_V4VERF); - } - - /* XXX wccflag */ - if (wccflag) - VTONFS(vp)->n_mtime = VTONFS(vp)->n_vattr.va_mtime; - - error = nfs_v4postop(&cp, error); - - m_freem(mrep); - mrep = NULL; - if (error) - break; - tsiz -= len; - } -nfsmout: - if (mrep != NULL) - m_freem(mrep); - *iomode = committed; - if (error) - uiop->uio_resid = tsiz; - return (error); -} - -/* ARGSUSED */ -static int -nfs4_mknod(struct vop_mknod_args *ap) -{ - struct vattr *vap = ap->a_vap; - struct vnode *newvp = NULL; - int error; - - error = nfs4_createrpc(ap->a_dvp, &newvp, - ap->a_cnp, (nfstype)vap->va_type, vap, NULL); - - /* XXX - is this actually referenced here? */ - if (error == 0) { - *ap->a_vpp = newvp; - vrele(newvp); - } - - return (error); -} - -static int -nfs4_createrpc(struct vnode *dvp, struct vnode **vpp, struct componentname *cnp, - nfstype ftype, struct vattr *vap, char *linktarget) -{ - struct nfsnode *dnp = VTONFS(dvp); - struct nfsnode *np = NULL; - struct vnode *newvp = NULL; - struct nfs4_compound cp; - struct nfs4_oparg_create c; - struct nfs4_oparg_getattr ga; - struct nfs4_oparg_getfh gfh; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - int error = 0; - - nfsstats.rpccnt[NFSPROC_CREATE]++; - - mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - bzero(&c, sizeof(c)); - bzero(&ga, sizeof(ga)); - - c.type = ftype; - c.vap = vap; - c.linktext = linktarget; - c.name = cnp->cn_nameptr; - c.namelen = cnp->cn_namelen; - - ga.bm = &nfsv4_getattrbm; - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_createrpc()"); - nfsm_v4build_putfh(&cp, dvp); - nfsm_v4build_create(&cp, &c); - nfsm_v4build_getattr(&cp, &ga); - nfsm_v4build_getfh(&cp, &gfh); - nfsm_v4build_finalize(&cp); - - nfsm_request(dvp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_create(&cp, &c); - nfsm_v4dissect_getattr(&cp, &ga); - nfsm_v4dissect_getfh(&cp, &gfh); - - error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np, LK_EXCLUSIVE); - if (error != 0) - goto nfsmout; - - newvp = NFSTOV(np); - nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL); - - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, newvp, cnp); - - dnp->n_flag |= NMODIFIED; - dnp->n_attrstamp = 0; - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - /* XXX */ - /*free(cnp->cn_pnbuf, M_NAMEI);*/ - if (error != 0 && newvp != NULL) - vput(newvp); - else if (error == 0) - *vpp = newvp; - - return (error); -} - -static int -nfs4_renamerpc(struct vnode *fdvp, const char *fnameptr, int fnamelen, - struct vnode *tdvp, const char *tnameptr, int tnamelen, - struct ucred *cred, struct thread *td) -{ - - struct nfsnode *fnp = VTONFS(fdvp), *tnp = VTONFS(tdvp); - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - struct nfs4_oparg_rename r; - int error = 0; - - nfsstats.rpccnt[NFSPROC_RENAME]++; - - r.fname = fnameptr; - r.fnamelen = fnamelen; - r.tname = tnameptr; - r.tnamelen = tnamelen; - nfs_v4initcompound(&cp); - - mreq = nfsm_reqhead(fdvp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_renamerpc()"); - nfsm_v4build_putfh(&cp, fdvp); - nfsm_v4build_savefh(&cp); - nfsm_v4build_putfh(&cp, tdvp); - nfsm_v4build_rename(&cp, &r); - nfsm_v4build_finalize(&cp); - - nfsm_request(fdvp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_savefh(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_rename(&cp); - - /* XXX should this always be performed? */ - fnp->n_flag |= NMODIFIED; - tnp->n_flag |= NMODIFIED; - fnp->n_attrstamp = tnp->n_attrstamp = 0; - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -/* - * nfs file create call - */ -static int -nfs4_create(struct vop_create_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - struct vattr *vap = ap->a_vap; - struct nfsnode *dnp = VTONFS(dvp); - struct componentname *cnp = ap->a_cnp; - struct vnode *newvp = NULL; - int error = 0, fmode = (O_CREAT | FREAD | FWRITE); - struct vattr vattr; - - if ((error = VOP_GETATTR(dvp, &vattr, cnp->cn_cred)) != 0) - return (error); - - if (vap->va_vaflags & VA_EXCLUSIVE) - fmode |= O_EXCL; - - error = nfs4_openrpc(dvp, &newvp, cnp, fmode, vap); - if (error != 0) - goto out; - - VTONFS(newvp)->n_flag |= NCREATED; - - if (cnp->cn_flags & MAKEENTRY) - cache_enter(dvp, newvp, cnp); - - *ap->a_vpp = newvp; - - dnp->n_flag |= NMODIFIED; - dnp->n_attrstamp = 0; /* XXX; wccflag */ - - out: - return (error); -} - -/* - * nfs file remove call - * To try and make nfs semantics closer to ufs semantics, a file that has - * other processes using the vnode is renamed instead of removed and then - * removed later on the last close. - * - If v_usecount > 1 - * If a rename is not already in the works - * call nfs4_sillyrename() to set it up - * else - * do the remove rpc - */ -static int -nfs4_remove(struct vop_remove_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct componentname *cnp = ap->a_cnp; - struct nfsnode *np = VTONFS(vp); - int error = 0; - struct vattr vattr; - -#ifndef DIAGNOSTIC - if ((cnp->cn_flags & HASBUF) == 0) - panic("nfs4_remove: no name"); - if (vrefcnt(vp) < 1) - panic("nfs4_remove: bad v_usecount"); -#endif - if (vp->v_type == VDIR) - error = EPERM; - else if (vrefcnt(vp) == 1 || (np->n_sillyrename && - !VOP_GETATTR(vp, &vattr, cnp->cn_cred) && vattr.va_nlink > 1)) { - /* - * Purge the name cache so that the chance of a lookup for - * the name succeeding while the remove is in progress is - * minimized. Without node locking it can still happen, such - * that an I/O op returns ESTALE, but since you get this if - * another host removes the file.. - */ - cache_purge(vp); - /* - * throw away biocache buffers, mainly to avoid - * unnecessary delayed writes later. - */ - error = nfs_vinvalbuf(vp, 0, cnp->cn_thread, 1); - /* Do the rpc */ - if (error != EINTR) - error = nfs4_removerpc(dvp, cnp->cn_nameptr, - cnp->cn_namelen, cnp->cn_cred, cnp->cn_thread); - /* - * Kludge City: If the first reply to the remove rpc is lost.. - * the reply to the retransmitted request will be ENOENT - * since the file was in fact removed - * Therefore, we cheat and return success. - */ - if (error == ENOENT) - error = 0; - } else if (!np->n_sillyrename) - error = nfs4_sillyrename(dvp, vp, cnp); - np->n_attrstamp = 0; - return (error); -} - -/* - * nfs file remove rpc called from nfs_inactive - */ -int -nfs4_removeit(struct sillyrename *sp) -{ - /* - * Make sure that the directory vnode is still valid. - * XXX we should lock sp->s_dvp here. - */ - if (sp->s_dvp->v_type == VBAD) - return (0); - return (nfs4_removerpc(sp->s_dvp, sp->s_name, sp->s_namlen, sp->s_cred, - NULL)); -} - -/* - * Nfs remove rpc, called from nfs4_remove() and nfs4_removeit(). - */ -static int -nfs4_removerpc(struct vnode *dvp, const char *name, int namelen, - struct ucred *cred, struct thread *td) -{ - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - - nfsstats.rpccnt[NFSPROC_REMOVE]++; - - mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_removerpc()"); - nfsm_v4build_putfh(&cp, dvp); - nfsm_v4build_remove(&cp, name, namelen); - nfsm_v4build_finalize(&cp); - - nfsm_request(dvp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_remove(&cp); - - nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - VTONFS(dvp)->n_flag |= NMODIFIED; - VTONFS(dvp)->n_attrstamp = 0; /* XXX wccflag */ - - return (error); -} - -/* - * nfs file rename call - */ -static int -nfs4_rename(struct vop_rename_args *ap) -{ - struct vnode *fvp = ap->a_fvp; - struct vnode *tvp = ap->a_tvp; - struct vnode *fdvp = ap->a_fdvp; - struct vnode *tdvp = ap->a_tdvp; - struct componentname *tcnp = ap->a_tcnp; - struct componentname *fcnp = ap->a_fcnp; - int error; - - #ifndef DIAGNOSTIC - if ((tcnp->cn_flags & HASBUF) == 0 || - (fcnp->cn_flags & HASBUF) == 0) - panic("nfs4_rename: no name"); -#endif - /* Check for cross-device rename */ - if ((fvp->v_mount != tdvp->v_mount) || - (tvp && (fvp->v_mount != tvp->v_mount))) { - error = EXDEV; - goto out; - } - - if (fvp == tvp) { - printf("nfs4_rename: fvp == tvp (can't happen)\n"); - error = 0; - goto out; - } - if ((error = vn_lock(fvp, LK_EXCLUSIVE)) != 0) - goto out; - - /* - * We have to flush B_DELWRI data prior to renaming - * the file. If we don't, the delayed-write buffers - * can be flushed out later after the file has gone stale - * under NFSV3. NFSV2 does not have this problem because - * ( as far as I can tell ) it flushes dirty buffers more - * often. - */ - VOP_FSYNC(fvp, MNT_WAIT, fcnp->cn_thread); - VOP_UNLOCK(fvp, 0); - if (tvp) - VOP_FSYNC(tvp, MNT_WAIT, tcnp->cn_thread); - - /* - * If the tvp exists and is in use, sillyrename it before doing the - * rename of the new file over it. - * XXX Can't sillyrename a directory. - */ - if (tvp && vrefcnt(tvp) > 1 && !VTONFS(tvp)->n_sillyrename && - tvp->v_type != VDIR && !nfs4_sillyrename(tdvp, tvp, tcnp)) { - vput(tvp); - tvp = NULL; - } - - error = nfs4_renamerpc(fdvp, fcnp->cn_nameptr, fcnp->cn_namelen, - tdvp, tcnp->cn_nameptr, tcnp->cn_namelen, tcnp->cn_cred, - tcnp->cn_thread); - - if (fvp->v_type == VDIR) { - if (tvp != NULL && tvp->v_type == VDIR) - cache_purge(tdvp); - cache_purge(fdvp); - } - -out: - if (tdvp == tvp) - vrele(tdvp); - else - vput(tdvp); - if (tvp) - vput(tvp); - vrele(fdvp); - vrele(fvp); - /* - * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry. - */ - if (error == ENOENT) - error = 0; - return (error); -} - -/* - * nfs file rename rpc called from nfs4_remove() above - */ -static int -nfs4_renameit(struct vnode *sdvp, struct componentname *scnp, - struct sillyrename *sp) -{ - return (nfs4_renamerpc(sdvp, scnp->cn_nameptr, scnp->cn_namelen, sdvp, - sp->s_name, sp->s_namlen, scnp->cn_cred, scnp->cn_thread)); -} - -/* - * nfs hard link create call - */ -static int -nfs4_link(struct vop_link_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *tdvp = ap->a_tdvp; - struct componentname *cnp = ap->a_cnp; - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - struct nfs4_oparg_link l; - - if (vp->v_mount != tdvp->v_mount) { - return (EXDEV); - } - - /* - * Push all writes to the server, so that the attribute cache - * doesn't get "out of sync" with the server. - * XXX There should be a better way! - */ - VOP_FSYNC(vp, MNT_WAIT, cnp->cn_thread); - - nfsstats.rpccnt[NFSPROC_LINK]++; - - l.name = cnp->cn_nameptr; - l.namelen = cnp->cn_namelen; - nfs_v4initcompound(&cp); - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - nfsm_v4build_compound(&cp, "nfs4_link()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_savefh(&cp); - nfsm_v4build_putfh(&cp, tdvp); - nfsm_v4build_link(&cp, &l); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, cnp->cn_thread, cnp->cn_cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_savefh(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_link(&cp); - - VTONFS(tdvp)->n_flag |= NMODIFIED; - VTONFS(vp)->n_attrstamp = 0; - VTONFS(tdvp)->n_attrstamp = 0; - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - - return (error); -} - -/* - * nfs symbolic link create call - */ -static int -nfs4_symlink(struct vop_symlink_args *ap) -{ - struct vnode *dvp = ap->a_dvp; - int error = 0; - struct vnode *newvp = NULL; - - nfsstats.rpccnt[NFSPROC_SYMLINK]++; - - error = nfs4_createrpc(ap->a_dvp, &newvp, ap->a_cnp, NFLNK, - ap->a_vap, ap->a_target); - - if (error != 0 && newvp != NULL) - vput(newvp); - else if (error == 0) - *ap->a_vpp = newvp; - - VTONFS(dvp)->n_flag |= NMODIFIED; - VTONFS(dvp)->n_attrstamp = 0; /* XXX wccflags */ - - return (error); -} - -/* - * nfs make dir call - */ -static int -nfs4_mkdir(struct vop_mkdir_args *ap) -{ - return (nfs4_createrpc(ap->a_dvp, ap->a_vpp, ap->a_cnp, NFDIR, - ap->a_vap, NULL)); -} - -/* - * nfs remove directory call - */ -static int -nfs4_rmdir(struct vop_rmdir_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct vnode *dvp = ap->a_dvp; - struct nfsnode *dnp = VTONFS(dvp); - struct componentname *cnp = ap->a_cnp; - int error = 0; - - if (dvp == vp) - return (EINVAL); - - error = (nfs4_removerpc(dvp, cnp->cn_nameptr, cnp->cn_namelen, cnp->cn_cred, - NULL)); - if (error) - return (error); - - dnp->n_flag |= NMODIFIED; - dnp->n_attrstamp = 0; - cache_purge(dvp); - cache_purge(vp); - - return (error); -} - -/* - * nfs readdir call - */ -static int -nfs4_readdir(struct vop_readdir_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - struct uio *uio = ap->a_uio; - int tresid, error; - struct vattr vattr; - - if (vp->v_type != VDIR) - return (EPERM); - /* - * First, check for hit on the EOF offset cache - */ - if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset && - (np->n_flag & NMODIFIED) == 0) { - if (!VOP_GETATTR(vp, &vattr, ap->a_cred) && - !NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) { - nfsstats.direofcache_hits++; - return (0); - } - } - - /* - * Call nfs_bioread() to do the real work. - */ - tresid = uio->uio_resid; - error = nfs_bioread(vp, uio, 0, ap->a_cred); - - if (!error && uio->uio_resid == tresid) - nfsstats.direofcache_misses++; - return (error); -} - -static u_char fty_to_dty[] = { - DT_UNKNOWN, /* NFNON */ - DT_REG, /* NFREG */ - DT_DIR, /* NFDIR */ - DT_BLK, /* NFBLK */ - DT_CHR, /* NFCHR */ - DT_LNK, /* NFLNK */ - DT_SOCK, /* NFSOCK */ - DT_FIFO, /* NFFIFO */ - DT_UNKNOWN, /* NFATTRDIT */ - DT_UNKNOWN, /* NFNAMEDATTR */ - DT_UNKNOWN, /* NFBAD */ -}; - -/* - * Readdir rpc call. - * Called from below the buffer cache by nfs_doio(). - */ -int -nfs4_readdirrpc(struct vnode *vp, struct uio *uiop, struct ucred *cred) -{ - int len, left; - struct dirent *dp = NULL; - u_int32_t *tl; - caddr_t p; - uint64_t *cookiep; - caddr_t bpos, dpos; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - uint64_t cookie; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - struct nfsnode *dnp = VTONFS(vp); - int error = 0, tlen, more_dirs = 1, blksiz = 0, bigenough = 1; - struct nfs4_compound cp; - struct nfs4_oparg_readdir readdir; - struct nfsv4_fattr fattr; - u_int fty; - -#ifndef DIAGNOSTIC - if (uiop->uio_iovcnt != 1 || (uiop->uio_offset & (DIRBLKSIZ - 1)) || - (uiop->uio_resid & (DIRBLKSIZ - 1))) - panic("nfs readdirrpc bad uio"); -#endif - - /* - * If there is no cookie, assume directory was stale. - */ - cookiep = nfs4_getcookie(dnp, uiop->uio_offset, 0); - if (cookiep) - cookie = *cookiep; - else - return (NFSERR_BAD_COOKIE); - - /* Generate fake entries for "." and ".." */ - while (cookie < 2 && bigenough) { - cookie++; - len = 4 + DIRHDSIZ; - - if (len > uiop->uio_resid) { - bigenough = 0; - break; - } - dp = (struct dirent *)uiop->uio_iov->iov_base; - - dp->d_namlen = cookie; - dp->d_reclen = len; - dp->d_type = DT_DIR; - if (cookie == 1) - dp->d_fileno = dnp->n_vattr.va_fileid; /* XXX has problems with pynfs virtualhandles */ - else - dp->d_fileno = dnp->n_dvp != NULL ? - VTONFS(dnp->n_dvp)->n_vattr.va_fileid : cookie; - - p = dp->d_name; - *p++ = '.'; - if (cookie == 2) - *p++ = '.'; - *p = '\0'; - - blksiz += len; - if (blksiz == DIRBLKSIZ) - blksiz = 0; - uiop->uio_offset += len; - uiop->uio_resid -= len; - uiop->uio_iov->iov_base = (char *)uiop->uio_iov->iov_base + len; - uiop->uio_iov->iov_len -= len; - } - - if (cookie == 2) - cookie = 0; - - /* This is sort of ugly, to prevent v4postop() from acting weird */ - bzero(&cp, sizeof(cp)); - - /* - * Loop around doing readdir rpc's of size nm_readdirsize - * truncated to a multiple of DIRBLKSIZ. - * The stopping criteria is EOF or buffer full. - */ - /* - * XXX this is sort of ugly for nfsv4; we don't maintain the - * strict abstraction, but do the decoding inline. that's ok. - */ - while (more_dirs && bigenough) { - nfsstats.rpccnt[NFSPROC_READDIR]++; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - readdir.cnt = nmp->nm_readdirsize; - readdir.cookie = cookie; - readdir.bm = &nfsv4_readdirbm; - if (cookie == 0) - bzero(&readdir.verf, sizeof(readdir.verf)); - else - bcopy(&dnp->n_cookieverf, &readdir.verf, - sizeof(readdir.verf)); - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_readdirrpc()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_readdir(&cp, &readdir); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, uiop->uio_td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - - /* - * XXX - Readdir gets handled inline like in - * NFSv{2,3}. This is a nasty inconsistency and - * should be fixed. - */ - - tl = nfsm_dissect(uint32_t *, 5 * NFSX_UNSIGNED); - if (fxdr_unsigned(uint32_t, *tl++) != NFSV4OP_READDIR) { - error = EBADRPC; - goto nfsmout; - } - if (fxdr_unsigned(uint32_t, *tl++) != 0) { - error = EBADRPC; - goto nfsmout; - } - - bcopy(tl, &dnp->n_cookieverf, NFSX_V4VERF); - tl += 2; - more_dirs = fxdr_unsigned(int, *tl++); - - /* loop thru the dir entries, doctoring them to 4bsd form */ - while (more_dirs && bigenough) { - tl = nfsm_dissect(uint32_t *, 3 * NFSX_UNSIGNED); - cookie = fxdr_hyper(tl); - tl += 2; - /* XXX cookie sanity check */ - len = fxdr_unsigned(int, *tl++); - if (len <= 0 || len > NFS_MAXNAMLEN) { - error = EBADRPC; - goto nfsmout; - } - tlen = nfsm_rndup(len); - if (tlen == len) - tlen += 4; /* To ensure null termination */ - left = DIRBLKSIZ - blksiz; - if ((tlen + DIRHDSIZ) > left) { - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - blksiz = 0; - } - if ((tlen + DIRHDSIZ) > uiop->uio_resid) - bigenough = 0; - if (bigenough) { - dp = (struct dirent *)uiop->uio_iov->iov_base; - - dp->d_namlen = len; - dp->d_reclen = tlen + DIRHDSIZ; - - blksiz += dp->d_reclen; - if (blksiz == DIRBLKSIZ) - blksiz = 0; - uiop->uio_offset += DIRHDSIZ; - uiop->uio_resid -= DIRHDSIZ; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + DIRHDSIZ; - uiop->uio_iov->iov_len -= DIRHDSIZ; - - /* Copy name */ - nfsm_mtouio(uiop, len); - p = uiop->uio_iov->iov_base; - tlen -= len; - *p = '\0'; /* null terminate */ - /* printf("nfs4_readdirrpc: name: \"%s\" cookie %d\n", - p - len, (int) cookie);*/ - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + tlen; - uiop->uio_iov->iov_len -= tlen; - uiop->uio_offset += tlen; - uiop->uio_resid -= tlen; - - /* Copy attributes */ - nfsm_v4dissect_attrs(&fattr); - - dp->d_fileno = nfs_v4fileid4_to_fileid( - fattr.fa4_valid & FA4V_FILEID && - fattr.fa4_fileid ? - fattr.fa4_fileid : cookie); - - fty = (u_int)fattr.fa4_type; - dp->d_type = fattr.fa4_valid & FA4V_TYPE && - (fty < sizeof(fty_to_dty)) ? - fty_to_dty[fty] : DT_UNKNOWN; - } else - nfsm_adv(nfsm_rndup(len)); - - tl = nfsm_dissect(uint32_t *, NFSX_UNSIGNED); - more_dirs = fxdr_unsigned(int, *tl++); - } - /* - * If at end of rpc data, get the eof boolean - */ - if (!more_dirs) { - tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); - more_dirs = (fxdr_unsigned(int, *tl) == 0); - } - - error = nfs_v4postop(&cp, error); - - m_freem(mrep); - mrep = NULL; - } - /* - * Fill last record, iff any, out to a multiple of DIRBLKSIZ - * by increasing d_reclen for the last record. - */ - if (blksiz > 0) { - left = DIRBLKSIZ - blksiz; - dp->d_reclen += left; - uiop->uio_iov->iov_base = - (char *)uiop->uio_iov->iov_base + left; - uiop->uio_iov->iov_len -= left; - uiop->uio_offset += left; - uiop->uio_resid -= left; - } - - /* - * We are now either at the end of the directory or have filled the - * block. - */ - if (bigenough) - dnp->n_direofoffset = uiop->uio_offset; - else { - if (uiop->uio_resid > 0) - printf("EEK! readdirrpc resid > 0\n"); - cookiep = nfs4_getcookie(dnp, uiop->uio_offset, 1); - *cookiep = cookie; - } -nfsmout: - if (mrep != NULL) - m_freem(mrep); - return (error); -} - -/* - * Silly rename. To make the NFS filesystem that is stateless look a little - * more like the "ufs" a remove of an active vnode is translated to a rename - * to a funny looking filename that is removed by nfs_inactive on the - * nfsnode. There is the potential for another process on a different client - * to create the same funny name between the nfs_lookitup() fails and the - * nfs_rename() completes, but... - */ -static int -nfs4_sillyrename(struct vnode *dvp, struct vnode *vp, struct componentname *cnp) -{ - struct sillyrename *sp; - struct nfsnode *np; - int error; - short pid; - - cache_purge(dvp); - np = VTONFS(vp); -#ifndef DIAGNOSTIC - if (vp->v_type == VDIR) - panic("nfs: sillyrename dir"); -#endif - sp = malloc(sizeof (struct sillyrename), M_NFSREQ, M_WAITOK); - sp->s_cred = crhold(cnp->cn_cred); - sp->s_dvp = dvp; - sp->s_removeit = nfs4_removeit; - VREF(dvp); - - /* Fudge together a funny name */ - pid = cnp->cn_thread->td_proc->p_pid; - sp->s_namlen = sprintf(sp->s_name, ".nfsA%04x4.4", pid); - - /* Try lookitups until we get one that isn't there */ - while (nfs4_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, - cnp->cn_thread, NULL) == 0) { - sp->s_name[4]++; - if (sp->s_name[4] > 'z') { - error = EINVAL; - goto bad; - } - } - error = nfs4_renameit(dvp, cnp, sp); - if (error) - goto bad; - error = nfs4_lookitup(dvp, sp->s_name, sp->s_namlen, sp->s_cred, - cnp->cn_thread, &np); - np->n_sillyrename = sp; - return (0); -bad: - vrele(sp->s_dvp); - crfree(sp->s_cred); - free((caddr_t)sp, M_NFSREQ); - return (error); -} - -/* - * Look up a file name and optionally either update the file handle or - * allocate an nfsnode, depending on the value of npp. - * npp == NULL --> just do the lookup - * *npp == NULL --> allocate a new nfsnode and make sure attributes are - * handled too - * *npp != NULL --> update the file handle in the vnode - */ -static int -nfs4_lookitup(struct vnode *dvp, const char *name, int len, struct ucred *cred, - struct thread *td, struct nfsnode **npp) -{ - struct vnode *newvp = NULL; - struct nfsnode *np, *dnp = VTONFS(dvp); - caddr_t bpos, dpos; - int error = 0, fhlen; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - nfsfh_t *nfhp; - struct nfs4_compound cp; - struct nfs4_oparg_lookup l; - struct nfs4_oparg_getfh gfh; - struct nfs4_oparg_getattr ga; - - nfsstats.rpccnt[NFSPROC_RENAME]++; - - mreq = nfsm_reqhead(dvp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - l.name = name; - l.namelen = len; - - nfs_v4initcompound(&cp); - - ga.bm = &nfsv4_getattrbm; - - nfsm_v4build_compound(&cp, "nfs4_renamerpc()"); - nfsm_v4build_putfh(&cp, dvp); - nfsm_v4build_lookup(&cp, &l); - nfsm_v4build_getfh(&cp, &gfh); - nfsm_v4build_getattr(&cp, &ga); - - nfsm_request(dvp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_lookup(&cp); - nfsm_v4dissect_getfh(&cp, &gfh); - nfsm_v4dissect_getattr(&cp, &ga); - - if (npp != NULL && error == 0) { - nfhp = &gfh.fh_val; - fhlen = gfh.fh_len; - - if (*npp != NULL) { - np = *npp; - if (np->n_fhsize > NFS_SMALLFH && fhlen <= NFS_SMALLFH) { - free((caddr_t)np->n_fhp, M_NFSBIGFH); - np->n_fhp = &np->n_fh; - } else if (np->n_fhsize <= NFS_SMALLFH && fhlen>NFS_SMALLFH) - np->n_fhp =(nfsfh_t *)malloc(fhlen, M_NFSBIGFH, M_WAITOK); - bcopy((caddr_t)nfhp, (caddr_t)np->n_fhp, fhlen); - np->n_fhsize = fhlen; - newvp = NFSTOV(np); - } else if (NFS_CMPFH(dnp, nfhp, fhlen)) { - VREF(dvp); - newvp = dvp; - } else { - error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE); - if (error) { - m_freem(mrep); - return (error); - } - newvp = NFSTOV(np); - } - - if (newvp != dvp) { - np->n_dvp = dvp; - np->n_namelen = len; - if (np->n_name != NULL) - free(np->n_name, M_NFSREQ); - np->n_name = malloc(np->n_namelen + 1, M_NFSREQ, M_WAITOK); - memcpy(np->n_name, name, len); - np->n_name[len] = '\0'; - } - nfs4_vnop_loadattrcache(newvp, &ga.fa, NULL); - } - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep != NULL) - m_freem(mrep); - if (npp && *npp == NULL) { - if (error) { - if (newvp) { - if (newvp == dvp) - vrele(newvp); - else - vput(newvp); - } - } else - *npp = np; - } - - - return (error); -} - -/* - * Nfs Version 3 commit rpc - */ -int -nfs4_commit(struct vnode *vp, u_quad_t offset, int cnt, struct ucred *cred, - struct thread *td) -{ - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - caddr_t bpos, dpos; - int error = 0; - struct mbuf *mreq, *mrep = NULL, *md, *mb; - struct nfs4_compound cp; - struct nfs4_oparg_commit commit; - - if ((nmp->nm_state & NFSSTA_HASWRITEVERF) == 0) - return (0); - nfsstats.rpccnt[NFSPROC_COMMIT]++; - - mreq = nfsm_reqhead(vp, NFSV4PROC_COMPOUND, 0); - mb = mreq; - bpos = mtod(mb, caddr_t); - - commit.start = offset; - commit.len = cnt; - - nfs_v4initcompound(&cp); - - nfsm_v4build_compound(&cp, "nfs4_commit()"); - nfsm_v4build_putfh(&cp, vp); - nfsm_v4build_commit(&cp, &commit); - nfsm_v4build_finalize(&cp); - - nfsm_request(vp, NFSV4PROC_COMPOUND, td, cred); - if (error != 0) - goto nfsmout; - - nfsm_v4dissect_compound(&cp); - nfsm_v4dissect_putfh(&cp); - nfsm_v4dissect_commit(&cp, &commit); - - /* XXX */ - /* nfsm_wcc_data(vp, wccflag);*/ - if (bcmp(nmp->nm_verf, commit.verf, NFSX_V4VERF)) { - bcopy(commit.verf, nmp->nm_verf, NFSX_V4VERF); - error = NFSERR_STALEWRITEVERF; - } - -nfsmout: - error = nfs_v4postop(&cp, error); - - if (mrep == NULL) - m_freem(mrep); - return (error); -} - -/* - * Strategy routine. - * For async requests when nfsiod(s) are running, queue the request by - * calling nfs_asyncio(), otherwise just all nfs_doio() to do the - * request. - */ -static int -nfs4_strategy(struct vop_strategy_args *ap) -{ - struct buf *bp = ap->a_bp; - struct ucred *cr; - int error = 0; - - KASSERT(!(bp->b_flags & B_DONE), - ("nfs4_strategy: buffer %p unexpectedly marked B_DONE", bp)); - BUF_ASSERT_HELD(bp); - - if (bp->b_iocmd == BIO_READ) - cr = bp->b_rcred; - else - cr = bp->b_wcred; - - /* - * If the op is asynchronous and an i/o daemon is waiting - * queue the request, wake it up and wait for completion - * otherwise just do it ourselves. - */ - if ((bp->b_flags & B_ASYNC) == 0 || - nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread)) - error = nfs_doio(ap->a_vp, bp, cr, curthread); - return (error); -} - -/* - * fsync vnode op. Just call nfs4_flush() with commit == 1. - */ -/* ARGSUSED */ -static int -nfs4_fsync(struct vop_fsync_args *ap) -{ - return (nfs4_flush(ap->a_vp, ap->a_waitfor, ap->a_td, 1)); -} - -/* - * Flush all the blocks associated with a vnode. - * Walk through the buffer pool and push any dirty pages - * associated with the vnode. - */ -static int -nfs4_flush(struct vnode *vp, int waitfor, struct thread *td, - int commit) -{ - struct nfsnode *np = VTONFS(vp); - struct bufobj *bo; - struct buf *bp; - int i; - struct buf *nbp; - struct nfsmount *nmp = VFSTONFS(vp->v_mount); - int error = 0, slptimeo = 0, slpflag = 0, retv, bvecpos; - int passone = 1; - u_quad_t off, endoff, toff; - struct ucred* wcred = NULL; - struct buf **bvec = NULL; -#ifndef NFS_COMMITBVECSIZ -#define NFS_COMMITBVECSIZ 20 -#endif - struct buf *bvec_on_stack[NFS_COMMITBVECSIZ]; - int bvecsize = 0, bveccount; - bo = &vp->v_bufobj; - - if (nmp->nm_flag & NFSMNT_INT) - slpflag = PCATCH; - if (!commit) - passone = 0; - /* - * A b_flags == (B_DELWRI | B_NEEDCOMMIT) block has been written to the - * server, but nas not been committed to stable storage on the server - * yet. On the first pass, the byte range is worked out and the commit - * rpc is done. On the second pass, nfs_writebp() is called to do the - * job. - */ -again: - off = (u_quad_t)-1; - endoff = 0; - bvecpos = 0; - if (NFS_ISV3(vp) && commit) { - if (bvec != NULL && bvec != bvec_on_stack) - free(bvec, M_TEMP); - /* - * Count up how many buffers waiting for a commit. - */ - bveccount = 0; - BO_LOCK(bo); - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (!BUF_ISLOCKED(bp) && - (bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) - == (B_DELWRI | B_NEEDCOMMIT)) - bveccount++; - } - /* - * Allocate space to remember the list of bufs to commit. It is - * important to use M_NOWAIT here to avoid a race with nfs4_write. - * If we can't get memory (for whatever reason), we will end up - * committing the buffers one-by-one in the loop below. - */ - if (bveccount > NFS_COMMITBVECSIZ) { - /* - * Release the vnode interlock to avoid a lock - * order reversal. - */ - BO_UNLOCK(bo); - bvec = (struct buf **) - malloc(bveccount * sizeof(struct buf *), - M_TEMP, M_NOWAIT); - BO_LOCK(bo); - if (bvec == NULL) { - bvec = bvec_on_stack; - bvecsize = NFS_COMMITBVECSIZ; - } else - bvecsize = bveccount; - } else { - bvec = bvec_on_stack; - bvecsize = NFS_COMMITBVECSIZ; - } - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (bvecpos >= bvecsize) - break; - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { - nbp = TAILQ_NEXT(bp, b_bobufs); - continue; - } - if ((bp->b_flags & (B_DELWRI | B_NEEDCOMMIT)) != - (B_DELWRI | B_NEEDCOMMIT)) { - BUF_UNLOCK(bp); - nbp = TAILQ_NEXT(bp, b_bobufs); - continue; - } - BO_UNLOCK(bo); - bremfree(bp); - /* - * Work out if all buffers are using the same cred - * so we can deal with them all with one commit. - * - * NOTE: we are not clearing B_DONE here, so we have - * to do it later on in this routine if we intend to - * initiate I/O on the bp. - * - * Note: to avoid loopback deadlocks, we do not - * assign b_runningbufspace. - */ - if (wcred == NULL) - wcred = bp->b_wcred; - else if (wcred != bp->b_wcred) - wcred = NOCRED; - vfs_busy_pages(bp, 1); - - BO_LOCK(bo); - /* - * bp is protected by being locked, but nbp is not - * and vfs_busy_pages() may sleep. We have to - * recalculate nbp. - */ - nbp = TAILQ_NEXT(bp, b_bobufs); - - /* - * A list of these buffers is kept so that the - * second loop knows which buffers have actually - * been committed. This is necessary, since there - * may be a race between the commit rpc and new - * uncommitted writes on the file. - */ - bvec[bvecpos++] = bp; - toff = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + - bp->b_dirtyoff; - if (toff < off) - off = toff; - toff += (u_quad_t)(bp->b_dirtyend - bp->b_dirtyoff); - if (toff > endoff) - endoff = toff; - } - BO_UNLOCK(bo); - } - if (bvecpos > 0) { - /* - * Commit data on the server, as required. - * If all bufs are using the same wcred, then use that with - * one call for all of them, otherwise commit each one - * separately. - */ - if (wcred != NOCRED) - retv = nfs4_commit(vp, off, (int)(endoff - off), - wcred, td); - else { - retv = 0; - for (i = 0; i < bvecpos; i++) { - off_t off, size; - bp = bvec[i]; - off = ((u_quad_t)bp->b_blkno) * DEV_BSIZE + - bp->b_dirtyoff; - size = (u_quad_t)(bp->b_dirtyend - - bp->b_dirtyoff); - retv = nfs4_commit(vp, off, (int)size, - bp->b_wcred, td); - if (retv) break; - } - } - - if (retv == NFSERR_STALEWRITEVERF) - nfs_clearcommit(vp->v_mount); - - /* - * Now, either mark the blocks I/O done or mark the - * blocks dirty, depending on whether the commit - * succeeded. - */ - for (i = 0; i < bvecpos; i++) { - bp = bvec[i]; - bp->b_flags &= ~(B_NEEDCOMMIT | B_CLUSTEROK); - if (retv) { - /* - * Error, leave B_DELWRI intact - */ - vfs_unbusy_pages(bp); - brelse(bp); - } else { - /* - * Success, remove B_DELWRI ( bundirty() ). - * - * b_dirtyoff/b_dirtyend seem to be NFS - * specific. We should probably move that - * into bundirty(). XXX - */ - bufobj_wref(bo); - bp->b_flags |= B_ASYNC; - bundirty(bp); - bp->b_flags &= ~B_DONE; - bp->b_ioflags &= ~BIO_ERROR; - bp->b_dirtyoff = bp->b_dirtyend = 0; - bufdone(bp); - } - } - } - - /* - * Start/do any write(s) that are required. - */ -loop: - BO_LOCK(bo); - TAILQ_FOREACH_SAFE(bp, &bo->bo_dirty.bv_hd, b_bobufs, nbp) { - if (BUF_LOCK(bp, LK_EXCLUSIVE | LK_NOWAIT, NULL)) { - if (waitfor != MNT_WAIT || passone) - continue; - - error = BUF_TIMELOCK(bp, - LK_EXCLUSIVE | LK_SLEEPFAIL | LK_INTERLOCK, - BO_MTX(bo), "nfsfsync", slpflag, slptimeo); - if (error == 0) - panic("nfs4_fsync: inconsistent lock"); - if (error == ENOLCK) { - error = 0; - goto loop; - } - if (nfs4_sigintr(nmp, NULL, td)) { - error = EINTR; - goto done; - } - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - goto loop; - } - if ((bp->b_flags & B_DELWRI) == 0) - panic("nfs4_fsync: not dirty"); - if ((passone || !commit) && (bp->b_flags & B_NEEDCOMMIT)) { - BUF_UNLOCK(bp); - continue; - } - BO_LOCK(bo); - bremfree(bp); - if (passone || !commit) - bp->b_flags |= B_ASYNC; - else - bp->b_flags |= B_ASYNC; - bwrite(bp); - goto loop; - } - if (passone) { - passone = 0; - BO_UNLOCK(bo); - goto again; - } - if (waitfor == MNT_WAIT) { - while (bo->bo_numoutput) { - error = bufobj_wwait(bo, slpflag, slptimeo); - if (error) { - BO_UNLOCK(bo); - if (nfs4_sigintr(nmp, NULL, td)) { - error = EINTR; - goto done; - } - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - BO_LOCK(bo); - } - } - if (vp->v_bufobj.bo_dirty.bv_cnt > 0 && commit) { - BO_UNLOCK(bo); - goto loop; - } - } - BO_UNLOCK(bo); - if (np->n_flag & NWRITEERR) { - error = np->n_error; - np->n_flag &= ~NWRITEERR; - } -done: - if (bvec != NULL && bvec != bvec_on_stack) - free(bvec, M_TEMP); - return (error); -} - -/* - * NFS advisory byte-level locks. - */ -static int -nfs4_advlock(struct vop_advlock_args *ap) -{ - struct vnode *vp = ap->a_vp; - u_quad_t size; - int error; - - return (EPERM); - - error = vn_lock(vp, LK_SHARED); - if (error) - return (error); - if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - size = VTONFS(vp)->n_size; - VOP_UNLOCK(vp, 0); - error = lf_advlock(ap, &(vp->v_lockf), size); - } else - error = nfs_dolock(ap); - return (error); -} - -/* - * NFS advisory byte-level locks. - */ -static int -nfs4_advlockasync(struct vop_advlockasync_args *ap) -{ - struct vnode *vp = ap->a_vp; - u_quad_t size; - int error; - - return (EPERM); - - error = vn_lock(vp, LK_SHARED); - if (error) - return (error); - if ((VFSTONFS(vp->v_mount)->nm_flag & NFSMNT_NOLOCKD) != 0) { - size = VTONFS(vp)->n_size; - VOP_UNLOCK(vp, 0); - error = lf_advlockasync(ap, &(vp->v_lockf), size); - } else { - VOP_UNLOCK(vp, 0); - error = EOPNOTSUPP; - } - return (error); -} - -/* - * Print out the contents of an nfsnode. - */ -static int -nfs4_print(struct vop_print_args *ap) -{ - struct vnode *vp = ap->a_vp; - struct nfsnode *np = VTONFS(vp); - - printf("\tfileid %ld fsid 0x%x", - np->n_vattr.va_fileid, np->n_vattr.va_fsid); - if (vp->v_type == VFIFO) - fifo_printinfo(vp); - printf("\n"); - return (0); -} - -/* - * This is the "real" nfs::bwrite(struct buf*). - * We set B_CACHE if this is a VMIO buffer. - */ -int -nfs4_writebp(struct buf *bp, int force __unused, struct thread *td) -{ - int s; - int oldflags = bp->b_flags; -#if 0 - int retv = 1; - off_t off; -#endif - - BUF_ASSERT_HELD(bp); - - if (bp->b_flags & B_INVAL) { - brelse(bp); - return(0); - } - - bp->b_flags |= B_CACHE; - - /* - * Undirty the bp. We will redirty it later if the I/O fails. - */ - - s = splbio(); - bundirty(bp); - bp->b_flags &= ~B_DONE; - bp->b_ioflags &= ~BIO_ERROR; - bp->b_iocmd = BIO_WRITE; - - bufobj_wref(bp->b_bufobj); - curthread->td_ru.ru_oublock++; - splx(s); - - /* - * Note: to avoid loopback deadlocks, we do not - * assign b_runningbufspace. - */ - vfs_busy_pages(bp, 1); - - BUF_KERNPROC(bp); - bp->b_iooffset = dbtob(bp->b_blkno); - bstrategy(bp); - - if( (oldflags & B_ASYNC) == 0) { - int rtval = bufwait(bp); - - if (oldflags & B_DELWRI) { - s = splbio(); - reassignbuf(bp); - splx(s); - } - - brelse(bp); - return (rtval); - } - - return (0); -} - -/* - * Just call nfs_writebp() with the force argument set to 1. - * - * NOTE: B_DONE may or may not be set in a_bp on call. - */ -static int -nfs4_bwrite(struct buf *bp) -{ - - return (nfs4_writebp(bp, 1, curthread)); -} - -struct buf_ops buf_ops_nfs4 = { - .bop_name = "buf_ops_nfs4", - .bop_write = nfs4_bwrite, - .bop_strategy = bufstrategy, - .bop_sync = bufsync, - .bop_bdflush = bufbdflush, -}; diff --git a/sys/nfs4client/nfs4m_subs.h b/sys/nfs4client/nfs4m_subs.h deleted file mode 100644 index 60d0758637de..000000000000 --- a/sys/nfs4client/nfs4m_subs.h +++ /dev/null @@ -1,498 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: nfs4m_subs.h,v 1.36 2003/11/05 14:59:01 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -#ifndef _NFS4CLIENT_NFSM4_SUBS_H -#define _NFS4CLIENT_NFSM4_SUBS_H - -void nfsm_v4init(void); - -void nfsm_buildf_xx(struct mbuf **mb, caddr_t *bpos, char *fmt, ...); -int nfsm_dissectf_xx(struct mbuf **md, caddr_t *dpos, char *fmt, ...); - -int nfsm_v4build_compound_xx(struct nfs4_compound *, char *, - struct mbuf **, caddr_t *); -int nfsm_v4build_putfh_xx(struct nfs4_compound *, struct vnode *, - struct mbuf **, caddr_t *); -int nfsm_v4build_putfh_nv_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *, - struct mbuf **, caddr_t *); -int nfsm_v4build_getattr_xx(struct nfs4_compound *, struct nfs4_oparg_getattr *, - struct mbuf **, caddr_t *); -int nfsm_v4build_finalize_xx(struct nfs4_compound *, struct mbuf **, caddr_t *); -int nfsm_v4build_getfh_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *, - struct mbuf **, caddr_t *); -int nfsm_v4build_lookup_xx(struct nfs4_compound *, struct nfs4_oparg_lookup *, - struct mbuf **, caddr_t *); -int nfsm_v4build_setclientid_xx(struct nfs4_compound *, - struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *); -int nfsm_v4build_setclientid_confirm_xx(struct nfs4_compound *, - struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *); -int nfsm_v4build_close_xx(struct nfs4_compound *, struct nfs4_fctx *, - struct mbuf **, caddr_t *); -int nfsm_v4build_access_xx(struct nfs4_compound *, struct nfs4_oparg_access *, - struct mbuf **, caddr_t *); -int nfsm_v4build_open_xx(struct nfs4_compound *, struct nfs4_oparg_open *, - struct mbuf **, caddr_t *); -int nfsm_v4build_open_confirm_xx(struct nfs4_compound *, struct nfs4_oparg_open *, - struct mbuf **, caddr_t *); -int nfsm_v4build_read_xx(struct nfs4_compound *, struct nfs4_oparg_read *, - struct mbuf **, caddr_t *); -int nfsm_v4build_write_xx(struct nfs4_compound *, struct nfs4_oparg_write *, - struct mbuf **, caddr_t *); -int nfsm_v4build_commit_xx(struct nfs4_compound *, struct nfs4_oparg_commit *, - struct mbuf **, caddr_t *); -int nfsm_v4build_readdir_xx(struct nfs4_compound *, struct nfs4_oparg_readdir *, - struct mbuf **, caddr_t *); -int nfsm_v4build_renew_xx(struct nfs4_compound *, uint64_t, - struct mbuf **, caddr_t *); -int nfsm_v4build_setattr_xx(struct nfs4_compound *, struct vattr *, - struct nfs4_fctx *, struct mbuf **, caddr_t *); -int nfsm_v4build_create_xx(struct nfs4_compound *, struct nfs4_oparg_create *, - struct mbuf **, caddr_t *); -int nfsm_v4build_rename_xx(struct nfs4_compound *, struct nfs4_oparg_rename *, - struct mbuf **, caddr_t *); -int nfsm_v4build_link_xx(struct nfs4_compound *, struct nfs4_oparg_link *, - struct mbuf **, caddr_t *); -int nfsm_v4build_remove_xx(struct nfs4_compound *, const char *, u_int, - struct mbuf **, caddr_t *); - -int nfsm_v4dissect_compound_xx(struct nfs4_compound *, struct mbuf **, caddr_t *); -int nfsm_v4dissect_getattr_xx(struct nfs4_compound *, struct nfs4_oparg_getattr *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_getfh_xx(struct nfs4_compound *, struct nfs4_oparg_getfh *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_setclientid_xx(struct nfs4_compound *, - struct nfs4_oparg_setclientid *, struct mbuf **, caddr_t *); -int nfsm_v4dissect_close_xx(struct nfs4_compound *, struct nfs4_fctx *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_access_xx(struct nfs4_compound *, struct nfs4_oparg_access *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_open_xx(struct nfs4_compound *, struct nfs4_oparg_open *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_open_confirm_xx(struct nfs4_compound *, struct nfs4_oparg_open *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_read_xx(struct nfs4_compound *, struct nfs4_oparg_read *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_write_xx(struct nfs4_compound *, struct nfs4_oparg_write *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_commit_xx(struct nfs4_compound *, struct nfs4_oparg_commit *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_setattr_xx(struct nfs4_compound *, struct mbuf **, caddr_t *); -int nfsm_v4dissect_create_xx(struct nfs4_compound *, struct nfs4_oparg_create *, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_readlink_xx(struct nfs4_compound *, struct uio *, - struct mbuf **, caddr_t *); - -int nfsm_v4dissect_attrs_xx(struct nfsv4_fattr *, struct mbuf **, caddr_t *); - -int nfsm_v4build_simple_xx(struct nfs4_compound *, uint32_t, - struct mbuf **, caddr_t *); -int nfsm_v4dissect_simple_xx(struct nfs4_compound *, uint32_t, - uint32_t, struct mbuf **, caddr_t *); - -#define nfsm_v4build_putrootfh_xx(cp, mb, bpos) \ - nfsm_v4build_simple_xx((cp), NFSV4OP_PUTROOTFH, (mb), (bpos)) - -#define nfsm_v4build_lookupp_xx(cp, mb, bpos) \ - nfsm_v4build_simple_xx((cp), NFSV4OP_LOOKUPP, (mb), (bpos)) - -#define nfsm_v4build_savefh_xx(cp, mb, bpos) \ - nfsm_v4build_simple_xx((cp), NFSV4OP_SAVEFH, (mb), (bpos)) - -#define nfsm_v4build_readlink_xx(cp, mb, bpos) \ - nfsm_v4build_simple_xx((cp), NFSV4OP_READLINK, (mb), (bpos)) - - -#define nfsm_v4dissect_putrootfh_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_PUTROOTFH, 0, (mb), (bpos)) - -#define nfsm_v4dissect_lookup_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_LOOKUP, 0, (mb), (bpos)) - -#define nfsm_v4dissect_lookupp_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_LOOKUPP, 0, (mb), (bpos)) - -#define nfsm_v4dissect_putfh_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_PUTFH, 0, (mb), (bpos)) - -#define nfsm_v4dissect_renew_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_RENEW, 0, (mb), (bpos)) - -#define nfsm_v4dissect_setclientid_confirm_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_SETCLIENTID_CONFIRM, 0, (mb), (bpos)) - -#define nfsm_v4dissect_rename_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_RENAME, 0, (mb), (bpos)) - -#define nfsm_v4dissect_link_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_LINK, 0, (mb), (bpos)) - -#define nfsm_v4dissect_savefh_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_SAVEFH, 0, (mb), (bpos)) - -#define nfsm_v4dissect_remove_xx(cp, mb, bpos) \ - nfsm_v4dissect_simple_xx((cp), NFSV4OP_REMOVE, 0, (mb), (bpos)) - -#define nfsm_v4build_compound(cp, tag) do { \ - int32_t t1; \ - t1 = nfsm_v4build_compound_xx((cp), (tag), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_finalize(cp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_finalize_xx((cp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_putfh(cp, vp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_putfh_xx((cp), (vp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_putfh_nv(cp, gfh) do { \ - int32_t t1; \ - t1 = nfsm_v4build_putfh_nv_xx((cp), (gfh), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_putrootfh(cp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_putrootfh_xx((cp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_getattr(cp, ga) do { \ - int32_t t1; \ - t1 = nfsm_v4build_getattr_xx((cp), (ga), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_setattr(cp, vap, fcp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_setattr_xx((cp), (vap), (fcp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_lookup(cp, l) do { \ - int32_t t1; \ - t1 = nfsm_v4build_lookup_xx((cp), (l), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_lookupp(cp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_lookupp_xx((cp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_getfh(cp, gfh) do { \ - int32_t t1; \ - t1 = nfsm_v4build_getfh_xx((cp), (gfh), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_close(cp, fcp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_close_xx((cp), (fcp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_access(cp, acc) do { \ - int32_t t1; \ - t1 = nfsm_v4build_access_xx((cp), (acc), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_open(cp, o) do { \ - int32_t t1; \ - t1 = nfsm_v4build_open_xx((cp), (o), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_open_confirm(cp, o) do { \ - int32_t t1; \ - t1 = nfsm_v4build_open_confirm_xx((cp), (o), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_read(cp, r) do { \ - int32_t t1; \ - t1 = nfsm_v4build_read_xx((cp), (r), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_write(cp, w) do { \ - int32_t t1; \ - t1 = nfsm_v4build_write_xx((cp), (w), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_commit(cp, c) do { \ - int32_t t1; \ - t1 = nfsm_v4build_commit_xx((cp), (c), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_readdir(cp, r) do { \ - int32_t t1; \ - t1 = nfsm_v4build_readdir_xx((cp), (r), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_renew(cp, cid) do { \ - int32_t t1; \ - t1 = nfsm_v4build_renew_xx((cp), (cid), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_setclientid(cp, cid) do { \ - int32_t t1; \ - t1 = nfsm_v4build_setclientid_xx((cp), (cid), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_setclientid_confirm(cp, cid) do { \ - int32_t t1; \ - t1 = nfsm_v4build_setclientid_confirm_xx((cp), (cid), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_create(cp, c) do { \ - int32_t t1; \ - t1 = nfsm_v4build_create_xx((cp), (c), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_rename(cp, r) do { \ - int32_t t1; \ - t1 = nfsm_v4build_rename_xx((cp), (r), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_link(cp, r) do { \ - int32_t t1; \ - t1 = nfsm_v4build_link_xx((cp), (r), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_savefh(cp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_savefh_xx((cp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_readlink(cp) do { \ - int32_t t1; \ - t1 = nfsm_v4build_readlink_xx((cp), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -#define nfsm_v4build_remove(cp, name, namelen) do { \ - int32_t t1; \ - t1 = nfsm_v4build_remove_xx((cp), (name), (namelen), &mb, &bpos); \ - nfsm_bcheck(t1, mreq); \ -} while (0) - -/* --- */ - -#define nfsm_v4dissect_compound(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_compound_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_putfh(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_putfh_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_putrootfh(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_putrootfh_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_getattr(cp, ga) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_getattr_xx((cp), (ga), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_setattr(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_setattr_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_lookup(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_lookup_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_lookupp(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_lookupp_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_getfh(cp, gfh) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_getfh_xx((cp), (gfh), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_setclientid(cp, sci) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_setclientid_xx((cp), (sci), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_setclientid_confirm(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_setclientid_confirm_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_close(cp, fcp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_close_xx((cp), (fcp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_access(cp, acc) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_access_xx((cp), (acc), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_open(cp, openp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_open_xx((cp), (openp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_open_confirm(cp, openp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_open_confirm_xx((cp), (openp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_read(cp, r) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_read_xx((cp), (r), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_write(cp, w) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_write_xx((cp), (w), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_commit(cp, c) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_commit_xx((cp), (c), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_attrs(fattr) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_attrs_xx((fattr), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_renew(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_renew_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_create(cp, c) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_create_xx((cp), (c), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_rename(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_rename_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_link(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_link_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_savefh(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_savefh_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_readlink(cp, uiop) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_readlink_xx((cp), (uiop), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#define nfsm_v4dissect_remove(cp) \ -do { \ - int32_t t1; \ - t1 = nfsm_v4dissect_remove_xx((cp), &md, &dpos); \ - nfsm_dcheck(t1, mrep); \ -} while (0) - -#endif /* _NFS4CLIENT_NFSM4_SUBS_H */ diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index f9bc5bffc558..05702f604ddc 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -68,8 +68,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include diff --git a/sys/nfsclient/krpc_subr.c b/sys/nfsclient/krpc_subr.c index 5682083cecee..20239043e1cc 100644 --- a/sys/nfsclient/krpc_subr.c +++ b/sys/nfsclient/krpc_subr.c @@ -57,8 +57,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include diff --git a/sys/nfsclient/nfs.h b/sys/nfsclient/nfs.h index 7f3a0f311650..845f82626f98 100644 --- a/sys/nfsclient/nfs.h +++ b/sys/nfsclient/nfs.h @@ -111,18 +111,6 @@ */ #define NFS_NFSSTATS 1 /* struct: struct nfsstats */ -/* - * File context information for nfsv4. Currently, there is only one - * lockowner for the whole machine "0." - */ -struct nfs4_fctx { - TAILQ_ENTRY(nfs4_fstate) next; - uint32_t refcnt; - struct nfs4_lowner *lop; - struct nfsnode *np; - char stateid[NFSX_V4STATEID]; -}; - #ifdef _KERNEL #ifdef MALLOC_DECLARE diff --git a/sys/nfsclient/nfs_bio.c b/sys/nfsclient/nfs_bio.c index 6c468fbe6046..92be17c0238f 100644 --- a/sys/nfsclient/nfs_bio.c +++ b/sys/nfsclient/nfs_bio.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -56,8 +57,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include @@ -65,8 +64,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - static struct buf *nfs_getcacheblk(struct vnode *vp, daddr_t bn, int size, struct thread *td); static int nfs_directio_write(struct vnode *vp, struct uio *uiop, @@ -1612,17 +1609,13 @@ nfs_doio(struct vnode *vp, struct buf *bp, struct ucred *cr, struct thread *td) case VDIR: nfsstats.readdir_bios++; uiop->uio_offset = ((u_quad_t)bp->b_lblkno) * NFS_DIRBLKSIZ; - if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) - error = nfs4_readdirrpc(vp, uiop, cr); - else { - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) { - error = nfs_readdirplusrpc(vp, uiop, cr); - if (error == NFSERR_NOTSUPP) - nmp->nm_flag &= ~NFSMNT_RDIRPLUS; - } - if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0) - error = nfs_readdirrpc(vp, uiop, cr); + if ((nmp->nm_flag & NFSMNT_RDIRPLUS) != 0) { + error = nfs_readdirplusrpc(vp, uiop, cr); + if (error == NFSERR_NOTSUPP) + nmp->nm_flag &= ~NFSMNT_RDIRPLUS; } + if ((nmp->nm_flag & NFSMNT_RDIRPLUS) == 0) + error = nfs_readdirrpc(vp, uiop, cr); /* * end-of-directory sets B_INVAL but does not generate an * error. diff --git a/sys/nfsclient/nfs_diskless.c b/sys/nfsclient/nfs_diskless.c index d6d6b2111f10..26a27b97f4b6 100644 --- a/sys/nfsclient/nfs_diskless.c +++ b/sys/nfsclient/nfs_diskless.c @@ -55,7 +55,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c index 7f5c624062e2..1aa398ebb5ce 100644 --- a/sys/nfsclient/nfs_krpc.c +++ b/sys/nfsclient/nfs_krpc.c @@ -60,7 +60,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include @@ -70,8 +69,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #ifndef NFS_LEGACYRPC #ifdef KDTRACE_HOOKS @@ -445,8 +442,6 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, return (ESTALE); } nmp = VFSTONFS(vp->v_mount); - if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) - return nfs4_request(vp, mreq, procnum, td, cred, mrp, mdp, dposp); bzero(&nf, sizeof(struct nfs_feedback_arg)); nf.nf_mount = nmp; nf.nf_td = td; @@ -740,8 +735,6 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td) struct proc *p; sigset_t tmpset; - if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) - return nfs4_sigintr(nmp, rep, td); /* Terminate all requests while attempting a forced unmount. */ if (nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF) return (EIO); diff --git a/sys/nfsclient/nfs_lock.c b/sys/nfsclient/nfs_lock.c index 19ad06641fa8..ea6649e2b36a 100644 --- a/sys/nfsclient/nfs_lock.c +++ b/sys/nfsclient/nfs_lock.c @@ -53,8 +53,6 @@ __FBSDID("$FreeBSD$"); #include -#include - #include #include #include diff --git a/sys/nfsclient/nfs_nfsiod.c b/sys/nfsclient/nfs_nfsiod.c index 9e0e272cd1b7..7dc3f19377ee 100644 --- a/sys/nfsclient/nfs_nfsiod.c +++ b/sys/nfsclient/nfs_nfsiod.c @@ -63,8 +63,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include diff --git a/sys/nfsclient/nfs_node.c b/sys/nfsclient/nfs_node.c index 517c3a9cc694..a7f00ca8bb16 100644 --- a/sys/nfsclient/nfs_node.c +++ b/sys/nfsclient/nfs_node.c @@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -49,8 +50,6 @@ __FBSDID("$FreeBSD$"); #include -#include - #include #include #include @@ -133,19 +132,13 @@ nfs_nget(struct mount *mntp, nfsfh_t *fhp, int fhsize, struct nfsnode **npp, int */ np = uma_zalloc(nfsnode_zone, M_WAITOK | M_ZERO); - if (nmp->nm_flag & NFSMNT_NFSV4) - error = getnewvnode("nfs4", mntp, &nfs4_vnodeops, &nvp); - else - error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp); + error = getnewvnode("nfs", mntp, &nfs_vnodeops, &nvp); if (error) { uma_zfree(nfsnode_zone, np); return (error); } vp = nvp; - if (nmp->nm_flag & NFSMNT_NFSV4) - vp->v_bufobj.bo_ops = &buf_ops_nfs4; - else - vp->v_bufobj.bo_ops = &buf_ops_nfs; + vp->v_bufobj.bo_ops = &buf_ops_nfs; vp->v_data = np; np->n_vnode = vp; /* diff --git a/sys/nfsclient/nfs_socket.c b/sys/nfsclient/nfs_socket.c index 42ef65589274..64951faaddc8 100644 --- a/sys/nfsclient/nfs_socket.c +++ b/sys/nfsclient/nfs_socket.c @@ -62,8 +62,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include @@ -72,8 +70,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #ifdef NFS_LEGACYRPC #define TRUE 1 @@ -1145,8 +1141,6 @@ nfs_request(struct vnode *vp, struct mbuf *mrest, int procnum, return (ESTALE); } nmp = VFSTONFS(vp->v_mount); - if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) - return nfs4_request(vp, mrest, procnum, td, cred, mrp, mdp, dposp); rep = malloc(sizeof(struct nfsreq), M_NFSREQ, M_WAITOK); bzero(rep, sizeof(struct nfsreq)); rep->r_nmp = nmp; @@ -1747,8 +1741,6 @@ nfs_sigintr(struct nfsmount *nmp, struct nfsreq *rep, struct thread *td) struct proc *p; sigset_t tmpset; - if ((nmp->nm_flag & NFSMNT_NFSV4) != 0) - return nfs4_sigintr(nmp, rep, td); if (rep) { mtx_lock(&rep->r_mtx); if (rep->r_flags & R_SOFTTERM) { diff --git a/sys/nfsclient/nfs_subs.c b/sys/nfsclient/nfs_subs.c index 1453dbf826cf..71d4fb185f60 100644 --- a/sys/nfsclient/nfs_subs.c +++ b/sys/nfsclient/nfs_subs.c @@ -65,8 +65,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include - #include #include #include diff --git a/sys/nfsclient/nfs_vfsops.c b/sys/nfsclient/nfs_vfsops.c index d8ce36c1584e..7d4802365d02 100644 --- a/sys/nfsclient/nfs_vfsops.c +++ b/sys/nfsclient/nfs_vfsops.c @@ -66,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include diff --git a/sys/nfsclient/nfs_vnops.c b/sys/nfsclient/nfs_vnops.c index 27d2c59a0aea..9f0d67a5e68b 100644 --- a/sys/nfsclient/nfs_vnops.c +++ b/sys/nfsclient/nfs_vnops.c @@ -70,8 +70,6 @@ __FBSDID("$FreeBSD$"); #include -#include - #include #include #include diff --git a/sys/nfsclient/nfsm_subs.h b/sys/nfsclient/nfsm_subs.h index 3dd817fbc12f..51d2611b949e 100644 --- a/sys/nfsclient/nfsm_subs.h +++ b/sys/nfsclient/nfsm_subs.h @@ -147,17 +147,6 @@ do { \ } \ } while (0) -#define nfsm_request_mnt(n, t, p, c) \ -do { \ - error = nfs4_request_mnt((n), mreq, (t), (p), (c), &mrep, &md, &dpos); \ - if (error != 0) { \ - if (error & NFSERR_RETERR) \ - error &= ~NFSERR_RETERR; \ - else \ - goto nfsmout; \ - } \ -} while (0) - /* *********************************** */ /* Reply interpretation phase macros */ diff --git a/sys/nfsclient/nfsmount.h b/sys/nfsclient/nfsmount.h index 75360fe03fed..85f85015834f 100644 --- a/sys/nfsclient/nfsmount.h +++ b/sys/nfsclient/nfsmount.h @@ -79,7 +79,6 @@ struct nfsmount { int nm_numgrps; /* Max. size of groupslist */ u_char nm_fh[NFSX_V4FH]; /* File handle of root dir */ int nm_fhsize; /* Size of root file handle */ - struct rpcclnt nm_rpcclnt; /* rpc state */ #ifdef NFS_LEGACYRPC struct socket *nm_so; /* Rpc socket */ #endif diff --git a/sys/nfsclient/nfsnode.h b/sys/nfsclient/nfsnode.h index 6f10d793241f..29198d8c20a2 100644 --- a/sys/nfsclient/nfsnode.h +++ b/sys/nfsclient/nfsnode.h @@ -135,8 +135,6 @@ struct nfsnode { short n_fhsize; /* size in bytes, of fh */ short n_flag; /* Flag for locking.. */ nfsfh_t n_fh; /* Small File Handle */ - struct nfs4_fctx n_rfc; - struct nfs4_fctx n_wfc; u_char *n_name; /* leaf name, for v4 OPEN op */ uint32_t n_namelen; int n_directio_opens; @@ -188,9 +186,7 @@ extern struct nfsmount *nfs_iodmount[NFS_MAXASYNCDAEMON]; extern struct vop_vector nfs_fifoops; extern struct vop_vector nfs_vnodeops; -extern struct vop_vector nfs4_vnodeops; extern struct buf_ops buf_ops_nfs; -extern struct buf_ops buf_ops_nfs4; extern vop_advlock_t *nfs_advlock_p; extern vop_reclaim_t *nfs_reclaim_p; @@ -206,12 +202,9 @@ int nfs_reclaim(struct vop_reclaim_args *); /* other stuff */ int nfs_removeit(struct sillyrename *); -int nfs4_removeit(struct sillyrename *); int nfs_nget(struct mount *, nfsfh_t *, int, struct nfsnode **, int flags); nfsuint64 *nfs_getcookie(struct nfsnode *, off_t, int); -uint64_t *nfs4_getcookie(struct nfsnode *, off_t, int); void nfs_invaldir(struct vnode *); -void nfs4_invaldir(struct vnode *); int nfs_upgrade_vnlock(struct vnode *vp); void nfs_downgrade_vnlock(struct vnode *vp, int old_lock); void nfs_printf(const char *fmt, ...); diff --git a/sys/nlm/nlm_advlock.c b/sys/nlm/nlm_advlock.c index a2c62f04c113..761ed73ad7e5 100644 --- a/sys/nlm/nlm_advlock.c +++ b/sys/nlm/nlm_advlock.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -44,7 +45,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include #include diff --git a/sys/rpc/rpcclnt.c b/sys/rpc/rpcclnt.c deleted file mode 100644 index 1c90ff6eb52d..000000000000 --- a/sys/rpc/rpcclnt.c +++ /dev/null @@ -1,2114 +0,0 @@ -/* $FreeBSD$ */ -/* $Id: rpcclnt.c,v 1.9 2003/11/05 14:59:03 rees Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/*- - * Copyright (c) 1989, 1991, 1993, 1995 The Regents of the University of - * California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by Rick Macklem at - * The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. 2. - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. 3. All advertising - * materials mentioning features or use of this software must display the - * following acknowledgement: This product includes software developed by the - * University of California, Berkeley and its contributors. 4. Neither the - * name of the University nor the names of its contributors may be used to - * endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfs_socket.c 8.5 (Berkeley) 3/30/95 - */ - -/* XXX: kill ugly debug strings */ -/* XXX: get rid of proct, as it is not even being used... (or keep it so v{2,3} - * can run, but clean it up! */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include - -#include -#include - -/* memory management */ -#ifdef __OpenBSD__ -struct pool rpctask_pool; -struct pool rpcclnt_pool; -#define RPCTASKPOOL_LWM 10 -#define RPCTASKPOOL_HWM 40 -#else -static MALLOC_DEFINE(M_RPCCLNT, "rpcclnt", "rpc state"); -#endif - -#define RPC_RETURN(X) do { RPCDEBUG("returning %d", X); return X; }while(0) - -/* - * Estimate rto for an nfs rpc sent via. an unreliable datagram. Use the mean - * and mean deviation of rtt for the appropriate type of rpc for the frequent - * rpcs and a default for the others. The justification for doing "other" - * this way is that these rpcs happen so infrequently that timer est. would - * probably be stale. Also, since many of these rpcs are non-idempotent, a - * conservative timeout is desired. getattr, lookup - A+2D read, write - - * A+4D other - nm_timeo - */ -#define RPC_RTO(n, t) \ - ((t) == 0 ? (n)->rc_timeo : \ - ((t) < 3 ? \ - (((((n)->rc_srtt[t-1] + 3) >> 2) + (n)->rc_sdrtt[t-1] + 1) >> 1) : \ - ((((n)->rc_srtt[t-1] + 7) >> 3) + (n)->rc_sdrtt[t-1] + 1))) - -#define RPC_SRTT(s,r) (r)->r_rpcclnt->rc_srtt[rpcclnt_proct((s),\ - (r)->r_procnum) - 1] - -#define RPC_SDRTT(s,r) (r)->r_rpcclnt->rc_sdrtt[rpcclnt_proct((s),\ - (r)->r_procnum) - 1] - - -/* - * There is a congestion window for outstanding rpcs maintained per mount - * point. The cwnd size is adjusted in roughly the way that: Van Jacobson, - * Congestion avoidance and Control, In "Proceedings of SIGCOMM '88". ACM, - * August 1988. describes for TCP. The cwnd size is chopped in half on a - * retransmit timeout and incremented by 1/cwnd when each rpc reply is - * received and a full cwnd of rpcs is in progress. (The sent count and cwnd - * are scaled for integer arith.) Variants of "slow start" were tried and - * were found to be too much of a performance hit (ave. rtt 3 times larger), - * I suspect due to the large rtt that nfs rpcs have. - */ -#define RPC_CWNDSCALE 256 -#define RPC_MAXCWND (RPC_CWNDSCALE * 32) -static const int rpcclnt_backoff[8] = {2, 4, 8, 16, 32, 64, 128, 256,}; - -/* XXX ugly debug strings */ -#define RPC_ERRSTR_ACCEPTED_SIZE 6 -char *rpc_errstr_accepted[RPC_ERRSTR_ACCEPTED_SIZE] = { - "", /* no good message... */ - "remote server hasn't exported program.", - "remote server can't support version number.", - "program can't support procedure.", - "procedure can't decode params.", - "remote error. remote side memory allocation failure?" -}; - -char *rpc_errstr_denied[2] = { - "remote server doesnt support rpc version 2!", - "remote server authentication error." -}; - -#define RPC_ERRSTR_AUTH_SIZE 6 -char *rpc_errstr_auth[RPC_ERRSTR_AUTH_SIZE] = { - "", - "auth error: bad credential (seal broken).", - "auth error: client must begin new session.", - "auth error: bad verifier (seal broken).", - "auth error: verifier expired or replayed.", - "auth error: rejected for security reasons.", -}; - -/* - * Static data, mostly RPC constants in XDR form - */ -static u_int32_t rpc_reply, rpc_call, rpc_vers; - -/* - * rpc_msgdenied, rpc_mismatch, rpc_auth_unix, rpc_msgaccepted, - * rpc_autherr, rpc_auth_kerb; - */ - -static u_int32_t rpcclnt_xid = 0; -static u_int32_t rpcclnt_xid_touched = 0; -struct rpcstats rpcstats; -int rpcclnt_ticks; -static int fake_wchan; - -SYSCTL_NODE(_kern, OID_AUTO, rpc, CTLFLAG_RD, 0, "RPC Subsystem"); - -SYSCTL_UINT(_kern_rpc, OID_AUTO, retries, CTLFLAG_RD, &rpcstats.rpcretries, 0, "retries"); -SYSCTL_UINT(_kern_rpc, OID_AUTO, request, CTLFLAG_RD, &rpcstats.rpcrequests, 0, "request"); -SYSCTL_UINT(_kern_rpc, OID_AUTO, timeouts, CTLFLAG_RD, &rpcstats.rpctimeouts, 0, "timeouts"); -SYSCTL_UINT(_kern_rpc, OID_AUTO, unexpected, CTLFLAG_RD, &rpcstats.rpcunexpected, 0, "unexpected"); -SYSCTL_UINT(_kern_rpc, OID_AUTO, invalid, CTLFLAG_RD, &rpcstats.rpcinvalid, 0, "invalid"); - - -#ifdef RPCCLNT_DEBUG -int rpcdebugon = 0; -SYSCTL_UINT(_kern_rpc, OID_AUTO, debug_on, CTLFLAG_RW, &rpcdebugon, 0, "RPC Debug messages"); -#endif - -/* - * Queue head for rpctask's - */ -static -TAILQ_HEAD(, rpctask) rpctask_q; -struct callout rpcclnt_callout; - -#ifdef __OpenBSD__ -static int rpcclnt_send(struct socket *, struct mbuf *, struct mbuf *, struct rpctask *); -static int rpcclnt_receive(struct rpctask *, struct mbuf **, struct mbuf **, RPC_EXEC_CTX); -#else -static int rpcclnt_send(struct socket *, struct sockaddr *, struct mbuf *, struct rpctask *); -static int rpcclnt_receive(struct rpctask *, struct sockaddr **, struct mbuf **, RPC_EXEC_CTX); -#endif - -static int rpcclnt_msg(RPC_EXEC_CTX, const char *, char *); - -static int rpcclnt_reply(struct rpctask *, RPC_EXEC_CTX); -static void rpcclnt_timer(void *); -static int rpcclnt_sndlock(int *, struct rpctask *); -static void rpcclnt_sndunlock(int *); -static int rpcclnt_rcvlock(struct rpctask *); -static void rpcclnt_rcvunlock(int *); -#if 0 -void rpcclnt_realign(struct mbuf *, int); -#else -static void rpcclnt_realign(struct mbuf **, int); -#endif - -static struct mbuf *rpcclnt_buildheader(struct rpcclnt *, int, struct mbuf *, u_int32_t, int *, struct mbuf **, struct ucred *); -static int rpcm_disct(struct mbuf **, caddr_t *, int, int, caddr_t *); -static u_int32_t rpcclnt_proct(struct rpcclnt *, u_int32_t); -static int rpc_adv(struct mbuf **, caddr_t *, int, int); -static void rpcclnt_softterm(struct rpctask * task); - -static int rpcauth_buildheader(struct rpc_auth * auth, struct ucred *, struct mbuf **, caddr_t *); - -void -rpcclnt_init(void) -{ -#ifdef __OpenBSD__ - static struct timeout rpcclnt_timer_to; -#endif - - rpcclnt_ticks = (hz * RPC_TICKINTVL + 500) / 1000; - if (rpcclnt_ticks < 1) - rpcclnt_ticks = 1; - rpcstats.rpcretries = 0; - rpcstats.rpcrequests = 0; - rpcstats.rpctimeouts = 0; - rpcstats.rpcunexpected = 0; - rpcstats.rpcinvalid = 0; - - /* - * rpc constants how about actually using more than one of these! - */ - - rpc_reply = txdr_unsigned(RPC_REPLY); - rpc_vers = txdr_unsigned(RPC_VER2); - rpc_call = txdr_unsigned(RPC_CALL); -#if 0 - rpc_msgdenied = txdr_unsigned(RPC_MSGDENIED); - rpc_msgaccepted = txdr_unsigned(RPC_MSGACCEPTED); - rpc_mismatch = txdr_unsigned(RPC_MISMATCH); - rpc_autherr = txdr_unsigned(RPC_AUTHERR); - rpc_auth_unix = txdr_unsigned(RPCAUTH_UNIX); - rpc_auth_kerb = txdr_unsigned(RPCAUTH_KERB4); -#endif - - /* initialize rpctask queue */ - TAILQ_INIT(&rpctask_q); - -#ifdef __OpenBSD__ - /* initialize pools */ - pool_init(&rpctask_pool, sizeof(struct rpctask), 0, 0, RPCTASKPOOL_LWM, - "rpctask_p", NULL); - pool_setlowat(&rpctask_pool, RPCTASKPOOL_LWM); - pool_sethiwat(&rpctask_pool, RPCTASKPOOL_HWM); - - pool_init(&rpcclnt_pool, sizeof(struct rpcclnt), 0, 0, 1, "rpcclnt_p", NULL); - - /* initialize timers */ - timeout_set(&rpcclnt_timer_to, rpcclnt_timer, &rpcclnt_timer_to); - rpcclnt_timer(&rpcclnt_timer_to); -#else /* !__OpenBSD__ */ - callout_init(&rpcclnt_callout, 0); -#endif /* !__OpenBSD__ */ - - RPCDEBUG("rpc initialed"); - - return; -} - -void -rpcclnt_uninit(void) -{ - RPCDEBUG("uninit"); - /* XXX delete sysctl variables? */ - callout_stop(&rpcclnt_callout); -} - -int -rpcclnt_setup(clnt, program, addr, sotype, soproto, auth, max_read_size, max_write_size, flags) - struct rpcclnt * clnt; - struct rpc_program * program; - struct sockaddr * addr; - int sotype; - int soproto; - struct rpc_auth * auth; - int max_read_size; - int max_write_size; - int flags; -{ - if (clnt == NULL || program == NULL || addr == NULL || auth == NULL) - RPC_RETURN (EFAULT); - - if (program->prog_name == NULL) - RPC_RETURN (EFAULT); - clnt->rc_prog = program; - - clnt->rc_name = addr; - clnt->rc_sotype = sotype; - clnt->rc_soproto = soproto; - clnt->rc_auth = auth; - clnt->rc_rsize = max_read_size; - clnt->rc_wsize = max_write_size; - clnt->rc_flag = flags; - - clnt->rc_proctlen = 0; - clnt->rc_proct = NULL; - - RPC_RETURN (0); -} - -/* - * Initialize sockets and congestion for a new RPC connection. We do not free - * the sockaddr if error. - */ -int -rpcclnt_connect(rpc, td) - struct rpcclnt *rpc; - RPC_EXEC_CTX td; -{ - struct socket *so; - int s, error, rcvreserve, sndreserve; - struct sockaddr *saddr; - -#ifdef __OpenBSD__ - struct sockaddr_in *sin; - struct mbuf *m; -#else - struct sockaddr_in sin; - - int soarg; - struct sockopt opt; -#endif - - if (rpc == NULL) { - RPCDEBUG("no rpcclnt struct!\n"); - RPC_RETURN(EFAULT); - } - - /* create the socket */ - rpc->rc_so = NULL; - - saddr = rpc->rc_name; - - error = socreate(saddr->sa_family, &rpc->rc_so, rpc->rc_sotype, - rpc->rc_soproto, td->td_ucred, td); - if (error) { - RPCDEBUG("error %d in socreate()", error); - RPC_RETURN(error); - } - so = rpc->rc_so; - rpc->rc_soflags = so->so_proto->pr_flags; - - /* - * Some servers require that the client port be a reserved port - * number. We always allocate a reserved port, as this prevents - * filehandle disclosure through UDP port capture. - */ - if (saddr->sa_family == AF_INET) { -#ifdef __OpenBSD__ - struct mbuf *mopt; - int *ip; -#endif - -#ifdef __OpenBSD__ - MGET(mopt, M_TRYWAIT, MT_SOOPTS); - mopt->m_len = sizeof(int); - ip = mtod(mopt, int *); - *ip = IP_PORTRANGE_LOW; - - error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); -#else - soarg = IP_PORTRANGE_LOW; - bzero(&opt, sizeof(struct sockopt)); - opt.sopt_dir = SOPT_SET; - opt.sopt_level = IPPROTO_IP; - opt.sopt_name = IP_PORTRANGE; - opt.sopt_val = &soarg; - opt.sopt_valsize = sizeof(soarg); - - error = sosetopt(so, &opt); -#endif - if (error) - goto bad; - -#ifdef __OpenBSD__ - MGET(m, M_TRYWAIT, MT_SONAME); - sin = mtod(m, struct sockaddr_in *); - sin->sin_len = m->m_len = sizeof(struct sockaddr_in); - sin->sin_family = AF_INET; - sin->sin_addr.s_addr = INADDR_ANY; - sin->sin_port = htons(0); - error = sobind(so, m); - m_freem(m); -#else - sin.sin_len = sizeof(struct sockaddr_in); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = INADDR_ANY; - sin.sin_port = htons(0); - /* - * &thread0 gives us root credentials to ensure sobind - * will give us a reserved ephemeral port. - */ - error = sobind(so, (struct sockaddr *) & sin, &thread0); -#endif - if (error) - goto bad; - -#ifdef __OpenBSD__ - MGET(mopt, M_TRYWAIT, MT_SOOPTS); - mopt->m_len = sizeof(int); - ip = mtod(mopt, int *); - *ip = IP_PORTRANGE_DEFAULT; - error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); -#else - soarg = IP_PORTRANGE_DEFAULT; - bzero(&opt, sizeof(struct sockopt)); - opt.sopt_dir = SOPT_SET; - opt.sopt_level = IPPROTO_IP; - opt.sopt_name = IP_PORTRANGE; - opt.sopt_val = &soarg; - opt.sopt_valsize = sizeof(soarg); - error = sosetopt(so, &opt); -#endif - if (error) - goto bad; - } - /* - * Protocols that do not require connections may be optionally left - * unconnected for servers that reply from a port other than - * NFS_PORT. - */ - if (rpc->rc_flag & RPCCLNT_NOCONN) { - if (rpc->rc_soflags & PR_CONNREQUIRED) { - error = ENOTCONN; - goto bad; - } - } else { - error = soconnect(so, saddr, td); - if (error) - goto bad; - - /* - * Wait for the connection to complete. Cribbed from the - * connect system call but with the wait timing out so that - * interruptible mounts don't hang here for a long time. - */ -#ifdef __OpenBSD__ - s = splsoftnet(); -#else - s = splnet(); -#endif - while ((so->so_state & SS_ISCONNECTING) && so->so_error == 0) { - (void)tsleep((caddr_t) & so->so_timeo, PSOCK, - "rpc", 2 * hz); - - /* - * XXX needs to catch interrupt signals. something - * like this: if ((so->so_state & SS_ISCONNECTING) && - * so->so_error == 0 && rep && (error = - * nfs_sigintr(nmp, rep, rep->r_td)) != 0) { - * so->so_state &= ~SS_ISCONNECTING; splx(s); goto - * bad; } - */ - } - if (so->so_error) { - error = so->so_error; - so->so_error = 0; - splx(s); - goto bad; - } - splx(s); - } - if (rpc->rc_flag & (RPCCLNT_SOFT | RPCCLNT_INT)) { - so->so_rcv.sb_timeo = (5 * hz); - so->so_snd.sb_timeo = (5 * hz); - } else { - so->so_rcv.sb_timeo = 0; - so->so_snd.sb_timeo = 0; - } - - - if (rpc->rc_sotype == SOCK_DGRAM) { - sndreserve = rpc->rc_wsize + RPC_MAXPKTHDR; - rcvreserve = rpc->rc_rsize + RPC_MAXPKTHDR; - } else if (rpc->rc_sotype == SOCK_SEQPACKET) { - sndreserve = (rpc->rc_wsize + RPC_MAXPKTHDR) * 2; - rcvreserve = (rpc->rc_rsize + RPC_MAXPKTHDR) * 2; - } else { - if (rpc->rc_sotype != SOCK_STREAM) - panic("rpcclnt_connect() bad sotype"); - if (so->so_proto->pr_flags & PR_CONNREQUIRED) { -#ifdef __OpenBSD__ - MGET(m, M_TRYWAIT, MT_SOOPTS); - *mtod(m, int32_t *) = 1; - m->m_len = sizeof(int32_t); - sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m); -#else - soarg = 1; - - bzero(&opt, sizeof(struct sockopt)); - opt.sopt_dir = SOPT_SET; - opt.sopt_level = SOL_SOCKET; - opt.sopt_name = SO_KEEPALIVE; - opt.sopt_val = &soarg; - opt.sopt_valsize = sizeof(soarg); - sosetopt(so, &opt); -#endif - } - if (so->so_proto->pr_protocol == IPPROTO_TCP) { -#ifdef __OpenBSD__ - MGET(m, M_TRYWAIT, MT_SOOPTS); - *mtod(m, int32_t *) = 1; - m->m_len = sizeof(int32_t); - sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m); -#else - soarg = 1; - - bzero(&opt, sizeof(struct sockopt)); - opt.sopt_dir = SOPT_SET; - opt.sopt_level = IPPROTO_TCP; - opt.sopt_name = TCP_NODELAY; - opt.sopt_val = &soarg; - opt.sopt_valsize = sizeof(soarg); - sosetopt(so, &opt); -#endif - } - sndreserve = (rpc->rc_wsize + RPC_MAXPKTHDR + - sizeof(u_int32_t)) * 2; - rcvreserve = (rpc->rc_rsize + RPC_MAXPKTHDR + - sizeof(u_int32_t)) * 2; - } - error = soreserve(so, sndreserve, rcvreserve); - if (error) - goto bad; - so->so_rcv.sb_flags |= SB_NOINTR; - so->so_snd.sb_flags |= SB_NOINTR; - - /* Initialize other non-zero congestion variables */ - rpc->rc_srtt[0] = rpc->rc_srtt[1] = rpc->rc_srtt[2] = - rpc->rc_srtt[3] = (RPC_TIMEO << 3); - rpc->rc_sdrtt[0] = rpc->rc_sdrtt[1] = rpc->rc_sdrtt[2] = - rpc->rc_sdrtt[3] = 0; - rpc->rc_cwnd = RPC_MAXCWND / 2; /* Initial send window */ - rpc->rc_sent = 0; - rpc->rc_timeouts = 0; - RPC_RETURN(0); - -bad: - rpcclnt_disconnect(rpc); - RPC_RETURN(error); -} - - -/* - * Reconnect routine: - * Called when a connection is broken on a reliable protocol. - * - clean up the old socket - * - rpcclnt_connect() again - * - set R_MUSTRESEND for all outstanding requests on mount point - * If this fails the mount point is DEAD! - * nb: Must be called with the rpcclnt_sndlock() set on the mount point. - */ -int -rpcclnt_reconnect(rep, td) - struct rpctask *rep; - RPC_EXEC_CTX td; -{ - struct rpctask *rp; - struct rpcclnt *rpc = rep->r_rpcclnt; - int error; - - rpcclnt_disconnect(rpc); - while ((error = rpcclnt_connect(rpc, td)) != 0) { - if (error == EINTR || error == ERESTART) - RPC_RETURN(EINTR); - tsleep(&fake_wchan, PSOCK, "rpccon", hz); - } - - /* - * Loop through outstanding request list and fix up all requests on - * old socket. - */ - for (rp = TAILQ_FIRST(&rpctask_q); rp != NULL; - rp = TAILQ_NEXT(rp, r_chain)) { - if (rp->r_rpcclnt == rpc) - rp->r_flags |= R_MUSTRESEND; - } - RPC_RETURN(0); -} - -/* - * RPC transport disconnect. Clean up and unlink. - */ -void -rpcclnt_disconnect(rpc) - struct rpcclnt *rpc; -{ - struct socket *so; - - if (rpc->rc_so) { - so = rpc->rc_so; - rpc->rc_so = NULL; - soshutdown(so, 2); - soclose(so); - } -} - -void -rpcclnt_safedisconnect(struct rpcclnt * rpc) -{ - struct rpctask dummytask; - - bzero(&dummytask, sizeof(dummytask)); - dummytask.r_rpcclnt = rpc; - rpcclnt_rcvlock(&dummytask); - rpcclnt_disconnect(rpc); - rpcclnt_rcvunlock(&rpc->rc_flag); -} - -/* - * This is the rpc send routine. For connection based socket types, it - * must be called with an rpcclnt_sndlock() on the socket. - * "rep == NULL" indicates that it has been called from a server. - * For the client side: - * - return EINTR if the RPC is terminated, 0 otherwise - * - set R_MUSTRESEND if the send fails for any reason - * - do any cleanup required by recoverable socket errors (?) - * For the server side: - * - return EINTR or ERESTART if interrupted by a signal - * - return EPIPE if a connection is lost for connection based sockets (TCP...) - * - do any cleanup required by recoverable socket errors (?) - */ -static int -rpcclnt_send(so, nam, top, rep) - struct socket *so; -#ifdef __OpenBSD__ - struct mbuf *nam; -#else - struct sockaddr *nam; -#endif - struct mbuf *top; - struct rpctask *rep; -{ -#ifdef __OpenBSD__ - struct mbuf *sendnam; -#else - struct sockaddr *sendnam; - struct thread *td = curthread; -#endif - int error, soflags, flags; - - if (rep) { - if (rep->r_flags & R_SOFTTERM) { - m_freem(top); - RPC_RETURN(EINTR); - } - if ((so = rep->r_rpcclnt->rc_so) == NULL) { - rep->r_flags |= R_MUSTRESEND; - m_freem(top); - RPC_RETURN(0); - } - rep->r_flags &= ~R_MUSTRESEND; - soflags = rep->r_rpcclnt->rc_soflags; - } else - soflags = so->so_proto->pr_flags; - - if ((soflags & PR_CONNREQUIRED) || (so->so_state & SS_ISCONNECTED)) - sendnam = NULL; - else - sendnam = nam; - - if (so->so_type == SOCK_SEQPACKET) - flags = MSG_EOR; - else - flags = 0; - - /* - * XXXRW: If/when this code becomes MPSAFE itself, Giant might have - * to be conditionally acquired earlier for the stack so has to avoid - * lock order reversals with any locks held over rpcclnt_send(). - */ - error = sosend(so, sendnam, NULL, top, NULL, flags, td); - if (error) { - if (rep) { - log(LOG_INFO, "rpc send error %d for service %s\n", error, - rep->r_rpcclnt->rc_prog->prog_name); - /* - * Deal with errors for the client side. - */ - if (rep->r_flags & R_SOFTTERM) - error = EINTR; - else - rep->r_flags |= R_MUSTRESEND; - } else - log(LOG_INFO, "rpc service send error %d\n", error); - - /* - * Handle any recoverable (soft) socket errors here. - */ - if (error != EINTR && error != ERESTART && - error != EWOULDBLOCK && error != EPIPE) - error = 0; - } - RPC_RETURN(error); -} - -/* - * Receive a Sun RPC Request/Reply. For SOCK_DGRAM, the work is all done by - * soreceive(), but for SOCK_STREAM we must deal with the Record Mark and - * consolidate the data into a new mbuf list. nb: Sometimes TCP passes the - * data up to soreceive() in long lists of small mbufs. For SOCK_STREAM we - * must be very careful to read an entire record once we have read any of it, - * even if the system call has been interrupted. - */ -static int -rpcclnt_receive(rep, aname, mp, td) - struct rpctask *rep; -#ifdef __OpenBSD__ - struct mbuf **aname; -#else - struct sockaddr **aname; -#endif - struct mbuf **mp; - RPC_EXEC_CTX td; -{ - struct socket *so; - struct uio auio; - struct iovec aio; - struct mbuf *m; - struct mbuf *control; - u_int32_t len; -#ifdef __OpenBSD__ - struct mbuf **getnam; -#else - struct sockaddr **getnam; -#endif - int error, sotype, rcvflg; - - /* - * Set up arguments for soreceive() - */ - *mp = NULL; - *aname = NULL; - sotype = rep->r_rpcclnt->rc_sotype; - - /* - * For reliable protocols, lock against other senders/receivers in - * case a reconnect is necessary. For SOCK_STREAM, first get the - * Record Mark to find out how much more there is to get. We must - * lock the socket against other receivers until we have an entire - * rpc request/reply. - */ - if (sotype != SOCK_DGRAM) { - error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep); - if (error) - RPC_RETURN(error); -tryagain: - /* - * Check for fatal errors and resending request. - */ - /* - * Ugh: If a reconnect attempt just happened, rc_so would - * have changed. NULL indicates a failed attempt that has - * essentially shut down this mount point. - */ - if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) { - rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag); - RPC_RETURN(EINTR); - } - so = rep->r_rpcclnt->rc_so; - if (!so) { - error = rpcclnt_reconnect(rep, td); - if (error) { - rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag); - RPC_RETURN(error); - } - goto tryagain; - } - while (rep->r_flags & R_MUSTRESEND) { - m = m_copym(rep->r_mreq, 0, M_COPYALL, M_WAIT); - rpcstats.rpcretries++; - error = rpcclnt_send(so, rep->r_rpcclnt->rc_name, m, rep); - if (error) { - if (error == EINTR || error == ERESTART || - (error = rpcclnt_reconnect(rep, td)) != 0) { - rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag); - RPC_RETURN(error); - } - goto tryagain; - } - } - rpcclnt_sndunlock(&rep->r_rpcclnt->rc_flag); - if (sotype == SOCK_STREAM) { - aio.iov_base = (caddr_t) & len; - aio.iov_len = sizeof(u_int32_t); - auio.uio_iov = &aio; - auio.uio_iovcnt = 1; - auio.uio_segflg = UIO_SYSSPACE; - auio.uio_rw = UIO_READ; - auio.uio_offset = 0; - auio.uio_resid = sizeof(u_int32_t); -#ifdef __OpenBSD__ - auio.uio_procp = td; -#else - auio.uio_td = td; -#endif - do { - rcvflg = MSG_WAITALL; - error = soreceive(so, NULL, &auio, NULL, NULL, &rcvflg); - if (error == EWOULDBLOCK && rep) { - if (rep->r_flags & R_SOFTTERM) - RPC_RETURN(EINTR); - } - } while (error == EWOULDBLOCK); - if (!error && auio.uio_resid > 0) { - log(LOG_INFO, - "short receive (%zu/%zu) from rpc server %s\n", - sizeof(u_int32_t) - auio.uio_resid, - sizeof(u_int32_t), - rep->r_rpcclnt->rc_prog->prog_name); - error = EPIPE; - } - if (error) - goto errout; - len = ntohl(len) & ~0x80000000; - /* - * This is SERIOUS! We are out of sync with the - * sender and forcing a disconnect/reconnect is all I - * can do. - */ - if (len > RPC_MAXPACKET) { - log(LOG_ERR, "%s (%d) from rpc server %s\n", - "impossible packet length", - len, - rep->r_rpcclnt->rc_prog->prog_name); - error = EFBIG; - goto errout; - } - auio.uio_resid = len; - do { - rcvflg = MSG_WAITALL; - error = soreceive(so, NULL, &auio, mp, NULL, &rcvflg); - } while (error == EWOULDBLOCK || error == EINTR || - error == ERESTART); - if (!error && auio.uio_resid > 0) { - log(LOG_INFO, - "short receive (%d/%d) from rpc server %s\n", - len - auio.uio_resid, len, - rep->r_rpcclnt->rc_prog->prog_name); - error = EPIPE; - } - } else { - /* - * NB: Since uio_resid is big, MSG_WAITALL is ignored - * and soreceive() will return when it has either a - * control msg or a data msg. We have no use for - * control msg., but must grab them and then throw - * them away so we know what is going on. - */ - auio.uio_resid = len = 100000000; /* Anything Big */ -#ifdef __OpenBSD__ - auio.uio_procp = td; -#else - auio.uio_td = td; -#endif - do { - rcvflg = 0; - error = soreceive(so, NULL, &auio, mp, &control, &rcvflg); - if (control) - m_freem(control); - if (error == EWOULDBLOCK && rep) { - if (rep->r_flags & R_SOFTTERM) - RPC_RETURN(EINTR); - } - } while (error == EWOULDBLOCK || - (!error && *mp == NULL && control)); - if ((rcvflg & MSG_EOR) == 0) - printf("Egad!!\n"); - if (!error && *mp == NULL) - error = EPIPE; - len -= auio.uio_resid; - } -errout: - if (error && error != EINTR && error != ERESTART) { - m_freem(*mp); - *mp = (struct mbuf *) 0; - if (error != EPIPE) - log(LOG_INFO, - "receive error %d from rpc server %s\n", - error, - rep->r_rpcclnt->rc_prog->prog_name); - error = rpcclnt_sndlock(&rep->r_rpcclnt->rc_flag, rep); - if (!error) - error = rpcclnt_reconnect(rep, td); - if (!error) - goto tryagain; - } - } else { - if ((so = rep->r_rpcclnt->rc_so) == NULL) - RPC_RETURN(EACCES); - if (so->so_state & SS_ISCONNECTED) - getnam = NULL; - else - getnam = aname; - auio.uio_resid = len = 1000000; -#ifdef __OpenBSD__ - auio.uio_procp = td; -#else - auio.uio_td = td; -#endif - - do { - rcvflg = 0; - error = soreceive(so, getnam, &auio, mp, NULL, &rcvflg); - RPCDEBUG("soreceive returns %d", error); - if (error == EWOULDBLOCK && (rep->r_flags & R_SOFTTERM)) { - RPCDEBUG("wouldblock && softerm -> EINTR"); - RPC_RETURN(EINTR); - } - } while (error == EWOULDBLOCK); - len -= auio.uio_resid; - } - if (error) { - m_freem(*mp); - *mp = NULL; - } else { - /* - * Search for any mbufs that are not a multiple of 4 bytes - * long or with m_data not longword aligned. These could - * cause pointer alignment problems, so copy them to well - * aligned mbufs. - */ - rpcclnt_realign(mp, 5 * RPCX_UNSIGNED); - } - RPC_RETURN(error); -} - - -/* - * Implement receipt of reply on a socket. We must search through the list of - * received datagrams matching them with outstanding requests using the xid, - * until ours is found. - */ -/* ARGSUSED */ -static int -rpcclnt_reply(myrep, td) - struct rpctask *myrep; - RPC_EXEC_CTX td; -{ - struct rpctask *rep; - struct rpcclnt *rpc = myrep->r_rpcclnt; - int32_t t1; - struct mbuf *mrep, *md; -#ifdef __OpenBSD__ - struct mbuf *nam; -#else - struct sockaddr *nam; -#endif - u_int32_t rxid, *tl; - caddr_t dpos, cp2; - int error; - - /* - * Loop around until we get our own reply - */ - for (;;) { - /* - * Lock against other receivers so that I don't get stuck in - * sbwait() after someone else has received my reply for me. - * Also necessary for connection based protocols to avoid - * race conditions during a reconnect. - */ - error = rpcclnt_rcvlock(myrep); - if (error) - RPC_RETURN(error); - /* Already received, bye bye */ - if (myrep->r_mrep != NULL) { - rpcclnt_rcvunlock(&rpc->rc_flag); - RPC_RETURN(0); - } - /* - * Get the next Rpc reply off the socket - */ - error = rpcclnt_receive(myrep, &nam, &mrep, td); - - rpcclnt_rcvunlock(&rpc->rc_flag); - - if (error) { - /* - * Ignore routing errors on connectionless - * protocols?? - */ - if (RPCIGNORE_SOERROR(rpc->rc_soflags, error)) { - rpc->rc_so->so_error = 0; - if (myrep->r_flags & R_GETONEREP) - RPC_RETURN(0); - RPCDEBUG("ingoring routing error on connectionless protocol."); - continue; - } - RPC_RETURN(error); - } -#ifdef __OpenBSD__ - if (nam) - m_freem(nam); -#else - if (nam) - free(nam, M_SONAME); -#endif - - /* - * Get the xid and check that it is an rpc reply - */ - md = mrep; - dpos = mtod(md, caddr_t); - rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED); - rxid = *tl++; - if (*tl != rpc_reply) { - rpcstats.rpcinvalid++; - m_freem(mrep); -rpcmout: - if (myrep->r_flags & R_GETONEREP) - RPC_RETURN(0); - continue; - } - /* - * Loop through the request list to match up the reply Iff no - * match, just drop the datagram - */ - TAILQ_FOREACH(rep, &rpctask_q, r_chain) { - if (rep->r_mrep == NULL && rxid == rep->r_xid) { - /* Found it.. */ - rep->r_mrep = mrep; - rep->r_md = md; - rep->r_dpos = dpos; - - /* - * Update congestion window. Do the additive - * increase of one rpc/rtt. - */ - if (rpc->rc_cwnd <= rpc->rc_sent) { - rpc->rc_cwnd += - (RPC_CWNDSCALE * RPC_CWNDSCALE + - (rpc->rc_cwnd >> 1)) / rpc->rc_cwnd; - if (rpc->rc_cwnd > RPC_MAXCWND) - rpc->rc_cwnd = RPC_MAXCWND; - } - rep->r_flags &= ~R_SENT; - rpc->rc_sent -= RPC_CWNDSCALE; - /* - * Update rtt using a gain of 0.125 on the - * mean and a gain of 0.25 on the deviation. - */ - if (rep->r_flags & R_TIMING) { - /* - * Since the timer resolution of - * NFS_HZ is so course, it can often - * result in r_rtt == 0. Since r_rtt - * == N means that the actual rtt is - * between N+dt and N+2-dt ticks, add - * 1. - */ - t1 = rep->r_rtt + 1; - t1 -= (RPC_SRTT(rpc, rep) >> 3); - RPC_SRTT(rpc, rep) += t1; - if (t1 < 0) - t1 = -t1; - t1 -= (RPC_SDRTT(rpc, rep) >> 2); - RPC_SDRTT(rpc, rep) += t1; - } - rpc->rc_timeouts = 0; - break; - } - } - /* - * If not matched to a request, drop it. If it's mine, get - * out. - */ - if (rep == 0) { - rpcstats.rpcunexpected++; - RPCDEBUG("rpc reply not matched\n"); - m_freem(mrep); - } else if (rep == myrep) { - if (rep->r_mrep == NULL) - panic("rpcreply nil"); - RPC_RETURN(0); - } - if (myrep->r_flags & R_GETONEREP) - RPC_RETURN(0); - } -} - -/* XXX: ignores tryagain! */ -/* - * code from nfs_request - goes something like this - * - fill in task struct - * - links task into list - * - calls rpcclnt_send() for first transmit - * - calls rpcclnt_reply() to get reply - * - fills in reply (which should be initialized prior to - * calling), which is valid when 0 is returned and is - * NEVER freed in this function - * - * nb: always frees the request header, but NEVER frees 'mrest' - * - * rpcclnt_setauth() should be used before calling this. EAUTH is returned if - * authentication fails. - * - * note that reply->result_* are invalid unless reply->type == - * RPC_MSGACCEPTED and reply->status == RPC_SUCCESS and that reply->verf_* - * are invalid unless reply->type == RPC_MSGACCEPTED - */ -int -rpcclnt_request(rpc, mrest, procnum, td, cred, reply) - struct rpcclnt *rpc; - struct mbuf *mrest; - int procnum; - RPC_EXEC_CTX td; - struct ucred *cred; - struct rpc_reply *reply; -{ - struct mbuf *m, *mrep; - struct rpctask *task; - u_int32_t *tl; - struct mbuf *md, *mheadend; - caddr_t dpos, cp2; - int t1, s, error = 0, mrest_len; - u_int32_t xid; - -#ifdef __OpenBSD__ - task = pool_get(&rpctask_pool, PR_WAITOK); -#else - task = malloc(sizeof(struct rpctask), M_RPCCLNT, (M_WAITOK | M_ZERO)); -#endif - - task->r_rpcclnt = rpc; - task->r_procnum = procnum; - task->r_td = td; - - mrest_len = m_length(mrest, NULL); - - m = rpcclnt_buildheader(rpc, procnum, mrest, mrest_len, &xid, &mheadend, - cred); - /* - * This can happen if the auth_type is neither UNIX or NULL - */ - if (m == NULL) { -#ifdef __OpenBSD__ - pool_put(&rpctask_pool, task); -#else - free(task, M_RPCCLNT); -#endif - error = EPROTONOSUPPORT; - goto rpcmout; - } - - /* - * For stream protocols, insert a Sun RPC Record Mark. - */ - if (rpc->rc_sotype == SOCK_STREAM) { - M_PREPEND(m, RPCX_UNSIGNED, M_WAIT); - *mtod(m, u_int32_t *) = htonl(0x80000000 | - (m->m_pkthdr.len - RPCX_UNSIGNED)); - } - task->r_mreq = m; - task->r_xid = xid; - - if (rpc->rc_flag & RPCCLNT_SOFT) - task->r_retry = rpc->rc_retry; - else - task->r_retry = RPC_MAXREXMIT + 1; /* past clip limit */ - task->r_rtt = task->r_rexmit = 0; - - if (rpcclnt_proct(rpc, procnum) > 0) - task->r_flags = R_TIMING; - else - task->r_flags = 0; - task->r_mrep = NULL; - - /* - * Do the client side RPC. - */ - rpcstats.rpcrequests++; - - /* - * Chain request into list of outstanding requests. Be sure to put it - * LAST so timer finds oldest requests first. - */ - s = splsoftclock(); - if (TAILQ_EMPTY(&rpctask_q)) - callout_reset(&rpcclnt_callout, rpcclnt_ticks, rpcclnt_timer, - NULL); - TAILQ_INSERT_TAIL(&rpctask_q, task, r_chain); - - /* - * If backing off another request or avoiding congestion, don't send - * this one now but let timer do it. If not timing a request, do it - * now. - */ - if (rpc->rc_so && (rpc->rc_sotype != SOCK_DGRAM || - (rpc->rc_flag & RPCCLNT_DUMBTIMR) || - rpc->rc_sent < rpc->rc_cwnd)) { - splx(s); - - if (rpc->rc_soflags & PR_CONNREQUIRED) - error = rpcclnt_sndlock(&rpc->rc_flag, task); - if (!error) { - error = rpcclnt_send(rpc->rc_so, rpc->rc_name, - m_copym(m, 0, M_COPYALL, M_WAIT), - task); - if (rpc->rc_soflags & PR_CONNREQUIRED) - rpcclnt_sndunlock(&rpc->rc_flag); - } - if (!error && (task->r_flags & R_MUSTRESEND) == 0) { - rpc->rc_sent += RPC_CWNDSCALE; - task->r_flags |= R_SENT; - } - } else { - splx(s); - task->r_rtt = -1; - } - - /* - * Wait for the reply from our send or the timer's. - */ - if (!error || error == EPIPE) - error = rpcclnt_reply(task, td); - - /* - * RPC done, unlink the request. - */ - s = splsoftclock(); - TAILQ_REMOVE(&rpctask_q, task, r_chain); - if (TAILQ_EMPTY(&rpctask_q)) - callout_stop(&rpcclnt_callout); - splx(s); - - /* - * Decrement the outstanding request count. - */ - if (task->r_flags & R_SENT) { - task->r_flags &= ~R_SENT; /* paranoia */ - rpc->rc_sent -= RPC_CWNDSCALE; - } - /* - * If there was a successful reply and a tprintf msg. tprintf a - * response. - */ - if (!error && (task->r_flags & R_TPRINTFMSG)) { - mtx_lock(&Giant); - rpcclnt_msg(task->r_td, rpc->rc_prog->prog_name, - "is alive again"); - mtx_unlock(&Giant); - } - - /* free request header (leaving mrest) */ - mheadend->m_next = NULL; - m_freem(task->r_mreq); - - /* initialize reply */ - reply->mrep = task->r_mrep; - reply->verf_md = NULL; - reply->result_md = NULL; - - mrep = task->r_mrep; - md = task->r_md; - dpos = task->r_dpos; - - /* task structure is no longer needed */ -#ifdef __OpenBSD__ - pool_put(&rpctask_pool, task); -#else - free(task, M_RPCCLNT); -#endif - - if (error) - goto rpcmout; - - /* - * break down the rpc header and check if ok - */ - - rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED); - reply->stat.type = fxdr_unsigned(u_int32_t, *tl); - - if (reply->stat.type == RPC_MSGDENIED) { - rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED); - reply->stat.status = fxdr_unsigned(u_int32_t, *tl); - - switch (reply->stat.status) { - case RPC_MISMATCH: - rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED); - reply->stat.mismatch_info.low = fxdr_unsigned(u_int32_t, *tl++); - reply->stat.mismatch_info.high = fxdr_unsigned(u_int32_t, *tl); - error = EOPNOTSUPP; - break; - case RPC_AUTHERR: - rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED); - reply->stat.autherr = fxdr_unsigned(u_int32_t, *tl); - error = EACCES; - break; - default: - error = EBADRPC; - break; - } - goto rpcmout; - } else if (reply->stat.type != RPC_MSGACCEPTED) { - error = EBADRPC; - goto rpcmout; - } - - rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED); - - reply->verf_md = md; - reply->verf_dpos = dpos; - - reply->verf_type = fxdr_unsigned(u_int32_t, *tl++); - reply->verf_size = fxdr_unsigned(u_int32_t, *tl); - - if (reply->verf_size != 0) - rpcm_adv(rpcm_rndup(reply->verf_size)); - - rpcm_dissect(tl, u_int32_t *, RPCX_UNSIGNED); - reply->stat.status = fxdr_unsigned(u_int32_t, *tl); - - if (reply->stat.status == RPC_SUCCESS) { - if ((uint32_t)(dpos - mtod(md, caddr_t)) >= md->m_len) { - RPCDEBUG("where is the next mbuf?"); - RPCDEBUG("%d -> %d", - (int)(dpos - mtod(md, caddr_t)), md->m_len); - if (md->m_next == NULL) { - error = EBADRPC; - goto rpcmout; - } else { - reply->result_md = md->m_next; - reply->result_dpos = mtod(reply->result_md, - caddr_t); - } - } else { - reply->result_md = md; - reply->result_dpos = dpos; - } - } else if (reply->stat.status == RPC_PROGMISMATCH) { - rpcm_dissect(tl, u_int32_t *, 2 * RPCX_UNSIGNED); - reply->stat.mismatch_info.low = fxdr_unsigned(u_int32_t, *tl++); - reply->stat.mismatch_info.high = fxdr_unsigned(u_int32_t, *tl); - error = EOPNOTSUPP; - goto rpcmout; - } else { - error = EPROTONOSUPPORT; - goto rpcmout; - } - error = 0; - -rpcmout: - RPC_RETURN(error); -} - - -/* - * RPC timer routine - * Scan the rpctask list and retranmit any requests that have timed out. - * To avoid retransmission attempts on STREAM sockets (in the future) make - * sure to set the r_retry field to 0 (implies nm_retry == 0). - */ -void -rpcclnt_timer(arg) - void *arg; -{ -#ifdef __OpenBSD__ - struct timeout *to = (struct timeout *) arg; -#endif - struct rpctask *rep; - struct mbuf *m; - struct socket *so; - struct rpcclnt *rpc; - int timeo; - int s, error; - -#ifndef __OpenBSD__ - struct thread *td = curthread; -#endif - -#ifdef __OpenBSD__ - s = splsoftnet(); -#else - s = splnet(); -#endif - mtx_lock(&Giant); /* rpc_msg -> tprintf */ - TAILQ_FOREACH(rep, &rpctask_q, r_chain) { - rpc = rep->r_rpcclnt; - if (rep->r_mrep || (rep->r_flags & R_SOFTTERM)) - continue; - if (rpcclnt_sigintr(rpc, rep, rep->r_td)) { - rep->r_flags |= R_SOFTTERM; - continue; - } - if (rep->r_rtt >= 0) { - rep->r_rtt++; - if (rpc->rc_flag & RPCCLNT_DUMBTIMR) - timeo = rpc->rc_timeo; - else - timeo = RPC_RTO(rpc, rpcclnt_proct(rep->r_rpcclnt, - rep->r_procnum)); - if (rpc->rc_timeouts > 0) - timeo *= rpcclnt_backoff[rpc->rc_timeouts - 1]; - if (rep->r_rtt <= timeo) - continue; - if (rpc->rc_timeouts < 8) - rpc->rc_timeouts++; - } - /* - * Check for server not responding - */ - if ((rep->r_flags & R_TPRINTFMSG) == 0 && - rep->r_rexmit > rpc->rc_deadthresh) { - rpcclnt_msg(rep->r_td, rpc->rc_prog->prog_name, - "not responding"); - rep->r_flags |= R_TPRINTFMSG; - } - if (rep->r_rexmit >= rep->r_retry) { /* too many */ - rpcstats.rpctimeouts++; - rep->r_flags |= R_SOFTTERM; - continue; - } - if (rpc->rc_sotype != SOCK_DGRAM) { - if (++rep->r_rexmit > RPC_MAXREXMIT) - rep->r_rexmit = RPC_MAXREXMIT; - continue; - } - if ((so = rpc->rc_so) == NULL) - continue; - - /* - * If there is enough space and the window allows.. Resend it - * Set r_rtt to -1 in case we fail to send it now. - */ - rep->r_rtt = -1; - if (sbspace(&so->so_snd) >= rep->r_mreq->m_pkthdr.len && - ((rpc->rc_flag & RPCCLNT_DUMBTIMR) || - (rep->r_flags & R_SENT) || - rpc->rc_sent < rpc->rc_cwnd) && - (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))) { - if ((rpc->rc_flag & RPCCLNT_NOCONN) == 0) - error = (*so->so_proto->pr_usrreqs->pru_send) (so, 0, m, - NULL, NULL, td); - else - error = (*so->so_proto->pr_usrreqs->pru_send)(so, 0, m, rpc->rc_name, NULL, td); - if (error) { - if (RPCIGNORE_SOERROR(rpc->rc_soflags, error)) - so->so_error = 0; - } else { - /* - * Iff first send, start timing else turn - * timing off, backoff timer and divide - * congestion window by 2. - */ - if (rep->r_flags & R_SENT) { - rep->r_flags &= ~R_TIMING; - if (++rep->r_rexmit > RPC_MAXREXMIT) - rep->r_rexmit = RPC_MAXREXMIT; - rpc->rc_cwnd >>= 1; - if (rpc->rc_cwnd < RPC_CWNDSCALE) - rpc->rc_cwnd = RPC_CWNDSCALE; - rpcstats.rpcretries++; - } else { - rep->r_flags |= R_SENT; - rpc->rc_sent += RPC_CWNDSCALE; - } - rep->r_rtt = 0; - } - } - } - mtx_unlock(&Giant); /* rpc_msg -> tprintf */ - splx(s); - -#ifdef __OpenBSD__ - timeout_add(rpcclnt_timer, to, rpcclnt_ticks); -#else - callout_reset(&rpcclnt_callout, rpcclnt_ticks, rpcclnt_timer, NULL); -#endif -} - -/* - * Test for a termination condition pending on the process. This is used for - * RPCCLNT_INT mounts. - */ -int -rpcclnt_sigintr(rpc, task, pr) - struct rpcclnt *rpc; - struct rpctask *task; - RPC_EXEC_CTX pr; -{ - struct proc *p; - - sigset_t tmpset; - - if (rpc == NULL) - return EFAULT; - - /* XXX deal with forced unmounts */ - - if (task && (task->r_flags & R_SOFTTERM)) - RPC_RETURN(EINTR); - - if (!(rpc->rc_flag & RPCCLNT_INT)) - RPC_RETURN(0); - - if (pr == NULL) - return (0); - -#ifdef __OpenBSD__ - p = pr; - if (p && p->p_siglist && - (((p->p_siglist & ~p->p_sigmask) & ~p->p_sigignore) & - RPCINT_SIGMASK)) - RPC_RETURN(EINTR); -#else - p = pr->td_proc; - PROC_LOCK(p); - tmpset = p->p_siglist; - SIGSETNAND(tmpset, pr->td_sigmask); - mtx_lock(&p->p_sigacts->ps_mtx); - SIGSETNAND(tmpset, p->p_sigacts->ps_sigignore); - mtx_unlock(&p->p_sigacts->ps_mtx); - if (SIGNOTEMPTY(p->p_siglist) && RPCCLNTINT_SIGMASK(tmpset)) { - PROC_UNLOCK(p); - RPC_RETURN(EINTR); - } - PROC_UNLOCK(p); -#endif - RPC_RETURN(0); -} - -/* - * Lock a socket against others. Necessary for STREAM sockets to ensure you - * get an entire rpc request/reply and also to avoid race conditions between - * the processes with nfs requests in progress when a reconnect is necessary. - */ -static int -rpcclnt_sndlock(flagp, task) - int *flagp; - struct rpctask *task; -{ - RPC_EXEC_CTX p; - int slpflag = 0, slptimeo = 0; - - p = task->r_td; - if (task->r_rpcclnt->rc_flag & RPCCLNT_INT) - slpflag = PCATCH; - while (*flagp & RPCCLNT_SNDLOCK) { - if (rpcclnt_sigintr(task->r_rpcclnt, task, p)) - RPC_RETURN(EINTR); - *flagp |= RPCCLNT_WANTSND; - (void)tsleep((caddr_t) flagp, slpflag | (PZERO - 1), "rpcsndlck", - slptimeo); - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - } - *flagp |= RPCCLNT_SNDLOCK; - RPC_RETURN(0); -} - -/* - * Unlock the stream socket for others. - */ -static void -rpcclnt_sndunlock(flagp) - int *flagp; -{ - - if ((*flagp & RPCCLNT_SNDLOCK) == 0) - panic("rpc sndunlock"); - *flagp &= ~RPCCLNT_SNDLOCK; - if (*flagp & RPCCLNT_WANTSND) { - *flagp &= ~RPCCLNT_WANTSND; - wakeup((caddr_t) flagp); - } -} - -static int -rpcclnt_rcvlock(task) - struct rpctask *task; -{ - int *flagp = &task->r_rpcclnt->rc_flag; - int slpflag, slptimeo = 0; - - if (*flagp & RPCCLNT_INT) - slpflag = PCATCH; - else - slpflag = 0; - while (*flagp & RPCCLNT_RCVLOCK) { - if (rpcclnt_sigintr(task->r_rpcclnt, task, task->r_td)) - RPC_RETURN(EINTR); - *flagp |= RPCCLNT_WANTRCV; - (void)tsleep((caddr_t) flagp, slpflag | (PZERO - 1), "rpcrcvlk", - slptimeo); - if (slpflag == PCATCH) { - slpflag = 0; - slptimeo = 2 * hz; - } - } - *flagp |= RPCCLNT_RCVLOCK; - RPC_RETURN(0); -} - -/* - * Unlock the stream socket for others. - */ -static void -rpcclnt_rcvunlock(flagp) - int *flagp; -{ - - if ((*flagp & RPCCLNT_RCVLOCK) == 0) - panic("nfs rcvunlock"); - *flagp &= ~RPCCLNT_RCVLOCK; - if (*flagp & RPCCLNT_WANTRCV) { - *flagp &= ~RPCCLNT_WANTRCV; - wakeup((caddr_t) flagp); - } -} - -#if 0 -/* - * Check for badly aligned mbuf data areas and realign data in an mbuf list - * by copying the data areas up, as required. - */ -void -rpcclnt_realign(m, hsiz) - struct mbuf *m; - int hsiz; -{ - struct mbuf *m2; - int siz, mlen, olen; - caddr_t tcp, fcp; - struct mbuf *mnew; - - while (m) { - /* - * This never happens for UDP, rarely happens for TCP but - * frequently happens for iso transport. - */ - if ((m->m_len & 0x3) || (mtod(m, long)&0x3)) { - olen = m->m_len; - fcp = mtod(m, caddr_t); - if ((long)fcp & 0x3) { - if (m->m_flags & M_PKTHDR) - m_tag_delete_chain(m, NULL); - m->m_flags &= ~M_PKTHDR; - if (m->m_flags & M_EXT) - m->m_data = m->m_ext.ext_buf + - ((m->m_ext.ext_size - olen) & ~0x3); - else - m->m_data = m->m_dat; - } - m->m_len = 0; - tcp = mtod(m, caddr_t); - mnew = m; - m2 = m->m_next; - - /* - * If possible, only put the first invariant part of - * the RPC header in the first mbuf. - */ - mlen = M_TRAILINGSPACE(m); - if (olen <= hsiz && mlen > hsiz) - mlen = hsiz; - - /* Loop through the mbuf list consolidating data. */ - while (m) { - while (olen > 0) { - if (mlen == 0) { - if (m2->m_flags & M_PKTHDR) - m_tag_delete_chain(m2, NULL); - m2->m_flags &= ~M_PKTHDR; - if (m2->m_flags & M_EXT) - m2->m_data = m2->m_ext.ext_buf; - else - m2->m_data = m2->m_dat; - m2->m_len = 0; - mlen = M_TRAILINGSPACE(m2); - tcp = mtod(m2, caddr_t); - mnew = m2; - m2 = m2->m_next; - } - siz = min(mlen, olen); - if (tcp != fcp) - bcopy(fcp, tcp, siz); - mnew->m_len += siz; - mlen -= siz; - olen -= siz; - tcp += siz; - fcp += siz; - } - m = m->m_next; - if (m) { - olen = m->m_len; - fcp = mtod(m, caddr_t); - } - } - - /* - * Finally, set m_len == 0 for any trailing mbufs - * that have been copied out of. - */ - while (m2) { - m2->m_len = 0; - m2 = m2->m_next; - } - return; - } - m = m->m_next; - } -} -#else -static void -rpcclnt_realign(struct mbuf **pm, int hsiz) -{ - struct mbuf *m; - struct mbuf *n = NULL; - int off = 0; - - RPCDEBUG("in rpcclnt_realign()"); - - while ((m = *pm) != NULL) { - if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_WAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_WAIT); - } - n->m_len = 0; - break; - } - pm = &m->m_next; - } - - /* - * If n is non-NULL, loop on m copying data, then replace the - * portion of the chain that had to be realigned. - */ - if (n != NULL) { - while (m) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - } - - RPCDEBUG("leave rpcclnt_realign()"); -} -#endif - -static int -rpcclnt_msg(p, server, msg) - RPC_EXEC_CTX p; - const char *server; - char *msg; -{ -#ifdef __OpenBSD__ - tpr_t tpr; - struct proc *pr = p; - - if (p) - tpr = tprintf_open(p); - else - tpr = NULL; - tprintf(tpr, "rpc server %s: %s\n", server, msg); - tprintf_close(tpr); - RPC_RETURN(0); -#else - GIANT_REQUIRED; - - tprintf(p ? p->td_proc : NULL, LOG_INFO, - "nfs server %s: %s\n", server, msg); - RPC_RETURN(0); -#endif -} - -/* - * Build the RPC header and fill in the authorization info. The authorization - * string argument is only used when the credentials come from outside of the - * kernel (AUTH_KERB). (likewise, the ucred is only used when inside the - * kernel) Returns the head of the mbuf list. - */ -static struct mbuf * -rpcclnt_buildheader(rc, procid, mrest, mrest_len, xidp, mheadend, cred) - struct rpcclnt *rc; - int procid; - struct mbuf *mrest; - u_int32_t mrest_len; - int *xidp; - struct mbuf **mheadend; - struct ucred * cred; -{ - /* register */ struct mbuf *mb; - register u_int32_t *tl; - /* register */ caddr_t bpos; - struct mbuf *mreq, *mb2; - int error; - - MGETHDR(mb, M_WAIT, MT_DATA); - if (6 * RPCX_UNSIGNED >= MINCLSIZE) { - MCLGET(mb, M_WAIT); - } else if (6 * RPCX_UNSIGNED < MHLEN) { - MH_ALIGN(mb, 6 * RPCX_UNSIGNED); - } else { - RPCDEBUG("mbuf too small"); - panic("cheap bailout"); - } - mb->m_len = 0; - mreq = mb; - bpos = mtod(mb, caddr_t); - - /* - * First the RPC header. - */ - rpcm_build(tl, u_int32_t *, 6 * RPCX_UNSIGNED); - - /* Get a new (non-zero) xid */ - if ((rpcclnt_xid == 0) && (rpcclnt_xid_touched == 0)) { - rpcclnt_xid = arc4random(); - rpcclnt_xid_touched = 1; - } else { - while ((*xidp = arc4random() % 256) == 0); - rpcclnt_xid += *xidp; - } - - /* XXX: funky... */ - *tl++ = *xidp = txdr_unsigned(rpcclnt_xid); - - *tl++ = rpc_call; - *tl++ = rpc_vers; - *tl++ = txdr_unsigned(rc->rc_prog->prog_id); - *tl++ = txdr_unsigned(rc->rc_prog->prog_version); - *tl++ = txdr_unsigned(procid); - - if ((error = rpcauth_buildheader(rc->rc_auth, cred, &mb, &bpos))) { - m_freem(mreq); - RPCDEBUG("rpcauth_buildheader failed %d", error); - return NULL; - } - - mb->m_next = mrest; - *mheadend = mb; - mreq->m_pkthdr.len = m_length(mreq, NULL); - mreq->m_pkthdr.rcvif = NULL; - return (mreq); -} - -/* - * Help break down an mbuf chain by setting the first siz bytes contiguous - * pointed to by returned val. This is used by the macros rpcm_dissect and - * rpcm_dissecton for tough cases. (The macros use the vars. dpos and dpos2) - */ -static int -rpcm_disct(mdp, dposp, siz, left, cp2) - struct mbuf **mdp; - caddr_t *dposp; - int siz; - int left; - caddr_t *cp2; -{ - struct mbuf *mp, *mp2; - int siz2, xfer; - caddr_t p; - - mp = *mdp; - while (left == 0) { - *mdp = mp = mp->m_next; - if (mp == NULL) - RPC_RETURN(EBADRPC); - left = mp->m_len; - *dposp = mtod(mp, caddr_t); - } - if (left >= siz) { - *cp2 = *dposp; - *dposp += siz; - } else if (mp->m_next == NULL) { - RPC_RETURN(EBADRPC); - } else if (siz > MHLEN) { - panic("rpc S too big"); - } else { - MGET(mp2, M_WAIT, MT_DATA); - mp2->m_next = mp->m_next; - mp->m_next = mp2; - mp->m_len -= left; - mp = mp2; - *cp2 = p = mtod(mp, caddr_t); - bcopy(*dposp, p, left); /* Copy what was left */ - siz2 = siz - left; - p += left; - mp2 = mp->m_next; - /* Loop around copying up the siz2 bytes */ - while (siz2 > 0) { - if (mp2 == NULL) - RPC_RETURN(EBADRPC); - xfer = (siz2 > mp2->m_len) ? mp2->m_len : siz2; - if (xfer > 0) { - bcopy(mtod(mp2, caddr_t), p, xfer); - RPCMADV(mp2, xfer); - mp2->m_len -= xfer; - p += xfer; - siz2 -= xfer; - } - if (siz2 > 0) - mp2 = mp2->m_next; - } - mp->m_len = siz; - *mdp = mp2; - *dposp = mtod(mp2, caddr_t); - } - RPC_RETURN(0); -} - - - -static u_int32_t -rpcclnt_proct(rpc, procid) - struct rpcclnt *rpc; - u_int32_t procid; -{ - if (rpc->rc_proctlen != 0 && rpc->rc_proct != NULL && - procid < rpc->rc_proctlen) { - return rpc->rc_proct[procid]; - } - return (0); -} - -static int -rpc_adv(mdp, dposp, offs, left) - struct mbuf **mdp; - caddr_t *dposp; - int offs; - int left; -{ - struct mbuf *m; - int s; - - m = *mdp; - s = left; - while (s < offs) { - offs -= s; - m = m->m_next; - if (m == NULL) - RPC_RETURN(EBADRPC); - s = m->m_len; - } - *mdp = m; - *dposp = mtod(m, caddr_t) + offs; - RPC_RETURN(0); -} - -int -rpcclnt_cancelreqs(rpc) - struct rpcclnt *rpc; -{ - struct rpctask *task; - int i, s; - - s = splnet(); - TAILQ_FOREACH(task, &rpctask_q, r_chain) { - if (rpc != task->r_rpcclnt || task->r_mrep != NULL || - (task->r_flags & R_SOFTTERM)) - continue; - rpcclnt_softterm(task); - } - splx(s); - - for (i = 0; i < 30; i++) { - s = splnet(); - TAILQ_FOREACH(task, &rpctask_q, r_chain) { - if (rpc == task->r_rpcclnt) - break; - } - splx(s); - if (task == NULL) - return (0); - tsleep(&fake_wchan, PSOCK, "nfscancel", hz); - } - return (EBUSY); -} - -static void -rpcclnt_softterm(struct rpctask * task) -{ - task->r_flags |= R_SOFTTERM; - if (task->r_flags & R_SENT) { - task->r_rpcclnt->rc_sent -= RPC_CWNDSCALE; - task->r_flags &= ~R_SENT; - } -} - - -#ifndef __OpenBSD__ -/* called by rpcclnt_get() */ -void -rpcclnt_create(struct rpcclnt ** rpc) -{ - *rpc = malloc(sizeof(struct rpcclnt), M_RPCCLNT, M_WAITOK | M_ZERO); -} - -/* called by rpcclnt_put() */ -void -rpcclnt_destroy(struct rpcclnt * rpc) -{ - if (rpc != NULL) { - free(rpc, M_RPCCLNT); - } else { - RPCDEBUG("attempting to free a NULL rpcclnt (not dereferenced)"); - } -} -#endif /* !__OpenBSD__ */ - - -/* XXX: add a lock around the auth structure in struct rpcclnt and make this - * call safe for calling durring a connection */ -static int -rpcauth_buildheader(struct rpc_auth * auth, struct ucred * cred, struct mbuf ** mhdr, caddr_t * bp) -{ - size_t authsiz, verfsiz; - uint32_t mlen, grpsiz; - register struct mbuf *mb, *mb2; - caddr_t bpos; - register u_int32_t *tl; - register int i; - - if (auth == NULL || mhdr == NULL) - return EFAULT; - - switch (auth->auth_type) { - case RPCAUTH_NULL: - authsiz = 0; - verfsiz = 0; - break; - case RPCAUTH_UNIX: - authsiz = (5 + cred->cr_ngroups) * RPCX_UNSIGNED; - verfsiz = 0; - break; - default: - return EPROTONOSUPPORT; - break; - }; - - mlen = rpcm_rndup(authsiz) + rpcm_rndup(verfsiz) + 4 * RPCX_UNSIGNED; - - mb = *mhdr; - bpos = *bp; - - rpcm_build(tl, u_int32_t *, mlen); - - *bp = bpos; - *mhdr = mb; - - *tl++ = txdr_unsigned(auth->auth_type); - *tl++ = txdr_unsigned(authsiz); - switch (auth->auth_type) { - case RPCAUTH_UNIX: - *tl++ = 0; - *tl++ = 0; - - *tl++ = txdr_unsigned(cred->cr_uid); - *tl++ = txdr_unsigned(cred->cr_groups[0]); - grpsiz = cred->cr_ngroups; - *tl++ = txdr_unsigned(grpsiz); - /* XXX: groups[0] is already sent... */ - for (i = 0 ; i < grpsiz ; i++) { - *tl++ = txdr_unsigned(cred->cr_groups[i]); - } - - /* null verification header */ - *tl++ = txdr_unsigned(RPCAUTH_NULL); - *tl++ = 0; - break; - case RPCAUTH_NULL: - /* just a null verf header */ - *tl++ = txdr_unsigned(RPCAUTH_NULL); - *tl = 0; - break; - default: - panic("inconsistent rpc auth type"); - break; - } - - return 0; -} diff --git a/sys/rpc/rpcclnt.h b/sys/rpc/rpcclnt.h deleted file mode 100644 index f57c4dc91dce..000000000000 --- a/sys/rpc/rpcclnt.h +++ /dev/null @@ -1,354 +0,0 @@ -/* $FreeBSD$ */ -/* $OpenBSD: nfsmount.h,v 1.11 2002/03/14 01:27:13 millert Exp $ */ -/* $NetBSD: nfsmount.h,v 1.10 1996/02/18 11:54:03 fvdl Exp $ */ - -/*- - * copyright (c) 2003 - * the regents of the university of michigan - * all rights reserved - * - * permission is granted to use, copy, create derivative works and redistribute - * this software and such derivative works for any purpose, so long as the name - * of the university of michigan is not used in any advertising or publicity - * pertaining to the use or distribution of this software without specific, - * written prior authorization. if the above copyright notice or any other - * identification of the university of michigan is included in any copy of any - * portion of this software, then the disclaimer below must also be included. - * - * this software is provided as is, without representation from the university - * of michigan as to its fitness for any purpose, and without warranty by the - * university of michigan of any kind, either express or implied, including - * without limitation the implied warranties of merchantability and fitness for - * a particular purpose. the regents of the university of michigan shall not be - * liable for any damages, including special, indirect, incidental, or - * consequential damages, with respect to any claim arising out of or in - * connection with the use of the software, even if it has been or is hereafter - * advised of the possibility of such damages. - */ - -/*- - * Copyright (c) 1989, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Rick Macklem at The University of Guelph. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)nfsmount.h 8.3 (Berkeley) 3/30/95 - */ - - -#ifndef _RPCCLNT_H_ -#define _RPCCLNT_H_ - -#include -#include -#include -#include - -#ifdef __OpenBSD__ - #define RPC_EXEC_CTX struct proc * -#else - #define RPC_EXEC_CTX struct thread * -#endif - - -#ifdef RPCCLNT_DEBUG -#define RPCDEBUG(args...) do{ \ - if(rpcdebugon != 0){ \ - printf("%s(): ", __func__);\ - printf(args); \ - printf("\n"); \ - }}while(0) -#else -#define RPCDEBUG(args...) -#endif - -/* from nfs/nfs.h */ -#define RPC_TICKINTVL 10 - - -/* from nfs/nfsproto.h */ -#define RPC_MAXDATA 32768 -#define RPC_MAXPKTHDR 404 -#define RPC_MAXPACKET (RPC_MAXPKTHDR + RPC_MAXDATA) - -#define RPCX_UNSIGNED 4 - -/* defines for rpcclnt's rc_flags - XXX these flags came from the NFSMNT_* flags in OpenBSD's sys/mount.h */ -#define RPCCLNT_SOFT 0x001 /* soft mount (hard is details) */ -#define RPCCLNT_INT 0x002 /* allow interrupts on hard mounts */ -#define RPCCLNT_NOCONN 0x004 /* dont connect the socket (udp) */ -#define RPCCLNT_DUMBTIMR 0x010 - -#define RPCCLNT_SNDLOCK 0x100 -#define RPCCLNT_WANTSND 0x200 -#define RPCCLNT_RCVLOCK 0x400 -#define RPCCLNT_WANTRCV 0x800 - - -/* Flag values for r_flags */ -#define R_TIMING 0x01 /* timing request (in mntp) */ -#define R_SENT 0x02 /* request has been sent */ -#define R_SOFTTERM 0x04 /* soft mnt, too many retries */ -#define R_INTR 0x08 /* intr mnt, signal pending */ -#define R_SOCKERR 0x10 /* Fatal error on socket */ -#define R_TPRINTFMSG 0x20 /* Did a tprintf msg. */ -#define R_MUSTRESEND 0x40 /* Must resend request */ -#define R_GETONEREP 0x80 /* Probe for one reply only */ - - -#define RPC_HZ (hz / rpcclnt_ticks) /* Ticks/sec */ -#define RPC_TIMEO (1 * RPC_HZ) /* Default timeout = 1 second */ - -#define RPC_MAXREXMIT 100 /* Stop counting after this many */ - - -#define RPCIGNORE_SOERROR(s, e) \ - ((e) != EINTR && (e) != ERESTART && (e) != EWOULDBLOCK && \ - ((s) & PR_CONNREQUIRED) == 0) - -#define RPCINT_SIGMASK (sigmask(SIGINT)|sigmask(SIGTERM)|sigmask(SIGKILL)| \ - sigmask(SIGHUP)|sigmask(SIGQUIT)) - -#define RPCMADV(m, s) (m)->m_data += (s) - -#define RPCAUTH_ROOTCREDS NULL - -#define RPCCLNTINT_SIGMASK(set) \ - (SIGISMEMBER(set, SIGINT) || SIGISMEMBER(set, SIGTERM) || \ - SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) || \ - SIGISMEMBER(set, SIGQUIT)) - - -#define fxdr_unsigned(t, v) ((t)ntohl((int32_t)(v))) -#define txdr_unsigned(v) (htonl((int32_t)(v))) - - -/* global rpcstats - * XXX should be per rpcclnt */ -struct rpcstats { - int rpcretries; - int rpcrequests; - int rpctimeouts; - int rpcunexpected; - int rpcinvalid; -}; - -struct rpc_program { - u_int32_t prog_id; - u_int32_t prog_version; - char * prog_name; -}; - -struct rpc_auth { - unsigned int auth_type; -}; - -struct rpctask { - TAILQ_ENTRY(rpctask) r_chain; - struct mbuf *r_mreq; - struct mbuf *r_mrep; - struct mbuf *r_md; - caddr_t r_dpos; - - struct rpcclnt *r_rpcclnt; - - u_int32_t r_xid; - int r_flags; /* flags on request, see below */ - int r_retry; /* max retransmission count */ - int r_rexmit; /* current retrans count */ - int r_timer; /* tick counter on reply */ - int r_procnum; /* NFS procedure number */ - int r_rtt; /* RTT for rpc */ - RPC_EXEC_CTX r_td; -}; - -struct rpc_reply { - struct { - u_int32_t type; - u_int32_t status; - - /* used only when reply == RPC_MSGDENIED and - * status == RPC_AUTHERR */ - u_int32_t autherr; - - /* rpc mismatch info if reply == RPC_MSGDENIED and - * status == RPC_MISMATCH */ - struct { - u_int32_t low; - u_int32_t high; - } mismatch_info; - } stat; - - /* head of the mbuf chain */ - struct mbuf * mrep; - - /* mbuf and position of the verification opaque data - * note that this is only valid when stat.reply == RPC_MSGACCEPTED */ - u_int32_t verf_type; - u_int32_t verf_size; - struct mbuf * verf_md; - caddr_t verf_dpos; - - /* mbuf and postion of the result of the rpc request */ - struct mbuf * result_md; - caddr_t result_dpos; -}; - - -/* - * RPC Client connection context. - * One allocated on every NFS mount. - * Holds RPC specific information for mount. - */ -/* XXX: please note that all pointer type variables are just set (not copied), - * so it is up to the user to free these values */ -struct rpcclnt { - int rc_flag; /* For RPCCLNT_* flags */ - - int rc_wsize; /* Max size of the request data */ - int rc_rsize; /* Max size of the response data */ - struct sockaddr *rc_name; - struct socket *rc_so; /* Rpc socket */ - int rc_sotype; /* Type of socket */ - int rc_soproto; /* and protocol */ - int rc_soflags; /* pr_flags for socket protocol */ - - int rc_timeo; /* Init timer for NFSMNT_DUMBTIMR */ - int rc_retry; /* Max retries */ - int rc_srtt[4]; /* Timers for rpcs */ - int rc_sdrtt[4]; - int rc_sent; /* Request send count */ - int rc_cwnd; /* Request send window */ - int rc_timeouts; /* Request timeouts */ - -/* XXX: this is not being set!!!! */ - int rc_deadthresh; /* Threshold of timeouts-->dead server*/ - - - /* authentication: */ - /* currently can be RPCAUTH_NULL, RPCAUTH_KERBV4, RPCAUTH_UNIX */ - /* should be kept in XDR form */ - int rc_authtype; /* Authenticator type */ - - -#if 0 - /* RPCAUTH_KERB4 */ - int rc_authlen; /* and length */ - char *rc_authstr; /* Authenticator string */ - int rc_verflen; - char *rc_verfstr; /* and the verifier */ -#endif - - /* RPCAUTH_UNIX*/ - struct rpc_auth * rc_auth; /* authentication */ - -#if 0 - /* stored in XDR form (network byte order) */ - unsigned int rc_progid; /* program id */ - unsigned int rc_progvers; /* program version */ - - /* name of server for log messages */ - const char *rc_servername; /* for printing error messages */ -#else - struct rpc_program * rc_prog; -#endif - - /* XXX: this should be removed */ - int rc_proctlen; /* if == 0 then rc_proct == NULL */ - int * rc_proct; -}; - -#ifdef __OpenBSD__ -extern struct pool rpcreply_pool; -extern struct pool rpcclnt_pool; -#else -/* MALLOC_DECLARE(M_RPC); */ -#endif -extern int rpcdebugon; - - -#ifdef __OpenBSD__ -#define rpcclnt_get(X) \ - do { \ - (X) = pool_get(&rpcclnt_pool, PR_WAITOK); \ - bzero((X), sizeof(struct rpcclnt)); \ - }while(0) - -#define rpcclnt_put(X) \ - do { \ - if ((X) != NULL){ \ - pool_put(&rpcclnt_pool, (X)); \ - }}while(0) - -#else /* !__OpenBSD__ */ - -/* usage count for module (un)loading */ -extern unsigned int rpcclnt_usage; -extern struct mtx rpcclnt_usage_mutex; - -void rpcclnt_create(struct rpcclnt ** rpc); -void rpcclnt_destroy(struct rpcclnt * rpc); - -#define rpcclnt_get(X) rpcclnt_create(&(X)) -#define rpcclnt_put(X) rpcclnt_destroy(X) - -#ifdef RPCCLNT_TEST -struct rpcclnt_test_args { - int nothing; -}; -int rpcclnt_test(struct thread *, struct rpcclnt_test_args *); - -#define RPC_RETURN(X) do { RPCDEBUG("returning %d", X); return X; }while(0) -#endif /* RPCCLNT_TEST */ - -#endif /* !__OpenBSD__ */ - -void rpcclnt_init(void); -void rpcclnt_uninit(void); -#if 0 -int rpcclnt_setup(struct rpcclnt *, int, struct sockaddr *, int, int, int, int, const char *, int, int); -#endif - -int rpcclnt_setup(struct rpcclnt *, struct rpc_program *, struct sockaddr *, int, int, struct rpc_auth *, int, int, int); - - -int rpcclnt_connect(struct rpcclnt *, RPC_EXEC_CTX td); -int rpcclnt_reconnect(struct rpctask *, RPC_EXEC_CTX td); -void rpcclnt_disconnect(struct rpcclnt *); -void rpcclnt_safedisconnect(struct rpcclnt *); - -void rpcclnt_setauth(struct rpcclnt *, u_int32_t, u_int32_t, char *, u_int32_t, char *, struct ucred *); -int rpcclnt_request(struct rpcclnt *, struct mbuf *, int, RPC_EXEC_CTX, struct ucred *, struct rpc_reply *); -int rpcclnt_err(struct rpc_reply *); - -int rpcclnt_cancelreqs(struct rpcclnt *); -int rpcclnt_sigintr(struct rpcclnt *, struct rpctask *, RPC_EXEC_CTX); - - -#endif /* _RPCCLNT_H_ */ From 8ab21fb261f8b7b4e945deb61e7a69539b377606 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 22 May 2009 13:56:16 +0000 Subject: [PATCH 401/544] Further idmapd garbage collection -- remove rc.d Makefile reference and default settings. Submitted by: Pawel Worach --- etc/defaults/rc.conf | 2 -- etc/rc.d/Makefile | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 71b88a1b9362..b1f09df61709 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -300,8 +300,6 @@ nfs_client_enable="NO" # This host is an NFS client (or NO). nfs_access_cache="60" # Client cache timeout in seconds nfs_server_enable="NO" # This host is an NFS server (or NO). nfs_server_flags="-u -t -n 4" # Flags to nfsd (if enabled). -idmapd_enable="NO" # Run the NFS4 id mapper (YES/NO). -idmapd_flags="" # Additional flags for idmapd. mountd_enable="NO" # Run mountd (or NO). mountd_flags="-r" # Flags to mountd (if NFS server enabled). weak_mountd_authentication="NO" # Allow non-root mount requests to be served. diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index d28fb8b5c69f..d1b90e2b1692 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -14,7 +14,7 @@ FILES= DAEMON FILESYSTEMS LOGIN NETWORKING SERVERS \ gbde geli geli2 gssd \ hcsecd \ hostapd hostid hostname \ - idmapd inetd initrandom \ + inetd initrandom \ ip6addrctl ip6fw ipfilter ipfs ipfw ipmon \ ipnat ipsec ipxrouted \ jail \ From 5cc27cc3527992b532d4573cdeadc874ec25662d Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Fri, 22 May 2009 13:57:44 +0000 Subject: [PATCH 402/544] Add University of Michigan removed files to ObsoleteFiles.inc. Submitted by: Pawel Worach --- ObsoleteFiles.inc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index d552080f3782..ee2e2a95c9ac 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -14,6 +14,11 @@ # The file is partitioned: OLD_FILES first, then OLD_LIBS and OLD_DIRS last. # +# 20090522: removal of University of Michigan NFSv4 client +OLD_FILES+=etc/rc.d/idmapd +OLD_FILES+=sbin/idmapd +OLD_FILES+=sbin/mount_nfs4 +OLD_FILES+=usr/share/man/man8/mount_nfs4.8.gz # 20090417: removal of legacy versions of USB network interface drivers OLD_FILES+=usr/include/legacy/dev/usb/if_auereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_axereg.h From 795123550214c759e379ed4f51f6f888ed19d1ac Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 14:53:26 +0000 Subject: [PATCH 403/544] Fix the comment in sys/fs/nfs/nfs.h to correctly reflect the current use of the R_xxx flags. This changed when the NFS_LEGACYRPC code was removed from the subsystem. Approved by: kib (mentor) --- sys/fs/nfs/nfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index 250ce1a58db8..0160af2a1894 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -477,7 +477,7 @@ struct nfssockreq { */ TAILQ_HEAD(nfsreqhead, nfsreq); -/* First 8 R_xxx flags defined in rpc/rpcclnt.h, the rest are here */ +/* This is the only nfsreq R_xxx flag still used. */ #define R_DONTRECOVER 0x00000100 /* don't initiate recovery when this rpc gets a stale state reply */ From 6ffb637d4a303f7c03ba18ca0f78292cd4a18495 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 15:01:47 +0000 Subject: [PATCH 404/544] Change the code in the experimental nfs client to avoid flushing writes upon close when a write delegation is held by the client. This should be safe to do, now that nfsv4 Close operations are delayed until ncl_inactive() is called for the vnode. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clvnops.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvnops.c b/sys/fs/nfsclient/nfs_clvnops.c index 4b320ac881e3..047e3eb65a86 100644 --- a/sys/fs/nfsclient/nfs_clvnops.c +++ b/sys/fs/nfsclient/nfs_clvnops.c @@ -687,12 +687,8 @@ nfs_close(struct vop_close_args *ap) int cm = newnfs_commit_on_close ? 1 : 0; error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm); /* np->n_flag &= ~NMODIFIED; */ - } else if (NFS_ISV4(vp)) { - int cm; - if (newnfs_commit_on_close != 0) - cm = 1; - else - cm = nfscl_mustflush(vp); + } else if (NFS_ISV4(vp) && nfscl_mustflush(vp)) { + int cm = newnfs_commit_on_close ? 1 : 0; error = ncl_flush(vp, MNT_WAIT, cred, ap->a_td, cm); /* as above w.r.t. races when clearing NMODIFIED */ /* np->n_flag &= ~NMODIFIED; */ From c2009a4c90853a08129783a36b5d8d5dd8fcdfed Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Fri, 22 May 2009 15:06:03 +0000 Subject: [PATCH 405/544] Fix a possible panic cxgb_controller_attach() routine that would occur only if prepping the adapter failed. Slight adjustment to comments. Fix a bug whereby downing the interface didn't preven it from processing packets. Submitted by: Navdeep Parhar MFC after: 1 week --- sys/dev/cxgb/cxgb_main.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index e51002559563..621fd389cfab 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -404,8 +404,9 @@ upgrade_fw(adapter_t *sc) * 5. Allocate the BAR for doing MSI-X. * 6. Setup the line interrupt iff MSI-X is not supported. * 7. Create the driver's taskq. - * 8. Start the task queue threads. - * 9. Update the firmware if required. + * 8. Start one task queue service thread. + * 9. Check if the firmware and SRAM are up-to-date. They will be + * auto-updated later (before FULL_INIT_DONE), if required. * 10. Create a child device for each MAC (port) * 11. Initialize T3 private state. * 12. Trigger the LED @@ -665,7 +666,7 @@ cxgb_controller_attach(device_t dev) } /* - * The cxgb_controlller_detach routine is called with the device is + * The cxgb_controller_detach routine is called with the device is * unloaded from the system. */ @@ -685,7 +686,7 @@ cxgb_controller_detach(device_t dev) * The cxgb_free() is called by the cxgb_controller_detach() routine * to tear down the structures that were built up in * cxgb_controller_attach(), and should be the final piece of work - * done when fullly unloading the driver. + * done when fully unloading the driver. * * * 1. Shutting down the threads started by the cxgb_controller_attach() @@ -724,7 +725,8 @@ cxgb_free(struct adapter *sc) bus_generic_detach(sc->dev); for (i = 0; i < (sc)->params.nports; i++) { - if (device_delete_child(sc->dev, sc->portdev[i]) != 0) + if (sc->portdev[i] && + device_delete_child(sc->dev, sc->portdev[i]) != 0) device_printf(sc->dev, "failed to delete child port\n"); } @@ -1768,7 +1770,7 @@ cxgb_up(struct adapter *sc) /* - * Release resources when all the ports and offloading have been stopped. + * Bring down the interface but do not free any resources. */ static void cxgb_down_locked(struct adapter *sc) @@ -1903,6 +1905,7 @@ cxgb_init_locked(struct port_info *p) callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_sge_reset_adapter(sc); + sc->flags &= ~CXGB_SHUTDOWN; ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } @@ -1923,10 +1926,13 @@ static void cxgb_stop_locked(struct port_info *pi) { struct ifnet *ifp; + adapter_t *sc = pi->adapter; PORT_LOCK_ASSERT_OWNED(pi); ADAPTER_LOCK_ASSERT_NOTOWNED(pi->adapter); + sc->flags |= CXGB_SHUTDOWN; + ifp = pi->ifp; t3_port_intr_disable(pi->adapter, pi->port_id); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); From 682eec57c4d5bf357744d47e2f23bb0ee8829b39 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 15:08:12 +0000 Subject: [PATCH 406/544] Modify the mount handling code in the experimental nfs client to use the newer nmount() style arguments, as is used by mount_nfs.c. This prepares the kernel code for the use of a mount_nfs.c with changes for the experimental client integrated into it. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clvfsops.c | 297 +++++++++++++++++++++++++------- 1 file changed, 232 insertions(+), 65 deletions(-) diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 992a7644a410..412ad1db0d84 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -93,6 +93,7 @@ static int nfs_tprintf_delay = NFS_TPRINTF_DELAY; SYSCTL_INT(_vfs_newnfs, NFS_TPRINTF_DELAY, downdelayinterval, CTLFLAG_RW, &nfs_tprintf_delay, 0, ""); +static void nfs_sec_name(char *, int *); static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, struct ucred *, struct thread *); static int mountnfs(struct nfs_args *, struct mount *, @@ -507,6 +508,17 @@ nfs_mountdiskless(char *path, return (0); } +static void +nfs_sec_name(char *sec, int *flagsp) +{ + if (!strcmp(sec, "krb5")) + *flagsp |= NFSMNT_KERB; + else if (!strcmp(sec, "krb5i")) + *flagsp |= (NFSMNT_KERB | NFSMNT_INTEGRITY); + else if (!strcmp(sec, "krb5p")) + *flagsp |= (NFSMNT_KERB | NFSMNT_PRIVACY); +} + static void nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, struct ucred *cred, struct thread *td) @@ -652,12 +664,14 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp, } } -static const char *nfs_opts[] = { "from", "nfs_args", +static const char *nfs_opts[] = { "from", "noatime", "noexec", "suiddir", "nosuid", "nosymfollow", "union", "noclusterr", "noclusterw", "multilabel", "acls", "force", "update", - "async", "dumbtimer", "noconn", "nolockd", "intr", "rdirplus", "resvport", - "readdirsize", "soft", "hard", "mntudp", "tcp", "wsize", "rsize", - "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", + "async", "noconn", "nolockd", "conn", "lockd", "intr", "rdirplus", + "readdirsize", "soft", "hard", "mntudp", "tcp", "udp", "wsize", "rsize", + "retrans", "acregmin", "acregmax", "acdirmin", "acdirmax", "resvport", + "readahead", "hostname", "timeout", "addr", "fh", "nfsv3", "sec", + "principal", "nfsv4", "gssname", "allgssname", "dirpath", NULL }; /* @@ -697,14 +711,15 @@ nfs_mount(struct mount *mp) .acdirmax = NFS_MAXDIRATTRTIMO, .dirlen = 0, .krbnamelen = 0, + .srvkrbnamelen = 0, }; - int error; - struct sockaddr *nam; + int error = 0, ret, len; + struct sockaddr *nam = NULL; struct vnode *vp; struct thread *td; char hst[MNAMELEN]; - size_t len; u_char nfh[NFSX_FHMAX], krbname[100], dirpath[100], srvkrbname[100]; + char *opt, *name, *secname; if (vfs_filteropt(mp->mnt_optnew, nfs_opts)) { error = EINVAL; @@ -717,17 +732,172 @@ nfs_mount(struct mount *mp) goto out; } - error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, sizeof args); - if (error) - goto out; - - if (args.version != NFS_ARGSVERSION) { - error = EPROGMISMATCH; - goto out; - } - nfscl_init(); + /* Handle the new style options. */ + if (vfs_getopt(mp->mnt_optnew, "noconn", NULL, NULL) == 0) + args.flags |= NFSMNT_NOCONN; + if (vfs_getopt(mp->mnt_optnew, "conn", NULL, NULL) == 0) + args.flags |= NFSMNT_NOCONN; + if (vfs_getopt(mp->mnt_optnew, "nolockd", NULL, NULL) == 0) + args.flags |= NFSMNT_NOLOCKD; + if (vfs_getopt(mp->mnt_optnew, "lockd", NULL, NULL) == 0) + args.flags &= ~NFSMNT_NOLOCKD; + if (vfs_getopt(mp->mnt_optnew, "intr", NULL, NULL) == 0) + args.flags |= NFSMNT_INT; + if (vfs_getopt(mp->mnt_optnew, "rdirplus", NULL, NULL) == 0) + args.flags |= NFSMNT_RDIRPLUS; + if (vfs_getopt(mp->mnt_optnew, "resvport", NULL, NULL) == 0) + args.flags |= NFSMNT_RESVPORT; + if (vfs_getopt(mp->mnt_optnew, "noresvport", NULL, NULL) == 0) + args.flags &= ~NFSMNT_RESVPORT; + if (vfs_getopt(mp->mnt_optnew, "soft", NULL, NULL) == 0) + args.flags |= NFSMNT_SOFT; + if (vfs_getopt(mp->mnt_optnew, "hard", NULL, NULL) == 0) + args.flags &= ~NFSMNT_SOFT; + if (vfs_getopt(mp->mnt_optnew, "mntudp", NULL, NULL) == 0) + args.sotype = SOCK_DGRAM; + if (vfs_getopt(mp->mnt_optnew, "udp", NULL, NULL) == 0) + args.sotype = SOCK_DGRAM; + if (vfs_getopt(mp->mnt_optnew, "tcp", NULL, NULL) == 0) + args.sotype = SOCK_STREAM; + if (vfs_getopt(mp->mnt_optnew, "nfsv3", NULL, NULL) == 0) + args.flags |= NFSMNT_NFSV3; + if (vfs_getopt(mp->mnt_optnew, "nfsv4", NULL, NULL) == 0) { + args.flags |= NFSMNT_NFSV4; + args.sotype = SOCK_STREAM; + } + if (vfs_getopt(mp->mnt_optnew, "allgssname", NULL, NULL) == 0) + args.flags |= NFSMNT_ALLGSSNAME; + if (vfs_getopt(mp->mnt_optnew, "readdirsize", (void **)&opt, NULL) == 0) { + if (opt == NULL) { + vfs_mount_error(mp, "illegal readdirsize"); + error = EINVAL; + goto out; + } + ret = sscanf(opt, "%d", &args.readdirsize); + if (ret != 1 || args.readdirsize <= 0) { + vfs_mount_error(mp, "illegal readdirsize: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_READDIRSIZE; + } + if (vfs_getopt(mp->mnt_optnew, "readahead", (void **)&opt, NULL) == 0) { + if (opt == NULL) { + vfs_mount_error(mp, "illegal readahead"); + error = EINVAL; + goto out; + } + ret = sscanf(opt, "%d", &args.readahead); + if (ret != 1 || args.readahead <= 0) { + vfs_mount_error(mp, "illegal readahead: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_READAHEAD; + } + if (vfs_getopt(mp->mnt_optnew, "wsize", (void **)&opt, NULL) == 0) { + if (opt == NULL) { + vfs_mount_error(mp, "illegal wsize"); + error = EINVAL; + goto out; + } + ret = sscanf(opt, "%d", &args.wsize); + if (ret != 1 || args.wsize <= 0) { + vfs_mount_error(mp, "illegal wsize: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_WSIZE; + } + if (vfs_getopt(mp->mnt_optnew, "rsize", (void **)&opt, NULL) == 0) { + if (opt == NULL) { + vfs_mount_error(mp, "illegal rsize"); + error = EINVAL; + goto out; + } + ret = sscanf(opt, "%d", &args.rsize); + if (ret != 1 || args.rsize <= 0) { + vfs_mount_error(mp, "illegal wsize: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_RSIZE; + } + if (vfs_getopt(mp->mnt_optnew, "retrans", (void **)&opt, NULL) == 0) { + if (opt == NULL) { + vfs_mount_error(mp, "illegal retrans"); + error = EINVAL; + goto out; + } + ret = sscanf(opt, "%d", &args.retrans); + if (ret != 1 || args.retrans <= 0) { + vfs_mount_error(mp, "illegal retrans: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_RETRANS; + } + if (vfs_getopt(mp->mnt_optnew, "acregmin", (void **)&opt, NULL) == 0) { + ret = sscanf(opt, "%d", &args.acregmin); + if (ret != 1 || args.acregmin < 0) { + vfs_mount_error(mp, "illegal acregmin: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_ACREGMIN; + } + if (vfs_getopt(mp->mnt_optnew, "acregmax", (void **)&opt, NULL) == 0) { + ret = sscanf(opt, "%d", &args.acregmax); + if (ret != 1 || args.acregmax < 0) { + vfs_mount_error(mp, "illegal acregmax: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_ACREGMAX; + } + if (vfs_getopt(mp->mnt_optnew, "acdirmin", (void **)&opt, NULL) == 0) { + ret = sscanf(opt, "%d", &args.acdirmin); + if (ret != 1 || args.acdirmin < 0) { + vfs_mount_error(mp, "illegal acdirmin: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_ACDIRMIN; + } + if (vfs_getopt(mp->mnt_optnew, "acdirmax", (void **)&opt, NULL) == 0) { + ret = sscanf(opt, "%d", &args.acdirmax); + if (ret != 1 || args.acdirmax < 0) { + vfs_mount_error(mp, "illegal acdirmax: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_ACDIRMAX; + } + if (vfs_getopt(mp->mnt_optnew, "timeout", (void **)&opt, NULL) == 0) { + ret = sscanf(opt, "%d", &args.timeo); + if (ret != 1 || args.timeo <= 0) { + vfs_mount_error(mp, "illegal timeout: %s", + opt); + error = EINVAL; + goto out; + } + args.flags |= NFSMNT_TIMEO; + } + if (vfs_getopt(mp->mnt_optnew, "sec", + (void **) &secname, NULL) == 0) + nfs_sec_name(secname, &args.flags); + if (mp->mnt_flag & MNT_UPDATE) { struct nfsmount *nmp = VFSTONFS(mp); @@ -769,62 +939,58 @@ nfs_mount(struct mount *mp) */ if (nfs_ip_paranoia == 0) args.flags |= NFSMNT_NOCONN; - if (args.fhsize < 0 || args.fhsize > NFSX_FHMAX) { + + if (vfs_getopt(mp->mnt_optnew, "fh", (void **)&args.fh, + &args.fhsize) == 0) { + if (args.fhsize > NFSX_FHMAX) { + vfs_mount_error(mp, "Bad file handle"); + error = EINVAL; + goto out; + } + bcopy(args.fh, nfh, args.fhsize); + } else { + args.fhsize = 0; + } + + (void) vfs_getopt(mp->mnt_optnew, "hostname", (void **)&args.hostname, + &len); + if (args.hostname == NULL) { + vfs_mount_error(mp, "Invalid hostname"); error = EINVAL; goto out; } - if (args.fhsize > 0) { - error = copyin((caddr_t)args.fh, (caddr_t)nfh, args.fhsize); - if (error) - goto out; - } - error = copyinstr(args.hostname, hst, MNAMELEN-1, &len); - if (error) - goto out; - bzero(&hst[len], MNAMELEN - len); - if (args.krbnamelen > 0) { - if (args.krbnamelen >= 100) { - error = EINVAL; - goto out; - } - error = copyin(args.krbname, krbname, args.krbnamelen); - if (error) - goto out; - krbname[args.krbnamelen] = '\0'; - } else { + bcopy(args.hostname, hst, MNAMELEN); + hst[MNAMELEN - 1] = '\0'; + + if (vfs_getopt(mp->mnt_optnew, "principal", (void **)&name, NULL) == 0) + strlcpy(srvkrbname, name, sizeof (srvkrbname)); + else + snprintf(srvkrbname, sizeof (srvkrbname), "nfs@%s", hst); + args.srvkrbnamelen = strlen(srvkrbname); + + if (vfs_getopt(mp->mnt_optnew, "gssname", (void **)&name, NULL) == 0) + strlcpy(krbname, name, sizeof (krbname)); + else krbname[0] = '\0'; - args.krbnamelen = 0; - } - if (args.dirlen > 0) { - if (args.dirlen >= 100) { - error = EINVAL; - goto out; - } - error = copyin(args.dirpath, dirpath, args.dirlen); - if (error) - goto out; - dirpath[args.dirlen] = '\0'; - } else { + args.krbnamelen = strlen(krbname); + + if (vfs_getopt(mp->mnt_optnew, "dirpath", (void **)&name, NULL) == 0) + strlcpy(dirpath, name, sizeof (dirpath)); + else dirpath[0] = '\0'; - args.dirlen = 0; - } - if (args.srvkrbnamelen > 0) { - if (args.srvkrbnamelen >= 100) { - error = EINVAL; + args.dirlen = strlen(dirpath); + + if (vfs_getopt(mp->mnt_optnew, "addr", (void **)&args.addr, + &args.addrlen) == 0) { + if (args.addrlen > SOCK_MAXADDRLEN) { + error = ENAMETOOLONG; goto out; } - error = copyin(args.srvkrbname, srvkrbname, args.srvkrbnamelen); - if (error) - goto out; - srvkrbname[args.srvkrbnamelen] = '\0'; - } else { - srvkrbname[0] = '\0'; - args.srvkrbnamelen = 0; + nam = malloc(args.addrlen, M_SONAME, M_WAITOK); + bcopy(args.addr, nam, args.addrlen); + nam->sa_len = args.addrlen; } - /* sockargs() call must be after above copyin() calls */ - error = getsockaddr(&nam, (caddr_t)args.addr, args.addrlen); - if (error) - goto out; + args.fh = nfh; error = mountnfs(&args, mp, nam, hst, krbname, dirpath, srvkrbname, &vp, td->td_ucred, td); @@ -939,6 +1105,8 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, nmp->nm_mountp = mp; mtx_init(&nmp->nm_mtx, "NFSmount lock", NULL, MTX_DEF | MTX_DUPOK); + nfs_decode_args(mp, nmp, argp, cred, td); + /* * V2 can only handle 32 bit filesizes. A 4GB-1 limit may be too * high, depending on whether we end up with negative offsets in @@ -986,7 +1154,6 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, else nmp->nm_sockreq.nr_vers = NFS_VER2; - nfs_decode_args(mp, nmp, argp, cred, td); /* * For Connection based sockets (TCP,...) do the connect here, From ae1add4e55214610068712ef35b5787f01fcae53 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Fri, 22 May 2009 15:56:43 +0000 Subject: [PATCH 407/544] Make 'struct acl' larger, as required to support NFSv4 ACLs. Provide compatibility interfaces in both kernel and libc. Reviewed by: rwatson --- bin/cp/Makefile | 2 +- lib/libc/posix1e/Makefile.inc | 3 + lib/libc/posix1e/Symbol.map | 9 +- lib/libc/posix1e/acl_compat.c | 59 +++++++ lib/libc/posix1e/acl_delete.c | 6 +- lib/libc/posix1e/acl_entry.c | 2 + lib/libc/posix1e/acl_get.c | 5 + lib/libc/posix1e/acl_init.c | 4 +- lib/libc/posix1e/acl_set.c | 3 + lib/libc/posix1e/acl_support.c | 21 +++ lib/libc/posix1e/acl_support.h | 1 + lib/libc/posix1e/acl_valid.c | 4 +- sbin/restore/Makefile | 2 +- sys/kern/subr_acl_posix1e.c | 2 + sys/kern/vfs_acl.c | 147 +++++++++++++++- sys/sys/acl.h | 119 +++++++++++-- sys/ufs/ufs/ufs_acl.c | 302 ++++++++++++++++++--------------- 17 files changed, 525 insertions(+), 166 deletions(-) create mode 100644 lib/libc/posix1e/acl_compat.c diff --git a/bin/cp/Makefile b/bin/cp/Makefile index 9180efe26c3f..5a5e1a457d16 100644 --- a/bin/cp/Makefile +++ b/bin/cp/Makefile @@ -3,6 +3,6 @@ PROG= cp SRCS= cp.c utils.c -CFLAGS+= -DVM_AND_BUFFER_CACHE_SYNCHRONIZED +CFLAGS+= -DVM_AND_BUFFER_CACHE_SYNCHRONIZED -D_ACL_PRIVATE .include diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index 99f58e3c42e2..8e60366e1b89 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -2,8 +2,11 @@ .PATH: ${.CURDIR}/posix1e +CFLAGS+=-D_ACL_PRIVATE + SRCS+= acl_calc_mask.c \ acl_copy.c \ + acl_compat.c \ acl_delete.c \ acl_delete_entry.c \ acl_entry.c \ diff --git a/lib/libc/posix1e/Symbol.map b/lib/libc/posix1e/Symbol.map index dd3c08fe0689..16f452ad1994 100644 --- a/lib/libc/posix1e/Symbol.map +++ b/lib/libc/posix1e/Symbol.map @@ -21,15 +21,12 @@ FBSD_1.0 { acl_get_link_np; acl_get_fd; acl_get_fd_np; - acl_get_perm_np; acl_get_permset; acl_get_qualifier; acl_get_tag_type; acl_init; acl_dup; - acl_add_perm; acl_clear_perms; - acl_delete_perm; acl_set_file; acl_set_link_np; acl_set_fd; @@ -67,3 +64,9 @@ FBSD_1.0 { mac_set_link; mac_set_proc; }; + +FBSD_1.1 { + acl_add_perm; + acl_delete_perm; + acl_get_perm_np; +}; diff --git a/lib/libc/posix1e/acl_compat.c b/lib/libc/posix1e/acl_compat.c new file mode 100644 index 000000000000..6172f5e48aff --- /dev/null +++ b/lib/libc/posix1e/acl_compat.c @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2008 Edward Tomasz Napierała + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE + * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include + +/* + * Compatibility wrappers for applications compiled against libc from before + * NFSv4 ACLs were added. + */ +int +__oldacl_get_perm_np(acl_permset_t permset_d, oldacl_perm_t perm) +{ + + return (acl_get_perm_np(permset_d, perm)); +} + +int +__oldacl_add_perm(acl_permset_t permset_d, oldacl_perm_t perm) +{ + + return (acl_add_perm(permset_d, perm)); +} + +int +__oldacl_delete_perm(acl_permset_t permset_d, oldacl_perm_t perm) +{ + + return (acl_delete_perm(permset_d, perm)); +} + +__sym_compat(acl_get_perm_np, __oldacl_get_perm_np, FBSD_1.0); +__sym_compat(acl_add_perm, __oldacl_add_perm, FBSD_1.0); +__sym_compat(acl_delete_perm, __oldacl_delete_perm, FBSD_1.0); diff --git a/lib/libc/posix1e/acl_delete.c b/lib/libc/posix1e/acl_delete.c index a93cd7b2ec9d..1bbadd583396 100644 --- a/lib/libc/posix1e/acl_delete.c +++ b/lib/libc/posix1e/acl_delete.c @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" #include +#include "acl_support.h" + int acl_delete_def_file(const char *path_p) { @@ -56,6 +58,7 @@ int acl_delete_file_np(const char *path_p, acl_type_t type) { + type = _acl_type_unold(type); return (__acl_delete_file(path_p, type)); } @@ -63,13 +66,14 @@ int acl_delete_link_np(const char *path_p, acl_type_t type) { + type = _acl_type_unold(type); return (__acl_delete_link(path_p, type)); } - int acl_delete_fd_np(int filedes, acl_type_t type) { + type = _acl_type_unold(type); return (___acl_delete_fd(filedes, type)); } diff --git a/lib/libc/posix1e/acl_entry.c b/lib/libc/posix1e/acl_entry.c index f5bdbede9c5c..aaef6113f6ee 100644 --- a/lib/libc/posix1e/acl_entry.c +++ b/lib/libc/posix1e/acl_entry.c @@ -61,6 +61,8 @@ acl_create_entry(acl_t *acl_p, acl_entry_t *entry_p) (**entry_p).ae_tag = ACL_UNDEFINED_TAG; (**entry_p).ae_id = ACL_UNDEFINED_ID; (**entry_p).ae_perm = ACL_PERM_NONE; + (**entry_p).ae_entry_type = 0; + (**entry_p).ae_flags = 0; (*acl_p)->ats_cur_entry = 0; diff --git a/lib/libc/posix1e/acl_get.c b/lib/libc/posix1e/acl_get.c index 1f97baaecabc..6c98fe9e509d 100644 --- a/lib/libc/posix1e/acl_get.c +++ b/lib/libc/posix1e/acl_get.c @@ -50,6 +50,8 @@ __FBSDID("$FreeBSD$"); #include #include +#include "acl_support.h" + acl_t acl_get_file(const char *path_p, acl_type_t type) { @@ -60,6 +62,7 @@ acl_get_file(const char *path_p, acl_type_t type) if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); error = __acl_get_file(path_p, type, &aclp->ats_acl); if (error) { acl_free(aclp); @@ -79,6 +82,7 @@ acl_get_link_np(const char *path_p, acl_type_t type) if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); error = __acl_get_link(path_p, type, &aclp->ats_acl); if (error) { acl_free(aclp); @@ -117,6 +121,7 @@ acl_get_fd_np(int fd, acl_type_t type) if (aclp == NULL) return (NULL); + type = _acl_type_unold(type); error = ___acl_get_fd(fd, type, &aclp->ats_acl); if (error) { acl_free(aclp); diff --git a/lib/libc/posix1e/acl_init.c b/lib/libc/posix1e/acl_init.c index 6ce40de47969..905df60bce0f 100644 --- a/lib/libc/posix1e/acl_init.c +++ b/lib/libc/posix1e/acl_init.c @@ -54,8 +54,10 @@ acl_init(int count) } acl = malloc(sizeof(struct acl_t_struct)); - if (acl != NULL) + if (acl != NULL) { bzero(acl, sizeof(struct acl_t_struct)); + acl->ats_acl.acl_maxcnt = ACL_MAX_ENTRIES; + } return (acl); } diff --git a/lib/libc/posix1e/acl_set.c b/lib/libc/posix1e/acl_set.c index 34d5a336e093..8abbe1b197ef 100644 --- a/lib/libc/posix1e/acl_set.c +++ b/lib/libc/posix1e/acl_set.c @@ -58,6 +58,7 @@ acl_set_file(const char *path_p, acl_type_t type, acl_t acl) errno = EINVAL; return (-1); } + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -80,6 +81,7 @@ acl_set_link_np(const char *path_p, acl_type_t type, acl_t acl) errno = EINVAL; return (-1); } + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -114,6 +116,7 @@ acl_set_fd_np(int fd, acl_t acl, acl_type_t type) { int error; + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { diff --git a/lib/libc/posix1e/acl_support.c b/lib/libc/posix1e/acl_support.c index 7c1e8789c98b..8943f15860fc 100644 --- a/lib/libc/posix1e/acl_support.c +++ b/lib/libc/posix1e/acl_support.c @@ -376,3 +376,24 @@ _posix1e_acl_add_entry(acl_t acl, acl_tag_t tag, uid_t id, acl_perm_t perm) return (0); } + +/* + * Convert "old" type - ACL_TYPE_{ACCESS,DEFAULT}_OLD - into its "new" + * counterpart. It's neccessary for the old (pre-NFS4 ACLs) binaries + * to work with new libc and kernel. Fixing 'type' for old binaries with + * old libc and new kernel is being done by kern/vfs_acl.c:type_unold(). + */ +int +_acl_type_unold(acl_type_t type) +{ + switch (type) { + case ACL_TYPE_ACCESS_OLD: + return (ACL_TYPE_ACCESS); + + case ACL_TYPE_DEFAULT_OLD: + return (ACL_TYPE_DEFAULT); + + default: + return (type); + } +} diff --git a/lib/libc/posix1e/acl_support.h b/lib/libc/posix1e/acl_support.h index a5c93c01a043..c5cbc9ca50eb 100644 --- a/lib/libc/posix1e/acl_support.h +++ b/lib/libc/posix1e/acl_support.h @@ -34,6 +34,7 @@ #define _POSIX1E_ACL_STRING_PERM_MAXSIZE 3 /* read, write, exec */ +int _acl_type_unold(acl_type_t type); int _posix1e_acl_check(acl_t acl); int _posix1e_acl_sort(acl_t acl); int _posix1e_acl(acl_t acl, acl_type_t type); diff --git a/lib/libc/posix1e/acl_valid.c b/lib/libc/posix1e/acl_valid.c index 9b1f9b96c4d2..166e6142cdea 100644 --- a/lib/libc/posix1e/acl_valid.c +++ b/lib/libc/posix1e/acl_valid.c @@ -81,6 +81,7 @@ acl_valid_file_np(const char *pathp, acl_type_t type, acl_t acl) errno = EINVAL; return (-1); } + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -101,6 +102,7 @@ acl_valid_link_np(const char *pathp, acl_type_t type, acl_t acl) errno = EINVAL; return (-1); } + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -121,6 +123,7 @@ acl_valid_fd_np(int fd, acl_type_t type, acl_t acl) errno = EINVAL; return (-1); } + type = _acl_type_unold(type); if (_posix1e_acl(acl, type)) { error = _posix1e_acl_sort(acl); if (error) { @@ -131,6 +134,5 @@ acl_valid_fd_np(int fd, acl_type_t type, acl_t acl) acl->ats_cur_entry = 0; - return (___acl_aclcheck_fd(fd, type, &acl->ats_acl)); } diff --git a/sbin/restore/Makefile b/sbin/restore/Makefile index c06a3db9116c..8097190d5d59 100644 --- a/sbin/restore/Makefile +++ b/sbin/restore/Makefile @@ -5,7 +5,7 @@ PROG= restore LINKS= ${BINDIR}/restore ${BINDIR}/rrestore -CFLAGS+=-DRRESTORE +CFLAGS+=-DRRESTORE -D_ACL_PRIVATE WARNS?= 0 SRCS= main.c interactive.c restore.c dirs.c symtab.c tape.c utilities.c \ dumprmt.c diff --git a/sys/kern/subr_acl_posix1e.c b/sys/kern/subr_acl_posix1e.c index 1c6b14830e9f..e0016e7e7673 100644 --- a/sys/kern/subr_acl_posix1e.c +++ b/sys/kern/subr_acl_posix1e.c @@ -409,6 +409,8 @@ acl_posix1e_mode_to_entry(acl_tag_t tag, uid_t uid, gid_t gid, mode_t mode) acl_entry.ae_tag = tag; acl_entry.ae_perm = acl_posix1e_mode_to_perm(tag, mode); + acl_entry.ae_entry_type = 0; + acl_entry.ae_flags = 0; switch(tag) { case ACL_USER_OBJ: acl_entry.ae_id = uid; diff --git a/sys/kern/vfs_acl.c b/sys/kern/vfs_acl.c index e8618c8840cc..dfbff09bf3e7 100644 --- a/sys/kern/vfs_acl.c +++ b/sys/kern/vfs_acl.c @@ -56,7 +56,9 @@ __FBSDID("$FreeBSD$"); #include -static MALLOC_DEFINE(M_ACL, "acl", "Access Control Lists"); +CTASSERT(ACL_MAX_ENTRIES >= OLDACL_MAX_ENTRIES); + +MALLOC_DEFINE(M_ACL, "acl", "Access Control Lists"); static int vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, struct acl *aclp); @@ -65,6 +67,133 @@ static int vacl_get_acl(struct thread *td, struct vnode *vp, static int vacl_aclcheck(struct thread *td, struct vnode *vp, acl_type_t type, struct acl *aclp); +int +acl_copy_oldacl_into_acl(const struct oldacl *source, struct acl *dest) +{ + int i; + + if (source->acl_cnt < 0 || source->acl_cnt > OLDACL_MAX_ENTRIES) + return (EINVAL); + + bzero(dest, sizeof(*dest)); + + dest->acl_cnt = source->acl_cnt; + dest->acl_maxcnt = ACL_MAX_ENTRIES; + + for (i = 0; i < dest->acl_cnt; i++) { + dest->acl_entry[i].ae_tag = source->acl_entry[i].ae_tag; + dest->acl_entry[i].ae_id = source->acl_entry[i].ae_id; + dest->acl_entry[i].ae_perm = source->acl_entry[i].ae_perm; + } + + return (0); +} + +int +acl_copy_acl_into_oldacl(const struct acl *source, struct oldacl *dest) +{ + int i; + + if (source->acl_cnt < 0 || source->acl_cnt > OLDACL_MAX_ENTRIES) + return (EINVAL); + + bzero(dest, sizeof(*dest)); + + dest->acl_cnt = source->acl_cnt; + + for (i = 0; i < dest->acl_cnt; i++) { + dest->acl_entry[i].ae_tag = source->acl_entry[i].ae_tag; + dest->acl_entry[i].ae_id = source->acl_entry[i].ae_id; + dest->acl_entry[i].ae_perm = source->acl_entry[i].ae_perm; + } + + return (0); +} + +/* + * At one time, "struct ACL" was extended in order to add support for NFSv4 + * ACLs. Instead of creating compatibility versions of all the ACL-related + * syscalls, they were left intact. It's possible to find out what the code + * calling these syscalls (libc) expects basing on "type" argument - if it's + * either ACL_TYPE_ACCESS_OLD or ACL_TYPE_DEFAULT_OLD (which previously were + * known as ACL_TYPE_ACCESS and ACL_TYPE_DEFAULT), then it's the "struct + * oldacl". If it's something else, then it's the new "struct acl". In the + * latter case, the routines below just copyin/copyout the contents. In the + * former case, they copyin the "struct oldacl" and convert it to the new + * format. + */ +static int +acl_copyin(void *user_acl, struct acl *kernel_acl, acl_type_t type) +{ + int error; + struct oldacl old; + + switch (type) { + case ACL_TYPE_ACCESS_OLD: + case ACL_TYPE_DEFAULT_OLD: + error = copyin(user_acl, &old, sizeof(old)); + if (error != 0) + break; + acl_copy_oldacl_into_acl(&old, kernel_acl); + break; + + default: + error = copyin(user_acl, kernel_acl, sizeof(*kernel_acl)); + if (kernel_acl->acl_maxcnt != ACL_MAX_ENTRIES) + return (EINVAL); + } + + return (error); +} + +static int +acl_copyout(struct acl *kernel_acl, void *user_acl, acl_type_t type) +{ + int error; + struct oldacl old; + + switch (type) { + case ACL_TYPE_ACCESS_OLD: + case ACL_TYPE_DEFAULT_OLD: + error = acl_copy_acl_into_oldacl(kernel_acl, &old); + if (error != 0) + break; + + error = copyout(&old, user_acl, sizeof(old)); + break; + + default: + if (fuword((char *)user_acl + + offsetof(struct acl, acl_maxcnt)) != ACL_MAX_ENTRIES) + return (EINVAL); + + error = copyout(kernel_acl, user_acl, sizeof(*kernel_acl)); + } + + return (error); +} + +/* + * Convert "old" type - ACL_TYPE_{ACCESS,DEFAULT}_OLD - into its "new" + * counterpart. It's required for old (pre-NFS4 ACLs) libc to work + * with new kernel. Fixing 'type' for old binaries with new libc + * is being done in lib/libc/posix1e/acl_support.c:_acl_type_unold(). + */ +static int +acl_type_unold(int type) +{ + switch (type) { + case ACL_TYPE_ACCESS_OLD: + return (ACL_TYPE_ACCESS); + + case ACL_TYPE_DEFAULT_OLD: + return (ACL_TYPE_DEFAULT); + + default: + return (type); + } +} + /* * These calls wrap the real vnode operations, and are called by the syscall * code once the syscall has converted the path or file descriptor to a vnode @@ -85,7 +214,7 @@ vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, int error; inkernelacl = acl_alloc(M_WAITOK); - error = copyin(aclp, inkernelacl, sizeof(struct acl)); + error = acl_copyin(aclp, inkernelacl, type); if (error) goto out; error = vn_start_write(vp, &mp, V_WAIT | PCATCH); @@ -97,7 +226,8 @@ vacl_set_acl(struct thread *td, struct vnode *vp, acl_type_t type, if (error != 0) goto out_unlock; #endif - error = VOP_SETACL(vp, type, inkernelacl, td->td_ucred, td); + error = VOP_SETACL(vp, acl_type_unold(type), inkernelacl, + td->td_ucred, td); #ifdef MAC out_unlock: #endif @@ -125,13 +255,15 @@ vacl_get_acl(struct thread *td, struct vnode *vp, acl_type_t type, if (error != 0) goto out; #endif - error = VOP_GETACL(vp, type, inkernelacl, td->td_ucred, td); + error = VOP_GETACL(vp, acl_type_unold(type), inkernelacl, + td->td_ucred, td); + #ifdef MAC out: #endif VOP_UNLOCK(vp, 0); if (error == 0) - error = copyout(inkernelacl, aclp, sizeof(struct acl)); + error = acl_copyout(inkernelacl, aclp, type); acl_free(inkernelacl); return (error); } @@ -154,7 +286,7 @@ vacl_delete(struct thread *td, struct vnode *vp, acl_type_t type) if (error) goto out; #endif - error = VOP_SETACL(vp, type, 0, td->td_ucred, td); + error = VOP_SETACL(vp, acl_type_unold(type), 0, td->td_ucred, td); #ifdef MAC out: #endif @@ -174,7 +306,7 @@ vacl_aclcheck(struct thread *td, struct vnode *vp, acl_type_t type, int error; inkernelacl = acl_alloc(M_WAITOK); - error = copyin(aclp, inkernelacl, sizeof(struct acl)); + error = acl_copyin(aclp, inkernelacl, type); if (error) goto out; error = VOP_ACLCHECK(vp, type, inkernelacl, td->td_ucred, td); @@ -430,6 +562,7 @@ acl_alloc(int flags) struct acl *aclp; aclp = malloc(sizeof(*aclp), M_ACL, flags); + aclp->acl_maxcnt = ACL_MAX_ENTRIES; return (aclp); } diff --git a/sys/sys/acl.h b/sys/sys/acl.h index 6e4a7317ba3f..c14423a554bf 100644 --- a/sys/sys/acl.h +++ b/sys/sys/acl.h @@ -43,39 +43,104 @@ * POSIX.1e ACL types and related constants. */ +typedef uint32_t acl_tag_t; +typedef uint32_t acl_perm_t; +typedef uint16_t acl_entry_type_t; +typedef uint16_t acl_flag_t; +typedef int acl_type_t; +typedef int *acl_permset_t; +typedef uint16_t *acl_flagset_t; + +/* + * With 254 entries, "struct acl_t_struct" is exactly one 4kB page big. + * Note that with NFS4 ACLs, the maximum number of ACL entries one + * may set on file or directory is about half of ACL_MAX_ENTRIES. + * + * If you increase this, you might also need to increase + * _ACL_T_ALIGNMENT_BITS in lib/libc/posix1e/acl_support.h. + * + * The maximum number of POSIX.1e ACLs is controlled + * by OLDACL_MAX_ENTRIES. Changing that one will break binary + * compatibility with pre-8.0 userland and change on-disk ACL layout. + */ +#define ACL_MAX_ENTRIES 254 + +#if defined(_KERNEL) || defined(_ACL_PRIVATE) + #define POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM #define POSIX1E_ACL_ACCESS_EXTATTR_NAME "posix1e.acl_access" #define POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM #define POSIX1E_ACL_DEFAULT_EXTATTR_NAME "posix1e.acl_default" -#define ACL_MAX_ENTRIES 32 /* maximum entries in an ACL */ +#define NFS4_ACL_EXTATTR_NAMESPACE EXTATTR_NAMESPACE_SYSTEM +#define NFS4_ACL_EXTATTR_NAME "nfs4.acl" +#define OLDACL_MAX_ENTRIES 32 -typedef int acl_type_t; -typedef int acl_tag_t; -typedef mode_t acl_perm_t; -typedef mode_t *acl_permset_t; +/* + * "struct oldacl" is used in compatibility ACL syscalls and for on-disk + * storage of POSIX.1e ACLs. + */ +typedef int oldacl_tag_t; +typedef mode_t oldacl_perm_t; +struct oldacl_entry { + oldacl_tag_t ae_tag; + uid_t ae_id; + oldacl_perm_t ae_perm; +}; +typedef struct oldacl_entry *oldacl_entry_t; + +struct oldacl { + int acl_cnt; + struct oldacl_entry acl_entry[OLDACL_MAX_ENTRIES]; +}; + +/* + * Current "struct acl". + */ struct acl_entry { acl_tag_t ae_tag; uid_t ae_id; acl_perm_t ae_perm; + /* "allow" or "deny". Unused in POSIX ACLs. */ + acl_entry_type_t ae_entry_type; + /* Flags control inheritance. Unused in POSIX ACLs. */ + acl_flag_t ae_flags; }; typedef struct acl_entry *acl_entry_t; -/* internal ACL structure */ +/* + * Internal ACL structure, used in libc, kernel APIs and for on-disk + * storage of NFS4 ACLs. POSIX.1e ACLs use "struct oldacl" for on-disk + * storage. + */ struct acl { - int acl_cnt; + unsigned int acl_maxcnt; + unsigned int acl_cnt; + /* Will be required e.g. to implement NFSv4.1 ACL inheritance. */ + int acl_spare[4]; struct acl_entry acl_entry[ACL_MAX_ENTRIES]; }; -/* external ACL structure */ +/* + * ACL structure internal to libc. + */ struct acl_t_struct { struct acl ats_acl; int ats_cur_entry; + /* Will be used for ACL branding. */ + int ats_spare; }; typedef struct acl_t_struct *acl_t; +#else /* _KERNEL || _ACL_PRIVATE */ + +typedef void *acl_entry_t; +typedef void *acl_t; + +#endif /* !_KERNEL && !_ACL_PRIVATE */ + /* - * Possible valid values for ae_tag field. + * Possible valid values for ae_tag field. For explanation, see acl(9). */ #define ACL_UNDEFINED_TAG 0x00000000 #define ACL_USER_OBJ 0x00000001 @@ -87,13 +152,17 @@ typedef struct acl_t_struct *acl_t; #define ACL_OTHER_OBJ ACL_OTHER /* - * Possible valid values for acl_type_t arguments. + * Possible valid values for acl_type_t arguments. First two + * are provided only for backwards binary compatibility. */ -#define ACL_TYPE_ACCESS 0x00000000 -#define ACL_TYPE_DEFAULT 0x00000001 +#define ACL_TYPE_ACCESS_OLD 0x00000000 +#define ACL_TYPE_DEFAULT_OLD 0x00000001 +#define ACL_TYPE_ACCESS 0x00000002 +#define ACL_TYPE_DEFAULT 0x00000003 /* - * Possible flags in ae_perm field. + * Possible flags in ae_perm field for POSIX.1e ACLs. Note + * that ACL_EXECUTE may be used in both NFSv4 and POSIX.1e ACLs. */ #define ACL_EXECUTE 0x0001 #define ACL_WRITE 0x0002 @@ -103,13 +172,14 @@ typedef struct acl_t_struct *acl_t; #define ACL_POSIX1E_BITS (ACL_EXECUTE | ACL_WRITE | ACL_READ) /* - * Possible entry_id values for acl_get_entry() + * Possible entry_id values for acl_get_entry(3). */ #define ACL_FIRST_ENTRY 0 #define ACL_NEXT_ENTRY 1 /* - * Undefined value in ae_id field + * Undefined value in ae_id field. ae_id should be set to this value + * iff ae_tag is ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_OTHER or ACL_EVERYONE. */ #define ACL_UNDEFINED_ID ((uid_t)-1) @@ -126,7 +196,7 @@ typedef struct acl_t_struct *acl_t; #define ACL_PRESERVE_MASK (~ACL_OVERRIDE_MASK) /* - * File system independent code to move back and forth between POSIX mode and + * Filesystem-independent code to move back and forth between POSIX mode and * POSIX.1e ACL representations. */ acl_perm_t acl_posix1e_mode_to_perm(acl_tag_t tag, mode_t mode); @@ -141,17 +211,28 @@ mode_t acl_posix1e_newfilemode(mode_t cmode, struct acl *dacl); struct acl *acl_alloc(int flags); void acl_free(struct acl *aclp); +int acl_copy_oldacl_into_acl(const struct oldacl *source, + struct acl *dest); +int acl_copy_acl_into_oldacl(const struct acl *source, + struct oldacl *dest); /* - * File system independent syntax check for a POSIX.1e ACL. + * To allocate 'struct acl', use acl_alloc()/acl_free() instead of this. + */ +MALLOC_DECLARE(M_ACL); + +/* + * Filesystem-independent syntax check for a POSIX.1e ACL. */ int acl_posix1e_check(struct acl *acl); #else /* !_KERNEL */ +#if defined(_ACL_PRIVATE) + /* * Syscall interface -- use the library calls instead as the syscalls have - * strict acl entry ordering requirements. + * strict ACL entry ordering requirements. */ __BEGIN_DECLS int __acl_aclcheck_fd(int _filedes, acl_type_t _type, struct acl *_aclp); @@ -170,6 +251,8 @@ int __acl_set_file(const char *_path, acl_type_t _type, struct acl *_aclp); int __acl_set_link(const char *_path, acl_type_t _type, struct acl *_aclp); __END_DECLS +#endif /* _ACL_PRIVATE */ + /* * Supported POSIX.1e ACL manipulation and assignment/retrieval API _np calls * are local extensions that reflect an environment capable of opening file diff --git a/sys/ufs/ufs/ufs_acl.c b/sys/ufs/ufs/ufs_acl.c index 89488c7995fb..c04a5d2ffaac 100644 --- a/sys/ufs/ufs/ufs_acl.c +++ b/sys/ufs/ufs/ufs_acl.c @@ -140,6 +140,56 @@ ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip) DIP_SET(ip, i_mode, ip->i_mode); } +/* + * Read POSIX.1e ACL from an EA. Return error if its not found + * or if any other error has occured. + */ +static int +ufs_get_oldacl(acl_type_t type, struct oldacl *old, struct vnode *vp, + struct thread *td) +{ + int error, len; + struct inode *ip = VTOI(vp); + + len = sizeof(*old); + + switch (type) { + case ACL_TYPE_ACCESS: + error = vn_extattr_get(vp, IO_NODELOCKED, + POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE, + POSIX1E_ACL_ACCESS_EXTATTR_NAME, &len, (char *) old, + td); + break; + case ACL_TYPE_DEFAULT: + if (vp->v_type != VDIR) + return (EINVAL); + error = vn_extattr_get(vp, IO_NODELOCKED, + POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE, + POSIX1E_ACL_DEFAULT_EXTATTR_NAME, &len, (char *) old, + td); + break; + default: + return (EINVAL); + } + + if (error != 0) + return (error); + + if (len != sizeof(*old)) { + /* + * A short (or long) read, meaning that for some reason + * the ACL is corrupted. Return EPERM since the object + * DAC protections are unsafe. + */ + printf("ufs_get_oldacl(): Loaded invalid ACL " + "(len = %d), inumber %d on %s\n", len, + ip->i_number, ip->i_fs->fs_fsmnt); + return (EPERM); + } + + return (0); +} + /* * Retrieve the ACL on a file. * @@ -147,18 +197,12 @@ ufs_sync_inode_from_acl(struct acl *acl, struct inode *ip) * assemble both into a final ACL product. Right now this is not done * very efficiently. */ -int -ufs_getacl(ap) - struct vop_getacl_args /* { - struct vnode *vp; - struct acl_type_t type; - struct acl *aclp; - struct ucred *cred; - struct thread *td; - } */ *ap; +static int +ufs_getacl_posix1e(struct vop_getacl_args *ap) { struct inode *ip = VTOI(ap->a_vp); - int error, len; + int error; + struct oldacl *old; /* * XXX: If ufs_getacl() should work on file systems not supporting @@ -167,121 +211,83 @@ ufs_getacl(ap) if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) return (EOPNOTSUPP); + old = malloc(sizeof(*old), M_ACL, M_WAITOK | M_ZERO); + /* - * Attempt to retrieve the ACL based on the ACL type. + * Attempt to retrieve the ACL from the extended attributes. */ - bzero(ap->a_aclp, sizeof(*ap->a_aclp)); - len = sizeof(*ap->a_aclp); - switch(ap->a_type) { - case ACL_TYPE_ACCESS: - /* - * ACL_TYPE_ACCESS ACLs may or may not be stored in the - * EA, as they are in fact a combination of the inode - * ownership/permissions and the EA contents. If the - * EA is present, merge the two in a temporary ACL - * storage, otherwise just return the inode contents. - */ - error = vn_extattr_get(ap->a_vp, IO_NODELOCKED, - POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE, - POSIX1E_ACL_ACCESS_EXTATTR_NAME, &len, (char *) ap->a_aclp, - ap->a_td); - switch (error) { - /* XXX: If ufs_getacl() should work on filesystems without - * the EA configured, add case EOPNOTSUPP here. */ - case ENOATTR: + error = ufs_get_oldacl(ap->a_type, old, ap->a_vp, ap->a_td); + switch (error) { + /* + * XXX: If ufs_getacl() should work on filesystems + * without the EA configured, add case EOPNOTSUPP here. + */ + case ENOATTR: + switch (ap->a_type) { + case ACL_TYPE_ACCESS: /* * Legitimately no ACL set on object, purely * emulate it through the inode. These fields will * be updated when the ACL is synchronized with * the inode later. */ - ap->a_aclp->acl_cnt = 3; - ap->a_aclp->acl_entry[0].ae_tag = ACL_USER_OBJ; - ap->a_aclp->acl_entry[0].ae_id = ACL_UNDEFINED_ID; - ap->a_aclp->acl_entry[0].ae_perm = ACL_PERM_NONE; - ap->a_aclp->acl_entry[1].ae_tag = ACL_GROUP_OBJ; - ap->a_aclp->acl_entry[1].ae_id = ACL_UNDEFINED_ID; - ap->a_aclp->acl_entry[1].ae_perm = ACL_PERM_NONE; - ap->a_aclp->acl_entry[2].ae_tag = ACL_OTHER; - ap->a_aclp->acl_entry[2].ae_id = ACL_UNDEFINED_ID; - ap->a_aclp->acl_entry[2].ae_perm = ACL_PERM_NONE; + old->acl_cnt = 3; + old->acl_entry[0].ae_tag = ACL_USER_OBJ; + old->acl_entry[0].ae_id = ACL_UNDEFINED_ID; + old->acl_entry[0].ae_perm = ACL_PERM_NONE; + old->acl_entry[1].ae_tag = ACL_GROUP_OBJ; + old->acl_entry[1].ae_id = ACL_UNDEFINED_ID; + old->acl_entry[1].ae_perm = ACL_PERM_NONE; + old->acl_entry[2].ae_tag = ACL_OTHER; + old->acl_entry[2].ae_id = ACL_UNDEFINED_ID; + old->acl_entry[2].ae_perm = ACL_PERM_NONE; + break; + + case ACL_TYPE_DEFAULT: + /* + * Unlike ACL_TYPE_ACCESS, there is no relationship + * between the inode contents and the ACL, and it is + * therefore possible for the request for the ACL + * to fail since the ACL is undefined. In this + * situation, return success and an empty ACL, + * as required by POSIX.1e. + */ + old->acl_cnt = 0; + break; + } + + error = 0; + + /* FALLTHROUGH */ + case 0: + error = acl_copy_oldacl_into_acl(old, ap->a_aclp); + if (error != 0) + break; + + if (ap->a_type == ACL_TYPE_ACCESS) ufs_sync_acl_from_inode(ip, ap->a_aclp); - error = 0; - break; - - case 0: - if (len != sizeof(*ap->a_aclp)) { - /* - * A short (or long) read, meaning that for - * some reason the ACL is corrupted. Return - * EPERM since the object DAC protections - * are unsafe. - */ - printf("ufs_getacl(): Loaded invalid ACL (" - "%d bytes), inumber %d on %s\n", len, - ip->i_number, ip->i_fs->fs_fsmnt); - return (EPERM); - } - ufs_sync_acl_from_inode(ip, ap->a_aclp); - break; - - default: - break; - } - break; - - case ACL_TYPE_DEFAULT: - if (ap->a_vp->v_type != VDIR) { - error = EINVAL; - break; - } - error = vn_extattr_get(ap->a_vp, IO_NODELOCKED, - POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE, - POSIX1E_ACL_DEFAULT_EXTATTR_NAME, &len, - (char *) ap->a_aclp, ap->a_td); - /* - * Unlike ACL_TYPE_ACCESS, there is no relationship between - * the inode contents and the ACL, and it is therefore - * possible for the request for the ACL to fail since the - * ACL is undefined. In this situation, return success - * and an empty ACL, as required by POSIX.1e. - */ - switch (error) { - /* XXX: If ufs_getacl() should work on filesystems without - * the EA configured, add case EOPNOTSUPP here. */ - case ENOATTR: - bzero(ap->a_aclp, sizeof(*ap->a_aclp)); - ap->a_aclp->acl_cnt = 0; - error = 0; - break; - - case 0: - if (len != sizeof(*ap->a_aclp)) { - /* - * A short (or long) read, meaning that for - * some reason the ACL is corrupted. Return - * EPERM since the object default DAC - * protections are unsafe. - */ - printf("ufs_getacl(): Loaded invalid ACL (" - "%d bytes), inumber %d on %s\n", len, - ip->i_number, ip->i_fs->fs_fsmnt); - return (EPERM); - } - break; - - default: - break; - } - break; - default: - error = EINVAL; + break; } + free(old, M_ACL); return (error); } +int +ufs_getacl(ap) + struct vop_getacl_args /* { + struct vnode *vp; + acl_type_t type; + struct acl *aclp; + struct ucred *cred; + struct thread *td; + } */ *ap; +{ + + return (ufs_getacl_posix1e(ap)); +} + /* * Set the ACL on a file. * @@ -291,18 +297,12 @@ ufs_getacl(ap) * a fair number of different access checks may be required to go ahead * with the operation at all. */ -int -ufs_setacl(ap) - struct vop_setacl_args /* { - struct vnode *vp; - acl_type_t type; - struct acl *aclp; - struct ucred *cred; - struct proc *p; - } */ *ap; +static int +ufs_setacl_posix1e(struct vop_setacl_args *ap) { struct inode *ip = VTOI(ap->a_vp); int error; + struct oldacl *old; if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) return (EOPNOTSUPP); @@ -349,10 +349,15 @@ ufs_setacl(ap) switch(ap->a_type) { case ACL_TYPE_ACCESS: - error = vn_extattr_set(ap->a_vp, IO_NODELOCKED, - POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE, - POSIX1E_ACL_ACCESS_EXTATTR_NAME, sizeof(*ap->a_aclp), - (char *) ap->a_aclp, ap->a_td); + old = malloc(sizeof(*old), M_ACL, M_WAITOK | M_ZERO); + error = acl_copy_acl_into_oldacl(ap->a_aclp, old); + if (error == 0) { + error = vn_extattr_set(ap->a_vp, IO_NODELOCKED, + POSIX1E_ACL_ACCESS_EXTATTR_NAMESPACE, + POSIX1E_ACL_ACCESS_EXTATTR_NAME, sizeof(*old), + (char *) old, ap->a_td); + } + free(old, M_ACL); break; case ACL_TYPE_DEFAULT: @@ -372,11 +377,17 @@ ufs_setacl(ap) */ if (error == ENOATTR) error = 0; - } else - error = vn_extattr_set(ap->a_vp, IO_NODELOCKED, - POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE, - POSIX1E_ACL_DEFAULT_EXTATTR_NAME, - sizeof(*ap->a_aclp), (char *) ap->a_aclp, ap->a_td); + } else { + old = malloc(sizeof(*old), M_ACL, M_WAITOK | M_ZERO); + error = acl_copy_acl_into_oldacl(ap->a_aclp, old); + if (error == 0) { + error = vn_extattr_set(ap->a_vp, IO_NODELOCKED, + POSIX1E_ACL_DEFAULT_EXTATTR_NAMESPACE, + POSIX1E_ACL_DEFAULT_EXTATTR_NAME, + sizeof(*old), (char *) old, ap->a_td); + } + free(old, M_ACL); + } break; default: @@ -404,12 +415,9 @@ ufs_setacl(ap) return (0); } -/* - * Check the validity of an ACL for a file. - */ int -ufs_aclcheck(ap) - struct vop_aclcheck_args /* { +ufs_setacl(ap) + struct vop_setacl_args /* { struct vnode *vp; acl_type_t type; struct acl *aclp; @@ -418,6 +426,13 @@ ufs_aclcheck(ap) } */ *ap; { + return (ufs_setacl_posix1e(ap)); +} + +static int +ufs_aclcheck_posix1e(struct vop_aclcheck_args *ap) +{ + if ((ap->a_vp->v_mount->mnt_flag & MNT_ACLS) == 0) return (EOPNOTSUPP); @@ -438,7 +453,28 @@ ufs_aclcheck(ap) default: return (EINVAL); } + + if (ap->a_aclp->acl_cnt > OLDACL_MAX_ENTRIES) + return (EINVAL); + return (acl_posix1e_check(ap->a_aclp)); } +/* + * Check the validity of an ACL for a file. + */ +int +ufs_aclcheck(ap) + struct vop_aclcheck_args /* { + struct vnode *vp; + acl_type_t type; + struct acl *aclp; + struct ucred *cred; + struct thread *td; + } */ *ap; +{ + + return (ufs_aclcheck_posix1e(ap)); +} + #endif /* !UFS_ACL */ From 199685bca9ef3e720c40c645dff2681455e40fa9 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 16:41:33 +0000 Subject: [PATCH 408/544] Change the reboot panic that would have occurred if clientid numbers wrapped around to a printf() warning of a possible DOS attack, in the experimental nfsv4 server. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdstate.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 37ba36e3c5b5..70d722bc03e5 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3705,12 +3705,8 @@ nfsrv_nextclientindex(void) if (client_index != 0) return (client_index); - /* - * In practice we'll never get here, but the panic is here - * just for fun. (client_index will not wrap around on any real server) - */ - panic("nfsv4 server out of clientids"); - return (0); /* Just to shut the compiler up */ + printf("out of clientids, possible DOS attack\n"); + return (client_index); } /* From 8757104e6b71eee02227976dc5212765ff4584de Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 16:46:01 +0000 Subject: [PATCH 409/544] Change the comment at the beginning of the function to reflect the change from panic() to printf() done by r192588. --- sys/fs/nfsserver/nfs_nfsdstate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index 70d722bc03e5..b154e4145949 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3691,8 +3691,8 @@ nfsrv_docallback(struct nfsclient *clp, int procnum, /* * Return the next index# for a clientid. Mostly just increment and return * the next one, but... if the 32bit unsigned does actually wrap around, - * reboot. This is here more for fun than practical purposes. At an - * average rate of one new client per second, it will wrap around in + * it should be rebooted. + * At an average rate of one new client per second, it will wrap around in * approximately 136 years. (I think the server will have been shut * down or rebooted before then.) */ From 476174008c51fabecea3b956dbf397b11e8f4d49 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 18:10:39 +0000 Subject: [PATCH 410/544] Modified the printf message of r192590 to remove the possible DOS attack, as suggested by Sam. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index b154e4145949..fc947e31ac7d 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3705,7 +3705,7 @@ nfsrv_nextclientindex(void) if (client_index != 0) return (client_index); - printf("out of clientids, possible DOS attack\n"); + printf("out of clientids\n"); return (client_index); } From 7529967798a61ad246cb189f9d67e11fedc2d710 Mon Sep 17 00:00:00 2001 From: "George V. Neville-Neil" Date: Fri, 22 May 2009 18:26:47 +0000 Subject: [PATCH 411/544] Partial reversion of previous commit. The CXGB_SHUTDOWN flag does NOT need to be inverted when doing an ifconfig down of an interface. Pointed out by: Navdeep Parhar MFC after: 1 week --- sys/dev/cxgb/cxgb_main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sys/dev/cxgb/cxgb_main.c b/sys/dev/cxgb/cxgb_main.c index 621fd389cfab..3efcbb73ccf5 100644 --- a/sys/dev/cxgb/cxgb_main.c +++ b/sys/dev/cxgb/cxgb_main.c @@ -1905,7 +1905,6 @@ cxgb_init_locked(struct port_info *p) callout_reset(&sc->cxgb_tick_ch, CXGB_TICKS(sc), cxgb_tick, sc); t3_sge_reset_adapter(sc); - sc->flags &= ~CXGB_SHUTDOWN; ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; } @@ -1926,13 +1925,10 @@ static void cxgb_stop_locked(struct port_info *pi) { struct ifnet *ifp; - adapter_t *sc = pi->adapter; PORT_LOCK_ASSERT_OWNED(pi); ADAPTER_LOCK_ASSERT_NOTOWNED(pi->adapter); - sc->flags |= CXGB_SHUTDOWN; - ifp = pi->ifp; t3_port_intr_disable(pi->adapter, pi->port_id); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); From ed41a7cceebb06efff1c7ed37149b5aae89d97f1 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 19:05:48 +0000 Subject: [PATCH 412/544] Change the printf of r192595 to identify the function, as requested by Sam. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdstate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsserver/nfs_nfsdstate.c b/sys/fs/nfsserver/nfs_nfsdstate.c index fc947e31ac7d..27fe446dc217 100644 --- a/sys/fs/nfsserver/nfs_nfsdstate.c +++ b/sys/fs/nfsserver/nfs_nfsdstate.c @@ -3705,7 +3705,7 @@ nfsrv_nextclientindex(void) if (client_index != 0) return (client_index); - printf("out of clientids\n"); + printf("%s: out of clientids\n", __func__); return (client_index); } From 8141fda06eb1e51f128f55c3835bd15134ad4e31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Fri, 22 May 2009 20:07:39 +0000 Subject: [PATCH 413/544] Expand $FreeBSD$ From 9dd7554f09ddd7089463b88d0de08e6e535022a5 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 20:55:29 +0000 Subject: [PATCH 414/544] Fix the name of the module common to the client and server in the experimental nfs subsystem to the correct one for the MODULE_DEPEND() macro. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clport.c b/sys/fs/nfsclient/nfs_clport.c index bb18fcb17823..3b5e3675081c 100644 --- a/sys/fs/nfsclient/nfs_clport.c +++ b/sys/fs/nfsclient/nfs_clport.c @@ -1267,5 +1267,5 @@ DECLARE_MODULE(nfscl, nfscl_mod, SI_SUB_VFS, SI_ORDER_ANY); /* So that loader and kldload(2) can find us, wherever we are.. */ MODULE_VERSION(nfscl, 1); -MODULE_DEPEND(nfscl, newnfsd, 1, 1, 1); +MODULE_DEPEND(nfscl, nfscommon, 1, 1, 1); From e0c14af9b3bc6751b5ae5e8754cf41243412b323 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 22 May 2009 22:09:00 +0000 Subject: [PATCH 415/544] Introduce the if_vmove() function, which will be used in the future for reassigning ifnets from one vnet to another. if_vmove() works by calling a restricted subset of actions normally executed by if_detach() on an ifnet in the current vnet, and then switches to the target vnet and executes an appropriate subset of if_attach() actions there. if_attach() and if_detach() have become wrapper functions around if_attach_internal() and if_detach_internal(), where the later variants have an additional argument, a flag indicating whether a full attach or detach sequence is to be executed, or only a restricted subset suitable for moving an ifnet from one vnet to another. Hence, if_vmove() will not call if_detach() and if_attach() directly, but will call the if_detach_internal() and if_attach_internal() variants instead, with the vmove flag set. While here, staticize ifnet_setbyindex() since it is not referenced from outside of sys/net/if.c. Also rename ifccnt field in struct vimage to ifcnt, and do some minor whitespace garbage collection where appropriate. This change should have no functional impact on nooptions VIMAGE kernel builds. Reviewed by: bz, rwatson, brooks? Approved by: julian (mentor) --- sys/kern/kern_vimage.c | 2 +- sys/net/if.c | 257 ++++++++++++++++++++++++++++------------- sys/net/if_var.h | 2 +- sys/sys/vimage.h | 2 +- 4 files changed, 179 insertions(+), 84 deletions(-) diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index e20b382029f5..d4c48b5401f1 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -391,7 +391,7 @@ DB_SHOW_COMMAND(vnets, db_show_vnets) #endif VNET_FOREACH(vnet_iter) { db_printf("%p %3d %5d", - vnet_iter, vnet_iter->ifccnt, vnet_iter->sockcnt); + vnet_iter, vnet_iter->ifcnt, vnet_iter->sockcnt); db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_NET]); db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_INET]); db_vnet_ptr(vnet_iter->mod_data[VNET_MOD_INET6]); diff --git a/sys/net/if.c b/sys/net/if.c index a67f31b6a27c..fea9db774161 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -142,6 +142,8 @@ static void do_link_state_change(void *, int); static int if_getgroup(struct ifgroupreq *, struct ifnet *); static int if_getgroupmembers(struct ifgroupreq *); static void if_delgroups(struct ifnet *); +static void if_attach_internal(struct ifnet *, int); +static void if_detach_internal(struct ifnet *, int); #ifdef INET6 /* @@ -239,7 +241,7 @@ ifnet_byindex_ref(u_short idx) return (ifp); } -void +static void ifnet_setbyindex(u_short idx, struct ifnet *ifp) { INIT_VNET_NET(curvnet); @@ -520,8 +522,8 @@ if_alloc(u_char type) IF_ADDR_LOCK_INIT(ifp); TASK_INIT(&ifp->if_linktask, 0, do_link_state_change, ifp); - IF_AFDATA_LOCK_INIT(ifp); ifp->if_afdata_initialized = 0; + IF_AFDATA_LOCK_INIT(ifp); TAILQ_INIT(&ifp->if_addrhead); TAILQ_INIT(&ifp->if_prefixhead); TAILQ_INIT(&ifp->if_multiaddrs); @@ -546,7 +548,7 @@ if_alloc(u_char type) static void if_free_internal(struct ifnet *ifp) { - INIT_VNET_NET(ifp->if_vnet); + INIT_VNET_NET(curvnet); /* ifp->if_vnet is already NULL here */ KASSERT((ifp->if_flags & IFF_DYING), ("if_free_internal: interface not dying")); @@ -653,7 +655,10 @@ ifq_detach(struct ifaltq *ifq) /* * Perform generic interface initalization tasks and attach the interface - * to the list of "active" interfaces. + * to the list of "active" interfaces. If vmove flag is set on entry + * to if_attach_internal(), perform only a limited subset of initialization + * tasks, given that we are moving from one vnet to another an ifnet which + * has already been fully initialized. * * XXX: * - The decision to return void and thus require this function to @@ -663,6 +668,13 @@ ifq_detach(struct ifaltq *ifq) */ void if_attach(struct ifnet *ifp) +{ + + if_attach_internal(ifp, 0); +} + +static void +if_attach_internal(struct ifnet *ifp, int vmove) { INIT_VNET_NET(curvnet); unsigned socksize, ifasize; @@ -692,60 +704,63 @@ if_attach(struct ifnet *ifp) ifp->if_qflush = if_qflush; } + if (!vmove) { #ifdef MAC - mac_ifnet_create(ifp); + mac_ifnet_create(ifp); #endif - if (IS_DEFAULT_VNET(curvnet)) { - ifdev_setbyindex(ifp->if_index, make_dev(&net_cdevsw, - ifp->if_index, UID_ROOT, GID_WHEEL, 0600, "%s/%s", - net_cdevsw.d_name, ifp->if_xname)); - make_dev_alias(ifdev_byindex(ifp->if_index), "%s%d", - net_cdevsw.d_name, ifp->if_index); + if (IS_DEFAULT_VNET(curvnet)) { + ifdev_setbyindex(ifp->if_index, make_dev(&net_cdevsw, + ifp->if_index, UID_ROOT, GID_WHEEL, 0600, "%s/%s", + net_cdevsw.d_name, ifp->if_xname)); + make_dev_alias(ifdev_byindex(ifp->if_index), "%s%d", + net_cdevsw.d_name, ifp->if_index); + } + + ifq_attach(&ifp->if_snd, ifp); + + /* + * Create a Link Level name for this device. + */ + namelen = strlen(ifp->if_xname); + /* + * Always save enough space for any possiable name so we + * can do a rename in place later. + */ + masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ; + socksize = masklen + ifp->if_addrlen; + if (socksize < sizeof(*sdl)) + socksize = sizeof(*sdl); + socksize = roundup2(socksize, sizeof(long)); + ifasize = sizeof(*ifa) + 2 * socksize; + ifa = malloc(ifasize, M_IFADDR, M_WAITOK | M_ZERO); + IFA_LOCK_INIT(ifa); + sdl = (struct sockaddr_dl *)(ifa + 1); + sdl->sdl_len = socksize; + sdl->sdl_family = AF_LINK; + bcopy(ifp->if_xname, sdl->sdl_data, namelen); + sdl->sdl_nlen = namelen; + sdl->sdl_index = ifp->if_index; + sdl->sdl_type = ifp->if_type; + ifp->if_addr = ifa; + ifa->ifa_ifp = ifp; + ifa->ifa_rtrequest = link_rtrequest; + ifa->ifa_addr = (struct sockaddr *)sdl; + sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); + ifa->ifa_netmask = (struct sockaddr *)sdl; + sdl->sdl_len = masklen; + while (namelen != 0) + sdl->sdl_data[--namelen] = 0xff; + ifa->ifa_refcnt = 1; + TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); + /* Reliably crash if used uninitialized. */ + ifp->if_broadcastaddr = NULL; } - ifq_attach(&ifp->if_snd, ifp); - - /* - * create a Link Level name for this device - */ - namelen = strlen(ifp->if_xname); - /* - * Always save enough space for any possiable name so we can do - * a rename in place later. - */ - masklen = offsetof(struct sockaddr_dl, sdl_data[0]) + IFNAMSIZ; - socksize = masklen + ifp->if_addrlen; - if (socksize < sizeof(*sdl)) - socksize = sizeof(*sdl); - socksize = roundup2(socksize, sizeof(long)); - ifasize = sizeof(*ifa) + 2 * socksize; - ifa = malloc(ifasize, M_IFADDR, M_WAITOK | M_ZERO); - IFA_LOCK_INIT(ifa); - sdl = (struct sockaddr_dl *)(ifa + 1); - sdl->sdl_len = socksize; - sdl->sdl_family = AF_LINK; - bcopy(ifp->if_xname, sdl->sdl_data, namelen); - sdl->sdl_nlen = namelen; - sdl->sdl_index = ifp->if_index; - sdl->sdl_type = ifp->if_type; - ifp->if_addr = ifa; - ifa->ifa_ifp = ifp; - ifa->ifa_rtrequest = link_rtrequest; - ifa->ifa_addr = (struct sockaddr *)sdl; - sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl); - ifa->ifa_netmask = (struct sockaddr *)sdl; - sdl->sdl_len = masklen; - while (namelen != 0) - sdl->sdl_data[--namelen] = 0xff; - ifa->ifa_refcnt = 1; - TAILQ_INSERT_HEAD(&ifp->if_addrhead, ifa, ifa_link); - ifp->if_broadcastaddr = NULL; /* reliably crash if used uninitialized */ - IFNET_WLOCK(); TAILQ_INSERT_TAIL(&V_ifnet, ifp, if_link); #ifdef VIMAGE - curvnet->ifccnt++; + curvnet->ifcnt++; #endif IFNET_WUNLOCK(); @@ -759,10 +774,10 @@ if_attach(struct ifnet *ifp) /* Announce the interface. */ rt_ifannouncemsg(ifp, IFAN_ARRIVAL); - if (ifp->if_watchdog != NULL) { + if (!vmove && ifp->if_watchdog != NULL) { if_printf(ifp, "WARNING: using obsoleted if_watchdog interface\n"); - + /* * Note that we need if_slowtimo(). If this happens after * boot, then call if_slowtimo() directly. @@ -877,19 +892,28 @@ if_purgemaddrs(struct ifnet *ifp) } /* - * Detach an interface, removing it from the - * list of "active" interfaces. + * Detach an interface, removing it from the list of "active" interfaces. + * If vmove flag is set on entry to if_detach_internal(), perform only a + * limited subset of cleanup tasks, given that we are moving an ifnet from + * one vnet to another, where it must be fully operational. * * XXXRW: There are some significant questions about event ordering, and * how to prevent things from starting to use the interface during detach. */ void if_detach(struct ifnet *ifp) +{ + + if_detach_internal(ifp, 0); +} + +static void +if_detach_internal(struct ifnet *ifp, int vmove) { INIT_VNET_NET(ifp->if_vnet); struct ifaddr *ifa; struct radix_node_head *rnh; - int s, i, j; + int i, j; struct domain *dp; struct ifnet *iter; int found = 0; @@ -903,11 +927,15 @@ if_detach(struct ifnet *ifp) } #ifdef VIMAGE if (found) - curvnet->ifccnt--; + curvnet->ifcnt--; #endif IFNET_WUNLOCK(); - if (!found) - return; + if (!found) { + if (vmove) + panic("interface not in it's own ifnet list"); + else + return; /* XXX this should panic as well? */ + } /* * Remove/wait for pending events. @@ -917,7 +945,6 @@ if_detach(struct ifnet *ifp) /* * Remove routes and flush queues. */ - s = splnet(); if_down(ifp); #ifdef ALTQ if (ALTQ_IS_ENABLED(&ifp->if_snd)) @@ -943,25 +970,27 @@ if_detach(struct ifnet *ifp) #endif if_purgemaddrs(ifp); - /* - * Prevent further calls into the device driver via ifnet. - */ - if_dead(ifp); + if (!vmove) { + /* + * Prevent further calls into the device driver via ifnet. + */ + if_dead(ifp); - /* - * Remove link ifaddr pointer and maybe decrement if_index. - * Clean up all addresses. - */ - ifp->if_addr = NULL; - if (IS_DEFAULT_VNET(curvnet)) - destroy_dev(ifdev_byindex(ifp->if_index)); - ifdev_setbyindex(ifp->if_index, NULL); + /* + * Remove link ifaddr pointer and maybe decrement if_index. + * Clean up all addresses. + */ + ifp->if_addr = NULL; + if (IS_DEFAULT_VNET(curvnet)) + destroy_dev(ifdev_byindex(ifp->if_index)); + ifdev_setbyindex(ifp->if_index, NULL); - /* We can now free link ifaddr. */ - if (!TAILQ_EMPTY(&ifp->if_addrhead)) { - ifa = TAILQ_FIRST(&ifp->if_addrhead); - TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); - IFAFREE(ifa); + /* We can now free link ifaddr. */ + if (!TAILQ_EMPTY(&ifp->if_addrhead)) { + ifa = TAILQ_FIRST(&ifp->if_addrhead); + TAILQ_REMOVE(&ifp->if_addrhead, ifa, ifa_link); + IFAFREE(ifa); + } } /* @@ -994,13 +1023,79 @@ if_detach(struct ifnet *ifp) ifp->if_afdata[dp->dom_family]); } IF_AFDATA_UNLOCK(ifp); - ifq_detach(&ifp->if_snd); -#ifdef VIMAGE - ifp->if_vnet = NULL; -#endif - splx(s); + ifp->if_afdata_initialized = 0; + + if (!vmove) + ifq_detach(&ifp->if_snd); } +#ifdef VIMAGE +/* + * if_vmove() performs a limited version of if_detach() in current + * vnet and if_attach()es the ifnet to the vnet specified as 2nd arg. + * An attempt is made to shrink if_index in current vnet, find an + * unused if_index in target vnet and calls if_grow() if necessary, + * and finally find an unused if_xname for the target vnet. + */ +void +if_vmove(struct ifnet *ifp, struct vnet *new_vnet) +{ + + /* + * Detach from current vnet, but preserve LLADDR info, do not + * mark as dead etc. so that the ifnet can be reattached later. + */ + if_detach_internal(ifp, 1); + + /* + * Unlink the ifnet from ifindex_table[] in current vnet, + * and shrink the if_index for that vnet if possible. + * do / while construct below is needed to confine the scope + * of INIT_VNET_NET(). + */ + { + INIT_VNET_NET(curvnet); + + IFNET_WLOCK(); + ifnet_setbyindex(ifp->if_index, NULL); + while (V_if_index > 0 && \ + ifnet_byindex_locked(V_if_index) == NULL) + V_if_index--; + IFNET_WUNLOCK(); + }; + + /* + * Switch to the context of the target vnet. + */ + CURVNET_SET_QUIET(new_vnet); + INIT_VNET_NET(new_vnet); + + /* + * Try to find an empty slot below if_index. If we fail, take + * the next slot. + */ + IFNET_WLOCK(); + for (ifp->if_index = 1; ifp->if_index <= V_if_index; ifp->if_index++) { + if (ifnet_byindex_locked(ifp->if_index) == NULL) + break; + } + /* Catch if_index overflow. */ + if (ifp->if_index < 1) + panic("if_index overflow"); + + if (ifp->if_index > V_if_index) + V_if_index = ifp->if_index; + if (V_if_index >= V_if_indexlim) + if_grow(); + ifnet_setbyindex(ifp->if_index, ifp); + IFNET_WUNLOCK(); + + if_attach_internal(ifp, 1); + + CURVNET_RESTORE(); +} +#endif /* VIMAGE */ + /* * Add a group to an interface */ diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 18084aa63769..6124352cbbb3 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -733,7 +733,6 @@ struct ifindex_entry { struct ifnet *ifnet_byindex(u_short idx); struct ifnet *ifnet_byindex_locked(u_short idx); struct ifnet *ifnet_byindex_ref(u_short idx); -void ifnet_setbyindex(u_short idx, struct ifnet *ifp); /* * Given the index, ifaddr_byindex() returns the one and only @@ -761,6 +760,7 @@ void if_grow(void); int if_delmulti(struct ifnet *, struct sockaddr *); void if_delmulti_ifma(struct ifmultiaddr *); void if_detach(struct ifnet *); +void if_vmove(struct ifnet *, struct vnet *); void if_purgeaddrs(struct ifnet *); void if_purgemaddrs(struct ifnet *); void if_down(struct ifnet *); diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index 0c76fdb8b3d5..b2c0bc129005 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -178,7 +178,7 @@ struct vnet { LIST_ENTRY(vnet) vnet_le; /* all vnets list */ u_int vnet_magic_n; u_int vnet_id; /* ID num */ - u_int ifccnt; + u_int ifcnt; u_int sockcnt; }; From e2da1d0e7946c757c98f0a9f42e9012f91e2e9c3 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Fri, 22 May 2009 22:13:29 +0000 Subject: [PATCH 416/544] Add myself to the src committers graph. Approved by: ed (mentor) --- share/misc/committers-src.dot | 3 +++ 1 file changed, 3 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index 014ec5072bd0..a1bf5b24a7cd 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -106,6 +106,7 @@ ivoras [label="Ivan Voras\nivoras@FreeBSD.org\n2008/06/10"] jake [label="Jake Burkholder\njake@FreeBSD.org\n2000/05/16"] jamie [label="Jamie Gritton\njamie@FreeBSD.org\n2009/01/28"] jayanth [label="Jayanth Vijayaraghavan\njayanth@FreeBSD.org\n2000/05/08"] +jilles [label="Jilles Tjoelker\njilles@FreeBSD.org\n2009/05/22"] jinmei [label="JINMEI Tatuya\njinmei@FreeBSD.org\n2007/03/17"] jdp [label="John Polstra\njdp@FreeBSD.org\n????/??/??"] jhb [label="John Baldwin\njhb@FreeBSD.org\n1999/08/23"] @@ -247,6 +248,8 @@ dwmalone -> fanf dwmalone -> peadar dwmalone -> snb +ed -> jilles + eivind -> des eivind -> rwatson From 67da1f3d8d5cb490e8991f75c302fb892ee355bd Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Fri, 22 May 2009 22:22:21 +0000 Subject: [PATCH 417/544] Set ifp->if_afdata_initialized to 0 while holding IF_AFDATA_LOCK on ifp, not after the lock has been released. Reviewed by: bz Discussed with: rwatson --- sys/net/if.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/if.c b/sys/net/if.c index fea9db774161..7248768439c1 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -1022,8 +1022,8 @@ if_detach_internal(struct ifnet *ifp, int vmove) (*dp->dom_ifdetach)(ifp, ifp->if_afdata[dp->dom_family]); } - IF_AFDATA_UNLOCK(ifp); ifp->if_afdata_initialized = 0; + IF_AFDATA_UNLOCK(ifp); if (!vmove) ifq_detach(&ifp->if_snd); From f81a8a320c101d1025ac6ccf94c00ca942bcc0de Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Fri, 22 May 2009 23:03:15 +0000 Subject: [PATCH 418/544] If including vnet.h one has to include opt_route.h as well. This is because struct vnet_net holds the rt_tables[][] for MRT and array size is compile time dependent. If you had ROUTETABLES set to >1 after r192011 V_loif was pointing into nonsense leading to strange results or even panics for some people. Reviewed by: mz --- sys/netinet/in.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netinet/in.c b/sys/netinet/in.c index 6f408eb92860..a656102da0e7 100644 --- a/sys/netinet/in.c +++ b/sys/netinet/in.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); #include "opt_carp.h" +#include "opt_route.h" #include #include From b66124f314b2f7053e0ed22ffbd54e5b57520b22 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Fri, 22 May 2009 23:22:56 +0000 Subject: [PATCH 419/544] Change the sysctl_base argument to svcpool_create() to NULL for client side callbacks so that leaf names are not re-used, since they are already being used by the server. Approved by: kib (mentor) --- sys/fs/nfsclient/nfs_clkrpc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/fs/nfsclient/nfs_clkrpc.c b/sys/fs/nfsclient/nfs_clkrpc.c index 37e6d58d6f3d..e1ff177ed15e 100644 --- a/sys/fs/nfsclient/nfs_clkrpc.c +++ b/sys/fs/nfsclient/nfs_clkrpc.c @@ -289,7 +289,7 @@ nfsrvd_cbinit(int terminating) NFSD_UNLOCK(); - nfscbd_pool = svcpool_create("nfscbd", SYSCTL_STATIC_CHILDREN(_vfs_newnfs)); + nfscbd_pool = svcpool_create("nfscbd", NULL); nfscbd_pool->sp_rcache = NULL; nfscbd_pool->sp_assign = NULL; nfscbd_pool->sp_done = NULL; From a43c797788f6c68b747599084e53c45db3adaa20 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 00:07:55 +0000 Subject: [PATCH 420/544] It seems this file was ignored by MRT, rnh locking changes and new-arpv2. So let the V_irtualization people finally make the disabled debugging code compile again. MFC after: 2 weeks X-MFC: MRT and adapt rnh locking --- sys/nfsclient/bootp_subr.c | 20 +++----------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index 05702f604ddc..be6a588725fd 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -242,7 +242,6 @@ static void bootpc_tag_helper(struct bootpc_tagcontext *tctx, #ifdef BOOTP_DEBUG void bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma); -void bootpboot_p_ma(struct sockaddr *ma); void bootpboot_p_rtentry(struct rtentry *rt); void bootpboot_p_tree(struct radix_node *rn); void bootpboot_p_rtlist(void); @@ -325,25 +324,12 @@ bootpboot_p_sa(struct sockaddr *sa, struct sockaddr *ma) } } -void -bootpboot_p_ma(struct sockaddr *ma) -{ - - if (ma == NULL) { - printf(""); - return; - } - printf("%x", *(int *)ma); -} - void bootpboot_p_rtentry(struct rtentry *rt) { bootpboot_p_sa(rt_key(rt), rt_mask(rt)); printf(" "); - bootpboot_p_ma(rt->rt_genmask); - printf(" "); bootpboot_p_sa(rt->rt_gateway, NULL); printf(" "); printf("flags %x", (unsigned short) rt->rt_flags); @@ -375,9 +361,9 @@ bootpboot_p_rtlist(void) { printf("Routing table:\n"); - RADIX_NODE_LOCK(V_rt_tables[AF_INET]); /* could sleep XXX */ - bootpboot_p_tree(V_rt_tables[AF_INET]->rnh_treetop); - RADIX_NODE_UNLOCK(V_rt_tables[AF_INET]); + RADIX_NODE_HEAD_RLOCK(V_rt_tables[0][AF_INET]); /* could sleep XXX */ + bootpboot_p_tree(V_rt_tables[0][AF_INET]->rnh_treetop); + RADIX_NODE_HEAD_RUNLOCK(V_rt_tables[0][AF_INET]); } void From e2b84e0308dc8dc483b4dc880d998a8d2f65e26a Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sat, 23 May 2009 00:40:17 +0000 Subject: [PATCH 421/544] Fix the rpc_gss_secfind() call in nfs_commonkrpc.c so that the code will build when "options KGSSAPI" is specified without requiring the proposed changes that add host based initiator principal support. It will not handle the case where the client uses a host based initiator principal until those changes are committed. The code that uses those changes is #ifdef'd notyet until the krpc rpcsec_changes are committed. Approved by: kib (mentor) --- sys/fs/nfs/nfs_commonkrpc.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 4b37802454de..7abff3290667 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -299,7 +299,9 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, #ifdef KGSSAPI rpc_gss_service_t svc; AUTH *auth; +#ifdef notyet rpc_gss_options_req_t req_options; +#endif #endif switch (secflavour) { @@ -317,6 +319,7 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, svc = rpc_gss_svc_integrity; else svc = rpc_gss_svc_privacy; +#ifdef notyet req_options.req_flags = GSS_C_MUTUAL_FLAG; req_options.time_req = 0; req_options.my_cred = GSS_C_NO_CREDENTIAL; @@ -326,8 +329,20 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, auth = rpc_gss_secfind(nrp->nr_client, cred, clnt_principal, srv_principal, mech_oid, svc, &req_options); - return (auth); +#else + /* + * Until changes to the rpcsec_gss code are committed, + * there is no support for host based initiator + * principals. As such, that case cannot yet be handled. + */ + if (clnt_principal == NULL) + auth = rpc_gss_secfind(nrp->nr_client, cred, + srv_principal, mech_oid, svc); + else + auth = NULL; #endif + return (auth); +#endif /* KGSSAPI */ case AUTH_SYS: default: return (authunix_create(cred)); From 87820315766125901188aaa6d4d69f422baa1327 Mon Sep 17 00:00:00 2001 From: Kip Macy Date: Sat, 23 May 2009 00:47:23 +0000 Subject: [PATCH 422/544] Add zfs/zpool to rescue programs PR: bin/125878 Submitted by: nork@ MFC after: 3 days --- rescue/rescue/Makefile | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/rescue/rescue/Makefile b/rescue/rescue/Makefile index 30a9d466734a..c1400c488054 100644 --- a/rescue/rescue/Makefile +++ b/rescue/rescue/Makefile @@ -72,7 +72,7 @@ CRUNCH_SRCDIRS+= bin CRUNCH_PROGS_bin= cat chflags chio chmod cp date dd df echo \ ed expr getfacl hostname kenv kill ln ls mkdir mv \ pkill ps pwd realpath rm rmdir setfacl sh stty sync test -CRUNCH_LIBS+= -lcrypt -ledit -lkvm -ll -lm -ltermcap -lutil +CRUNCH_LIBS+= -lcrypt -ledit -lkvm -ll -ltermcap -lutil # Additional options for specific programs CRUNCH_ALIAS_test= [ @@ -128,6 +128,10 @@ CRUNCH_PROGS_sbin+= ping6 .if ${MK_IPFILTER} != "no" CRUNCH_PROGS_sbin+= ipf .endif +.if ${MK_ZFS} != "no" +CRUNCH_PROGS_sbin+= zfs +CRUNCH_PROGS_sbin+= zpool +.endif # crunchgen does not like C++ programs; this should be fixed someday # CRUNCH_PROGS+= devd @@ -136,6 +140,9 @@ CRUNCH_LIBS+= -lalias -lcam -lcurses -ldevstat -lipsec .if ${MK_IPX} != "no" CRUNCH_LIBS+= -lipx .endif +.if ${MK_ZFS} != "no" +CRUNCH_LIBS+= -lzfs -lnvpair -luutil -lavl +.endif CRUNCH_LIBS+= -lgeom -lbsdxml -lkiconv -lmd -lreadline -lsbuf -lufs -lz .if ${MACHINE_ARCH} == "i386" @@ -173,6 +180,10 @@ CRUNCH_SRCDIR_fore_dnld= $(.CURDIR)/../../sbin/atm/fore_dnld CRUNCH_SRCDIR_ilmid= $(.CURDIR)/../../sbin/atm/ilmid CRUNCH_SRCDIR_rtquery= $(.CURDIR)/../../sbin/routed/rtquery CRUNCH_SRCDIR_ipf= $(.CURDIR)/../../sbin/ipf/ipf +.if ${MK_ZFS} != "no" +CRUNCH_SRCDIR_zfs= ${.CURDIR}/../../cddl/sbin/zfs +CRUNCH_SRCDIR_zpool= ${.CURDIR}/../../cddl/sbin/zpool +.endif CRUNCH_ALIAS_reboot= fastboot halt fasthalt CRUNCH_ALIAS_restore= rrestore CRUNCH_ALIAS_dump= rdump @@ -218,6 +229,8 @@ CRUNCH_PROGS_usr.sbin= chroot CRUNCH_PROGS_usr.sbin+= chown CRUNCH_ALIAS_chown= chgrp +################################################################## +CRUNCH_LIBS+= -lm ################################################################## # The following is pretty nearly a generic crunchgen-handling makefile From 9f1994b5e6c53601611a28bbad7e11ac327e8c9c Mon Sep 17 00:00:00 2001 From: Tim Kientzle Date: Sat, 23 May 2009 04:31:05 +0000 Subject: [PATCH 423/544] Include the 2 byte length field for the optional "extra data" field when computing the length of the gzip header. Thanks to Dag-Erling for pointing me to the OpenSSH tarballs, which are the first files I've seen that actually used this field. --- lib/libarchive/archive_read_support_compression_gzip.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/libarchive/archive_read_support_compression_gzip.c b/lib/libarchive/archive_read_support_compression_gzip.c index 14535405d148..b20c7697b14d 100644 --- a/lib/libarchive/archive_read_support_compression_gzip.c +++ b/lib/libarchive/archive_read_support_compression_gzip.c @@ -148,6 +148,7 @@ peek_at_header(struct archive_read_filter *filter, int *pbits) if (p == NULL) return (0); len += ((int)p[len + 1] << 8) | (int)p[len]; + len += 2; } /* Null-terminated optional filename. */ From dfc79e892f85abf6795318009680a31a8813109c Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sat, 23 May 2009 06:31:50 +0000 Subject: [PATCH 424/544] MFV of tzcode2009e: Upgrade of the tzcode from 2004a to 2009e. Changes are numerous, but include... - New format of the output of zic, which supports both 32 and 64 bit time_t formats. - zdump on 64 bit platforms will actually produce some output instead of doing nothing for a looooooooong time. - linux_base-fX, with X >= at least 8, will work without problems related to the local time again. The original patch, based on the 2008e, has been running for a long time on both my laptop and desktop machine and have been tested by other people. After the installation of this code and the running of zic(8), you need to run tzsetup(8) again to install the new datafile. Approved by: wollman@ for usr.sbin/zic MFC after: 1 month --- UPDATING | 4 + lib/libc/stdtime/asctime.c | 106 +++- lib/libc/stdtime/difftime.c | 98 ++- lib/libc/stdtime/localtime.c | 743 ++++++++++++++++------ lib/libc/stdtime/private.h | 156 +++-- lib/libc/stdtime/strftime.c | 110 +++- lib/libc/stdtime/time2posix.3 | 3 + lib/libc/stdtime/tzfile.5 | 22 +- lib/libc/stdtime/tzfile.h | 62 +- usr.sbin/zic/Arts.htm | 178 ------ usr.sbin/zic/README | 13 +- usr.sbin/zic/Theory | 111 ++-- usr.sbin/zic/ialloc.c | 7 +- usr.sbin/zic/private.h | 139 ++++- usr.sbin/zic/scheck.c | 14 +- usr.sbin/zic/tz-art.htm | 278 --------- usr.sbin/zic/tz-link.htm | 443 ------------- usr.sbin/zic/zdump.8 | 18 +- usr.sbin/zic/zdump.c | 521 ++++++++++++---- usr.sbin/zic/zic.8 | 105 +++- usr.sbin/zic/zic.c | 1101 +++++++++++++++++++++++---------- 21 files changed, 2419 insertions(+), 1813 deletions(-) delete mode 100644 usr.sbin/zic/Arts.htm delete mode 100644 usr.sbin/zic/tz-art.htm delete mode 100644 usr.sbin/zic/tz-link.htm diff --git a/UPDATING b/UPDATING index 11ca4b1d35e2..8dcc53070b7d 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,10 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090523: + The newly imported zic(8) produces a new format in the + output. Please run tzsetup(8) to install a newly /etc/localtime. + 20090520: The sysctl tree for the usb stack has renamed from hw.usb2.* to hw.usb.* and is now consistent again with previous releases. diff --git a/lib/libc/stdtime/asctime.c b/lib/libc/stdtime/asctime.c index 0f4212f81c14..30606f1692a7 100644 --- a/lib/libc/stdtime/asctime.c +++ b/lib/libc/stdtime/asctime.c @@ -1,12 +1,18 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. +*/ + +/* +** Avoid the temptation to punt entirely to strftime; +** the output of strftime is supposed to be locale specific +** whereas the output of asctime is supposed to be constant. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)asctime.c 7.9"; +static char elsieid[] __unused = "@(#)asctime.c 8.2"; #endif /* !defined NOID */ #endif /* !defined lint */ __FBSDID("$FreeBSD$"); @@ -19,7 +25,57 @@ __FBSDID("$FreeBSD$"); #include "tzfile.h" /* -** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, Second Edition, 1996-07-12. +** Some systems only handle "%.2d"; others only handle "%02d"; +** "%02.2d" makes (most) everybody happy. +** At least some versions of gcc warn about the %02.2d; +** we conditionalize below to avoid the warning. +*/ +/* +** All years associated with 32-bit time_t values are exactly four digits long; +** some years associated with 64-bit time_t values are not. +** Vintage programs are coded for years that are always four digits long +** and may assume that the newline always lands in the same place. +** For years that are less than four digits, we pad the output with +** leading zeroes to get the newline in the traditional place. +** The -4 ensures that we get four characters of output even if +** we call a strftime variant that produces fewer characters for some years. +** The ISO C 1999 and POSIX 1003.1-2004 standards prohibit padding the year, +** but many implementations pad anyway; most likely the standards are buggy. +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %-4s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %-4s\n" +#endif /* !defined __GNUC__ */ +/* +** For years that are more than four digits we put extra spaces before the year +** so that code trying to overwrite the newline won't end up overwriting +** a digit within a year and truncating the year (operating on the assumption +** that no output is better than wrong output). +*/ +#ifdef __GNUC__ +#define ASCTIME_FMT_B "%.3s %.3s%3d %2.2d:%2.2d:%2.2d %s\n" +#else /* !defined __GNUC__ */ +#define ASCTIME_FMT_B "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %s\n" +#endif /* !defined __GNUC__ */ + +#define STD_ASCTIME_BUF_SIZE 26 +/* +** Big enough for something such as +** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n +** (two three-character abbreviations, five strings denoting integers, +** seven explicit spaces, two explicit colons, a newline, +** and a trailing ASCII nul). +** The values above are for systems where an int is 32 bits and are provided +** as an example; the define below calculates the maximum for the system at +** hand. +*/ +#define MAX_ASCTIME_BUF_SIZE (2*3+5*INT_STRLEN_MAXIMUM(int)+7+2+1+1) + +static char buf_asctime[MAX_ASCTIME_BUF_SIZE]; + +/* +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * @@ -36,6 +92,8 @@ char * buf; }; const char * wn; const char * mn; + char year[INT_STRLEN_MAXIMUM(int) + 2]; + char result[MAX_ASCTIME_BUF_SIZE]; if (timeptr->tm_wday < 0 || timeptr->tm_wday >= DAYSPERWEEK) wn = "???"; @@ -44,35 +102,41 @@ char * buf; mn = "???"; else mn = mon_name[timeptr->tm_mon]; /* - ** The X3J11-suggested format is - ** "%.3s %.3s%3d %02.2d:%02.2d:%02.2d %d\n" - ** Since the .2 in 02.2d is ignored, we drop it. + ** Use strftime's %Y to generate the year, to avoid overflow problems + ** when computing timeptr->tm_year + TM_YEAR_BASE. + ** Assume that strftime is unaffected by other out-of-range members + ** (e.g., timeptr->tm_mday) when processing "%Y". */ - (void) sprintf(buf, "%.3s %.3s%3d %02d:%02d:%02d %d\n", + (void) strftime(year, sizeof year, "%Y", timeptr); + /* + ** We avoid using snprintf since it's not available on all systems. + */ + (void) sprintf(result, + ((strlen(year) <= 4) ? ASCTIME_FMT : ASCTIME_FMT_B), wn, mn, timeptr->tm_mday, timeptr->tm_hour, timeptr->tm_min, timeptr->tm_sec, - TM_YEAR_BASE + timeptr->tm_year); - return buf; + year); + if (strlen(result) < STD_ASCTIME_BUF_SIZE || buf == buf_asctime) { + (void) strcpy(buf, result); + return buf; + } else { +#ifdef EOVERFLOW + errno = EOVERFLOW; +#else /* !defined EOVERFLOW */ + errno = EINVAL; +#endif /* !defined EOVERFLOW */ + return NULL; + } } /* -** A la X3J11, with core dump avoidance. +** A la ISO/IEC 9945-1, ANSI/IEEE Std 1003.1, 2004 Edition. */ char * asctime(timeptr) const struct tm * timeptr; { - /* - ** Big enough for something such as - ** ??? ???-2147483648 -2147483648:-2147483648:-2147483648 -2147483648\n - ** (two three-character abbreviations, five strings denoting integers, - ** three explicit spaces, two explicit colons, a newline, - ** and a trailing ASCII nul). - */ - static char result[3 * 2 + 5 * INT_STRLEN_MAXIMUM(int) + - 3 + 2 + 1 + 1]; - - return asctime_r(timeptr, result); + return asctime_r(timeptr, buf_asctime); } diff --git a/lib/libc/stdtime/difftime.c b/lib/libc/stdtime/difftime.c index 596ea82f67ca..d16f9a0cdeee 100644 --- a/lib/libc/stdtime/difftime.c +++ b/lib/libc/stdtime/difftime.c @@ -1,12 +1,12 @@ /* ** This file is in the public domain, so clarified as of -** June 5, 1996 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)difftime.c 7.9"; +static char elsieid[] __unused = "@(#)difftime.c 8.1"; #endif /* !defined NOID */ #endif /* !defined lint */ __FBSDID("$FreeBSD$"); @@ -14,74 +14,56 @@ __FBSDID("$FreeBSD$"); /*LINTLIBRARY*/ #include "namespace.h" -#include "private.h" +#include "private.h" /* for time_t, TYPE_INTEGRAL, and TYPE_SIGNED */ #include "un-namespace.h" -/* -** Algorithm courtesy Paul Eggert (eggert@twinsun.com). -*/ - -#ifdef HAVE_LONG_DOUBLE -#define long_double long double -#endif /* defined HAVE_LONG_DOUBLE */ -#ifndef HAVE_LONG_DOUBLE -#define long_double double -#endif /* !defined HAVE_LONG_DOUBLE */ - double difftime(time1, time0) const time_t time1; const time_t time0; { - time_t delta; - time_t hibit; - - { - time_t tt; - double d; - long_double ld; - - if (sizeof tt < sizeof d) - return (double) time1 - (double) time0; - if (sizeof tt < sizeof ld) - return (long_double) time1 - (long_double) time0; + /* + ** If (sizeof (double) > sizeof (time_t)) simply convert and subtract + ** (assuming that the larger type has more precision). + ** This is the common real-world case circa 2004. + */ + if (sizeof (double) > sizeof (time_t)) + return (double) time1 - (double) time0; + if (!TYPE_INTEGRAL(time_t)) { + /* + ** time_t is floating. + */ + return time1 - time0; + } + if (!TYPE_SIGNED(time_t)) { + /* + ** time_t is integral and unsigned. + ** The difference of two unsigned values can't overflow + ** if the minuend is greater than or equal to the subtrahend. + */ + if (time1 >= time0) + return time1 - time0; + else return -((double) (time0 - time1)); } - if (time1 < time0) - return -difftime(time0, time1); /* - ** As much as possible, avoid loss of precision - ** by computing the difference before converting to double. + ** time_t is integral and signed. + ** Handle cases where both time1 and time0 have the same sign + ** (meaning that their difference cannot overflow). */ - delta = time1 - time0; - if (delta >= 0) - return delta; + if ((time1 < 0) == (time0 < 0)) + return time1 - time0; /* - ** Repair delta overflow. + ** time1 and time0 have opposite signs. + ** Punt if unsigned long is too narrow. */ - hibit = (~ (time_t) 0) << (TYPE_BIT(time_t) - 1); + if (sizeof (unsigned long) < sizeof (time_t)) + return (double) time1 - (double) time0; /* - ** The following expression rounds twice, which means - ** the result may not be the closest to the true answer. - ** For example, suppose time_t is 64-bit signed int, - ** long_double is IEEE 754 double with default rounding, - ** time1 = 9223372036854775807 and time0 = -1536. - ** Then the true difference is 9223372036854777343, - ** which rounds to 9223372036854777856 - ** with a total error of 513. - ** But delta overflows to -9223372036854774273, - ** which rounds to -9223372036854774784, and correcting - ** this by subtracting 2 * (long_double) hibit - ** (i.e. by adding 2**64 = 18446744073709551616) - ** yields 9223372036854776832, which - ** rounds to 9223372036854775808 - ** with a total error of 1535 instead. - ** This problem occurs only with very large differences. - ** It's too painful to fix this portably. - ** We are not alone in this problem; - ** some C compilers round twice when converting - ** large unsigned types to small floating types, - ** so if time_t is unsigned the "return delta" above - ** has the same double-rounding problem with those compilers. + ** Stay calm...decent optimizers will eliminate the complexity below. */ - return delta - 2 * (long_double) hibit; + if (time1 >= 0 /* && time0 < 0 */) + return (unsigned long) time1 + + (unsigned long) (-(time0 + 1)) + 1; + return -(double) ((unsigned long) time0 + + (unsigned long) (-(time1 + 1)) + 1); } diff --git a/lib/libc/stdtime/localtime.c b/lib/libc/stdtime/localtime.c index 59289435c8bf..83cecd17c351 100644 --- a/lib/libc/stdtime/localtime.c +++ b/lib/libc/stdtime/localtime.c @@ -1,20 +1,19 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ #include #ifndef lint #ifndef NOID -static char elsieid[] __unused = "@(#)localtime.c 7.78"; +static char elsieid[] __unused = "@(#)localtime.c 8.9"; #endif /* !defined NOID */ #endif /* !defined lint */ __FBSDID("$FreeBSD$"); /* -** Leap second handling from Bradley White (bww@k.gp.cs.cmu.edu). -** POSIX-style TZ environment variable handling from Guy Harris -** (guy@auspex.com). +** Leap second handling from Bradley White. +** POSIX-style TZ environment variable handling from Guy Harris. */ /*LINTLIBRARY*/ @@ -28,6 +27,20 @@ __FBSDID("$FreeBSD$"); #include "un-namespace.h" #include "tzfile.h" +#include "float.h" /* for FLT_MAX and DBL_MAX */ + +#ifndef TZ_ABBR_MAX_LEN +#define TZ_ABBR_MAX_LEN 16 +#endif /* !defined TZ_ABBR_MAX_LEN */ + +#ifndef TZ_ABBR_CHAR_SET +#define TZ_ABBR_CHAR_SET \ + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 :+-._" +#endif /* !defined TZ_ABBR_CHAR_SET */ + +#ifndef TZ_ABBR_ERR_CHAR +#define TZ_ABBR_ERR_CHAR '_' +#endif /* !defined TZ_ABBR_ERR_CHAR */ #include "libc_private.h" @@ -74,16 +87,16 @@ __FBSDID("$FreeBSD$"); ** 5. They might reference tm.TM_ZONE after calling offtime. ** What's best to do in the above cases is open to debate; ** for now, we just set things up so that in any of the five cases -** WILDABBR is used. Another possibility: initialize tzname[0] to the +** WILDABBR is used. Another possibility: initialize tzname[0] to the ** string "tzname[0] used before set", and similarly for the other cases. -** And another: initialize tzname[0] to "ERA", with an explanation in the +** And another: initialize tzname[0] to "ERA", with an explanation in the ** manual page of what this "time zone abbreviation" means (doing this so ** that tzname[0] has the "normal" length of three characters). */ #define WILDABBR " " #endif /* !defined WILDABBR */ -static char wildabbr[] = "WILDABBR"; +static char wildabbr[] = WILDABBR; /* * In June 2004 it was decided UTC was a more appropriate default time @@ -130,6 +143,8 @@ struct state { int timecnt; int typecnt; int charcnt; + int goback; + int goahead; time_t ats[TZ_MAX_TIMES]; unsigned char types[TZ_MAX_TIMES]; struct ttinfo ttis[TZ_MAX_TYPES]; @@ -155,40 +170,49 @@ struct rule { */ static long detzcode(const char * codep); +static time_t detzcode64(const char * codep); +static int differ_by_repeat(time_t t1, time_t t0); static const char * getzname(const char * strp); +static const char * getqzname(const char * strp, const int delim); static const char * getnum(const char * strp, int * nump, int min, int max); static const char * getsecs(const char * strp, long * secsp); static const char * getoffset(const char * strp, long * offsetp); static const char * getrule(const char * strp, struct rule * rulep); static void gmtload(struct state * sp); -static void gmtsub(const time_t * timep, long offset, +static struct tm * gmtsub(const time_t * timep, long offset, struct tm * tmp); -static void localsub(const time_t * timep, long offset, +static struct tm * localsub(const time_t * timep, long offset, struct tm * tmp); static int increment_overflow(int * number, int delta); +static int leaps_thru_end_of(int y); +static int long_increment_overflow(long * number, int delta); +static int long_normalize_overflow(long * tensptr, + int * unitsptr, int base); static int normalize_overflow(int * tensptr, int * unitsptr, int base); static void settzname(void); static time_t time1(struct tm * tmp, - void(*funcp) (const time_t *, + struct tm * (*funcp)(const time_t *, long, struct tm *), long offset); static time_t time2(struct tm *tmp, - void(*funcp) (const time_t *, + struct tm * (*funcp)(const time_t *, long, struct tm*), long offset, int * okayp); static time_t time2sub(struct tm *tmp, - void(*funcp) (const time_t *, + struct tm * (*funcp)(const time_t *, long, struct tm*), long offset, int * okayp, int do_norm_secs); -static void timesub(const time_t * timep, long offset, +static struct tm * timesub(const time_t * timep, long offset, const struct state * sp, struct tm * tmp); static int tmcomp(const struct tm * atmp, const struct tm * btmp); static time_t transtime(time_t janfirst, int year, const struct rule * rulep, long offset); -static int tzload(const char * name, struct state * sp); +static int typesequiv(const struct state * sp, int a, int b); +static int tzload(const char * name, struct state * sp, + int doextend); static int tzparse(const char * name, struct state * sp, int lastditch); @@ -224,7 +248,7 @@ char * tzname[2] = { ** Except for the strftime function, these functions [asctime, ** ctime, gmtime, localtime] return values in one of two static ** objects: a broken-down time structure and an array of char. -** Thanks to Paul Eggert (eggert@twinsun.com) for noting this. +** Thanks to Paul Eggert for noting this. */ static struct tm tm; @@ -245,12 +269,25 @@ const char * const codep; long result; int i; - result = (codep[0] & 0x80) ? ~0L : 0L; + result = (codep[0] & 0x80) ? ~0L : 0; for (i = 0; i < 4; ++i) result = (result << 8) | (codep[i] & 0xff); return result; } +static time_t +detzcode64(codep) +const char * const codep; +{ + register time_t result; + register int i; + + result = (codep[0] & 0x80) ? (~(int_fast64_t) 0) : 0; + for (i = 0; i < 8; ++i) + result = result * 256 + (codep[i] & 0xff); + return result; +} + static void settzname(void) { @@ -299,16 +336,58 @@ settzname(void) tzname[ttisp->tt_isdst] = &sp->chars[ttisp->tt_abbrind]; } + /* + ** Finally, scrub the abbreviations. + ** First, replace bogus characters. + */ + for (i = 0; i < sp->charcnt; ++i) + if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL) + sp->chars[i] = TZ_ABBR_ERR_CHAR; + /* + ** Second, truncate long abbreviations. + */ + for (i = 0; i < sp->typecnt; ++i) { + register const struct ttinfo * const ttisp = &sp->ttis[i]; + register char * cp = &sp->chars[ttisp->tt_abbrind]; + + if (strlen(cp) > TZ_ABBR_MAX_LEN && + strcmp(cp, GRANDPARENTED) != 0) + *(cp + TZ_ABBR_MAX_LEN) = '\0'; + } } static int -tzload(name, sp) +differ_by_repeat(t1, t0) +const time_t t1; +const time_t t0; +{ + int_fast64_t _t0 = t0; + int_fast64_t _t1 = t1; + + if (TYPE_INTEGRAL(time_t) && + TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS) + return 0; + //turn ((int_fast64_t)(t1 - t0) == SECSPERREPEAT); + return _t1 - _t0 == SECSPERREPEAT; +} + +static int +tzload(name, sp, doextend) const char * name; struct state * const sp; +register const int doextend; { const char * p; int i; int fid; + int stored; + int nread; + union { + struct tzhead tzhead; + char buf[2 * sizeof(struct tzhead) + + 2 * sizeof *sp + + 4 * TZ_MAX_TIMES]; + } u; /* XXX The following is from OpenBSD, and I'm not sure it is correct */ if (name != NULL && issetugid() != 0) @@ -356,18 +435,13 @@ struct state * const sp; return -1; } } - { - struct tzhead * tzhp; - union { - struct tzhead tzhead; - char buf[sizeof *sp + sizeof *tzhp]; - } u; + nread = _read(fid, u.buf, sizeof u.buf); + if (_close(fid) < 0 || nread <= 0) + return -1; + for (stored = 4; stored <= 8; stored *= 2) { int ttisstdcnt; int ttisgmtcnt; - i = _read(fid, u.buf, sizeof u.buf); - if (_close(fid) != 0) - return -1; ttisstdcnt = (int) detzcode(u.tzhead.tzh_ttisstdcnt); ttisgmtcnt = (int) detzcode(u.tzhead.tzh_ttisgmtcnt); sp->leapcnt = (int) detzcode(u.tzhead.tzh_leapcnt); @@ -382,17 +456,19 @@ struct state * const sp; (ttisstdcnt != sp->typecnt && ttisstdcnt != 0) || (ttisgmtcnt != sp->typecnt && ttisgmtcnt != 0)) return -1; - if (i - (p - u.buf) < sp->timecnt * 4 + /* ats */ + if (nread - (p - u.buf) < + sp->timecnt * stored + /* ats */ sp->timecnt + /* types */ - sp->typecnt * (4 + 2) + /* ttinfos */ + sp->typecnt * 6 + /* ttinfos */ sp->charcnt + /* chars */ - sp->leapcnt * (4 + 4) + /* lsinfos */ + sp->leapcnt * (stored + 4) + /* lsinfos */ ttisstdcnt + /* ttisstds */ ttisgmtcnt) /* ttisgmts */ return -1; for (i = 0; i < sp->timecnt; ++i) { - sp->ats[i] = detzcode(p); - p += 4; + sp->ats[i] = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; } for (i = 0; i < sp->timecnt; ++i) { sp->types[i] = (unsigned char) *p++; @@ -420,8 +496,9 @@ struct state * const sp; struct lsinfo * lsisp; lsisp = &sp->lsis[i]; - lsisp->ls_trans = detzcode(p); - p += 4; + lsisp->ls_trans = (stored == 4) ? + detzcode(p) : detzcode64(p); + p += stored; lsisp->ls_corr = detzcode(p); p += 4; } @@ -451,10 +528,127 @@ struct state * const sp; return -1; } } + /* + ** Out-of-sort ats should mean we're running on a + ** signed time_t system but using a data file with + ** unsigned values (or vice versa). + */ + for (i = 0; i < sp->timecnt - 2; ++i) + if (sp->ats[i] > sp->ats[i + 1]) { + ++i; + if (TYPE_SIGNED(time_t)) { + /* + ** Ignore the end (easy). + */ + sp->timecnt = i; + } else { + /* + ** Ignore the beginning (harder). + */ + register int j; + + for (j = 0; j + i < sp->timecnt; ++j) { + sp->ats[j] = sp->ats[j + i]; + sp->types[j] = sp->types[j + i]; + } + sp->timecnt = j; + } + break; + } + /* + ** If this is an old file, we're done. + */ + if (u.tzhead.tzh_version[0] == '\0') + break; + nread -= p - u.buf; + for (i = 0; i < nread; ++i) + u.buf[i] = p[i]; + /* + ** If this is a narrow integer time_t system, we're done. + */ + if (stored >= (int) sizeof(time_t) && TYPE_INTEGRAL(time_t)) + break; + } + if (doextend && nread > 2 && + u.buf[0] == '\n' && u.buf[nread - 1] == '\n' && + sp->typecnt + 2 <= TZ_MAX_TYPES) { + struct state ts; + register int result; + + u.buf[nread - 1] = '\0'; + result = tzparse(&u.buf[1], &ts, FALSE); + if (result == 0 && ts.typecnt == 2 && + sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) { + for (i = 0; i < 2; ++i) + ts.ttis[i].tt_abbrind += + sp->charcnt; + for (i = 0; i < ts.charcnt; ++i) + sp->chars[sp->charcnt++] = + ts.chars[i]; + i = 0; + while (i < ts.timecnt && + ts.ats[i] <= + sp->ats[sp->timecnt - 1]) + ++i; + while (i < ts.timecnt && + sp->timecnt < TZ_MAX_TIMES) { + sp->ats[sp->timecnt] = + ts.ats[i]; + sp->types[sp->timecnt] = + sp->typecnt + + ts.types[i]; + ++sp->timecnt; + ++i; + } + sp->ttis[sp->typecnt++] = ts.ttis[0]; + sp->ttis[sp->typecnt++] = ts.ttis[1]; + } + } + sp->goback = sp->goahead = FALSE; + if (sp->timecnt > 1) { + for (i = 1; i < sp->timecnt; ++i) + if (typesequiv(sp, sp->types[i], sp->types[0]) && + differ_by_repeat(sp->ats[i], sp->ats[0])) { + sp->goback = TRUE; + break; + } + for (i = sp->timecnt - 2; i >= 0; --i) + if (typesequiv(sp, sp->types[sp->timecnt - 1], + sp->types[i]) && + differ_by_repeat(sp->ats[sp->timecnt - 1], + sp->ats[i])) { + sp->goahead = TRUE; + break; + } } return 0; } +static int +typesequiv(sp, a, b) +const struct state * const sp; +const int a; +const int b; +{ + register int result; + + if (sp == NULL || + a < 0 || a >= sp->typecnt || + b < 0 || b >= sp->typecnt) + result = FALSE; + else { + register const struct ttinfo * ap = &sp->ttis[a]; + register const struct ttinfo * bp = &sp->ttis[b]; + result = ap->tt_gmtoff == bp->tt_gmtoff && + ap->tt_isdst == bp->tt_isdst && + ap->tt_ttisstd == bp->tt_ttisstd && + ap->tt_ttisgmt == bp->tt_ttisgmt && + strcmp(&sp->chars[ap->tt_abbrind], + &sp->chars[bp->tt_abbrind]) == 0; + } + return result; +} + static const int mon_lengths[2][MONSPERYEAR] = { { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } @@ -466,7 +660,7 @@ static const int year_lengths[2] = { /* ** Given a pointer into a time zone string, scan until a character that is not -** a valid character in a zone name is found. Return a pointer to that +** a valid character in a zone name is found. Return a pointer to that ** character. */ @@ -482,6 +676,25 @@ const char * strp; return strp; } +/* +** Given a pointer into an extended time zone string, scan until the ending +** delimiter of the zone name is located. Return a pointer to the delimiter. +** +** As with getzname above, the legal character set is actually quite +** restricted, with other characters producing undefined results. +** We don't do any checking here; checking is done later in common-case code. +*/ + +static const char * +getqzname(register const char *strp, const int delim) +{ + register int c; + + while ((c = *strp) != '\0' && c != delim) + ++strp; + return strp; +} + /* ** Given a pointer into a time zone string, extract a number from that string. ** Check that the number is within a specified range; if it is not, return @@ -547,7 +760,7 @@ long * const secsp; *secsp += num * SECSPERMIN; if (*strp == ':') { ++strp; - /* `SECSPERMIN' allows for leap seconds. */ + /* `SECSPERMIN' allows for leap seconds. */ strp = getnum(strp, &num, 0, SECSPERMIN); if (strp == NULL) return NULL; @@ -586,7 +799,7 @@ long * const offsetp; /* ** Given a pointer into a time zone string, extract a rule in the form -** date[/time]. See POSIX section 8 for the format of "date" and "time". +** date[/time]. See POSIX section 8 for the format of "date" and "time". ** If a valid rule is not found, return NULL. ** Otherwise, return a pointer to the first character not part of the rule. */ @@ -705,7 +918,7 @@ const long offset; dow += DAYSPERWEEK; /* - ** "dow" is the day-of-week of the first day of the month. Get + ** "dow" is the day-of-week of the first day of the month. Get ** the day-of-month (zero-origin) of the first "dow" day of the ** month. */ @@ -728,7 +941,7 @@ const long offset; /* ** "value" is the Epoch-relative time of 00:00:00 UTC on the day in - ** question. To get the Epoch-relative time of the specified local + ** question. To get the Epoch-relative time of the specified local ** time on that day, add the transition time and the current offset ** from UTC. */ @@ -766,10 +979,18 @@ const int lastditch; stdlen = (sizeof sp->chars) - 1; stdoffset = 0; } else { - name = getzname(name); - stdlen = name - stdname; - if (stdlen < 3) - return -1; + if (*name == '<') { + name++; + stdname = name; + name = getqzname(name, '>'); + if (*name != '>') + return (-1); + stdlen = name - stdname; + name++; + } else { + name = getzname(name); + stdlen = name - stdname; + } if (*name == '\0') return -1; /* was "stdoffset = 0;" */ else { @@ -778,15 +999,22 @@ const int lastditch; return -1; } } - load_result = tzload(TZDEFRULES, sp); + load_result = tzload(TZDEFRULES, sp, FALSE); if (load_result != 0) sp->leapcnt = 0; /* so, we're off a little */ if (*name != '\0') { - dstname = name; - name = getzname(name); - dstlen = name - dstname; /* length of DST zone name */ - if (dstlen < 3) - return -1; + if (*name == '<') { + dstname = ++name; + name = getqzname(name, '>'); + if (*name != '>') + return -1; + dstlen = name - dstname; + name++; + } else { + dstname = name; + name = getzname(name); + dstlen = name - dstname; /* length of DST zone name */ + } if (*name != '\0' && *name != ',' && *name != ';') { name = getoffset(name, &dstoffset); if (name == NULL) @@ -813,11 +1041,8 @@ const int lastditch; return -1; sp->typecnt = 2; /* standard time and DST */ /* - ** Two transitions per year, from EPOCH_YEAR to 2037. + ** Two transitions per year, from EPOCH_YEAR forward. */ - sp->timecnt = 2 * (2037 - EPOCH_YEAR + 1); - if (sp->timecnt > TZ_MAX_TIMES) - return -1; sp->ttis[0].tt_gmtoff = -dstoffset; sp->ttis[0].tt_isdst = 1; sp->ttis[0].tt_abbrind = stdlen + 1; @@ -827,7 +1052,12 @@ const int lastditch; atp = sp->ats; typep = sp->types; janfirst = 0; - for (year = EPOCH_YEAR; year <= 2037; ++year) { + sp->timecnt = 0; + for (year = EPOCH_YEAR; + sp->timecnt + 2 <= TZ_MAX_TIMES; + ++year) { + time_t newfirst; + starttime = transtime(janfirst, year, &start, stdoffset); endtime = transtime(janfirst, year, &end, @@ -843,8 +1073,13 @@ const int lastditch; *atp++ = endtime; *typep++ = 1; /* DST ends */ } - janfirst += year_lengths[isleap(year)] * + sp->timecnt += 2; + newfirst = janfirst; + newfirst += year_lengths[isleap(year)] * SECSPERDAY; + if (newfirst <= janfirst) + break; + janfirst = newfirst; } } else { long theirstdoffset; @@ -959,7 +1194,7 @@ static void gmtload(sp) struct state * const sp; { - if (tzload(gmt, sp) != 0) + if (tzload(gmt, sp, TRUE) != 0) (void) tzparse(gmt, sp, TRUE); } @@ -990,7 +1225,7 @@ tzsetwall_basic(int rdlocked) } } #endif /* defined ALL_STATE */ - if (tzload((char *) NULL, lclptr) != 0) + if (tzload((char *) NULL, lclptr, TRUE) != 0) gmtload(lclptr); settzname(); _RWLOCK_UNLOCK(&lcl_rwlock); @@ -1053,7 +1288,7 @@ tzset_basic(int rdlocked) lclptr->ttis[0].tt_gmtoff = 0; lclptr->ttis[0].tt_abbrind = 0; (void) strcpy(lclptr->chars, gmt); - } else if (tzload(name, lclptr) != 0) + } else if (tzload(name, lclptr, TRUE) != 0) if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0) (void) gmtload(lclptr); settzname(); @@ -1072,14 +1307,14 @@ tzset(void) /* ** The easy way to behave "as if no library function calls" localtime ** is to not call it--so we drop its guts into "localsub", which can be -** freely called. (And no, the PANS doesn't require the above behavior-- +** freely called. (And no, the PANS doesn't require the above behavior-- ** but it *is* desirable.) ** ** The unused offset argument is for the benefit of mktime variants. */ /*ARGSUSED*/ -static void +static struct tm * localsub(timep, offset, tmp) const time_t * const timep; const long offset; @@ -1088,15 +1323,53 @@ struct tm * const tmp; struct state * sp; const struct ttinfo * ttisp; int i; - const time_t t = *timep; + struct tm * result; + const time_t t = *timep; sp = lclptr; #ifdef ALL_STATE - if (sp == NULL) { - gmtsub(timep, offset, tmp); - return; - } + if (sp == NULL) + return gmtsub(timep, offset, tmp); #endif /* defined ALL_STATE */ + if ((sp->goback && t < sp->ats[0]) || + (sp->goahead && t > sp->ats[sp->timecnt - 1])) { + time_t newt = t; + register time_t seconds; + register time_t tcycles; + register int_fast64_t icycles; + + if (t < sp->ats[0]) + seconds = sp->ats[0] - t; + else seconds = t - sp->ats[sp->timecnt - 1]; + --seconds; + tcycles = seconds / YEARSPERREPEAT / AVGSECSPERYEAR; + ++tcycles; + icycles = tcycles; + if (tcycles - icycles >= 1 || icycles - tcycles >= 1) + return NULL; + seconds = icycles; + seconds *= YEARSPERREPEAT; + seconds *= AVGSECSPERYEAR; + if (t < sp->ats[0]) + newt += seconds; + else newt -= seconds; + if (newt < sp->ats[0] || + newt > sp->ats[sp->timecnt - 1]) + return NULL; /* "cannot happen" */ + result = localsub(&newt, offset, tmp); + if (result == tmp) { + register time_t newy; + + newy = tmp->tm_year; + if (t < sp->ats[0]) + newy -= icycles * YEARSPERREPEAT; + else newy += icycles * YEARSPERREPEAT; + tmp->tm_year = newy; + if (tmp->tm_year != newy) + return NULL; + } + return result; + } if (sp->timecnt == 0 || t < sp->ats[0]) { i = 0; while (sp->ttis[i].tt_isdst) @@ -1105,10 +1378,17 @@ struct tm * const tmp; break; } } else { - for (i = 1; i < sp->timecnt; ++i) - if (t < sp->ats[i]) - break; - i = sp->types[i - 1]; + register int lo = 1; + register int hi = sp->timecnt; + + while (lo < hi) { + register int mid = (lo + hi) >> 1; + + if (t < sp->ats[mid]) + hi = mid; + else lo = mid + 1; + } + i = (int) sp->types[lo - 1]; } ttisp = &sp->ttis[i]; /* @@ -1117,12 +1397,13 @@ struct tm * const tmp; ** t += ttisp->tt_gmtoff; ** timesub(&t, 0L, sp, tmp); */ - timesub(&t, ttisp->tt_gmtoff, sp, tmp); + result = timesub(&t, ttisp->tt_gmtoff, sp, tmp); tmp->tm_isdst = ttisp->tt_isdst; tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind]; #ifdef TM_ZONE tmp->TM_ZONE = &sp->chars[ttisp->tt_abbrind]; #endif /* defined TM_ZONE */ + return result; } struct tm * @@ -1168,27 +1449,29 @@ const time_t * const timep; */ struct tm * -localtime_r(timep, tm) +localtime_r(timep, tmp) const time_t * const timep; -struct tm * tm; +struct tm * tmp; { _RWLOCK_RDLOCK(&lcl_rwlock); tzset_basic(1); - localsub(timep, 0L, tm); + localsub(timep, 0L, tmp); _RWLOCK_UNLOCK(&lcl_rwlock); - return tm; + return tmp; } /* ** gmtsub is to gmtime as localsub is to localtime. */ -static void +static struct tm * gmtsub(timep, offset, tmp) const time_t * const timep; const long offset; struct tm * const tmp; { + register struct tm * result; + if (!gmt_is_set) { _MUTEX_LOCK(&gmt_mutex); if (!gmt_is_set) { @@ -1201,7 +1484,7 @@ struct tm * const tmp; } _MUTEX_UNLOCK(&gmt_mutex); } - timesub(timep, offset, gmtptr, tmp); + result = timesub(timep, offset, gmtptr, tmp); #ifdef TM_ZONE /* ** Could get fancy here and deliver something such as @@ -1221,6 +1504,7 @@ struct tm * const tmp; #endif /* State Farm */ } #endif /* defined TM_ZONE */ + return result; } struct tm * @@ -1267,12 +1551,11 @@ const time_t * const timep; */ struct tm * -gmtime_r(timep, tm) +gmtime_r(timep, tmp) const time_t * const timep; -struct tm * tm; +struct tm * tmp; { - gmtsub(timep, 0L, tm); - return tm; + return gmtsub(timep, 0L, tmp); } #ifdef STD_INSPIRED @@ -1282,13 +1565,25 @@ offtime(timep, offset) const time_t * const timep; const long offset; { - gmtsub(timep, offset, &tm); - return &tm; + return gmtsub(timep, offset, &tm); } #endif /* defined STD_INSPIRED */ -static void +/* +** Return the number of leap years through the end of the given year +** where, to make the math easy, the answer for year zero is defined as zero. +*/ + +static int +leaps_thru_end_of(y) +register const int y; +{ + return (y >= 0) ? (y / 4 - y / 100 + y / 400) : + -(leaps_thru_end_of(-(y + 1)) + 1); +} + +static struct tm * timesub(timep, offset, sp, tmp) const time_t * const timep; const long offset; @@ -1296,10 +1591,10 @@ const struct state * const sp; struct tm * const tmp; { const struct lsinfo * lp; - long days; + time_t tdays; + int idays; /* unsigned would be so 2003 */ long rem; - long y; - int yleap; + int y; const int * ip; long corr; int hit; @@ -1333,60 +1628,93 @@ struct tm * const tmp; break; } } - days = *timep / SECSPERDAY; - rem = *timep % SECSPERDAY; -#ifdef mc68k - if (*timep == 0x80000000) { - /* - ** A 3B1 muffs the division on the most negative number. - */ - days = -24855; - rem = -11648; + y = EPOCH_YEAR; + tdays = *timep / SECSPERDAY; + rem = *timep - tdays * SECSPERDAY; + while (tdays < 0 || tdays >= year_lengths[isleap(y)]) { + int newy; + register time_t tdelta; + register int idelta; + register int leapdays; + + tdelta = tdays / DAYSPERLYEAR; + idelta = tdelta; + if (tdelta - idelta >= 1 || idelta - tdelta >= 1) + return NULL; + if (idelta == 0) + idelta = (tdays < 0) ? -1 : 1; + newy = y; + if (increment_overflow(&newy, idelta)) + return NULL; + leapdays = leaps_thru_end_of(newy - 1) - + leaps_thru_end_of(y - 1); + tdays -= ((time_t) newy - y) * DAYSPERNYEAR; + tdays -= leapdays; + y = newy; } -#endif /* defined mc68k */ - rem += (offset - corr); + { + register long seconds; + + seconds = tdays * SECSPERDAY + 0.5; + tdays = seconds / SECSPERDAY; + rem += seconds - tdays * SECSPERDAY; + } + /* + ** Given the range, we can now fearlessly cast... + */ + idays = tdays; + rem += offset - corr; while (rem < 0) { rem += SECSPERDAY; - --days; + --idays; } while (rem >= SECSPERDAY) { rem -= SECSPERDAY; - ++days; + ++idays; } + while (idays < 0) { + if (increment_overflow(&y, -1)) + return NULL; + idays += year_lengths[isleap(y)]; + } + while (idays >= year_lengths[isleap(y)]) { + idays -= year_lengths[isleap(y)]; + if (increment_overflow(&y, 1)) + return NULL; + } + tmp->tm_year = y; + if (increment_overflow(&tmp->tm_year, -TM_YEAR_BASE)) + return NULL; + tmp->tm_yday = idays; + /* + ** The "extra" mods below avoid overflow problems. + */ + tmp->tm_wday = EPOCH_WDAY + + ((y - EPOCH_YEAR) % DAYSPERWEEK) * + (DAYSPERNYEAR % DAYSPERWEEK) + + leaps_thru_end_of(y - 1) - + leaps_thru_end_of(EPOCH_YEAR - 1) + + idays; + tmp->tm_wday %= DAYSPERWEEK; + if (tmp->tm_wday < 0) + tmp->tm_wday += DAYSPERWEEK; tmp->tm_hour = (int) (rem / SECSPERHOUR); - rem = rem % SECSPERHOUR; + rem %= SECSPERHOUR; tmp->tm_min = (int) (rem / SECSPERMIN); /* ** A positive leap second requires a special - ** representation. This uses "... ??:59:60" et seq. + ** representation. This uses "... ??:59:60" et seq. */ tmp->tm_sec = (int) (rem % SECSPERMIN) + hit; - tmp->tm_wday = (int) ((EPOCH_WDAY + days) % DAYSPERWEEK); - if (tmp->tm_wday < 0) - tmp->tm_wday += DAYSPERWEEK; - y = EPOCH_YEAR; -#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400) - while (days < 0 || days >= (long) year_lengths[yleap = isleap(y)]) { - long newy; - - newy = y + days / DAYSPERNYEAR; - if (days < 0) - --newy; - days -= (newy - y) * DAYSPERNYEAR + - LEAPS_THRU_END_OF(newy - 1) - - LEAPS_THRU_END_OF(y - 1); - y = newy; - } - tmp->tm_year = y - TM_YEAR_BASE; - tmp->tm_yday = (int) days; - ip = mon_lengths[yleap]; - for (tmp->tm_mon = 0; days >= (long) ip[tmp->tm_mon]; ++(tmp->tm_mon)) - days = days - (long) ip[tmp->tm_mon]; - tmp->tm_mday = (int) (days + 1); + ip = mon_lengths[isleap(y)]; + for (tmp->tm_mon = 0; idays >= ip[tmp->tm_mon]; ++(tmp->tm_mon)) + idays -= ip[tmp->tm_mon]; + tmp->tm_mday = (int) (idays + 1); tmp->tm_isdst = 0; #ifdef TM_GMTOFF tmp->TM_GMTOFF = offset; #endif /* defined TM_GMTOFF */ + return tmp; } char * @@ -1396,7 +1724,7 @@ const time_t * const timep; /* ** Section 4.12.3.2 of X3.159-1989 requires that ** The ctime function converts the calendar time pointed to by timer -** to local time in the form of a string. It is equivalent to +** to local time in the form of a string. It is equivalent to ** asctime(localtime(timer)) */ return asctime(localtime(timep)); @@ -1407,17 +1735,16 @@ ctime_r(timep, buf) const time_t * const timep; char * buf; { - struct tm tm; + struct tm mytm; - return asctime_r(localtime_r(timep, &tm), buf); + return asctime_r(localtime_r(timep, &mytm), buf); } /* ** Adapted from code provided by Robert Elz, who writes: ** The "best" way to do mktime I think is based on an idea of Bob ** Kridle's (so its said...) from a long time ago. -** [kridle@xinet.com as of 1996-01-16.] -** It does a binary search of the time_t space. Since time_t's are +** It does a binary search of the time_t space. Since time_t's are ** just 32 bits, its a max of 32 iterations (even at 64 bits it ** would still be very reasonable). */ @@ -1427,7 +1754,7 @@ char * buf; #endif /* !defined WRONG */ /* -** Simplified normalize logic courtesy Paul Eggert (eggert@twinsun.com). +** Simplified normalize logic courtesy Paul Eggert. */ static int @@ -1442,6 +1769,18 @@ int delta; return (*number < number0) != (delta < 0); } +static int +long_increment_overflow(number, delta) +long * number; +int delta; +{ + long number0; + + number0 = *number; + *number += delta; + return (*number < number0) != (delta < 0); +} + static int normalize_overflow(tensptr, unitsptr, base) int * const tensptr; @@ -1457,6 +1796,21 @@ const int base; return increment_overflow(tensptr, tensdelta); } +static int +long_normalize_overflow(tensptr, unitsptr, base) +long * const tensptr; +int * const unitsptr; +const int base; +{ + register int tensdelta; + + tensdelta = (*unitsptr >= 0) ? + (*unitsptr / base) : + (-1 - (-1 - *unitsptr) / base); + *unitsptr -= tensdelta * base; + return long_increment_overflow(tensptr, tensdelta); +} + static int tmcomp(atmp, btmp) const struct tm * const atmp; @@ -1476,19 +1830,22 @@ const struct tm * const btmp; static time_t time2sub(tmp, funcp, offset, okayp, do_norm_secs) struct tm * const tmp; -void (* const funcp)(const time_t*, long, struct tm*); +struct tm * (* const funcp)(const time_t*, long, struct tm*); const long offset; int * const okayp; const int do_norm_secs; { const struct state * sp; int dir; - int bits; - int i, j ; + int i, j; int saved_seconds; - time_t newt; - time_t t; - struct tm yourtm, mytm; + long li; + time_t lo; + time_t hi; + long y; + time_t newt; + time_t t; + struct tm yourtm, mytm; *okayp = FALSE; yourtm = *tmp; @@ -1501,45 +1858,49 @@ const int do_norm_secs; return WRONG; if (normalize_overflow(&yourtm.tm_mday, &yourtm.tm_hour, HOURSPERDAY)) return WRONG; - if (normalize_overflow(&yourtm.tm_year, &yourtm.tm_mon, MONSPERYEAR)) + y = yourtm.tm_year; + if (long_normalize_overflow(&y, &yourtm.tm_mon, MONSPERYEAR)) return WRONG; /* - ** Turn yourtm.tm_year into an actual year number for now. + ** Turn y into an actual year number for now. ** It is converted back to an offset from TM_YEAR_BASE later. */ - if (increment_overflow(&yourtm.tm_year, TM_YEAR_BASE)) + if (long_increment_overflow(&y, TM_YEAR_BASE)) return WRONG; while (yourtm.tm_mday <= 0) { - if (increment_overflow(&yourtm.tm_year, -1)) + if (long_increment_overflow(&y, -1)) return WRONG; - i = yourtm.tm_year + (1 < yourtm.tm_mon); - yourtm.tm_mday += year_lengths[isleap(i)]; + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday += year_lengths[isleap(li)]; } while (yourtm.tm_mday > DAYSPERLYEAR) { - i = yourtm.tm_year + (1 < yourtm.tm_mon); - yourtm.tm_mday -= year_lengths[isleap(i)]; - if (increment_overflow(&yourtm.tm_year, 1)) + li = y + (1 < yourtm.tm_mon); + yourtm.tm_mday -= year_lengths[isleap(li)]; + if (long_increment_overflow(&y, 1)) return WRONG; } for ( ; ; ) { - i = mon_lengths[isleap(yourtm.tm_year)][yourtm.tm_mon]; + i = mon_lengths[isleap(y)][yourtm.tm_mon]; if (yourtm.tm_mday <= i) break; yourtm.tm_mday -= i; if (++yourtm.tm_mon >= MONSPERYEAR) { yourtm.tm_mon = 0; - if (increment_overflow(&yourtm.tm_year, 1)) + if (long_increment_overflow(&y, 1)) return WRONG; } } - if (increment_overflow(&yourtm.tm_year, -TM_YEAR_BASE)) + if (long_increment_overflow(&y, -TM_YEAR_BASE)) + return WRONG; + yourtm.tm_year = y; + if (yourtm.tm_year != y) return WRONG; /* Don't go below 1900 for POLA */ if (yourtm.tm_year < 0) return WRONG; if (yourtm.tm_sec >= 0 && yourtm.tm_sec < SECSPERMIN) saved_seconds = 0; - else if (yourtm.tm_year + TM_YEAR_BASE < EPOCH_YEAR) { + else if (y + TM_YEAR_BASE < EPOCH_YEAR) { /* ** We can't set tm_sec to 0, because that might push the ** time below the minimum representable time. @@ -1557,33 +1918,53 @@ const int do_norm_secs; yourtm.tm_sec = 0; } /* - ** Divide the search space in half - ** (this works whether time_t is signed or unsigned). + ** Do a binary search (this works whatever time_t's type is). */ - bits = TYPE_BIT(time_t) - 1; - /* - ** If we have more than this, we will overflow tm_year for tmcomp(). - ** We should really return an error if we cannot represent it. - */ - if (bits > 48) - bits = 48; - /* - ** If time_t is signed, then 0 is just above the median, - ** assuming two's complement arithmetic. - ** If time_t is unsigned, then (1 << bits) is just above the median. - */ - t = TYPE_SIGNED(time_t) ? 0 : (((time_t) 1) << bits); + if (!TYPE_SIGNED(time_t)) { + lo = 0; + hi = lo - 1; + } else if (!TYPE_INTEGRAL(time_t)) { + if (sizeof(time_t) > sizeof(float)) + hi = (time_t) DBL_MAX; + else hi = (time_t) FLT_MAX; + lo = -hi; + } else { + lo = 1; + for (i = 0; i < (int) TYPE_BIT(time_t) - 1; ++i) + lo *= 2; + hi = -(lo + 1); + } for ( ; ; ) { - (*funcp)(&t, offset, &mytm); - dir = tmcomp(&mytm, &yourtm); + t = lo / 2 + hi / 2; + if (t < lo) + t = lo; + else if (t > hi) + t = hi; + if ((*funcp)(&t, offset, &mytm) == NULL) { + /* + ** Assume that t is too extreme to be represented in + ** a struct tm; arrange things so that it is less + ** extreme on the next pass. + */ + dir = (t > 0) ? 1 : -1; + } else dir = tmcomp(&mytm, &yourtm); if (dir != 0) { - if (bits-- < 0) + if (t == lo) { + ++t; + if (t <= lo) + return WRONG; + ++lo; + } else if (t == hi) { + --t; + if (t >= hi) + return WRONG; + --hi; + } + if (lo > hi) return WRONG; - if (bits < 0) - --t; /* may be needed if new t is minimal */ - else if (dir > 0) - t -= ((time_t) 1) << bits; - else t += ((time_t) 1) << bits; + if (dir > 0) + hi = t; + else lo = t; continue; } if (yourtm.tm_isdst < 0 || mytm.tm_isdst == yourtm.tm_isdst) @@ -1594,7 +1975,8 @@ const int do_norm_secs; ** It's okay to guess wrong since the guess ** gets checked. */ - sp = (funcp == localsub) ? lclptr : gmtptr; + sp = (const struct state *) + ((funcp == localsub) ? lclptr : gmtptr); #ifdef ALL_STATE if (sp == NULL) return WRONG; @@ -1607,7 +1989,8 @@ const int do_norm_secs; continue; newt = t + sp->ttis[j].tt_gmtoff - sp->ttis[i].tt_gmtoff; - (*funcp)(&newt, offset, &mytm); + if ((*funcp)(&newt, offset, &mytm) == NULL) + continue; if (tmcomp(&mytm, &yourtm) != 0) continue; if (mytm.tm_isdst != yourtm.tm_isdst) @@ -1626,15 +2009,15 @@ const int do_norm_secs; if ((newt < t) != (saved_seconds < 0)) return WRONG; t = newt; - (*funcp)(&t, offset, tmp); - *okayp = TRUE; + if ((*funcp)(&t, offset, tmp)) + *okayp = TRUE; return t; } static time_t time2(tmp, funcp, offset, okayp) struct tm * const tmp; -void (* const funcp)(const time_t*, long, struct tm*); +struct tm * (* const funcp)(const time_t*, long, struct tm*); const long offset; int * const okayp; { @@ -1652,7 +2035,7 @@ int * const okayp; static time_t time1(tmp, funcp, offset) struct tm * const tmp; -void (* const funcp)(const time_t *, long, struct tm *); +struct tm * (* const funcp)(const time_t *, long, struct tm *); const long offset; { time_t t; @@ -1670,7 +2053,7 @@ const long offset; t = time2(tmp, funcp, offset, &okay); #ifdef PCTS /* - ** PCTS code courtesy Grant Sullivan (grant@osf.org). + ** PCTS code courtesy Grant Sullivan. */ if (okay) return t; @@ -1687,7 +2070,7 @@ const long offset; ** We try to divine the type they started from and adjust to the ** type they need. */ - sp = (funcp == localsub) ? lclptr : gmtptr; + sp = (const struct state *) ((funcp == localsub) ? lclptr : gmtptr); #ifdef ALL_STATE if (sp == NULL) return WRONG; @@ -1833,7 +2216,7 @@ time_t t; tzset(); /* ** For a positive leap second hit, the result - ** is not unique. For a negative leap second + ** is not unique. For a negative leap second ** hit, the corresponding time doesn't exist, ** so we return an adjacent second. */ diff --git a/lib/libc/stdtime/private.h b/lib/libc/stdtime/private.h index a3c777834e3d..dda5befd737e 100644 --- a/lib/libc/stdtime/private.h +++ b/lib/libc/stdtime/private.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. ** ** $FreeBSD$ */ @@ -37,11 +37,13 @@ #ifndef lint #ifndef NOID /* -static char privatehid[] = "@(#)private.h 7.53"; +static char privatehid[] = "@(#)private.h 8.6"; */ #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -63,10 +65,6 @@ static char privatehid[] = "@(#)private.h 7.53"; #define HAVE_SETTIMEOFDAY 3 #endif /* !defined HAVE_SETTIMEOFDAY */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - #ifndef HAVE_SYMLINK #define HAVE_SYMLINK 1 #endif /* !defined HAVE_SYMLINK */ @@ -104,17 +102,17 @@ static char privatehid[] = "@(#)private.h 7.53"; #include "stdio.h" #include "errno.h" #include "string.h" -#include "limits.h" /* for CHAR_BIT */ +#include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ #ifndef WIFEXITED #define WIFEXITED(status) (((status) & 0xff) == 0) @@ -123,55 +121,84 @@ static char privatehid[] = "@(#)private.h 7.53"; #define WEXITSTATUS(status) (((status) >> 8) & 0xff) #endif /* !defined WEXITSTATUS */ -#if HAVE_UNISTD_H - 0 -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK, R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ -#if !(HAVE_UNISTD_H - 0) +#if !(HAVE_UNISTD_H) #ifndef F_OK #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ +#endif /* !(HAVE_UNISTD_H) */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) /* -** SunOS 4.1.1 headers lack FILENAME_MAX. +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + +/* +** Workarounds for compilers/systems. */ -#ifndef FILENAME_MAX +/* +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. +** Fix the former without affecting the latter. +*/ -#ifndef MAXPATHLEN -#ifdef unix -#include "sys/param.h" -#endif /* defined unix */ -#endif /* !defined MAXPATHLEN */ - -#ifdef MAXPATHLEN -#define FILENAME_MAX MAXPATHLEN -#endif /* defined MAXPATHLEN */ -#ifndef MAXPATHLEN -#define FILENAME_MAX 1024 /* Pure guesswork */ -#endif /* !defined MAXPATHLEN */ - -#endif /* !defined FILENAME_MAX */ +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif /* ** Private function declarations. */ -char * icalloc(int nelem, int elsize); -char * icatalloc(char * old, const char * new); -char * icpyalloc(const char * string); -char * imalloc(int n); -void * irealloc(void * pointer, int size); -void icfree(char * pointer); -void ifree(char * pointer); -char * scheck(const char *string, const char *format); +char * icalloc(int nelem, int elsize); +char * icatalloc(char * old, const char * new); +char * icpyalloc(const char * string); +char * imalloc(int n); +void * irealloc(void * pointer, int size); +void icfree(char * pointer); +void ifree(char * pointer); +const char * scheck(const char * string, const char * format); /* ** Finally, some convenience items. @@ -193,6 +220,24 @@ char * scheck(const char *string, const char *format); #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + #ifndef INT_STRLEN_MAXIMUM /* ** 302 / 1000 is log10(2.0) rounded up. @@ -201,7 +246,8 @@ char * scheck(const char *string, const char *format); ** add one more for a minus sign if the type is signed. */ #define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) #endif /* !defined INT_STRLEN_MAXIMUM */ /* @@ -235,11 +281,11 @@ char * scheck(const char *string, const char *format); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN @@ -252,6 +298,26 @@ char * scheck(const char *string, const char *format); char *asctime_r(struct tm const *, char *); char *ctime_r(time_t const *, char *); #endif /* HAVE_INCOMPATIBLE_CTIME_R */ + +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ /* ** UNIX was a registered trademark of The Open Group in 2003. diff --git a/lib/libc/stdtime/strftime.c b/lib/libc/stdtime/strftime.c index b0ba1ff028db..ac85830fbbde 100644 --- a/lib/libc/stdtime/strftime.c +++ b/lib/libc/stdtime/strftime.c @@ -7,7 +7,7 @@ * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the + * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR @@ -17,7 +17,7 @@ #ifndef lint #ifndef NOID -static const char elsieid[] = "@(#)strftime.c 7.64"; +static const char elsieid[] = "@(#)strftime.3 8.3"; /* ** Based on the UCB version with the ID appearing below. ** This is ANSIish only when "multibyte character == plain character". @@ -42,10 +42,9 @@ __FBSDID("$FreeBSD$"); static char * _add(const char *, char *, const char *); static char * _conv(int, const char *, char *, const char *); -static char * _fmt(const char *, const struct tm *, char *, const char *, int *); - -size_t strftime(char * __restrict, size_t, const char * __restrict, - const struct tm * __restrict); +static char * _fmt(const char *, const struct tm *, char *, const char *, + int *); +static char * _yconv(int, int, int, int, char *, const char *); extern char * tzname[]; @@ -53,7 +52,6 @@ extern char * tzname[]; #define YEAR_2000_NAME "CHECK_STRFTIME_FORMATS_FOR_TWO_DIGIT_YEARS" #endif /* !defined YEAR_2000_NAME */ - #define IN_NONE 0 #define IN_SOME 1 #define IN_THIS 2 @@ -170,8 +168,8 @@ int * warnp; ** something completely different. ** (ado, 1993-05-24) */ - pt = _conv((t->tm_year + TM_YEAR_BASE) / 100, - fmt_padding[PAD_FMT_CENTURY][PadIndex], pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 0, + pt, ptlim); continue; case 'c': { @@ -240,7 +238,7 @@ int * warnp; ** t->tm_hour % 12 : 12, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbins' - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -261,7 +259,7 @@ int * warnp; ** _conv(t->tm_hour, 2, ' '); ** ...and has been changed to the below to ** match SunOS 4.1.1 and Arnold Robbin's - ** strftime version 3.0. That is, "%k" and + ** strftime version 3.0. That is, "%k" and ** "%l" have been swapped. ** (ado, 1993-05-24) */ @@ -340,7 +338,7 @@ int * warnp; case 'G': /* ISO 8601 year (four digits) */ case 'g': /* ISO 8601 year (two digits) */ /* -** From Arnold Robbins' strftime version 3.0: "the week number of the +** From Arnold Robbins' strftime version 3.0: "the week number of the ** year (the first Monday as the first day of week 1) as a decimal number ** (01-53)." ** (ado, 1993-05-24) @@ -353,17 +351,19 @@ int * warnp; ** might also contain days from the previous year and the week before week ** 01 of a year is the last week (52 or 53) of the previous year even if ** it contains days from the new year. A week starts with Monday (day 1) -** and ends with Sunday (day 7). For example, the first week of the year +** and ends with Sunday (day 7). For example, the first week of the year ** 1997 lasts from 1996-12-30 to 1997-01-05..." ** (ado, 1996-01-02) */ { int year; + int base; int yday; int wday; int w; - year = t->tm_year + TM_YEAR_BASE; + year = t->tm_year; + base = TM_YEAR_BASE; yday = t->tm_yday; wday = t->tm_wday; for ( ; ; ) { @@ -371,7 +371,7 @@ int * warnp; int bot; int top; - len = isleap(year) ? + len = isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; /* @@ -390,7 +390,7 @@ int * warnp; top += DAYSPERWEEK; top += len; if (yday >= top) { - ++year; + ++base; w = 1; break; } @@ -399,26 +399,26 @@ int * warnp; DAYSPERWEEK); break; } - --year; - yday += isleap(year) ? + --base; + yday += isleap_sum(year, base) ? DAYSPERLYEAR : DAYSPERNYEAR; } #ifdef XPG4_1994_04_09 - if ((w == 52 - && t->tm_mon == TM_JANUARY) - || (w == 1 - && t->tm_mon == TM_DECEMBER)) - w = 53; + if ((w == 52 && + t->tm_mon == TM_JANUARY) || + (w == 1 && + t->tm_mon == TM_DECEMBER)) + w = 53; #endif /* defined XPG4_1994_04_09 */ if (*format == 'V') pt = _conv(w, fmt_padding[PAD_FMT_WEEKOFYEAR][PadIndex], pt, ptlim); else if (*format == 'g') { *warnp = IN_ALL; - pt = _conv(year % 100, fmt_padding[PAD_FMT_SHORTYEAR][PadIndex], + pt = _yconv(year, base, 0, 1, pt, ptlim); - } else pt = _conv(year, fmt_padding[PAD_FMT_YEAR][PadIndex], + } else pt = _yconv(year, base, 1, 1, pt, ptlim); } continue; @@ -456,12 +456,11 @@ int * warnp; continue; case 'y': *warnp = IN_ALL; - pt = _conv((t->tm_year + TM_YEAR_BASE) % 100, - fmt_padding[PAD_FMT_SHORTYEAR][PadIndex], pt, ptlim); + pt = _yconv(t->tm_year, TM_YEAR_BASE, 0, 1, + pt, ptlim); continue; case 'Y': - pt = _conv(t->tm_year + TM_YEAR_BASE, - fmt_padding[PAD_FMT_YEAR][PadIndex], + pt = _yconv(t->tm_year, TM_YEAR_BASE, 1, 1, pt, ptlim); continue; case 'Z': @@ -492,12 +491,12 @@ int * warnp; /* ** C99 says that the UTC offset must ** be computed by looking only at - ** tm_isdst. This requirement is + ** tm_isdst. This requirement is ** incorrect, since it means the code ** must rely on magic (in this case ** altzone and timezone), and the ** magic might not have the correct - ** offset. Doing things correctly is + ** offset. Doing things correctly is ** tricky and requires disobeying C99; ** see GNU C strftime for details. ** For now, punt and conform to the @@ -526,8 +525,10 @@ int * warnp; diff = -diff; } else sign = "+"; pt = _add(sign, pt, ptlim); - diff /= 60; - pt = _conv((diff/60)*100 + diff%60, + diff /= SECSPERMIN; + diff = (diff / MINSPERHOUR) * 100 + + (diff % MINSPERHOUR); + pt = _conv(diff, fmt_padding[PAD_FMT_YEAR][PadIndex], pt, ptlim); } continue; @@ -553,7 +554,7 @@ int * warnp; case '%': /* ** X311J/88-090 (4.12.3.5): if conversion char is - ** undefined, behavior is undefined. Print out the + ** undefined, behavior is undefined. Print out the ** character itself as printf(3) also does. */ default: @@ -590,3 +591,44 @@ const char * const ptlim; ++pt; return pt; } + +/* +** POSIX and the C Standard are unclear or inconsistent about +** what %C and %y do if the year is negative or exceeds 9999. +** Use the convention that %C concatenated with %y yields the +** same output as %Y, and that %Y contains at least 4 bytes, +** with more only if necessary. +*/ + +static char * +_yconv(a, b, convert_top, convert_yy, pt, ptlim) +const int a; +const int b; +const int convert_top; +const int convert_yy; +char * pt; +const char * const ptlim; +{ + register int lead; + register int trail; + +#define DIVISOR 100 + trail = a % DIVISOR + b % DIVISOR; + lead = a / DIVISOR + b / DIVISOR + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (convert_top) { + if (lead == 0 && trail < 0) + pt = _add("-0", pt, ptlim); + else pt = _conv(lead, "%02d", pt, ptlim); + } + if (convert_yy) + pt = _conv(((trail < 0) ? -trail : trail), "%02d", pt, ptlim); + return pt; +} diff --git a/lib/libc/stdtime/time2posix.3 b/lib/libc/stdtime/time2posix.3 index ce9c68d77155..e7c0f0163b18 100644 --- a/lib/libc/stdtime/time2posix.3 +++ b/lib/libc/stdtime/time2posix.3 @@ -118,3 +118,6 @@ degenerate to the identity function. .Xr localtime 3 , .Xr mktime 3 , .Xr time 3 +.\" @(#)time2posix.3 8.1 +.\" This file is in the public domain, so clarified as of +.\" 1996-06-05 by Arthur David Olson. diff --git a/lib/libc/stdtime/tzfile.5 b/lib/libc/stdtime/tzfile.5 index cc7e65966060..15625d273c9e 100644 --- a/lib/libc/stdtime/tzfile.5 +++ b/lib/libc/stdtime/tzfile.5 @@ -14,7 +14,9 @@ begin with the magic characters .Dq Li TZif to identify them as time zone information files, -followed by sixteen bytes reserved for future use, +followed by a character identifying the version of the file's format +(as of 2005, either an ASCII NUL or a '2') +followed by fifteen bytes containing zeroes reserved for future use, followed by four four-byte values written in a ``standard'' byte order (the high-order byte of the value is written first). @@ -56,7 +58,9 @@ each one tells which of the different types of ``local time'' types described in the file is associated with the same-indexed transition time. These values serve as indices into an array of .Fa ttinfo -structures that appears next in the file; +structures (with +.Fa tzh_typecnt +entries) that appears next in the file; these structures are defined as follows: .Pp .Bd -literal -offset indent @@ -129,10 +133,20 @@ if either .Li tzh_timecnt is zero or the time argument is less than the first transition time recorded in the file. +.Pp +For version-2-format time zone files, +the above header and data is followed by a second header and data, +identical in format except that eight bytes are used for each +transition time or leap second time. +After the second header and data comes a newline-enclosed, +POSIX-TZ-environment-variable-style string for use in handling instants +after the last transition time stored in the file +(with nothing between the newlines if there is no POSIX representation for +such instants). .Sh SEE ALSO .Xr ctime 3 , .Xr time2posix 3 , .Xr zic 8 -.\" @(#)tzfile.5 7.2 +.\" @(#)tzfile.5 8.2 .\" This file is in the public domain, so clarified as of -.\" 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +.\" 1996-06-05 by Arthur David Olson. diff --git a/lib/libc/stdtime/tzfile.h b/lib/libc/stdtime/tzfile.h index 89c569453c21..85b945e6dd75 100644 --- a/lib/libc/stdtime/tzfile.h +++ b/lib/libc/stdtime/tzfile.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. ** ** $FreeBSD$ */ @@ -24,7 +24,7 @@ #ifndef lint #ifndef NOID /* -static char tzfilehid[] = "@(#)tzfile.h 7.14"; +static char tzfilehid[] = "@(#)tzfile.h 8.1"; */ #endif /* !defined NOID */ #endif /* !defined lint */ @@ -52,8 +52,9 @@ static char tzfilehid[] = "@(#)tzfile.h 7.14"; #define TZ_MAGIC "TZif" struct tzhead { - char tzh_magic[4]; /* TZ_MAGIC */ - char tzh_reserved[16]; /* reserved for future use */ + char tzh_magic[4]; /* TZ_MAGIC */ + char tzh_version[1]; /* '\0' or '2' as of 2005 */ + char tzh_reserved[15]; /* reserved--must be zero */ char tzh_ttisgmtcnt[4]; /* coded number of trans. time flags */ char tzh_ttisstdcnt[4]; /* coded number of trans. time flags */ char tzh_leapcnt[4]; /* coded number of leap seconds */ @@ -87,19 +88,23 @@ struct tzhead { ** assumed to be local time */ +/* +** If tzh_version is '2' or greater, the above is followed by a second instance +** of tzhead and a second instance of the data in which each coded transition +** time uses 8 rather than 4 chars, +** then a POSIX-TZ-environment-variable-style string for use in handling +** instants after the last transition time stored in the file +** (with nothing between the newlines if there is no POSIX representation for +** such instants). +*/ + /* ** In the current implementation, "tzset()" refuses to deal with files that ** exceed any of the limits below. */ #ifndef TZ_MAX_TIMES -/* -** The TZ_MAX_TIMES value below is enough to handle a bit more than a -** year's worth of solar time (corrected daily to the nearest second) or -** 138 years of Pacific Presidential Election time -** (where there are three time zone transitions every fourth year). -*/ -#define TZ_MAX_TIMES 370 +#define TZ_MAX_TIMES 1200 #endif /* !defined TZ_MAX_TIMES */ #ifndef TZ_MAX_TYPES @@ -109,7 +114,7 @@ struct tzhead { #ifdef NOSOLAR /* ** Must be at least 14 for Europe/Riga as of Jan 12 1995, -** as noted by Earl Chew . +** as noted by Earl Chew. */ #define TZ_MAX_TYPES 20 /* Maximum number of local time types */ #endif /* !defined NOSOLAR */ @@ -160,33 +165,20 @@ struct tzhead { #define EPOCH_YEAR 1970 #define EPOCH_WDAY TM_THURSDAY -/* -** Accurate only for the past couple of centuries; -** that will probably do. -*/ - #define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) -#ifndef USG - /* -** Use of the underscored variants may cause problems if you move your code to -** certain System-V-based systems; for maximum portability, use the -** underscore-free variants. The underscored variants are provided for -** backward compatibility only; they may disappear from future versions of -** this file. +** Since everything in isleap is modulo 400 (or a factor of 400), we know that +** isleap(y) == isleap(y % 400) +** and so +** isleap(a + b) == isleap((a + b) % 400) +** or +** isleap(a + b) == isleap(a % 400 + b % 400) +** This is true even if % means modulo rather than Fortran remainder +** (which is allowed by C89 but not C99). +** We use this to avoid addition overflow problems. */ -#define SECS_PER_MIN SECSPERMIN -#define MINS_PER_HOUR MINSPERHOUR -#define HOURS_PER_DAY HOURSPERDAY -#define DAYS_PER_WEEK DAYSPERWEEK -#define DAYS_PER_NYEAR DAYSPERNYEAR -#define DAYS_PER_LYEAR DAYSPERLYEAR -#define SECS_PER_HOUR SECSPERHOUR -#define SECS_PER_DAY SECSPERDAY -#define MONS_PER_YEAR MONSPERYEAR - -#endif /* !defined USG */ +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) #endif /* !defined TZFILE_H */ diff --git a/usr.sbin/zic/Arts.htm b/usr.sbin/zic/Arts.htm deleted file mode 100644 index baa84ed77431..000000000000 --- a/usr.sbin/zic/Arts.htm +++ /dev/null @@ -1,178 +0,0 @@ - - - - -Time and the Arts - - -

Time and the Arts

-

-

-@(#)Arts.htm 7.18 -
-

-
- - diff --git a/usr.sbin/zic/README b/usr.sbin/zic/README index 985a5118468f..12420b9c467c 100644 --- a/usr.sbin/zic/README +++ b/usr.sbin/zic/README @@ -1,4 +1,5 @@ -@(#)README 7.11 +@(#)README 8.2 +$FreeBSD$ "What time is it?" -- Richard Deacon as The King "Any time you want it to be." -- Frank Baxter as The Scientist @@ -52,8 +53,10 @@ substituting your desired installation directory for "$HOME/tzdir": To use the new functions, use a "-ltz" option when compiling or linking. -Historical local time information has been included here not because it -is particularly useful, but rather to: +Historical local time information has been included here to: + +* provide a compendium of data about the history of civil time + that is useful even if the data are not 100% accurate; * give an idea of the variety of local time rules that have existed in the past and thus an idea of the variety that may be @@ -63,7 +66,9 @@ is particularly useful, but rather to: system. The information in the time zone data files is by no means authoritative; -if you know that the rules are different from those in a file, by all means +the files currently do not even attempt to cover all time stamps before +1970, and there are undoubtedly errors even for time stamps since 1970. +If you know that the rules are different from those in a file, by all means feel free to change file (and please send the changed version to tz@elsie.nci.nih.gov for use in the future). Europeans take note! diff --git a/usr.sbin/zic/Theory b/usr.sbin/zic/Theory index cbf53b9e7d73..ac67416d3622 100644 --- a/usr.sbin/zic/Theory +++ b/usr.sbin/zic/Theory @@ -1,5 +1,5 @@ -@(#)Theory 7.15 - +@(#)Theory 8.2 +$FreeBSD$ ----- Outline ----- @@ -12,26 +12,27 @@ ----- Time and date functions ----- -These time and date functions are upwards compatible with POSIX.1, +These time and date functions are upwards compatible with POSIX, an international standard for UNIX-like systems. -As of this writing, the current edition of POSIX.1 is: +As of this writing, the current edition of POSIX is: - Information technology --Portable Operating System Interface (POSIX (R)) - -- Part 1: System Application Program Interface (API) [C Language] - ISO/IEC 9945-1:1996 - ANSI/IEEE Std 1003.1, 1996 Edition - 1996-07-12 + Standard for Information technology + -- Portable Operating System Interface (POSIX (R)) + -- System Interfaces + IEEE Std 1003.1, 2004 Edition + + -POSIX.1 has the following properties and limitations. +POSIX has the following properties and limitations. -* In POSIX.1, time display in a process is controlled by the - environment variable TZ. Unfortunately, the POSIX.1 TZ string takes +* In POSIX, time display in a process is controlled by the + environment variable TZ. Unfortunately, the POSIX TZ string takes a form that is hard to describe and is error-prone in practice. - Also, POSIX.1 TZ strings can't deal with other (for example, Israeli) + Also, POSIX TZ strings can't deal with other (for example, Israeli) daylight saving time rules, or situations where more than two time zone abbreviations are used in an area. - The POSIX.1 TZ string takes the following form: + The POSIX TZ string takes the following form: stdoffset[dst[offset],date[/time],date[/time]] @@ -40,6 +41,9 @@ POSIX.1 has the following properties and limitations. std and dst are 3 or more characters specifying the standard and daylight saving time (DST) zone names. + Starting with POSIX.1-2001, std and dst may also be + in a quoted form like ""; this allows + "+" and "-" in the names. offset is of the form `[-]hh:[mm[:ss]]' and specifies the offset west of UTC. The default DST offset is one hour @@ -62,14 +66,25 @@ POSIX.1 has the following properties and limitations. and `5' stands for the last week in which day d appears (which may be either the 4th or 5th week). -* In POSIX.1, when a TZ value like "EST5EDT" is parsed, - typically the current US DST rules are used, + Here is an example POSIX TZ string, for US Pacific time using rules + appropriate from 1987 through 2006: + + TZ='PST8PDT,M4.1.0/02:00,M10.5.0/02:00' + + This POSIX TZ string is hard to remember, and mishandles time stamps + before 1987 and after 2006. With this package you can use this + instead: + + TZ='America/Los_Angeles' + +* POSIX does not define the exact meaning of TZ values like "EST5EDT". + Typically the current US DST rules are used to interpret such values, but this means that the US DST rules are compiled into each program that does time conversion. This means that when US time conversion rules change (as in the United States in 1987), all programs that do time conversion must be recompiled to ensure proper results. -* In POSIX.1, there's no tamper-proof way for a process to learn the +* In POSIX, there's no tamper-proof way for a process to learn the system's best idea of local wall clock. (This is important for applications that an administrator wants used only at certain times-- without regard to whether the user has fiddled the "TZ" environment @@ -78,9 +93,9 @@ POSIX.1 has the following properties and limitations. daylight saving time shifts--as might be required to limit phone calls to off-peak hours.) -* POSIX.1 requires that systems ignore leap seconds. +* POSIX requires that systems ignore leap seconds. -These are the extensions that have been made to the POSIX.1 functions: +These are the extensions that have been made to the POSIX functions: * The "TZ" environment variable is used in generating the name of a file from which time zone information is read (or is interpreted a la @@ -108,7 +123,7 @@ These are the extensions that have been made to the POSIX.1 functions: * To handle places where more than two time zone abbreviations are used, the functions "localtime" and "gmtime" set tzname[tmp->tm_isdst] (where "tmp" is the value the function returns) to the time zone - abbreviation to be used. This differs from POSIX.1, where the elements + abbreviation to be used. This differs from POSIX, where the elements of tzname are only changed as a result of calls to tzset. * Since the "TZ" environment variable can now be used to control time @@ -131,8 +146,7 @@ These are the extensions that have been made to the POSIX.1 functions: environment variable; portable applications should not, however, rely on this behavior since it's not the way SVR2 systems behave.) -* These functions can account for leap seconds, thanks to Bradley White - (bww@k.cs.cmu.edu). +* These functions can account for leap seconds, thanks to Bradley White. Points of interest to folks with other systems: @@ -173,9 +187,9 @@ Hewlett Packard, offer a wider selection of functions that provide capabilities beyond those provided here. The absence of such functions from this package is not meant to discourage the development, standardization, or use of such functions. Rather, their absence reflects the decision to make this package -contain valid extensions to POSIX.1, to ensure its broad -acceptability. If more powerful time conversion functions can be standardized, -so much the better. +contain valid extensions to POSIX, to ensure its broad acceptability. If +more powerful time conversion functions can be standardized, so much the +better. ----- Names of time zone rule files ----- @@ -228,6 +242,8 @@ in decreasing order of importance: Include at least one location per time zone rule set per country. One such location is enough. Use ISO 3166 (see the file iso3166.tab) to help decide whether something is a country. + However, uninhabited ISO 3166 regions like Bouvet Island + do not need locations, since local time is not defined there. If all the clocks in a country's region have agreed since 1970, don't bother to include more than one location even if subregions' clocks disagreed before 1970. @@ -263,7 +279,8 @@ in decreasing order of importance: If a name is changed, put its old spelling in the `backward' file. The file `zone.tab' lists the geographical locations used to name -time zone rule files. +time zone rule files. It is intended to be an exhaustive list +of canonical names for geographic regions. Older versions of this package used a different naming scheme, and these older names are still supported. @@ -277,7 +294,7 @@ and `Factory' (see the file `factory'). ----- Time zone abbreviations ----- When this package is installed, it generates time zone abbreviations -like `EST' to be compatible with human tradition and POSIX.1. +like `EST' to be compatible with human tradition and POSIX. Here are the general rules used for choosing time zone abbreviations, in decreasing order of importance: @@ -292,17 +309,16 @@ in decreasing order of importance: preferred "ChST", so the rule has been relaxed. This rule guarantees that all abbreviations could have - been specified by a POSIX.1 TZ string. POSIX.1 + been specified by a POSIX TZ string. POSIX requires at least three characters for an - abbreviation. POSIX.1-1996 says that an abbreviation + abbreviation. POSIX through 2000 says that an abbreviation cannot start with ':', and cannot contain ',', '-', - '+', NUL, or a digit. Draft 7 of POSIX 1003.1-200x - changes this rule to say that an abbreviation can - contain only '-', '+', and alphanumeric characters in - the current locale. To be portable to both sets of + '+', NUL, or a digit. POSIX from 2001 on changes this + rule to say that an abbreviation can contain only '-', '+', + and alphanumeric characters from the portable character set + in the current locale. To be portable to both sets of rules, an abbreviation must therefore use only ASCII - letters, as these are the only letters that are - alphabetic in all locales. + letters. Use abbreviations that are in common use among English-speakers, e.g. `EST' for Eastern Standard Time in North America. @@ -328,8 +344,9 @@ in decreasing order of importance: and then append `T', `ST', etc. as before; e.g. `VLAST' for VLAdivostok Summer Time. - Use "zzz" for locations while uninhabited. The mnemonic is that - these locations are, in some sense, asleep. + Use UTC (with time zone abbreviation "zzz") for locations while + uninhabited. The "zzz" mnemonic is that these locations are, + in some sense, asleep. Application writers should note that these abbreviations are ambiguous in practice: e.g. `EST' has a different meaning in Australia than @@ -343,10 +360,10 @@ abbreviations like `EST'; this avoids the ambiguity. Calendrical issues are a bit out of scope for a time zone database, but they indicate the sort of problems that we would run into if we extended the time zone database further into the past. An excellent -resource in this area is Nachum Dershowitz and Edward M. Reingold, - -Calendrical Calculations -, Cambridge University Press (1997). Other information and +resource in this area is Edward M. Reingold and Nachum Dershowitz, + +Calendrical Calculations: The Millennium Edition +, Cambridge University Press (2001). Other information and sources are given below. They sometimes disagree. @@ -359,7 +376,7 @@ and (in Paris only) 1871-05-06 through 1871-05-23. Russia -From Chris Carrier <72157.3334@CompuServe.COM> (1996-12-02): +From Chris Carrier (1996-12-02): On 1929-10-01 the Soviet Union instituted an ``Eternal Calendar'' with 30-day months plus 5 holidays, with a 5-day week. On 1931-12-01 it changed to a 6-day week; in 1934 it reverted to the @@ -374,7 +391,7 @@ by Frank Parise (1982, Facts on File, ISBN 0-8719-6467-8), page 377. But: From: Petteri Sulonen (via Usenet) Date: 14 Jan 1999 00:00:00 GMT -Message-ID: +... If your source is correct, how come documents between 1929 -- 1940 were still dated using the conventional, Gregorian calendar? @@ -387,7 +404,7 @@ Executive Committee of the Supreme Soviet, if you like. Sweden (and Finland) -From: msb@sq.com (Mark Brader) +From: Mark Brader Subject: Re: Gregorian reform -- a part of locale? @@ -415,11 +432,11 @@ kalendervasen" by Lars-Olof Lode'n (no date was given).) Grotefend's data -From: "Michael Palmer" [with one obvious typo fixed] +From: "Michael Palmer" [with one obvious typo fixed] Subject: Re: Gregorian Calendar (was Re: Another FHC related question Newsgroups: soc.genealogy.german Date: Tue, 9 Feb 1999 02:32:48 -800 -Message-ID: <199902091032.CAA09644@netcom10.netcom.com> +... The following is a(n incomplete) listing, arranged chronologically, of European states, with the date they converted from the Julian to the @@ -546,7 +563,7 @@ Sources: Michael Allison and Robert Schmunk, "Technical Notes on Mars Solar Time as Adopted by the Mars24 Sunclock" - (2004-03-15). + (2004-07-30). Jia-Rui Chong, "Workdays Fit for a Martian", Los Angeles Times (2004-01-14), pp A1, A20-A21. diff --git a/usr.sbin/zic/ialloc.c b/usr.sbin/zic/ialloc.c index a069032eda51..1694c2905c74 100644 --- a/usr.sbin/zic/ialloc.c +++ b/usr.sbin/zic/ialloc.c @@ -1,6 +1,11 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + #ifndef lint #ifndef NOID -static const char elsieid[] = "@(#)ialloc.c 8.29"; +static const char elsieid[] = "@(#)ialloc.c 8.30"; #endif /* !defined NOID */ #endif /* !defined lint */ diff --git a/usr.sbin/zic/private.h b/usr.sbin/zic/private.h index 315f33a4a2f1..ecbf6124859a 100644 --- a/usr.sbin/zic/private.h +++ b/usr.sbin/zic/private.h @@ -4,7 +4,7 @@ /* ** This file is in the public domain, so clarified as of -** 1996-06-05 by Arthur David Olson (arthur_david_olson@nih.gov). +** 1996-06-05 by Arthur David Olson. */ /* @@ -30,10 +30,12 @@ #ifndef lint #ifndef NOID -static const char privatehid[] = "@(#)private.h 7.53"; +static const char privatehid[] = "@(#)private.h 8.6"; #endif /* !defined NOID */ #endif /* !defined lint */ +#define GRANDPARENTED "Local time zone must be set--see zic manual page" + /* ** Defaults for preprocessor symbols. ** You can override these in your C compiler options, e.g. `-DHAVE_ADJTIME=0'. @@ -43,10 +45,6 @@ static const char privatehid[] = "@(#)private.h 7.53"; #define HAVE_GETTEXT 0 #endif /* !defined HAVE_GETTEXT */ -#ifndef HAVE_STRERROR -#define HAVE_STRERROR 1 -#endif /* !defined HAVE_STRERROR */ - #ifndef HAVE_SYMLINK #define HAVE_SYMLINK 1 #endif /* !defined HAVE_SYMLINK */ @@ -71,47 +69,94 @@ static const char privatehid[] = "@(#)private.h 7.53"; #include "stdio.h" #include "errno.h" #include "string.h" -#include "limits.h" /* for CHAR_BIT */ +#include "limits.h" /* for CHAR_BIT et al. */ #include "time.h" #include "stdlib.h" -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ -#if HAVE_SYS_WAIT_H - 0 +#if HAVE_SYS_WAIT_H #include /* for WIFEXITED and WEXITSTATUS */ -#endif /* HAVE_SYS_WAIT_H - 0 */ +#endif /* HAVE_SYS_WAIT_H */ -#if HAVE_UNISTD_H - 0 -#include "unistd.h" /* for F_OK and R_OK */ -#endif /* HAVE_UNISTD_H - 0 */ +#if HAVE_UNISTD_H +#include "unistd.h" /* for F_OK and R_OK, and other POSIX goodness */ +#endif /* HAVE_UNISTD_H */ -#if !(HAVE_UNISTD_H - 0) #ifndef F_OK #define F_OK 0 #endif /* !defined F_OK */ #ifndef R_OK #define R_OK 4 #endif /* !defined R_OK */ -#endif /* !(HAVE_UNISTD_H - 0) */ -/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ +/* Unlike 's isdigit, this also works if c < 0 | c > UCHAR_MAX. */ #define is_digit(c) ((unsigned)(c) - '0' <= 9) -#define P(x) x +/* +** Define HAVE_STDINT_H's default value here, rather than at the +** start, since __GLIBC__'s value depends on previously-included +** files. +** (glibc 2.1 and later have stdint.h, even with pre-C99 compilers.) +*/ +#ifndef HAVE_STDINT_H +#define HAVE_STDINT_H \ + (199901 <= __STDC_VERSION__ || \ + 2 < (__GLIBC__ + (0 < __GLIBC_MINOR__))) +#endif /* !defined HAVE_STDINT_H */ + +#if HAVE_STDINT_H +#include "stdint.h" +#endif /* !HAVE_STDINT_H */ + +#ifndef INT_FAST64_MAX +/* Pre-C99 GCC compilers define __LONG_LONG_MAX__ instead of LLONG_MAX. */ +#if defined LLONG_MAX || defined __LONG_LONG_MAX__ +typedef long long int_fast64_t; +#else /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#if (LONG_MAX >> 31) < 0xffffffff +Please use a compiler that supports a 64-bit integer type (or wider); +you may need to compile with "-DHAVE_STDINT_H". +#endif /* (LONG_MAX >> 31) < 0xffffffff */ +typedef long int_fast64_t; +#endif /* ! (defined LLONG_MAX || defined __LONG_LONG_MAX__) */ +#endif /* !defined INT_FAST64_MAX */ + +#ifndef INT32_MAX +#define INT32_MAX 0x7fffffff +#endif /* !defined INT32_MAX */ +#ifndef INT32_MIN +#define INT32_MIN (-1 - INT32_MAX) +#endif /* !defined INT32_MIN */ + +/* +** Workarounds for compilers/systems. + */ + +/* +** Some time.h implementations don't declare asctime_r. +** Others might define it as a macro. +** Fix the former without affecting the latter. + */ +#ifndef asctime_r +extern char * asctime_r(struct tm const *, char *); +#endif + + /* ** Private function declarations. */ -char * icalloc P((int nelem, int elsize)); -char * icatalloc P((char * old, const char * new)); -char * icpyalloc P((const char * string)); -char * imalloc P((int n)); -void * irealloc P((void * pointer, int size)); -void icfree P((char * pointer)); -void ifree P((char * pointer)); -char * scheck P((const char *string, const char *format)); +char * icalloc (int nelem, int elsize); +char * icatalloc (char * old, const char * new); +char * icpyalloc (const char * string); +char * imalloc (int n); +void * irealloc (void * pointer, int size); +void icfree (char * pointer); +void ifree (char * pointer); +const char * scheck (const char *string, const char *format); /* ** Finally, some convenience items. @@ -133,6 +178,15 @@ char * scheck P((const char *string, const char *format)); #define TYPE_SIGNED(type) (((type) -1) < 0) #endif /* !defined TYPE_SIGNED */ +/* +** Since the definition of TYPE_INTEGRAL contains floating point numbers, +** it cannot be used in preprocessor directives. +*/ + +#ifndef TYPE_INTEGRAL +#define TYPE_INTEGRAL(type) (((type) 0.5) != 0.5) +#endif /* !defined TYPE_INTEGRAL */ + #ifndef INT_STRLEN_MAXIMUM /* ** 302 / 1000 is log10(2.0) rounded up. @@ -141,7 +195,8 @@ char * scheck P((const char *string, const char *format)); ** add one more for a minus sign if the type is signed. */ #define INT_STRLEN_MAXIMUM(type) \ - ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + 1 + TYPE_SIGNED(type)) + ((TYPE_BIT(type) - TYPE_SIGNED(type)) * 302 / 1000 + \ + 1 + TYPE_SIGNED(type)) #endif /* !defined INT_STRLEN_MAXIMUM */ /* @@ -175,11 +230,11 @@ char * scheck P((const char *string, const char *format)); */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !HAVE_GETTEXT */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !HAVE_GETTEXT */ #endif /* !defined _ */ #ifndef TZ_DOMAIN @@ -190,4 +245,28 @@ char * scheck P((const char *string, const char *format)); ** UNIX was a registered trademark of The Open Group in 2003. */ +#ifndef YEARSPERREPEAT +#define YEARSPERREPEAT 400 /* years before a Gregorian repeat */ +#endif /* !defined YEARSPERREPEAT */ + +/* +** The Gregorian year averages 365.2425 days, which is 31556952 seconds. +*/ + +#ifndef AVGSECSPERYEAR +#define AVGSECSPERYEAR 31556952L +#endif /* !defined AVGSECSPERYEAR */ + +#ifndef SECSPERREPEAT +#define SECSPERREPEAT ((int_fast64_t) YEARSPERREPEAT * (int_fast64_t) AVGSECSPERYEAR) +#endif /* !defined SECSPERREPEAT */ + +#ifndef SECSPERREPEAT_BITS +#define SECSPERREPEAT_BITS 34 /* ceil(log2(SECSPERREPEAT)) */ +#endif /* !defined SECSPERREPEAT_BITS */ + + /* + ** UNIX was a registered trademark of The Open Group in 2003. + */ + #endif /* !defined PRIVATE_H */ diff --git a/usr.sbin/zic/scheck.c b/usr.sbin/zic/scheck.c index 692bf1a07934..abdb4ba5c79b 100644 --- a/usr.sbin/zic/scheck.c +++ b/usr.sbin/zic/scheck.c @@ -1,6 +1,11 @@ +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + #ifndef lint #ifndef NOID -static const char elsieid[] = "@(#)scheck.c 8.15"; +static const char elsieid[] = "@(#)scheck.c 8.19"; #endif /* !defined lint */ #endif /* !defined NOID */ @@ -13,7 +18,7 @@ static const char rcsid[] = #include "private.h" -char * +const char * scheck(string, format) const char * const string; const char * const format; @@ -22,11 +27,10 @@ const char * const format; register const char * fp; register char * tp; register int c; - register char * result; + register const char * result; char dummy; - static char nada; - result = &nada; + result = ""; if (string == NULL || format == NULL) return result; fbuf = imalloc((int) (2 * strlen(format) + 4)); diff --git a/usr.sbin/zic/tz-art.htm b/usr.sbin/zic/tz-art.htm deleted file mode 100644 index 56f78ace2e0d..000000000000 --- a/usr.sbin/zic/tz-art.htm +++ /dev/null @@ -1,278 +0,0 @@ - - - - - -Time and the Arts - - -

Time and the Arts

-
-@(#)tz-art.htm 7.53 -
-

-Please send corrections to this web page to the -time zone mailing list.

-

-See also Sources for Time Zone and Daylight Saving Time Data.

-
-

-Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArtistKarrin Allyson
CDI Didn't Know About You
Copyright Date1993
LabelConcord Jazz, Inc.
IDCCD-4543
Track Time3:44
PersonnelKarrin Allyson, vocal; -Russ Long, piano; -Gerald Spaits, bass; -Todd Strait, drums
NotesCD notes "additional lyric by Karrin Allyson; -arranged by Russ Long and Karrin Allyson"
ADO Rating1 star
AMG Rating4 stars
Penguin Rating3.5 stars
 
ArtistKevin Mahogany
CDDouble Rainbow
Copyright Date1993
LabelEnja Records
IDENJ-7097 2
Track Time6:27
PersonnelKevin Mahogany, vocal; -Kenny Barron, piano; -Ray Drummond, bass; -Ralph Moore, tenor saxophone; -Lewis Nash, drums
ADO Rating1.5 stars
AMG Rating3 stars
Penguin Rating3 stars
 
ArtistJoe Williams
CDHere's to Life
Copyright Date1994
LabelTelarc International Corporation
IDCD-83357
Track Time3:58
PersonnelJoe Williams, vocal -The Robert Farnon [39 piece] Orchestra
NotesThis CD is also available as part of a 3-CD package from -Telarc, "Triple Play" (CD-83461)
ADO Ratingblack dot
AMG Rating2 stars
Penguin Rating3 stars
 
ArtistCharles Fambrough
CDKeeper of the Spirit
Copyright Date1995
LabelAudioQuest Music
IDAQ-CD1033
Track Time7:07
PersonnelCharles Fambrough, bass; -Joel Levine, tenor recorder; -Edward Simon, piano; -Lenny White, drums; -Marion Simon, percussion
NotesOn-line information and samples available at -http://wwmusic.com/~music/audioq/rel/1033.html
ADO Rating2 stars
AMG Ratingunrated
Penguin Rating3 stars
-
-

Also of note:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ArtistHolly Cole Trio
CDBlame It On My Youth
Copyright Date1992
LabelManhattan
IDCDP 7 97349 2
Total Time37:45
PersonnelHolly Cole, voice; -Aaron Davis, piano; -David Piltch, string bass
NotesLyrical reference to "Eastern Standard Time" in -Tom Waits' "Purple Avenue"
ADO Rating2.5 stars
AMG Rating3 stars
Penguin Ratingunrated
 
ArtistMilt Hinton
CDOld Man Time
Copyright Date1990
LabelChiaroscuro
IDCR(D) 310
Total Time149:38 (two CDs)
PersonnelMilt Hinton, bass; -Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet; -Al Grey, trombone; -Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate, -clarinet and saxophone; -John Bunch, Red Richards, Norman Simmons, Derek Smith, -Ralph Sutton, piano; -Danny Barker, Al Casey, guitar; -Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams, -drums; -Lionel Hampton, vibraphone; -Cab Calloway, Joe Williams, vocal; -Buck Clayton, arrangements
Notestunes include Old Man Time, Time After Time, -Sometimes I'm Happy, -A Hot Time in the Old Town Tonight, -Four or Five Times, Now's the Time, -Time on My Hands, This Time It's Us, -and Good Time Charlie -On-line samples available at -http://www.chiaroscurojazz.com/albuminfo.php3?albumid=49
ADO Rating3 stars
AMG Rating4.5 stars
Penguin Rating3 stars
 
ArtistAlan Broadbent
CDPacific Standard Time
Copyright Date1995
LabelConcord Jazz, Inc.
IDCCD-4664
Total Time62:42
PersonnelAlan Broadbent, piano; -Putter Smith, Bass; -Frank Gibson, Jr., drums
NotesThe CD cover features an analemma for equation-of-time fans
ADO Rating1 star
AMG Rating4 stars
Penguin Rating3.5 stars
 
ArtistAnthony Braxton/Richard Teitelbaum
CDSilence/Time Zones
Copyright Date1996
LabelBlack Lion
IDBLCD 760221
Total Time72:58
PersonnelAnthony Braxton, sopranino and alto saxophones, -contrebasse clarinet, miscellaneous instruments; -Leo Smith, trumpet and miscellaneous instruments; -Leroy Jenkins, violin and miscellaneous instruments; -Richard Teitelbaum, modular moog and micromoog synthesizer
ADO Ratingblack dot
AMG Ratingunrated
 
ArtistJules Verne
BookLe Tour du Monde en Quatre-Vingts Jours -(Around the World in Eighty Days)
NotesWall-clock time plays a central role in the plot. -European readers of the 1870s clearly held the U.S. press in -deep contempt; the protagonists cross the U.S. without once -reading a paper. -An on-line French-language version of the book -"with illustrations from the original 1873 French-language edition" -is available at -http://fourmilab.ch/etexts/www/tdm80j -An on-line English-language translation of the book is available at -http://www.literature.org/Works/Jules-Verne/eighty
 
FilmBell Science - About Time
NotesThe Frank Baxter/Richard Deacon extravaganza -Information on ordering is available at -http://www.videoflicks.com/VF2/1035/1035893.ihtml
-
-
    -
  • -An episode of "The Adventures of Superman" entitled "The Mysterious -Cube," first aired 1958-02-24, had Superman convincing the controllers -of WWV to broadcast time signals five minutes ahead of actual time; -doing so got a crook trying to beat the statute of limitations to -emerge a bit too early from the titular enclosure. -
  • -
  • -The 1960s ITC television series "The Prisoner" included an episode -entitled "The Chimes of Big Ben" in which our protagonist tumbled to -the fraudulent nature of a Poland-to-England escape upon hearing "Big -Ben" chiming on Polish local time. -
  • -
  • -The series "Seinfeld" included an episode entitled "The Susie," first -broadcast 1997-02-13, in which Kramer decides that daylight saving time -isn't coming fast enough, so he sets his watch ahead an hour. -
  • -
  • -The syndicated comic strip "Dilbert" featured an all-too-rare example of -time zone humor on 1998-03-14. -
  • -
  • -Surrealist artist Guy Billout's work "Date Line" appeared on page 103 -of the 1999-11 Atlantic Monthly. -
  • -
  • -"Gloom, Gloom, Go Away" by Walter Kirn appeared on page 106 of Time -Magazine's 2002-11-11 issue; among other things, it proposed -year-round DST as a way of lessening wintertime despair. -
  • -
  • -The "20 Hours in America" episode of "The West Wing," first aired 2002-09-25, -saw White House staffers stranded in Indiana; they thought they had time to -catch Air Force One but were done in by intra-Indiana local time changes. -
  • -
  • -"In what time zone would you find New York City?" was a $200 question on -the 1999-11-13 United States airing of "Who Wants to Be a Millionaire?" -"In 1883, what industry led the movement to divide the U.S. into four time -zones?" was a $32,000 question on the 2001-05-23 United States airing of -"Who Wants to Be a Millionaire?" At this rate, the million-dollar time-zone -question should have been asked 2002-06-04. -
  • -
-
-
    -
  • -"We're been using the five-cent nickle in this country since 1492. -Now that's pretty near 100 years, daylight savings [sic]." -(Groucho Marx as Captain Spaulding in "Animal Crackers", 1930, -as noted by Will Fitzerald, wfitzgerald@ameritech.net) -
  • -
  • -"Good news." -"What did they do? Extend Daylight Saving Time year round?" -(Professional tanner George Hamilton, in dialog from a -May, 1999 episode of the syndicated television series "Baywatch") -
  • -
  • -"A fundamental belief held by Americans is that if you are on land, you -cannot be killed by a fish...So most Americans remain on land, believing -they're safe. Unfortunately, this belief—like so many myths, such as that -there's a reason for 'Daylight Saving Time'—is false." -(Dave Barry column, 2000-07-02) -
  • -
  • -"I once had sex for an hour and five minutes, but that was on the day -when you turn the clocks ahead." -(Garry Shandling, 52nd Annual Emmys, 2000-09-10) -
  • -
  • -"Would it impress you if I told you I invented Daylight Savings Time?" -("Sahjhan" to "Lilah" in dialog from the "Loyalty" episode of "Angel," -originally aired 2002-02-25) -
  • -
  • -"I thought you said Tulsa was a three hour flight." -"Well, you're forgetting about the time difference." -("Chandler" and "Joey" in dialog from the episode of "Friends" first -aired 2002-12-05) -
  • -
  • -"Is that a pertinent fact, -or are you trying to dazzle me with your command of time zones?" -(Kelsey Grammer as "Frasier Crane") -
  • -
  • -"Don't worry about the world coming to an end today. -It is already tomorrow in Australia." -(Charles M. Schulz, provided by Steve Summit) -
  • -
- - diff --git a/usr.sbin/zic/tz-link.htm b/usr.sbin/zic/tz-link.htm deleted file mode 100644 index 0e6307300709..000000000000 --- a/usr.sbin/zic/tz-link.htm +++ /dev/null @@ -1,443 +0,0 @@ - - - - -Sources for Time Zone and Daylight Saving Time Data - - - - - - - - - - -

Sources for Time Zone and Daylight Saving Time Data

-
-@(#)tz-link.htm 7.42 -
-

-Please send corrections to this web page to the -time zone mailing list. -

-

The tz database

-

-The public-domain time zone database contains code and data -that represent the history of local time -for many representative locations around the globe. -It is updated periodically to reflect changes made by political bodies -to UTC offsets and daylight-saving rules. -This database (often called tz or zoneinfo) -is used by several implementations, -including -the GNU C Library used in -GNU/Linux, -FreeBSD, -NetBSD, -OpenBSD, -Cygwin, -DJGPP, -HP-UX, -IRIX, -Mac OS X, -OpenVMS, -Solaris, -Tru64, and -UnixWare.

-

-Each location in the database represents a national region where all -clocks keeping local time have agreed since 1970. -Locations are identified by continent or ocean and then by the name of -the location, which is typically the largest city within the region. -For example, America/New_York -represents most of the US eastern time zone; -America/Indianapolis represents most of Indiana, which -uses eastern time without daylight saving time (DST); -America/Detroit represents most of Michigan, which uses -eastern time but with different DST rules in 1975; -and other entries represent smaller regions like Starke County, -Kentucky, which switched from central to eastern time in 1991. -To use the database, set the TZ environment variable to -the location's full name, e.g., TZ="America/New_York".

-

-In the tz database's -FTP distribution, -the code is in the file tzcodeC.tar.gz, -where C is the code's version; -similarly, the data are in tzdataD.tar.gz, -where D is the data's version. -The following shell commands download -these files to a GNU/Linux or similar host; see the downloaded -README file for what to do next.

-
wget 'ftp://elsie.nci.nih.gov/pub/tz*.tar.gz'
-gzip -dc tzcode*.tar.gz | tar -xf -
-gzip -dc tzdata*.tar.gz | tar -xf -
-
-

-The code lets you compile the tz source files into -machine-readable binary files, one for each location. It also lets -you read a tz binary file and interpret time stamps for that -location.

-

-The data are by no means authoritative. If you find errors, please -send changes to the time zone -mailing list. You can also subscribe to the -mailing list, retrieve the archive of old -messages (in gzip compressed format), or retrieve archived older versions of code -and data.

-

-The Web has several other sources for time zone and daylight saving time data. -Here are some recent links that may be of interest. -

-

Web pages using recent versions of the tz database

- -

Other time zone database formats

- -

Other tz compilers

- -

Other tz binary file readers

- -

Other tz-based time zone conversion software

- -

Other time zone databases

- -

Maps

- -

Time zone boundaries

- -

Civil time concepts and history

- -

National histories of legal time

-
-
Australia
-
The Community Relations Division of the New South Wales (NSW) -Attorney General's Department maintains a history of -daylight saving in NSW.
-
Austria
-
The Federal Office of Metrology and Surveying publishes a -table of daylight saving time in Austria (in German).
-
Belgium
-
The Royal Observatory of Belgium maintains a table of time in Belgium (in Dutch).
-
Brazil
-
The Time Service Department of the National Observatory -records Brazil's daylight saving time decrees (in -Portuguese).
-
Canada
-
The Institute for National Measurement Standards publishes current -and some older information about Time -Zones and Daylight Saving Time.
-
Chile
-
WebExhibits publishes a history of official time (in Spanish) originally -written by the Chilean Hydrographic and Oceanographic Service.
-
Germany
-
The National Institute for Science and Technology maintains the Realisation of -Legal Time in Germany.
-
Israel
-
The Interior Ministry periodically issues announcements (in Hebrew).
-
Mexico
-
The Investigation and Analysis Service of the Mexican Library of -Congress has published a history of Mexican local time (in Spanish).
-
Malaysia
-
See Singapore below.
-
Netherlands
-
Legal time in the Netherlands (in Dutch) -covers the history of local time in the Netherlands from ancient times.
-
New Zealand
-
The Department of Internal Affairs maintains a brief history about -daylight saving. The privately-maintained Time Changes in -New Zealand has more details.
-
Singapore
-
Why -is Singapore in the "Wrong" Time Zone? details the -history of legal time in Singapore and Malaysia.
-
United Kingdom
-
History of -legal time in Britain discusses in detail the country -with perhaps the best-documented history of clock adjustments. -The National Physical Laboratory also maintains an archive -of summer time dates.
-
-

Precision timekeeping

- -

Time notation

-
    -
  • -A Summary of -the International Standard Date and Time Notation is a good -summary of ISO -8601:1988 - Data elements and interchange formats - Information interchange -- Representation of dates and times (which has been superseded by -ISO 8601:2000).
  • -
  • -Section 3.3 of Internet RFC 2822 -specifies the time notation used in email and HTTP headers.
  • -
  • -Internet RFC -3339 specifies an ISO 8601 profile for use in new Internet -protocols.
  • -
  • -The -Best of Dates, the Worst of Dates covers many problems encountered -by software developers when handling dates and time stamps.
  • -
  • -Alphabetic time zone abbreviations should not be used as unique -identifiers for UTC offsets as they are ambiguous in practice. For -example, "EST" denotes 5 hours behind UTC in English-speaking North -America, but it denotes 10 or 11 hours ahead of UTC in Australia; -and French-speaking North Americans prefer "HNE" to "EST". For -compatibility with POSIX the -tz database contains English abbreviations for all time -stamps but in many cases these are merely inventions of the database -maintainers.
  • -
-

Related indexes

- - - diff --git a/usr.sbin/zic/zdump.8 b/usr.sbin/zic/zdump.8 index 3a685fd7ea0d..a7f09787dec4 100644 --- a/usr.sbin/zic/zdump.8 +++ b/usr.sbin/zic/zdump.8 @@ -12,7 +12,7 @@ .Nm .Op Fl -version .Op Fl v -.Op Fl c Ar cutoffyear +.Op Fl c Ar [loyear,]hiyear .Op Ar zonename ... .Sh DESCRIPTION The @@ -40,9 +40,21 @@ Each line ends with if the given time is Daylight Saving Time or .Em isdst=0 otherwise. -.It Fl c Ar cutoffyear -Cut off the verbose output near the start of the given year. +.It Fl c Ar loyear,hiyear +Cut off verbose output near the start of the given year(s). +By default, +the program cuts off verbose output near the starts of the years -500 and 2500. .El +.Sh LIMITATIONS +The +.Fl v +option may not be used on systems with floating-point time_t values +that are neither float nor double. +.Pp +Time discontinuities are found by sampling the results returned by localtime +at twelve-hour intervals. +This works in all real-world cases; +one can construct artificial time zones for which this fails. .Sh "SEE ALSO" .Xr ctime 3 , .Xr tzfile 5 , diff --git a/usr.sbin/zic/zdump.c b/usr.sbin/zic/zdump.c index 980c8a80d22d..ca9c3695e977 100644 --- a/usr.sbin/zic/zdump.c +++ b/usr.sbin/zic/zdump.c @@ -1,8 +1,7 @@ -static const char elsieid[] = "@(#)zdump.c 7.31"; - #ifndef lint static const char rcsid[] = "$FreeBSD$"; +static char elsieid[] = "@(#)zdump.c 8.8"; #endif /* not lint */ /* @@ -18,6 +17,19 @@ static const char rcsid[] = #include /* for time_t */ #include /* for struct tm */ #include +#include /* for FLT_MAX and DBL_MAX */ +#include /* for isalpha et al. */ +#ifndef isascii +#define isascii(x) 1 +#endif /* !defined isascii */ + +#ifndef ZDUMP_LO_YEAR +#define ZDUMP_LO_YEAR (-500) +#endif /* !defined ZDUMP_LO_YEAR */ + +#ifndef ZDUMP_HI_YEAR +#define ZDUMP_HI_YEAR 2500 +#endif /* !defined ZDUMP_HI_YEAR */ #ifndef MAX_STRING_LENGTH #define MAX_STRING_LENGTH 1024 @@ -68,19 +80,32 @@ static const char rcsid[] = #endif /* !defined DAYSPERNYEAR */ #ifndef isleap -#define isleap(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0) +#define isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0)) #endif /* !defined isleap */ -#if HAVE_GETTEXT - 0 +#ifndef isleap_sum +/* +** See tzfile.h for details on isleap_sum. +*/ +#define isleap_sum(a, b) isleap((a) % 400 + (b) % 400) +#endif /* !defined isleap_sum */ + +#define SECSPERDAY ((long) SECSPERHOUR * HOURSPERDAY) +#define SECSPERNYEAR (SECSPERDAY * DAYSPERNYEAR) +#define SECSPERLYEAR (SECSPERNYEAR + SECSPERDAY) + +#ifndef HAVE_GETTEXT +#define HAVE_GETTEXT 0 +#endif +#if HAVE_GETTEXT #include "locale.h" /* for setlocale */ #include "libintl.h" -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ #ifndef GNUC_or_lint #ifdef lint #define GNUC_or_lint -#endif /* defined lint */ -#ifndef lint +#else /* !defined lint */ #ifdef __GNUC__ #define GNUC_or_lint #endif /* defined __GNUC__ */ @@ -90,8 +115,7 @@ static const char rcsid[] = #ifndef INITIALIZE #ifdef GNUC_or_lint #define INITIALIZE(x) ((x) = 0) -#endif /* defined GNUC_or_lint */ -#ifndef GNUC_or_lint +#else /* !defined GNUC_or_lint */ #define INITIALIZE(x) #endif /* !defined GNUC_or_lint */ #endif /* !defined INITIALIZE */ @@ -103,35 +127,111 @@ static const char rcsid[] = */ #ifndef _ -#if HAVE_GETTEXT - 0 +#if HAVE_GETTEXT #define _(msgid) gettext(msgid) -#else /* !(HAVE_GETTEXT - 0) */ +#else /* !(HAVE_GETTEXT) */ #define _(msgid) msgid -#endif /* !(HAVE_GETTEXT - 0) */ +#endif /* !(HAVE_GETTEXT) */ #endif /* !defined _ */ #ifndef TZ_DOMAIN #define TZ_DOMAIN "tz" #endif /* !defined TZ_DOMAIN */ -#ifndef P -#ifdef __STDC__ -#define P(x) x -#endif /* defined __STDC__ */ -#ifndef __STDC__ -#define P(x) () -#endif /* !defined __STDC__ */ -#endif /* !defined P */ - extern char ** environ; extern char * tzname[2]; -static char * abbr P((struct tm * tmp)); -static long delta P((struct tm * newp, struct tm * oldp)); -static time_t hunt P((char * name, time_t lot, time_t hit)); +static time_t absolute_min_time; +static time_t absolute_max_time; static size_t longest; -static void show P((char * zone, time_t t, int v)); -static void usage(void); +static char * progname; +static int warned; + +static void usage(const char *progname, FILE *stream, int status); +static char * abbr(struct tm * tmp); +static void abbrok(const char * abbrp, const char * zone); +static long delta(struct tm * newp, struct tm * oldp); +static void dumptime(const struct tm * tmp); +static time_t hunt(char * name, time_t lot, time_t hit); +static void setabsolutes(void); +static void show(char * zone, time_t t, int v); +static const char * tformat(void); +static time_t yeartot(long y); + +#ifndef TYPECHECK +#define my_localtime localtime +#else /* !defined TYPECHECK */ +static struct tm * +my_localtime(tp) +time_t * tp; +{ + register struct tm * tmp; + + tmp = localtime(tp); + if (tp != NULL && tmp != NULL) { + struct tm tm; + register time_t t; + + tm = *tmp; + t = mktime(&tm); + if (t - *tp >= 1 || *tp - t >= 1) { + (void) fflush(stdout); + (void) fprintf(stderr, "\n%s: ", progname); + (void) fprintf(stderr, tformat(), *tp); + (void) fprintf(stderr, " ->"); + (void) fprintf(stderr, " year=%d", tmp->tm_year); + (void) fprintf(stderr, " mon=%d", tmp->tm_mon); + (void) fprintf(stderr, " mday=%d", tmp->tm_mday); + (void) fprintf(stderr, " hour=%d", tmp->tm_hour); + (void) fprintf(stderr, " min=%d", tmp->tm_min); + (void) fprintf(stderr, " sec=%d", tmp->tm_sec); + (void) fprintf(stderr, " isdst=%d", tmp->tm_isdst); + (void) fprintf(stderr, " -> "); + (void) fprintf(stderr, tformat(), t); + (void) fprintf(stderr, "\n"); + } + } + return tmp; +} +#endif /* !defined TYPECHECK */ + +static void +abbrok(abbrp, zone) +const char * const abbrp; +const char * const zone; +{ + register const char * cp; + register char * wp; + + if (warned) + return; + cp = abbrp; + wp = NULL; + while (isascii((unsigned char) *cp) && isalpha((unsigned char) *cp)) + ++cp; + if (cp - abbrp == 0) + wp = _("lacks alphabetic at start"); + else if (cp - abbrp < 3) + wp = _("has fewer than 3 alphabetics"); + else if (cp - abbrp > 6) + wp = _("has more than 6 alphabetics"); + if (wp == NULL && (*cp == '+' || *cp == '-')) { + ++cp; + if (isascii((unsigned char) *cp) && + isdigit((unsigned char) *cp)) + if (*cp++ == '1' && *cp >= '0' && *cp <= '4') + ++cp; + if (*cp != '\0') + wp = _("differs from POSIX standard"); + } + if (wp == NULL) + return; + (void) fflush(stdout); + (void) fprintf(stderr, + _("%s: warning: zone \"%s\" abbreviation \"%s\" %s\n"), + progname, zone, abbrp, wp); + warned = TRUE; +} int main(argc, argv) @@ -141,60 +241,77 @@ char * argv[]; register int i; register int c; register int vflag; - register char * cutoff; - register int cutyear; - register long cuttime; - char ** fakeenv; + register char * cutarg; + register long cutloyear = ZDUMP_LO_YEAR; + register long cuthiyear = ZDUMP_HI_YEAR; + register time_t cutlotime; + register time_t cuthitime; + register char ** fakeenv; time_t now; time_t t; time_t newt; - time_t hibit; struct tm tm; struct tm newtm; + register struct tm * tmp; + register struct tm * newtmp; - INITIALIZE(cuttime); -#if HAVE_GETTEXT - 0 + INITIALIZE(cutlotime); + INITIALIZE(cuthitime); +#if HAVE_GETTEXT (void) setlocale(LC_MESSAGES, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); -#endif /* defined(TEXTDOMAINDIR) */ +#endif /* TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { errx(EXIT_SUCCESS, "%s", elsieid); + } else if (strcmp(argv[i], "--help") == 0) { + usage(progname, stdout, EXIT_SUCCESS); } vflag = 0; - cutoff = NULL; + cutarg = NULL; while ((c = getopt(argc, argv, "c:v")) == 'c' || c == 'v') if (c == 'v') vflag = 1; - else cutoff = optarg; + else cutarg = optarg; if ((c != -1) || (optind == argc - 1 && strcmp(argv[optind], "=") == 0)) { - usage(); + usage(progname, stderr, EXIT_FAILURE); } - if (cutoff != NULL) { - int y; + if (vflag) { + if (cutarg != NULL) { + long lo; + long hi; + char dummy; - cutyear = atoi(cutoff); - cuttime = 0; - for (y = EPOCH_YEAR; y < cutyear; ++y) - cuttime += DAYSPERNYEAR + isleap(y); - cuttime *= SECSPERHOUR * HOURSPERDAY; + if (sscanf(cutarg, "%ld%c", &hi, &dummy) == 1) { + cuthiyear = hi; + } else if (sscanf(cutarg, "%ld,%ld%c", + &lo, &hi, &dummy) == 2) { + cutloyear = lo; + cuthiyear = hi; + } else { +(void) fprintf(stderr, _("%s: wild -c argument %s\n"), + progname, cutarg); + exit(EXIT_FAILURE); + } + } + setabsolutes(); + cutlotime = yeartot(cutloyear); + cuthitime = yeartot(cuthiyear); } (void) time(&now); longest = 0; for (i = optind; i < argc; ++i) if (strlen(argv[i]) > longest) longest = strlen(argv[i]); - for (hibit = 1; (hibit << 1) != 0; hibit <<= 1) - continue; { register int from; register int to; - for (i = 0; environ[i] != NULL; ++i) + for (i = 0; environ[i] != NULL; ++i) continue; fakeenv = (char **) malloc((size_t) ((i + 2) * sizeof *fakeenv)); @@ -219,43 +336,43 @@ char * argv[]; show(argv[i], now, FALSE); continue; } - /* - ** Get lowest value of t. - */ - t = hibit; - if (t > 0) /* time_t is unsigned */ - t = 0; + warned = FALSE; + t = absolute_min_time; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); - tm = *localtime(&t); - (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + if (t < cutlotime) + t = cutlotime; + tmp = my_localtime(&t); + if (tmp != NULL) { + tm = *tmp; + (void) strncpy(buf, abbr(&tm), (sizeof buf) - 1); + } for ( ; ; ) { - if (cutoff != NULL && t >= cuttime) + if (t >= cuthitime || t >= cuthitime - SECSPERHOUR * 12) break; newt = t + SECSPERHOUR * 12; - if (cutoff != NULL && newt >= cuttime) - break; - if (newt <= t) - break; - newtm = *localtime(&newt); - if (delta(&newtm, &tm) != (newt - t) || + newtmp = localtime(&newt); + if (newtmp != NULL) + newtm = *newtmp; + if ((tmp == NULL || newtmp == NULL) ? (tmp != newtmp) : + (delta(&newtm, &tm) != (newt - t) || newtm.tm_isdst != tm.tm_isdst || - strcmp(abbr(&newtm), buf) != 0) { + strcmp(abbr(&newtm), buf) != 0)) { newt = hunt(argv[i], t, newt); - newtm = *localtime(&newt); - (void) strncpy(buf, abbr(&newtm), - (sizeof buf) - 1); + newtmp = localtime(&newt); + if (newtmp != NULL) { + newtm = *newtmp; + (void) strncpy(buf, + abbr(&newtm), + (sizeof buf) - 1); + } } t = newt; tm = newtm; + tmp = newtmp; } - /* - ** Get highest value of t. - */ - t = ~((time_t) 0); - if (t < 0) /* time_t is signed */ - t &= ~hibit; + t = absolute_max_time; t -= SECSPERHOUR * HOURSPERDAY; show(argv[i], t, TRUE); t += SECSPERHOUR * HOURSPERDAY; @@ -264,45 +381,133 @@ char * argv[]; if (fflush(stdout) || ferror(stdout)) errx(EXIT_FAILURE, _("error writing standard output")); exit(EXIT_SUCCESS); - - /* gcc -Wall pacifier */ - for ( ; ; ) - continue; + /* If exit fails to exit... */ + return(EXIT_FAILURE); } static void -usage(void) +setabsolutes(void) { - fprintf(stderr, -_("usage: zdump [--version] [-v] [-c cutoff] zonename ...\n")); - exit(EXIT_FAILURE); + if (0.5 == (time_t) 0.5) { + /* + ** time_t is floating. + */ + if (sizeof (time_t) == sizeof (float)) { + absolute_min_time = (time_t) -FLT_MAX; + absolute_max_time = (time_t) FLT_MAX; + } else if (sizeof (time_t) == sizeof (double)) { + absolute_min_time = (time_t) -DBL_MAX; + absolute_max_time = (time_t) DBL_MAX; + } else { + (void) fprintf(stderr, +_("%s: use of -v on system with floating time_t other than float or double\n"), + progname); + exit(EXIT_FAILURE); + } + } else if (0 > (time_t) -1) { + /* + ** time_t is signed. Assume overflow wraps around. + */ + time_t t = 0; + time_t t1 = 1; + + while (t < t1) { + t = t1; + t1 = 2 * t1 + 1; + } + + absolute_max_time = t; + t = -t; + absolute_min_time = t - 1; + if (t < absolute_min_time) + absolute_min_time = t; + } else { + /* + ** time_t is unsigned. + */ + absolute_min_time = 0; + absolute_max_time = absolute_min_time - 1; + } } static time_t -hunt(name, lot, hit) -char * name; -time_t lot; -time_t hit; +yeartot(y) +const long y; { - time_t t; - struct tm lotm; - struct tm tm; - static char loab[MAX_STRING_LENGTH]; + register long myy; + register long seconds; + register time_t t; - lotm = *localtime(&lot); - (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); - while ((hit - lot) >= 2) { - t = lot / 2 + hit / 2; + myy = EPOCH_YEAR; + t = 0; + while (myy != y) { + if (myy < y) { + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + ++myy; + if (t > absolute_max_time - seconds) { + t = absolute_max_time; + break; + } + t += seconds; + } else { + --myy; + seconds = isleap(myy) ? SECSPERLYEAR : SECSPERNYEAR; + if (t < absolute_min_time + seconds) { + t = absolute_min_time; + break; + } + t -= seconds; + } + } + return t; +} + +static void +usage(const char *progname, FILE *stream, int status) +{ + fprintf(stream, +_("usage: %s [--version] [-v] [--help] [-c [loyear,]hiyear] zonename ...\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n"), progname); + exit(status); +} + +static time_t +hunt(char *name, time_t lot, time_t hit) +{ + time_t t; + long diff; + struct tm lotm; + register struct tm * lotmp; + struct tm tm; + register struct tm * tmp; + char loab[MAX_STRING_LENGTH]; + + lotmp = my_localtime(&lot); + if (lotmp != NULL) { + lotm = *lotmp; + (void) strncpy(loab, abbr(&lotm), (sizeof loab) - 1); + } + for ( ; ; ) { + diff = (long) (hit - lot); + if (diff < 2) + break; + t = lot; + t += diff / 2; if (t <= lot) ++t; else if (t >= hit) --t; - tm = *localtime(&t); - if (delta(&tm, &lotm) == (t - lot) && + tmp = my_localtime(&t); + if (tmp != NULL) + tm = *tmp; + if ((lotmp == NULL || tmp == NULL) ? (lotmp == tmp) : + (delta(&tm, &lotm) == (t - lot) && tm.tm_isdst == lotm.tm_isdst && - strcmp(abbr(&tm), loab) == 0) { + strcmp(abbr(&tm), loab) == 0)) { lot = t; lotm = tm; + lotmp = tmp; } else hit = t; } show(name, lot, TRUE); @@ -311,7 +516,7 @@ time_t hit; } /* -** Thanks to Paul Eggert (eggert@twinsun.com) for logic used in delta. +** Thanks to Paul Eggert for logic used in delta. */ static long @@ -319,14 +524,14 @@ delta(newp, oldp) struct tm * newp; struct tm * oldp; { - long result; - int tmy; + register long result; + register int tmy; if (newp->tm_year < oldp->tm_year) return -delta(oldp, newp); result = 0; for (tmy = oldp->tm_year; tmy < newp->tm_year; ++tmy) - result += DAYSPERNYEAR + isleap(tmy + TM_YEAR_BASE); + result += DAYSPERNYEAR + isleap_sum(tmy, TM_YEAR_BASE); result += newp->tm_yday - oldp->tm_yday; result *= HOURSPERDAY; result += newp->tm_hour - oldp->tm_hour; @@ -338,27 +543,36 @@ struct tm * oldp; } static void -show(zone, t, v) -char * zone; -time_t t; -int v; +show(char *zone, time_t t, int v) { - struct tm * tmp; + register struct tm * tmp; (void) printf("%-*s ", (int) longest, zone); - if (v) - (void) printf("%.24s UTC = ", asctime(gmtime(&t))); - tmp = localtime(&t); - (void) printf("%.24s", asctime(tmp)); - if (*abbr(tmp) != '\0') - (void) printf(" %s", abbr(tmp)); if (v) { - (void) printf(" isdst=%d", tmp->tm_isdst); + tmp = gmtime(&t); + if (tmp == NULL) { + (void) printf(tformat(), t); + } else { + dumptime(tmp); + (void) printf(" UTC"); + } + (void) printf(" = "); + } + tmp = my_localtime(&t); + dumptime(tmp); + if (tmp != NULL) { + if (*abbr(tmp) != '\0') + (void) printf(" %s", abbr(tmp)); + if (v) { + (void) printf(" isdst=%d", tmp->tm_isdst); #ifdef TM_GMTOFF - (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); + (void) printf(" gmtoff=%ld", tmp->TM_GMTOFF); #endif /* defined TM_GMTOFF */ + } } (void) printf("\n"); + if (tmp != NULL && *abbr(tmp) != '\0') + abbrok(abbr(tmp), zone); } static char * @@ -373,3 +587,84 @@ struct tm * tmp; result = tzname[tmp->tm_isdst]; return (result == NULL) ? &nada : result; } + +/* +** The code below can fail on certain theoretical systems; +** it works on all known real-world systems as of 2004-12-30. +*/ + +static const char * +tformat(void) +{ + if (0.5 == (time_t) 0.5) { /* floating */ + if (sizeof (time_t) > sizeof (double)) + return "%Lg"; + return "%g"; + } + if (0 > (time_t) -1) { /* signed */ + if (sizeof (time_t) > sizeof (long)) + return "%lld"; + if (sizeof (time_t) > sizeof (int)) + return "%ld"; + return "%d"; + } + if (sizeof (time_t) > sizeof (unsigned long)) + return "%llu"; + if (sizeof (time_t) > sizeof (unsigned int)) + return "%lu"; + return "%u"; +} + +static void +dumptime(timeptr) +register const struct tm * timeptr; +{ + static const char wday_name[][3] = { + "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" + }; + static const char mon_name[][3] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" + }; + register const char * wn; + register const char * mn; + register int lead; + register int trail; + + if (timeptr == NULL) { + (void) printf("NULL"); + return; + } + /* + ** The packaged versions of localtime and gmtime never put out-of-range + ** values in tm_wday or tm_mon, but since this code might be compiled + ** with other (perhaps experimental) versions, paranoia is in order. + */ + if (timeptr->tm_wday < 0 || timeptr->tm_wday >= + (int) (sizeof wday_name / sizeof wday_name[0])) + wn = "???"; + else wn = wday_name[timeptr->tm_wday]; + if (timeptr->tm_mon < 0 || timeptr->tm_mon >= + (int) (sizeof mon_name / sizeof mon_name[0])) + mn = "???"; + else mn = mon_name[timeptr->tm_mon]; + (void) printf("%.3s %.3s%3d %.2d:%.2d:%.2d ", + wn, mn, + timeptr->tm_mday, timeptr->tm_hour, + timeptr->tm_min, timeptr->tm_sec); +#define DIVISOR 10 + trail = timeptr->tm_year % DIVISOR + TM_YEAR_BASE % DIVISOR; + lead = timeptr->tm_year / DIVISOR + TM_YEAR_BASE / DIVISOR + + trail / DIVISOR; + trail %= DIVISOR; + if (trail < 0 && lead > 0) { + trail += DIVISOR; + --lead; + } else if (lead < 0 && trail > 0) { + trail -= DIVISOR; + ++lead; + } + if (lead == 0) + (void) printf("%d", trail); + else (void) printf("%d%d", lead, ((trail < 0) ? -trail : trail)); +} diff --git a/usr.sbin/zic/zic.8 b/usr.sbin/zic/zic.8 index 76a5a883cd9d..71a1bcbfb36c 100644 --- a/usr.sbin/zic/zic.8 +++ b/usr.sbin/zic/zic.8 @@ -120,9 +120,9 @@ Non-blank lines are expected to be of one of three types: rule lines, zone lines, and link lines. .Pp A rule line has the form: -.Dl "Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S" +.Dl "Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S For example: -.Dl "Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D" +.Dl "Rule US 1967 1973 \- Apr lastSun 2:00 1:00 D .Pp The fields that make up a rule line are: .Bl -tag -width "LETTER/S" -offset indent @@ -260,9 +260,9 @@ the variable part is null. .El .Pp A zone line has the form: -.Dl "Zone NAME GMTOFF RULES/SAVE FORMAT [UNTIL]" +.Dl "Zone NAME GMTOFF RULES/SAVE FORMAT [UNTILYEAR [MONTH [DAY [TIME]]]] For example: -.Dl "Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00" +.Dl "Zone Australia/Adelaide 9:30 Aus CST 1971 Oct 31 2:00 The fields that make up a zone line are: .Bl -tag -width indent .It NAME @@ -293,15 +293,15 @@ of the time zone abbreviation goes. Alternately, a slash (/) separates standard and daylight abbreviations. -.It UNTIL +.It UNTILYEAR [MONTH [DAY [TIME]]] The time at which the UTC offset or the rule(s) change for a location. It is specified as a year, a month, a day, and a time of day. If this is specified, the time zone information is generated from the given UTC offset and rule change until the time specified. The month, day, and time of day have the same format as the IN, ON, and AT -columns of a rule; trailing columns can be omitted, and default to the -earliest possible value for the missing columns. +fields of a rule; trailing fields can be omitted, and default to the +earliest possible value for the missing fields. .Pp The next line must be a .Dq continuation @@ -310,18 +310,18 @@ string .Dq Zone and the name are omitted, as the continuation line will place information starting at the time specified as the -.Em UNTIL -field in the previous line in the file used by the previous line. -Continuation lines may contain an -.Em UNTIL -field, just as zone lines do, indicating that the next line is a further +.Em until +information in the previous line in the file used by the previous line. +Continuation lines may contain +.Em until +information, just as zone lines do, indicating that the next line is a further continuation. .El .Pp A link line has the form -.Dl "Link LINK-FROM LINK-TO" +.Dl "Link LINK-FROM LINK-TO For example: -.Dl "Link Europe/Istanbul Asia/Istanbul" +.Dl "Link Europe/Istanbul Asia/Istanbul The .Em LINK-FROM field should appear as the @@ -335,9 +335,9 @@ Except for continuation lines, lines may appear in any order in the input. .Pp Lines in the file that describes leap seconds have the following form: -.Dl "Leap YEAR MONTH DAY HH:MM:SS CORR R/S" +.Dl "Leap YEAR MONTH DAY HH:MM:SS CORR R/S For example: -.Dl "Leap 1974 Dec 31 23:59:60 + S" +.Dl "Leap 1974 Dec 31 23:59:60 + S The .Em YEAR , .Em MONTH , @@ -376,12 +376,81 @@ or .Dq Rolling if the leap second time given by the other fields should be interpreted as local wall clock time. -.Sh NOTE +.Sh "EXTENDED EXAMPLE" +Here is an extended example of +.Nm +input, intended to illustrate many of its features. +.br +.ne 22 +.nf +.in +2m +.ta \w'# Rule\0\0'u +\w'NAME\0\0'u +\w'FROM\0\0'u +\w'1973\0\0'u +\w'TYPE\0\0'u +\w'Apr\0\0'u +\w'lastSun\0\0'u +\w'2:00\0\0'u +\w'SAVE\0\0'u +.sp +# Rule NAME FROM TO TYPE IN ON AT SAVE LETTER/S +Rule Swiss 1940 only - Nov 2 0:00 1:00 S +Rule Swiss 1940 only - Dec 31 0:00 0 - +Rule Swiss 1941 1942 - May Sun>=1 2:00 1:00 S +Rule Swiss 1941 1942 - Oct Sun>=1 0:00 0 +.sp .5 +Rule EU 1977 1980 - Apr Sun>=1 1:00u 1:00 S +Rule EU 1977 only - Sep lastSun 1:00u 0 - +Rule EU 1978 only - Oct 1 1:00u 0 - +Rule EU 1979 1995 - Sep lastSun 1:00u 0 - +Rule EU 1981 max - Mar lastSun 1:00u 1:00 S +Rule EU 1996 max - Oct lastSun 1:00u 0 - +.sp +.ta \w'# Zone\0\0'u +\w'Europe/Zurich\0\0'u +\w'0:34:08\0\0'u +\w'RULES/SAVE\0\0'u +\w'FORMAT\0\0'u +# Zone NAME GMTOFF RULES FORMAT UNTIL +Zone Europe/Zurich 0:34:08 - LMT 1848 Sep 12 + 0:29:44 - BMT 1894 Jun + 1:00 Swiss CE%sT 1981 + 1:00 EU CE%sT +.sp +Link Europe/Zurich Switzerland +.sp +.in +.fi +In this example, the zone is named Europe/Zurich but it has an alias +as Switzerland. +Zurich was 34 minutes and 8 seconds west of GMT until 1848-09-12 +at 00:00, when the offset changed to 29 minutes and 44 seconds. +After 1894-06-01 at 00:00 Swiss daylight saving rules (defined with +lines beginning with "Rule Swiss") apply, and the GMT offset became +one hour. +From 1981 to the present, EU daylight saving rules have applied, +and the UTC offset has remained at one hour. +.Pp +In 1940, daylight saving time applied from November 2 at 00:00 to +December 31 at 00:00. +In 1941 and 1942, daylight saving time applied from the first Sunday +in May at 02:00 to the first Sunday in October at 00:00. +The pre-1981 EU daylight-saving rules have no effect here, but are +included for completeness. +Since 1981, daylight saving has begun on the last Sunday in March +at 01:00 UTC. +Until 1995 it ended the last Sunday in September at 01:00 UTC, but +this changed to the last Sunday in October starting in 1996. +.Pp +For purposes of display, "LMT" and "BMT" were initially used, +respectively. +Since Swiss rules and later EU rules were applied, the display name +for the timezone has been CET for standard time and CEST for daylight +saving time. +.Sh NOTES For areas with more than two types of local time, you may need to use local standard time in the .Em AT field of the earliest transition time's rule to ensure that the earliest transition time recorded in the compiled file is correct. +.Pp +If, for a particular zone, a clock advance caused by the start of +daylight saving coincides with and is equal to a clock retreat +caused by a change in UTC offset, +.Nm +produces a single transition to daylight saving at the new UTC offset +(without any change in wall clock time). +To get separate transitions use multiple zone continuation lines +specifying transition instants using universal time. .Sh FILES .Bl -tag -width /usr/share/zoneinfo -compact .It /usr/share/zoneinfo @@ -391,4 +460,4 @@ standard directory used for created files .Xr ctime 3 , .Xr tzfile 5 , .Xr zdump 8 -.\" @(#)zic.8 7.18 +.\" @(#)zic.8 8.4 diff --git a/usr.sbin/zic/zic.c b/usr.sbin/zic/zic.c index 10d79a898a2c..cb959586a449 100644 --- a/usr.sbin/zic/zic.c +++ b/usr.sbin/zic/zic.c @@ -1,4 +1,9 @@ -static const char elsieid[] = "@(#)zic.c 7.116"; +/* +** This file is in the public domain, so clarified as of +** 2006-07-17 by Arthur David Olson. +*/ + +static const char elsieid[] = "@(#)zic.c 8.19"; #ifndef lint static const char rcsid[] = @@ -13,11 +18,19 @@ static const char rcsid[] = #include #include +#define ZIC_VERSION '2' + +typedef int_fast64_t zic_t; + +#ifndef ZIC_MAX_ABBR_LEN_WO_WARN +#define ZIC_MAX_ABBR_LEN_WO_WARN 6 +#endif /* !defined ZIC_MAX_ABBR_LEN_WO_WARN */ + #define MKDIR_UMASK (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) /* ** On some ancient hosts, predicates like `isspace(C)' are defined -** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, +** only if isascii(C) || C == EOF. Modern hosts obey the C Standard, ** which says they are defined only if C == ((unsigned char) C) || C == EOF. ** Neither the C Standard nor POSIX require that `isascii' exist. ** For portability, we check both ancient and modern requirements. @@ -28,6 +41,11 @@ static const char rcsid[] = #define isascii(x) 1 #endif +#define OFFSET_STRLEN_MAXIMUM (7 + INT_STRLEN_MAXIMUM(long)) +#define RULE_STRLEN_MAXIMUM 8 /* "Mdd.dd.d" */ + +#define end(cp) (strchr((cp), '\0')) + struct rule { const char * r_filename; int r_linenum; @@ -36,6 +54,8 @@ struct rule { int r_loyear; /* for example, 1986 */ int r_hiyear; /* for example, 1986 */ const char * r_yrtype; + int r_lowasnum; + int r_hiwasnum; int r_month; /* 0..11 */ @@ -52,7 +72,7 @@ struct rule { const char * r_abbrvar; /* variable part of abbreviation */ int r_todo; /* a rule to do (used in outzone) */ - time_t r_temp; /* used in outzone */ + zic_t r_temp; /* used in outzone */ }; /* @@ -78,73 +98,81 @@ struct zone { int z_nrules; struct rule z_untilrule; - time_t z_untiltime; + zic_t z_untiltime; }; -static void addtt P((time_t starttime, int type)); -static int addtype P((long gmtoff, const char * abbr, int isdst, - int ttisstd, int ttisgmt)); -static void leapadd P((time_t t, int positive, int rolling, int count)); -static void adjleap P((void)); -static void associate P((void)); -static int ciequal P((const char * ap, const char * bp)); -static void convert P((long val, char * buf)); -static void dolink P((const char * fromfile, const char * tofile)); -static void doabbr P((char * abbr, const char * format, - const char * letters, int isdst)); -static void eat P((const char * name, int num)); -static void eats P((const char * name, int num, - const char * rname, int rnum)); -static long eitol P((int i)); -static void error P((const char * message)); -static char ** getfields P((char * buf)); -static long gethms P((const char * string, const char * errstrng, - int signable)); -static void infile P((const char * filename)); -static void inleap P((char ** fields, int nfields)); -static void inlink P((char ** fields, int nfields)); -static void inrule P((char ** fields, int nfields)); -static int inzcont P((char ** fields, int nfields)); -static int inzone P((char ** fields, int nfields)); -static int inzsub P((char ** fields, int nfields, int iscont)); -static int itsabbr P((const char * abbr, const char * word)); -static int itsdir P((const char * name)); -static int lowerit P((int c)); -static char * memcheck P((char * tocheck)); -static int mkdirs P((char * filename)); -static void newabbr P((const char * abbr)); -static long oadd P((long t1, long t2)); -static void outzone P((const struct zone * zp, int ntzones)); -static void puttzcode P((long code, FILE * fp)); -static int rcomp P((const void * leftp, const void * rightp)); -static time_t rpytime P((const struct rule * rp, int wantedy)); -static void rulesub P((struct rule * rp, +static void addtt(zic_t starttime, int type); +static int addtype(long gmtoff, const char * abbr, int isdst, + int ttisstd, int ttisgmt); +static void leapadd(zic_t t, int positive, int rolling, int count); +static void adjleap(void); +static void associate(void); +static int ciequal(const char * ap, const char * bp); +static void convert(long val, char * buf); +static void convert64(zic_t val, char * buf); +static void dolink(const char * fromfield, const char * tofield); +static void doabbr(char * abbr, const char * format, + const char * letters, int isdst, int doquotes); +static void eat(const char * name, int num); +static void eats(const char * name, int num, + const char * rname, int rnum); +static long eitol(int i); +static void error(const char * message); +static char ** getfields(char * buf); +static long gethms(const char * string, const char * errstrng, + int signable); +static void infile(const char * filename); +static void inleap(char ** fields, int nfields); +static void inlink(char ** fields, int nfields); +static void inrule(char ** fields, int nfields); +static int inzcont(char ** fields, int nfields); +static int inzone(char ** fields, int nfields); +static int inzsub(char ** fields, int nfields, int iscont); +static int is32(zic_t x); +static int itsabbr(const char * abbr, const char * word); +static int itsdir(const char * name); +static int lowerit(int c); +static char * memcheck(char * tocheck); +static int mkdirs(char * filename); +static void newabbr(const char * abbr); +static long oadd(long t1, long t2); +static void outzone(const struct zone * zp, int ntzones); +static void puttzcode(long code, FILE * fp); +static void puttzcode64(zic_t code, FILE * fp); +static int rcomp(const void * leftp, const void * rightp); +static zic_t rpytime(const struct rule * rp, int wantedy); +static void rulesub(struct rule * rp, const char * loyearp, const char * hiyearp, const char * typep, const char * monthp, - const char * dayp, const char * timep)); -static void setboundaries P((void)); -static void setgroup P((gid_t *flag, const char *name)); -static void setuser P((uid_t *flag, const char *name)); -static time_t tadd P((time_t t1, long t2)); -static void usage P((void)); -static void writezone P((const char * name)); -static int yearistype P((int year, const char * type)); - -#if !(HAVE_STRERROR - 0) -static char * strerror P((int)); -#endif /* !(HAVE_STRERROR - 0) */ + const char * dayp, const char * timep); +static int stringoffset(char * result, long offset); +static int stringrule(char * result, const struct rule * rp, + long dstoff, long gmtoff); +static void stringzone(char * result, + const struct zone * zp, int ntzones); +static void setboundaries(void); +static void setgroup(gid_t *flag, const char *name); +static void setuser(uid_t *flag, const char *name); +static zic_t tadd(zic_t t1, long t2); +static void usage(FILE *stream, int status); +static void writezone(const char * name, const char * string); +static int yearistype(int year, const char * type); static int charcnt; static int errors; static const char * filename; static int leapcnt; +static int leapseen; +static int leapminyear; +static int leapmaxyear; static int linenum; -static time_t max_time; +static int max_abbrvar_len; +static int max_format_len; +static zic_t max_time; static int max_year; -static int max_year_representable; -static time_t min_time; +static zic_t min_time; static int min_year; -static int min_year_representable; +static zic_t min_time; static int noise; static const char * rfilename; static int rlinenum; @@ -253,8 +281,8 @@ struct lookup { const int l_value; }; -static struct lookup const * byword P((const char * string, - const struct lookup * lp)); +static struct lookup const * byword(const char * string, + const struct lookup * lp); static struct lookup const line_codes[] = { { "Rule", LC_RULE }, @@ -331,7 +359,7 @@ static const int len_years[2] = { }; static struct attype { - time_t at; + zic_t at; unsigned char type; } attypes[TZ_MAX_TIMES]; static long gmtoffs[TZ_MAX_TYPES]; @@ -340,7 +368,7 @@ static unsigned char abbrinds[TZ_MAX_TYPES]; static char ttisstds[TZ_MAX_TYPES]; static char ttisgmts[TZ_MAX_TYPES]; static char chars[TZ_MAX_CHARS]; -static time_t trans[TZ_MAX_LEAPS]; +static zic_t trans[TZ_MAX_LEAPS]; static long corr[TZ_MAX_LEAPS]; static char roll[TZ_MAX_LEAPS]; @@ -366,19 +394,6 @@ char * const ptr; ** Error handling. */ -#if !(HAVE_STRERROR - 0) -static char * -strerror(errnum) -int errnum; -{ - extern char * sys_errlist[]; - extern int sys_nerr; - - return (errnum > 0 && errnum <= sys_nerr) ? - sys_errlist[errnum] : _("Unknown system error"); -} -#endif /* !(HAVE_STRERROR - 0) */ - static void eats(name, num, rname, rnum) const char * const name; @@ -432,12 +447,14 @@ const char * const string; } static void -usage P((void)) -{ - (void) fprintf(stderr, "%s\n%s\n", -_("usage: zic [--version] [-s] [-v] [-l localtime] [-p posixrules] [-d directory]"), -_(" [-L leapseconds] [-y yearistype] [filename ... ]")); - (void) exit(EXIT_FAILURE); +usage(FILE *stream, int status) + { + (void) fprintf(stream, _("usage is zic \ +[ --version ] [--help] [ -v ] [ -l localtime ] [ -p posixrules ] \\\n\ +\t[ -d directory ] [ -L leapseconds ] [ -y yearistype ] [ filename ... ]\n\ +\n\ +Report bugs to tz@elsie.nci.nih.gov.\n")); + exit(status); } static const char * psxrules; @@ -445,7 +462,6 @@ static const char * lcltime; static const char * directory; static const char * leapsec; static const char * yitcommand; -static int sflag = FALSE; static int Dflag; static uid_t uflag = (uid_t)-1; static gid_t gflag = (gid_t)-1; @@ -464,21 +480,28 @@ char * argv[]; #ifdef unix (void) umask(umask(S_IWGRP | S_IWOTH) | (S_IWGRP | S_IWOTH)); #endif /* defined unix */ -#if HAVE_GETTEXT - 0 - (void) setlocale(LC_MESSAGES, ""); +#if HAVE_GETTEXT + (void) setlocale(LC_ALL, ""); #ifdef TZ_DOMAINDIR (void) bindtextdomain(TZ_DOMAIN, TZ_DOMAINDIR); #endif /* defined TEXTDOMAINDIR */ (void) textdomain(TZ_DOMAIN); -#endif /* HAVE_GETTEXT - 0 */ +#endif /* HAVE_GETTEXT */ + if (TYPE_BIT(zic_t) < 64) { + (void) fprintf(stderr, "zic: %s\n", + _("wild compilation-time specification of zic_t")); + exit(EXIT_FAILURE); + } for (i = 1; i < argc; ++i) if (strcmp(argv[i], "--version") == 0) { errx(EXIT_SUCCESS, "%s", elsieid); + } else if (strcmp(argv[i], "--help") == 0) { + usage(stdout, EXIT_SUCCESS); } while ((c = getopt(argc, argv, "Dd:g:l:m:p:L:u:vsy:")) != -1) switch (c) { default: - usage(); + usage(stderr, EXIT_FAILURE); case 'D': Dflag = 1; break; @@ -537,11 +560,11 @@ _("more than one -L option specified")); noise = TRUE; break; case 's': - sflag = TRUE; + (void) printf("zic: -s ignored\n"); break; } if (optind == argc - 1 && strcmp(argv[optind], "=") == 0) - usage(); /* usage message by request */ + usage(stderr, EXIT_FAILURE); /* usage message by request */ if (directory == NULL) directory = TZDIR; if (yitcommand == NULL) @@ -557,7 +580,7 @@ _("more than one -L option specified")); for (i = optind; i < argc; ++i) infile(argv[i]); if (errors) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); associate(); for (i = 0; i < nzones; i = j) { /* @@ -573,6 +596,11 @@ _("more than one -L option specified")); for (i = 0; i < nlinks; ++i) { eat(links[i].l_filename, links[i].l_linenum); dolink(links[i].l_from, links[i].l_to); + if (noise) + for (j = 0; j < nlinks; ++j) + if (strcmp(links[i].l_to, + links[j].l_from) == 0) + warning(_("link to link")); } if (lcltime != NULL) { eat("command line", 1); @@ -586,26 +614,26 @@ _("more than one -L option specified")); } static void -dolink(fromfile, tofile) -const char * const fromfile; -const char * const tofile; +dolink(fromfield, tofield) +const char * const fromfield; +const char * const tofield; { register char * fromname; register char * toname; - if (fromfile[0] == '/') - fromname = ecpyalloc(fromfile); + if (fromfield[0] == '/') + fromname = ecpyalloc(fromfield); else { fromname = ecpyalloc(directory); fromname = ecatalloc(fromname, "/"); - fromname = ecatalloc(fromname, fromfile); + fromname = ecatalloc(fromname, fromfield); } - if (tofile[0] == '/') - toname = ecpyalloc(tofile); + if (tofield[0] == '/') + toname = ecpyalloc(tofield); else { toname = ecpyalloc(directory); toname = ecatalloc(toname, "/"); - toname = ecatalloc(toname, tofile); + toname = ecatalloc(toname, tofield); } /* ** We get to be careful here since @@ -617,25 +645,30 @@ const char * const tofile; int result; if (mkdirs(toname) != 0) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); result = link(fromname, toname); -#if (HAVE_SYMLINK - 0) +#if HAVE_SYMLINK if (result != 0 && - access(fromname, F_OK) == 0 && - !itsdir(fromname)) { - const char *s = tofile; - register char * symlinkcontents = NULL; - while ((s = strchr(s+1, '/')) != NULL) - symlinkcontents = ecatalloc(symlinkcontents, "../"); - symlinkcontents = ecatalloc(symlinkcontents, fromfile); - - result = symlink(symlinkcontents, toname); - if (result == 0) + access(fromname, F_OK) == 0 && + !itsdir(fromname)) { + const char *s = tofield; + register char * symlinkcontents = NULL; + while ((s = strchr(s+1, '/')) != NULL) + symlinkcontents = + ecatalloc(symlinkcontents, + "../"); + symlinkcontents = + ecatalloc(symlinkcontents, + fromname); + result = + symlink(symlinkcontents, + toname); + if (result == 0) warning(_("hard link failed, symbolic link used")); - ifree(symlinkcontents); + ifree(symlinkcontents); } -#endif +#endif /* HAVE_SYMLINK */ if (result != 0) { err(EXIT_FAILURE, _("can't link from %s to %s"), fromname, toname); @@ -645,43 +678,17 @@ warning(_("hard link failed, symbolic link used")); ifree(toname); } -#ifndef INT_MAX -#define INT_MAX ((int) (((unsigned)~0)>>1)) -#endif /* !defined INT_MAX */ - -#ifndef INT_MIN -#define INT_MIN ((int) ~(((unsigned)~0)>>1)) -#endif /* !defined INT_MIN */ - -/* -** The tz file format currently allows at most 32-bit quantities. -** This restriction should be removed before signed 32-bit values -** wrap around in 2038, but unfortunately this will require a -** change to the tz file format. -*/ - -#define MAX_BITS_IN_FILE 32 -#define TIME_T_BITS_IN_FILE ((TYPE_BIT(time_t) < MAX_BITS_IN_FILE) ? TYPE_BIT(time_t) : MAX_BITS_IN_FILE) +#define TIME_T_BITS_IN_FILE 64 static void -setboundaries P((void)) +setboundaries (void) { - if (TYPE_SIGNED(time_t)) { - min_time = ~ (time_t) 0; - min_time <<= TIME_T_BITS_IN_FILE - 1; - max_time = ~ (time_t) 0 - min_time; - if (sflag) - min_time = 0; - } else { - min_time = 0; - max_time = 2 - sflag; - max_time <<= TIME_T_BITS_IN_FILE - 1; - --max_time; - } - min_year = TM_YEAR_BASE + gmtime(&min_time)->tm_year; - max_year = TM_YEAR_BASE + gmtime(&max_time)->tm_year; - min_year_representable = min_year; - max_year_representable = max_year; + register int i; + + min_time = -1; + for (i = 0; i < TIME_T_BITS_IN_FILE - 1; ++i) + min_time *= 2; + max_time = -(min_time + 1); } static int @@ -716,7 +723,7 @@ const void * cp2; } static void -associate P((void)) +associate(void) { register struct zone * zp; register struct rule * rp; @@ -778,7 +785,7 @@ associate P((void)) */ eat(zp->z_filename, zp->z_linenum); zp->z_stdoff = gethms(zp->z_rule, _("unruly zone"), - TRUE); + TRUE); /* ** Note, though, that if there's no rule, ** a '%s' in the format is a bad thing. @@ -788,7 +795,7 @@ associate P((void)) } } if (errors) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } static void @@ -817,7 +824,7 @@ const char * name; cp = strchr(buf, '\n'); if (cp == NULL) { error(_("line too long")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } *cp = '\0'; fields = getfields(buf); @@ -885,7 +892,8 @@ const char * string; const char * const errstring; const int signable; { - int hh, mm, ss, sign; + long hh; + int mm, ss, sign; if (string == NULL || *string == '\0') return 0; @@ -895,27 +903,32 @@ const int signable; sign = -1; ++string; } else sign = 1; - if (sscanf(string, scheck(string, "%d"), &hh) == 1) + if (sscanf(string, scheck(string, "%ld"), &hh) == 1) mm = ss = 0; - else if (sscanf(string, scheck(string, "%d:%d"), &hh, &mm) == 2) + else if (sscanf(string, scheck(string, "%ld:%d"), &hh, &mm) == 2) ss = 0; - else if (sscanf(string, scheck(string, "%d:%d:%d"), + else if (sscanf(string, scheck(string, "%ld:%d:%d"), &hh, &mm, &ss) != 3) { error(errstring); return 0; } - if ((hh < 0 || hh >= HOURSPERDAY || + if (hh < 0 || mm < 0 || mm >= MINSPERHOUR || - ss < 0 || ss > SECSPERMIN) && - !(hh == HOURSPERDAY && mm == 0 && ss == 0)) { + ss < 0 || ss > SECSPERMIN) { error(errstring); return 0; } - if (noise && hh == HOURSPERDAY) + if (LONG_MAX / SECSPERHOUR < hh) { + error(_("time overflow")); + return 0; + } + if (noise && hh == HOURSPERDAY && mm == 0 && ss == 0) warning(_("24:00 not handled by pre-1998 versions of zic")); - return eitol(sign) * - (eitol(hh * MINSPERHOUR + mm) * - eitol(SECSPERMIN) + eitol(ss)); + if (noise && (hh > HOURSPERDAY || + (hh == HOURSPERDAY && (mm != 0 || ss != 0)))) +warning(_("values over 24 hours not handled by pre-2007 versions of zic")); + return oadd(eitol(sign) * hh * eitol(SECSPERHOUR), + eitol(sign) * (eitol(mm) * eitol(SECSPERMIN) + eitol(ss))); } static void @@ -940,6 +953,8 @@ const int nfields; fields[RF_MONTH], fields[RF_DAY], fields[RF_TOD]); r.r_name = ecpyalloc(fields[RF_NAME]); r.r_abbrvar = ecpyalloc(fields[RF_ABBRVAR]); + if (max_abbrvar_len < strlen(r.r_abbrvar)) + max_abbrvar_len = strlen(r.r_abbrvar); rules = (struct rule *) (void *) erealloc((char *) rules, (int) ((nrules + 1) * sizeof *rules)); rules[nrules++] = r; @@ -1045,6 +1060,8 @@ const int iscont; } z.z_rule = ecpyalloc(fields[i_rule]); z.z_format = ecpyalloc(fields[i_format]); + if (max_format_len < strlen(z.z_format)) + max_format_len = strlen(z.z_format); hasuntil = nfields > i_untilyear; if (hasuntil) { z.z_untilrule.r_filename = filename; @@ -1065,7 +1082,9 @@ const int iscont; zones[nzones - 1].z_untiltime > min_time && zones[nzones - 1].z_untiltime < max_time && zones[nzones - 1].z_untiltime >= z.z_untiltime) { - error(_("Zone continuation line end time is not after end time of previous line")); + error(_( +"Zone continuation line end time is not after end time of previous line" + )); return FALSE; } } @@ -1089,7 +1108,7 @@ const int nfields; register int i, j; int year, month, day; long dayoff, tod; - time_t t; + zic_t t; if (nfields != LEAP_FIELDS) { error(_("wrong number of fields on Leap line")); @@ -1098,12 +1117,17 @@ const int nfields; dayoff = 0; cp = fields[LP_YEAR]; if (sscanf(cp, scheck(cp, "%d"), &year) != 1) { - /* - * Leapin' Lizards! - */ - error(_("invalid leaping year")); - return; + /* + ** Leapin' Lizards! + */ + error(_("invalid leaping year")); + return; } + if (!leapseen || leapmaxyear < year) + leapmaxyear = year; + if (!leapseen || leapminyear > year) + leapminyear = year; + leapseen = TRUE; j = EPOCH_YEAR; while (j != year) { if (year > j) { @@ -1133,7 +1157,7 @@ const int nfields; return; } dayoff = oadd(dayoff, eitol(day - 1)); - if (dayoff < 0 && !TYPE_SIGNED(time_t)) { + if (dayoff < 0 && !TYPE_SIGNED(zic_t)) { error(_("time before zero")); return; } @@ -1145,7 +1169,7 @@ const int nfields; error(_("time too large")); return; } - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; tod = gethms(fields[LP_TIME], _("invalid time of day"), FALSE); cp = fields[LP_CORR]; { @@ -1169,7 +1193,9 @@ const int nfields; return; } if ((lp = byword(fields[LP_ROLL], leap_types)) == NULL) { - error(_("illegal Rolling/Stationary field on Leap line")); + error(_( + "illegal Rolling/Stationary field on Leap line" + )); return; } leapadd(tadd(t, tod), positive, lp->l_value, count); @@ -1256,7 +1282,8 @@ const char * const timep; */ cp = loyearp; lp = byword(cp, begin_years); - if (lp != NULL) switch ((int) lp->l_value) { + rp->r_lowasnum = lp == NULL; + if (!rp->r_lowasnum) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_loyear = INT_MIN; break; @@ -1269,14 +1296,11 @@ const char * const timep; } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_loyear) != 1) { error(_("invalid starting year")); return; - } else if (noise) { - if (rp->r_loyear < min_year_representable) - warning(_("starting year too low to be represented")); - else if (rp->r_loyear > max_year_representable) - warning(_("starting year too high to be represented")); } cp = hiyearp; - if ((lp = byword(cp, end_years)) != NULL) switch ((int) lp->l_value) { + lp = byword(cp, end_years); + rp->r_hiwasnum = lp == NULL; + if (!rp->r_hiwasnum) switch ((int) lp->l_value) { case YR_MINIMUM: rp->r_hiyear = INT_MIN; break; @@ -1292,11 +1316,6 @@ const char * const timep; } else if (sscanf(cp, scheck(cp, "%d"), &rp->r_hiyear) != 1) { error(_("invalid ending year")); return; - } else if (noise) { - if (rp->r_loyear < min_year_representable) - warning(_("ending year too low to be represented")); - else if (rp->r_loyear > max_year_representable) - warning(_("ending year too high to be represented")); } if (rp->r_loyear > rp->r_hiyear) { error(_("starting year greater than ending year")); @@ -1311,8 +1330,6 @@ const char * const timep; } rp->r_yrtype = ecpyalloc(typep); } - if (rp->r_loyear < min_year && rp->r_loyear > 0) - min_year = rp->r_loyear; /* ** Day work. ** Accept things such as: @@ -1366,12 +1383,24 @@ const long val; char * const buf; { register int i; - register long shift; + register int shift; for (i = 0, shift = 24; i < 4; ++i, shift -= 8) buf[i] = val >> shift; } +static void +convert64(val, buf) +const zic_t val; +char * const buf; +{ + register int i; + register int shift; + + for (i = 0, shift = 56; i < 8; ++i, shift -= 8) + buf[i] = val >> shift; +} + static void puttzcode(val, fp) const long val; @@ -1383,28 +1412,50 @@ FILE * const fp; (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); } +static void +puttzcode64(val, fp) +const zic_t val; +FILE * const fp; +{ + char buf[8]; + + convert64(val, buf); + (void) fwrite((void *) buf, (size_t) sizeof buf, (size_t) 1, fp); +} + static int atcomp(avp, bvp) -void * avp; -void * bvp; +const void * avp; +const void * bvp; { - if (((struct attype *) avp)->at < ((struct attype *) bvp)->at) - return -1; - else if (((struct attype *) avp)->at > ((struct attype *) bvp)->at) - return 1; - else return 0; + const zic_t a = ((const struct attype *) avp)->at; + const zic_t b = ((const struct attype *) bvp)->at; + + return (a < b) ? -1 : (a > b); +} + +static int +is32(x) +const zic_t x; +{ + return INT32_MIN <= x && x <= INT32_MAX; } static void -writezone(name) +writezone(name, string) const char * const name; +const char * const string; { - register FILE * fp; - register int i, j; - static char * fullname; - static struct tzhead tzh; - time_t ats[TZ_MAX_TIMES]; - unsigned char types[TZ_MAX_TIMES]; + register FILE * fp; + register int i, j; + register int leapcnt32, leapi32; + register int timecnt32, timei32; + register int pass; + static char * fullname; + static const struct tzhead tzh0; + static struct tzhead tzh; + zic_t ats[TZ_MAX_TIMES]; + unsigned char types[TZ_MAX_TIMES]; /* ** Sort. @@ -1427,14 +1478,13 @@ const char * const name; while (fromi < timecnt && attypes[fromi].type == 0) ++fromi; /* handled by default rule */ for ( ; fromi < timecnt; ++fromi) { - if (toi != 0 - && ((attypes[fromi].at - + gmtoffs[attypes[toi - 1].type]) - <= (attypes[toi - 1].at - + gmtoffs[toi == 1 ? 0 - : attypes[toi - 2].type]))) { - attypes[toi - 1].type = attypes[fromi].type; - continue; + if (toi != 0 && ((attypes[fromi].at + + gmtoffs[attypes[toi - 1].type]) <= + (attypes[toi - 1].at + gmtoffs[toi == 1 ? 0 + : attypes[toi - 2].type]))) { + attypes[toi - 1].type = + attypes[fromi].type; + continue; } if (toi == 0 || attypes[toi - 1].type != attypes[fromi].type) @@ -1449,6 +1499,36 @@ const char * const name; ats[i] = attypes[i].at; types[i] = attypes[i].type; } + /* + ** Correct for leap seconds. + */ + for (i = 0; i < timecnt; ++i) { + j = leapcnt; + while (--j >= 0) + if (ats[i] > trans[j] - corr[j]) { + ats[i] = tadd(ats[i], corr[j]); + break; + } + } + /* + ** Figure out 32-bit-limited starts and counts. + */ + timecnt32 = timecnt; + timei32 = 0; + leapcnt32 = leapcnt; + leapi32 = 0; + while (timecnt32 > 0 && !is32(ats[timecnt32 - 1])) + --timecnt32; + while (timecnt32 > 0 && !is32(ats[timei32])) { + --timecnt32; + ++timei32; + } + while (leapcnt32 > 0 && !is32(trans[leapcnt32 - 1])) + --leapcnt32; + while (leapcnt32 > 0 && !is32(trans[leapi32])) { + --leapcnt32; + ++leapi32; + } fullname = erealloc(fullname, (int) (strlen(directory) + 1 + strlen(name) + 1)); (void) sprintf(fullname, "%s/%s", directory, name); @@ -1461,70 +1541,154 @@ const char * const name; if ((fp = fopen(fullname, "wb")) == NULL) { if (mkdirs(fullname) != 0) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); if ((fp = fopen(fullname, "wb")) == NULL) err(EXIT_FAILURE, _("can't create %s"), fullname); } - convert(eitol(typecnt), tzh.tzh_ttisgmtcnt); - convert(eitol(typecnt), tzh.tzh_ttisstdcnt); - convert(eitol(leapcnt), tzh.tzh_leapcnt); - convert(eitol(timecnt), tzh.tzh_timecnt); - convert(eitol(typecnt), tzh.tzh_typecnt); - convert(eitol(charcnt), tzh.tzh_charcnt); - (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); -#define DO(field) (void) fwrite((void *) tzh.field, (size_t) sizeof tzh.field, (size_t) 1, fp) - DO(tzh_magic); - DO(tzh_reserved); - DO(tzh_ttisgmtcnt); - DO(tzh_ttisstdcnt); - DO(tzh_leapcnt); - DO(tzh_timecnt); - DO(tzh_typecnt); - DO(tzh_charcnt); + for (pass = 1; pass <= 2; ++pass) { + register int thistimei, thistimecnt; + register int thisleapi, thisleapcnt; + register int thistimelim, thisleaplim; + int writetype[TZ_MAX_TIMES]; + int typemap[TZ_MAX_TYPES]; + register int thistypecnt; + char thischars[TZ_MAX_CHARS]; + char thischarcnt; + int indmap[TZ_MAX_CHARS]; + + if (pass == 1) { + thistimei = timei32; + thistimecnt = timecnt32; + thisleapi = leapi32; + thisleapcnt = leapcnt32; + } else { + thistimei = 0; + thistimecnt = timecnt; + thisleapi = 0; + thisleapcnt = leapcnt; + } + thistimelim = thistimei + thistimecnt; + thisleaplim = thisleapi + thisleapcnt; + for (i = 0; i < typecnt; ++i) + writetype[i] = thistimecnt == timecnt; + if (thistimecnt == 0) { + /* + ** No transition times fall in the current + ** (32- or 64-bit) window. + */ + if (typecnt != 0) + writetype[typecnt - 1] = TRUE; + } else { + for (i = thistimei - 1; i < thistimelim; ++i) + if (i >= 0) + writetype[types[i]] = TRUE; + /* + ** For America/Godthab and Antarctica/Palmer + */ + if (thistimei == 0) + writetype[0] = TRUE; + } + thistypecnt = 0; + for (i = 0; i < typecnt; ++i) + typemap[i] = writetype[i] ? thistypecnt++ : -1; + for (i = 0; i < sizeof indmap / sizeof indmap[0]; ++i) + indmap[i] = -1; + thischarcnt = 0; + for (i = 0; i < typecnt; ++i) { + register char * thisabbr; + + if (!writetype[i]) + continue; + if (indmap[abbrinds[i]] >= 0) + continue; + thisabbr = &chars[abbrinds[i]]; + for (j = 0; j < thischarcnt; ++j) + if (strcmp(&thischars[j], thisabbr) == 0) + break; + if (j == thischarcnt) { + (void) strcpy(&thischars[(int) thischarcnt], + thisabbr); + thischarcnt += strlen(thisabbr) + 1; + } + indmap[abbrinds[i]] = j; + } +#define DO(field) (void) fwrite((void *) tzh.field, \ + (size_t) sizeof tzh.field, (size_t) 1, fp) + tzh = tzh0; + (void) strncpy(tzh.tzh_magic, TZ_MAGIC, sizeof tzh.tzh_magic); + tzh.tzh_version[0] = ZIC_VERSION; + convert(eitol(thistypecnt), tzh.tzh_ttisgmtcnt); + convert(eitol(thistypecnt), tzh.tzh_ttisstdcnt); + convert(eitol(thisleapcnt), tzh.tzh_leapcnt); + convert(eitol(thistimecnt), tzh.tzh_timecnt); + convert(eitol(thistypecnt), tzh.tzh_typecnt); + convert(eitol(thischarcnt), tzh.tzh_charcnt); + DO(tzh_magic); + DO(tzh_version); + DO(tzh_reserved); + DO(tzh_ttisgmtcnt); + DO(tzh_ttisstdcnt); + DO(tzh_leapcnt); + DO(tzh_timecnt); + DO(tzh_typecnt); + DO(tzh_charcnt); #undef DO - for (i = 0; i < timecnt; ++i) { - j = leapcnt; - while (--j >= 0) - if (ats[i] >= trans[j]) { - ats[i] = tadd(ats[i], corr[j]); - break; + for (i = thistimei; i < thistimelim; ++i) + if (pass == 1) + puttzcode((long) ats[i], fp); + else puttzcode64(ats[i], fp); + for (i = thistimei; i < thistimelim; ++i) { + unsigned char uc; + + uc = typemap[types[i]]; + (void) fwrite((void *) &uc, + (size_t) sizeof uc, + (size_t) 1, + fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) { + puttzcode(gmtoffs[i], fp); + (void) putc(isdsts[i], fp); + (void) putc((unsigned char) indmap[abbrinds[i]], fp); } - puttzcode((long) ats[i], fp); + if (thischarcnt != 0) + (void) fwrite((void *) thischars, + (size_t) sizeof thischars[0], + (size_t) thischarcnt, fp); + for (i = thisleapi; i < thisleaplim; ++i) { + register zic_t todo; + + if (roll[i]) { + if (timecnt == 0 || trans[i] < ats[0]) { + j = 0; + while (isdsts[j]) + if (++j >= typecnt) { + j = 0; + break; + } + } else { + j = 1; + while (j < timecnt && + trans[i] >= ats[j]) + ++j; + j = types[j - 1]; + } + todo = tadd(trans[i], -gmtoffs[j]); + } else todo = trans[i]; + if (pass == 1) + puttzcode((long) todo, fp); + else puttzcode64(todo, fp); + puttzcode(corr[i], fp); + } + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisstds[i], fp); + for (i = 0; i < typecnt; ++i) + if (writetype[i]) + (void) putc(ttisgmts[i], fp); } - if (timecnt > 0) - (void) fwrite((void *) types, (size_t) sizeof types[0], - (size_t) timecnt, fp); - for (i = 0; i < typecnt; ++i) { - puttzcode((long) gmtoffs[i], fp); - (void) putc(isdsts[i], fp); - (void) putc(abbrinds[i], fp); - } - if (charcnt != 0) - (void) fwrite((void *) chars, (size_t) sizeof chars[0], - (size_t) charcnt, fp); - for (i = 0; i < leapcnt; ++i) { - if (roll[i]) { - if (timecnt == 0 || trans[i] < ats[0]) { - j = 0; - while (isdsts[j]) - if (++j >= typecnt) { - j = 0; - break; - } - } else { - j = 1; - while (j < timecnt && trans[i] >= ats[j]) - ++j; - j = types[j - 1]; - } - puttzcode((long) tadd(trans[i], -gmtoffs[j]), fp); - } else puttzcode((long) trans[i], fp); - puttzcode((long) corr[i], fp); - } - for (i = 0; i < typecnt; ++i) - (void) putc(ttisstds[i], fp); - for (i = 0; i < typecnt; ++i) - (void) putc(ttisgmts[i], fp); + (void) fprintf(fp, "\n%s\n", string); if (ferror(fp) || fclose(fp)) errx(EXIT_FAILURE, _("error writing %s"), fullname); if (chmod(fullname, mflag) < 0) @@ -1537,21 +1701,223 @@ const char * const name; } static void -doabbr(abbr, format, letters, isdst) +doabbr(abbr, format, letters, isdst, doquotes) char * const abbr; const char * const format; const char * const letters; const int isdst; +const int doquotes; { - if (strchr(format, '/') == NULL) { + register char * cp; + register char * slashp; + register int len; + + slashp = strchr(format, '/'); + if (slashp == NULL) { if (letters == NULL) (void) strcpy(abbr, format); else (void) sprintf(abbr, format, letters); - } else if (isdst) - (void) strcpy(abbr, strchr(format, '/') + 1); - else { - (void) strcpy(abbr, format); - *strchr(abbr, '/') = '\0'; + } else if (isdst) { + (void) strcpy(abbr, slashp + 1); + } else { + if (slashp > format) + (void) strncpy(abbr, format, + (unsigned) (slashp - format)); + abbr[slashp - format] = '\0'; + } + if (!doquotes) + return; + for (cp = abbr; *cp != '\0'; ++cp) + if (strchr("ABCDEFGHIJKLMNOPQRSTUVWXYZ", *cp) == NULL && + strchr("abcdefghijklmnopqrstuvwxyz", *cp) == NULL) + break; + len = strlen(abbr); + if (len > 0 && *cp == '\0') + return; + abbr[len + 2] = '\0'; + abbr[len + 1] = '>'; + for ( ; len > 0; --len) + abbr[len] = abbr[len - 1]; + abbr[0] = '<'; +} + +static void +updateminmax(x) +const int x; +{ + if (min_year > x) + min_year = x; + if (max_year < x) + max_year = x; +} + +static int +stringoffset(result, offset) +char * result; +long offset; +{ + register int hours; + register int minutes; + register int seconds; + + result[0] = '\0'; + if (offset < 0) { + (void) strcpy(result, "-"); + offset = -offset; + } + seconds = offset % SECSPERMIN; + offset /= SECSPERMIN; + minutes = offset % MINSPERHOUR; + offset /= MINSPERHOUR; + hours = offset; + if (hours >= HOURSPERDAY) { + result[0] = '\0'; + return -1; + } + (void) sprintf(end(result), "%d", hours); + if (minutes != 0 || seconds != 0) { + (void) sprintf(end(result), ":%02d", minutes); + if (seconds != 0) + (void) sprintf(end(result), ":%02d", seconds); + } + return 0; +} + +static int +stringrule(result, rp, dstoff, gmtoff) +char * result; +const struct rule * const rp; +const long dstoff; +const long gmtoff; +{ + register long tod; + + result = end(result); + if (rp->r_dycode == DC_DOM) { + register int month, total; + + if (rp->r_dayofmonth == 29 && rp->r_month == TM_FEBRUARY) + return -1; + total = 0; + for (month = 0; month < rp->r_month; ++month) + total += len_months[0][month]; + (void) sprintf(result, "J%d", total + rp->r_dayofmonth); + } else { + register int week; + + if (rp->r_dycode == DC_DOWGEQ) { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if ((week - 1) * DAYSPERWEEK + 1 != rp->r_dayofmonth) + return -1; + } else if (rp->r_dycode == DC_DOWLEQ) { + if (rp->r_dayofmonth == len_months[1][rp->r_month]) + week = 5; + else { + week = 1 + rp->r_dayofmonth / DAYSPERWEEK; + if (week * DAYSPERWEEK - 1 != rp->r_dayofmonth) + return -1; + } + } else return -1; /* "cannot happen" */ + (void) sprintf(result, "M%d.%d.%d", + rp->r_month + 1, week, rp->r_wday); + } + tod = rp->r_tod; + if (rp->r_todisgmt) + tod += gmtoff; + if (rp->r_todisstd && rp->r_stdoff == 0) + tod += dstoff; + if (tod < 0) { + result[0] = '\0'; + return -1; + } + if (tod != 2 * SECSPERMIN * MINSPERHOUR) { + (void) strcat(result, "/"); + if (stringoffset(end(result), tod) != 0) + return -1; + } + return 0; +} + +static void +stringzone(result, zpfirst, zonecount) +char * result; +const struct zone * const zpfirst; +const int zonecount; +{ + register const struct zone * zp; + register struct rule * rp; + register struct rule * stdrp; + register struct rule * dstrp; + register int i; + register const char * abbrvar; + + result[0] = '\0'; + zp = zpfirst + zonecount - 1; + stdrp = dstrp = NULL; + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (rp->r_hiwasnum || rp->r_hiyear != INT_MAX) + continue; + if (rp->r_yrtype != NULL) + continue; + if (rp->r_stdoff == 0) { + if (stdrp == NULL) + stdrp = rp; + else return; + } else { + if (dstrp == NULL) + dstrp = rp; + else return; + } + } + if (stdrp == NULL && dstrp == NULL) { + /* + ** There are no rules running through "max". + ** Let's find the latest rule. + */ + for (i = 0; i < zp->z_nrules; ++i) { + rp = &zp->z_rules[i]; + if (stdrp == NULL || rp->r_hiyear > stdrp->r_hiyear || + (rp->r_hiyear == stdrp->r_hiyear && + rp->r_month > stdrp->r_month)) + stdrp = rp; + } + if (stdrp != NULL && stdrp->r_stdoff != 0) + return; /* We end up in DST (a POSIX no-no). */ + /* + ** Horrid special case: if year is 2037, + ** presume this is a zone handled on a year-by-year basis; + ** do not try to apply a rule to the zone. + */ + if (stdrp != NULL && stdrp->r_hiyear == 2037) + return; + } + if (stdrp == NULL && zp->z_nrules != 0) + return; + abbrvar = (stdrp == NULL) ? "" : stdrp->r_abbrvar; + doabbr(result, zp->z_format, abbrvar, FALSE, TRUE); + if (stringoffset(end(result), -zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + if (dstrp == NULL) + return; + doabbr(end(result), zp->z_format, dstrp->r_abbrvar, TRUE, TRUE); + if (dstrp->r_stdoff != SECSPERMIN * MINSPERHOUR) + if (stringoffset(end(result), + -(zp->z_gmtoff + dstrp->r_stdoff)) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, dstrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; + } + (void) strcat(result, ","); + if (stringrule(result, stdrp, dstrp->r_stdoff, zp->z_gmtoff) != 0) { + result[0] = '\0'; + return; } } @@ -1564,7 +1930,7 @@ const int zonecount; register struct rule * rp; register int i, j; register int usestart, useuntil; - register time_t starttime, untiltime; + register zic_t starttime, untiltime; register long gmtoff; register long stdoff; register int year; @@ -1572,8 +1938,17 @@ const int zonecount; register int startttisstd; register int startttisgmt; register int type; - char startbuf[BUFSIZ]; + register char * startbuf; + register char * ab; + register char * envvar; + register int max_abbr_len; + register int max_envvar_len; + max_abbr_len = 2 + max_format_len + max_abbrvar_len; + max_envvar_len = 2 * max_abbr_len + 5 * 9; + startbuf = emalloc(max_abbr_len + 1); + ab = emalloc(max_abbr_len + 1); + envvar = emalloc(max_envvar_len + 1); INITIALIZE(untiltime); INITIALIZE(starttime); /* @@ -1583,11 +1958,57 @@ const int zonecount; typecnt = 0; charcnt = 0; /* - ** Thanks to Earl Chew (earl@dnd.icp.nec.com.au) + ** Thanks to Earl Chew ** for noting the need to unconditionally initialize startttisstd. */ startttisstd = FALSE; startttisgmt = FALSE; + min_year = max_year = EPOCH_YEAR; + if (leapseen) { + updateminmax(leapminyear); + updateminmax(leapmaxyear + (leapmaxyear < INT_MAX)); + } + for (i = 0; i < zonecount; ++i) { + zp = &zpfirst[i]; + if (i < zonecount - 1) + updateminmax(zp->z_untilrule.r_loyear); + for (j = 0; j < zp->z_nrules; ++j) { + rp = &zp->z_rules[j]; + if (rp->r_lowasnum) + updateminmax(rp->r_loyear); + if (rp->r_hiwasnum) + updateminmax(rp->r_hiyear); + } + } + /* + ** Generate lots of data if a rule can't cover all future times. + */ + stringzone(envvar, zpfirst, zonecount); + if (noise && envvar[0] == '\0') { + register char * wp; + +wp = ecpyalloc(_("no POSIX environment variable for zone")); + wp = ecatalloc(wp, " "); + wp = ecatalloc(wp, zpfirst->z_name); + warning(wp); + ifree(wp); + } + if (envvar[0] == '\0') { + if (min_year >= INT_MIN + YEARSPERREPEAT) + min_year -= YEARSPERREPEAT; + else min_year = INT_MIN; + if (max_year <= INT_MAX - YEARSPERREPEAT) + max_year += YEARSPERREPEAT; + else max_year = INT_MAX; + } + /* + ** For the benefit of older systems, + ** generate data from 1900 through 2037. + */ + if (min_year > 1900) + min_year = 1900; + if (max_year < 2037) + max_year = 2037; for (i = 0; i < zonecount; ++i) { /* ** A guess that may well be corrected later. @@ -1605,7 +2026,7 @@ const int zonecount; if (zp->z_nrules == 0) { stdoff = zp->z_stdoff; doabbr(startbuf, zp->z_format, - (char *) NULL, stdoff != 0); + (char *) NULL, stdoff != 0, FALSE); type = addtype(oadd(zp->z_gmtoff, stdoff), startbuf, stdoff != 0, startttisstd, startttisgmt); @@ -1633,9 +2054,8 @@ const int zonecount; } for ( ; ; ) { register int k; - register time_t jtime, ktime; + register zic_t jtime, ktime; register long offset; - char buf[BUFSIZ]; INITIALIZE(ktime); if (useuntil) { @@ -1691,23 +2111,27 @@ const int zonecount; stdoff); doabbr(startbuf, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0); + rp->r_stdoff != 0, + FALSE); continue; } if (*startbuf == '\0' && - startoff == oadd(zp->z_gmtoff, - stdoff)) { - doabbr(startbuf, zp->z_format, - rp->r_abbrvar, - rp->r_stdoff != 0); + startoff == oadd(zp->z_gmtoff, + stdoff)) { + doabbr(startbuf, + zp->z_format, + rp->r_abbrvar, + rp->r_stdoff != + 0, + FALSE); } } eats(zp->z_filename, zp->z_linenum, rp->r_filename, rp->r_linenum); - doabbr(buf, zp->z_format, rp->r_abbrvar, - rp->r_stdoff != 0); + doabbr(ab, zp->z_format, rp->r_abbrvar, + rp->r_stdoff != 0, FALSE); offset = oadd(zp->z_gmtoff, rp->r_stdoff); - type = addtype(offset, buf, rp->r_stdoff != 0, + type = addtype(offset, ab, rp->r_stdoff != 0, rp->r_todisstd, rp->r_todisgmt); addtt(ktime, type); } @@ -1740,12 +2164,15 @@ error(_("can't determine time zone abbreviation to use just after until time")); starttime = tadd(starttime, -gmtoff); } } - writezone(zpfirst->z_name); + writezone(zpfirst->z_name, envvar); + ifree(startbuf); + ifree(ab); + ifree(envvar); } static void addtt(starttime, type) -const time_t starttime; +const zic_t starttime; int type; { if (starttime <= min_time || @@ -1764,7 +2191,7 @@ int type; } if (timecnt >= TZ_MAX_TIMES) { error(_("too many transitions?!")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } attypes[timecnt].at = starttime; attypes[timecnt].type = type; @@ -1783,15 +2210,15 @@ const int ttisgmt; if (isdst != TRUE && isdst != FALSE) { error(_("internal error - addtype called with bad isdst")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (ttisstd != TRUE && ttisstd != FALSE) { error(_("internal error - addtype called with bad ttisstd")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } if (ttisgmt != TRUE && ttisgmt != FALSE) { error(_("internal error - addtype called with bad ttisgmt")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } /* ** See if there's already an entry for this zone type. @@ -1810,7 +2237,11 @@ const int ttisgmt; */ if (typecnt >= TZ_MAX_TYPES) { error(_("too many local time types")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); + } + if (! (-1L - 2147483647L <= gmtoff && gmtoff <= 2147483647L)) { + error(_("UTC offset out of range")); + exit(EXIT_FAILURE); } gmtoffs[i] = gmtoff; isdsts[i] = isdst; @@ -1829,7 +2260,7 @@ const int ttisgmt; static void leapadd(t, positive, rolling, count) -const time_t t; +const zic_t t; const int positive; const int rolling; int count; @@ -1838,13 +2269,13 @@ int count; if (leapcnt + (positive ? count : 1) > TZ_MAX_LEAPS) { error(_("too many leap seconds")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } for (i = 0; i < leapcnt; ++i) if (t <= trans[i]) { if (t == trans[i]) { error(_("repeated leap second moment")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } break; } @@ -1862,7 +2293,7 @@ int count; } static void -adjleap P((void)) +adjleap(void) { register int i; register long last = 0; @@ -1898,7 +2329,7 @@ const char * const type; error(_("wild result from command execution")); warnx(_("command was '%s', result was %d"), buf, result); for ( ; ; ) - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } static int @@ -1979,8 +2410,9 @@ register char * cp; emalloc((int) ((strlen(cp) + 1) * sizeof *array)); nsubs = 0; for ( ; ; ) { - while (isascii(*cp) && isspace((unsigned char) *cp)) - ++cp; + while (isascii((unsigned char) *cp) && + isspace((unsigned char) *cp)) + ++cp; if (*cp == '\0' || *cp == '#') break; array[nsubs++] = dp = cp; @@ -2014,17 +2446,17 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return t; } -static time_t +static zic_t tadd(t1, t2) -const time_t t1; +const zic_t t1; const long t2; { - register time_t t; + register zic_t t; if (t1 == max_time && t2 > 0) return max_time; @@ -2033,7 +2465,7 @@ const long t2; t = t1 + t2; if ((t2 > 0 && t <= t1) || (t2 < 0 && t >= t1)) { error(_("time overflow")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } return t; } @@ -2043,14 +2475,14 @@ const long t2; ** 1970, 00:00 LOCAL time - in that year that the rule refers to. */ -static time_t +static zic_t rpytime(rp, wantedy) register const struct rule * const rp; register const int wantedy; { register int y, m, i; register long dayoff; /* with a nod to Margaret O. */ - register time_t t; + register zic_t t; if (wantedy == INT_MIN) return min_time; @@ -2080,7 +2512,7 @@ register const int wantedy; --i; else { error(_("use of 2/29 in non leap-year")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } } --i; @@ -2114,16 +2546,15 @@ register const int wantedy; } if (i < 0 || i >= len_months[isleap(y)][m]) { if (noise) - warning(_("rule goes past start/end of month--will not work with pre-2004 versions of zic")); + warning(_("rule goes past start/end of month--\ +will not work with pre-2004 versions of zic")); } } - if (dayoff < 0 && !TYPE_SIGNED(time_t)) - return min_time; if (dayoff < min_time / SECSPERDAY) return min_time; if (dayoff > max_time / SECSPERDAY) return max_time; - t = (time_t) dayoff * SECSPERDAY; + t = (zic_t) dayoff * SECSPERDAY; return tadd(t, rp->r_tod); } @@ -2133,10 +2564,48 @@ const char * const string; { register int i; + if (strcmp(string, GRANDPARENTED) != 0) { + register const char * cp; + register char * wp; + + /* + ** Want one to ZIC_MAX_ABBR_LEN_WO_WARN alphabetics + ** optionally followed by a + or - and a number from 1 to 14. + */ + cp = string; + wp = NULL; + while (isascii((unsigned char) *cp) && + isalpha((unsigned char) *cp)) + ++cp; + if (cp - string == 0) +wp = _("time zone abbreviation lacks alphabetic at start"); + if (noise && cp - string > 3) +wp = _("time zone abbreviation has more than 3 alphabetics"); + if (cp - string > ZIC_MAX_ABBR_LEN_WO_WARN) +wp = _("time zone abbreviation has too many alphabetics"); + if (wp == NULL && (*cp == '+' || *cp == '-')) { + ++cp; + if (isascii((unsigned char) *cp) && + isdigit((unsigned char) *cp)) + if (*cp++ == '1' && + *cp >= '0' && *cp <= '4') + ++cp; + } + if (*cp != '\0') +wp = _("time zone abbreviation differs from POSIX standard"); + if (wp != NULL) { + wp = ecpyalloc(wp); + wp = ecatalloc(wp, " ("); + wp = ecatalloc(wp, string); + wp = ecatalloc(wp, ")"); + warning(wp); + ifree(wp); + } + } i = strlen(string) + 1; if (charcnt + i > TZ_MAX_CHARS) { error(_("too many, or too long, time zone abbreviations")); - (void) exit(EXIT_FAILURE); + exit(EXIT_FAILURE); } (void) strcpy(&chars[charcnt], string); charcnt += eitol(i); @@ -2144,7 +2613,7 @@ const char * const string; static int mkdirs(argname) -char * const argname; +char * argname; { register char * name; register char * cp; From 98ded69774d02759a5a4a71b980db224d84c3599 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sat, 23 May 2009 06:40:09 +0000 Subject: [PATCH 425/544] [patch] update share/misc/iso639 Updated against http://www.loc.gov/standards/iso639-2/langhome.html Snapshot was taken on 16 September 2008. PR: conf/127422 MFC after: 1 week --- share/misc/iso639 | 189 +++++++++++++++++++++++++++++----------------- 1 file changed, 118 insertions(+), 71 deletions(-) diff --git a/share/misc/iso639 b/share/misc/iso639 index 57d62a0c4050..ffe873c1790a 100644 --- a/share/misc/iso639 +++ b/share/misc/iso639 @@ -37,43 +37,48 @@ ab abk abk Abkhazian ace ace Achinese ach ach Acoli ada ada Adangme + ady ady Adyghe; Adygei afa afa Afro-Asiatic (Other) afh afh Afrihili af afr afr Afrikaans - aka aka Akan + ain ain Ainu +ak aka aka Akan akk akk Akkadian sq alb sqi Albanian ale ale Aleut alg alg Algonquian languages + alt alt Southern Altai am amh amh Amharic ang ang English, Old (ca.450-1100) + anp anp Angika apa apa Apache languages ar ara ara Arabic - arc arc Aramaic + arc arc Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE) +an arg arg Aragonese hy arm hye Armenian - arn arn Araucanian + arn arn Mapudungun; Mapuche arp arp Arapaho art art Artificial (Other) arw arw Arawak as asm asm Assamese - ast ast Asturian; Bable + ast ast Asturian; Bable; Leonese; Asturleonese ath ath Athapascan languages aus aus Australian languages - ava ava Avaric +av ava ava Avaric ae ave ave Avestan awa awa Awadhi ay aym aym Aymara az aze aze Azerbaijani - bad bad Banda + bad bad Banda languages bai bai Bamileke languages ba bak bak Bashkir bal bal Baluchi - bam bam Bambara +bm bam bam Bambara ban ban Balinese eu baq eus Basque bas bas Basa bat bat Baltic (Other) - bej bej Beja + bej bej Beja; Bedawiyet be bel bel Belarusian bem bem Bemba bn ben ben Bengali @@ -81,22 +86,23 @@ bn ben ben Bengali bho bho Bhojpuri bh bih bih Bihari bik bik Bikol - bin bin Bini + bin bin Bini; Edo bi bis bis Bislama bla bla Siksika bnt bnt Bantu (Other) bs bos bos Bosnian bra bra Braj br bre bre Breton - btk btk Batak (Indonesia) + btk btk Batak languages bua bua Buriat bug bug Buginese bg bul bul Bulgarian my bur mya Burmese + byn byn Blin; Bilin cad cad Caddo cai cai Central American Indian (Other) - car car Carib -ca cat cat Catalan + car car Galibi Carib +ca cat cat Catalan; Valencian cau cau Caucasian (Other) ceb ceb Cebuano cel cel Celtic (Other) @@ -109,9 +115,9 @@ zh chi zho Chinese chm chm Mari chn chn Chinook jargon cho cho Choctaw - chp chp Chipewyan + chp chp Chipewyan; Dene Suline chr chr Cherokee -cu chu chu Church Slavic +cu chu chu Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic cv chv chv Chuvash chy chy Cheyenne cmc cmc Chamic languages @@ -121,23 +127,27 @@ co cos cos Corsican cpe cpe Creoles and pidgins, English based (Other) cpf cpf Creoles and pidgins, French-based (Other) cpp cpp Creoles and pidgins, Portuguese-based (Other) - cre cre Cree +cr cre cre Cree + crh crh Crimean Tatar; Crimean Turkish crp crp Creoles and pidgins (Other) + csb csb Kashubian cus cus Cushitic (Other) cs cze ces Czech dak dak Dakota da dan dan Danish - day day Dayak + dar dar Dargwa + day day Land Dayak languages del del Delaware den den Slave (Athapascan) dgr dgr Dogrib din din Dinka - div div Divehi +dv div div Divehi; Dhivehi; Maldivian doi doi Dogri dra dra Dravidian (Other) + dsb dsb Lower Sorbian dua dua Duala dum dum Dutch, Middle (ca.1050-1350) -nl dut nld Dutch +nl dut nld Dutch; Flemish dyu dyu Dyula dz dzo dzo Dzongkha efi efi Efik @@ -148,20 +158,23 @@ en eng eng English enm enm English, Middle (1100-1500) eo epo epo Esperanto et est est Estonian - ewe ewe Ewe +ee ewe ewe Ewe ewo ewo Ewondo fan fan Fang fo fao fao Faroese fat fat Fanti fj fij fij Fijian + fil fil Filipino; Pilipino fi fin fin Finnish fiu fiu Finno-Ugrian (Other) fon fon Fon fr fre fra French frm frm French, Middle (ca.1400-1600) fro fro French, Old (842-ca.1400) -fy fry fry Frisian - ful ful Fulah + frr frr Northern Frisian + frs frs Eastern Frisian +fy fry fry Western Frisian +ff ful ful Fulah fur fur Friulian gaa gaa Ga gay gay Gayo @@ -171,9 +184,9 @@ ka geo kat Georgian de ger deu German gez gez Geez gil gil Gilbertese -gd gla gla Gaelic (Scots) +gd gla gla Gaelic; Scottish Gaelic ga gle gle Irish -gl glg glg Gallegan +gl glg glg Galician gv glv glv Manx gmh gmh German, Middle High (ca.1050-1500) goh goh German, Old High (ca.750-1050) @@ -184,9 +197,11 @@ gv glv glv Manx grc grc Greek, Ancient (to 1453) el gre ell Greek, Modern (1453-) gn grn grn Guarani + gsw gsw Swiss German; Alemannic; Alsatian gu guj guj Gujarati - gwi gwi Gwich´in + gwi gwi Gwich'in hai hai Haida +ht hat hat Haitian; Haitian Creole ha hau hau Hausa haw haw Hawaiian he heb heb Hebrew @@ -197,55 +212,64 @@ hi hin hin Hindi hit hit Hittite hmn hmn Hmong ho hmo hmo Hiri Motu +hr hrv hrv Croatian + hsb hsb Upper Sorbian hu hun hun Hungarian hup hup Hupa iba iba Iban - ibo ibo Igbo +ig ibo ibo Igbo is ice isl Icelandic - ijo ijo Ijo +io ido ido Ido +ii iii iii Sichuan Yi; Nuosu + ijo ijo Ijo languages iu iku iku Inuktitut -ie ile ile Interlingue +ie ile ile Interlingue; Occidental ilo ilo Iloko -ia ina ina Interlingua (International Auxiliary Language Association) +ia ina ina Interlingua (International Auxiliary Language Association) inc inc Indic (Other) id ind ind Indonesian ine ine Indo-European (Other) + inh inh Ingush ik ipk ipk Inupiaq ira ira Iranian (Other) iro iro Iroquoian languages it ita ita Italian jv jav jav Javanese + jbo jbo Lojban ja jpn jpn Japanese jpr jpr Judeo-Persian jrb jrb Judeo-Arabic kaa kaa Kara-Kalpak kab kab Kabyle - kac kac Kachin -kl kal kal Kalaallisut + kac kac Kachin; Jingpho +kl kal kal Kalaallisut; Greenlandic kam kam Kamba kn kan kan Kannada - kar kar Karen + kar kar Karen languages ks kas kas Kashmiri - kau kau Kanuri +kr kau kau Kanuri kaw kaw Kawi kk kaz kaz Kazakh + kbd kbd Kabardian kha kha Khasi khi khi Khoisan (Other) -km khm khm Khmer +km khm khm Central Khmer kho kho Khotanese -ki kik kik Kikuyu +ki kik kik Kikuyu; Gikuyu rw kin kin Kinyarwanda -ky kir kir Kirghiz +ky kir kir Kirghiz; Kyrgyz kmb kmb Kimbundu kok kok Konkani kv kom kom Komi - kon kon Kongo +kg kon kon Kongo ko kor kor Korean kos kos Kosraean kpe kpe Kpelle - kro kro Kru + krc krc Karachay-Balkar + krl krl Karelian + kro kro Kru languages kru kru Kurukh -kj kua kua Kuanyama +kj kua kua Kuanyama; Kwanyama kum kum Kumyk ku kur kur Kurdish kut kut Kutenai @@ -256,22 +280,23 @@ lo lao lao Lao la lat lat Latin lv lav lav Latvian lez lez Lezghian +li lim lim Limburgan; Limburger; Limburgish ln lin lin Lingala lt lit lit Lithuanian lol lol Mongo loz loz Lozi -lb ltz ltz Letzeburgesch +lb ltz ltz Luxembourgish; Letzeburgesch lua lua Luba-Lulua - lub lub Luba-Katanga - lug lug Ganda +lu lub lub Luba-Katanga +lg lug lug Ganda lui lui Luiseno lun lun Lunda luo luo Luo (Kenya and Tanzania) - lus lus lushai + lus lus Lushai mk mac mkd Macedonian mad mad Madurese mag mag Magahi -mh mah mah Marshall +mh mah mah Marshallese mai mai Maithili mak mak Makasar ml mal mal Malayalam @@ -281,12 +306,13 @@ mi mao mri Maori mr mar mar Marathi mas mas Masai ms may msa Malay + mdf mdf Moksha mdr mdr Mandar men men Mende mga mga Irish, Middle (900-1200) - mic mic Micmac + mic mic Mi'kmaq; Micmac min min Minangkabau - mis mis Miscellaneous languages + mis mis Uncoded languages mkh mkh Mon-Khmer (Other) mg mlg mlg Malagasy mt mlt mlt Maltese @@ -294,40 +320,46 @@ mt mlt mlt Maltese mni mni Manipuri mno mno Manobo languages moh moh Mohawk -mo mol mol Moldavian +mo mol mol Moldavian; Moldovan mn mon mon Mongolian mos mos Mossi mul mul Multiple languages mun mun Munda languages mus mus Creek + mwl mwl Mirandese mwr mwr Marwari myn myn Mayan languages - nah nah Nahuatl + myv myv Erzya + nah nah Nahuatl languages nai nai North American Indian + nap nap Neapolitan na nau nau Nauru -nv nav nav Navajo -nr nbl nbl Ndebele, South -nd nde nde Ndebele, North +nv nav nav Navajo; Navaho +nr nbl nbl Ndebele, South; South Ndebele +nd nde nde Ndebele, North; North Ndebele ng ndo ndo Ndonga nds nds Low German; Low Saxon; German, Low; Saxon, Low ne nep nep Nepali - new new Newari + new new Nepal Bhasa; Newari nia nia Nias nic nic Niger-Kordofanian (Other) niu niu Niuean + nog nog Nogai non non Norse, Old no nor nor Norwegian -nn nno nno Norwegian Nynorsk -nb nob nob Norwegian Bokmål - nso nso Sotho, Northern +nn nno nno Norwegian Nynorsk; Nynorsk, Norwegian +nb nob nob Bokmål, Norwegian; Norwegian Bokmål + nqo nqo N'Ko + nso nso Pedi; Sepedi; Northern Sotho nub nub Nubian languages -ny nya nya Chichewa; Nyanja + nwc nwc Classical Newari; Old Newari; Classical Nepal Bhasa +ny nya nya Chichewa; Chewa; Nyanja nym nym Nyamwezi nyn nyn Nyankole nyo nyo Nyoro nzi nzi Nzima oc oci oci Occitan (post 1500); Provençal - oji oji Ojibwa +oj oji oji Ojibwa or ori ori Oriya om orm orm Oromo osa osa Osage @@ -337,8 +369,8 @@ os oss oss Ossetian; Ossetic paa paa Papuan (Other) pag pag Pangasinan pal pal Pahlavi - pam pam Pampanga -pa pan pan Panjabi + pam pam Pampanga; Kapampangan +pa pan pan Panjabi; Punjabi pap pap Papiamento pau pau Palauan peo peo Persian, Old (ca.600-400 B.C.) @@ -351,17 +383,18 @@ pl pol pol Polish pt por por Portuguese pra pra Prakrit languages pro pro Provençal, Old (to 1500) -ps pus pus Pushto +ps pus pus Pushto; Pashto qaa-qtz qaa-qtz Reserved for local use qu que que Quechua raj raj Rajasthani rap rap Rapanui - rar rar Rarotongan + rar rar Rarotongan; Cook Islands Maori roa roa Romance (Other) -rm roh roh Raeto-Romance +rm roh roh Romansh rom rom Romany ro rum ron Romanian rn run run Rundi + rup rup Aromanian; Arumanian; Macedo-Romanian ru rus rus Russian sad sad Sandawe sg sag sag Sango @@ -372,33 +405,38 @@ sg sag sag Sango sa san san Sanskrit sas sas Sasak sat sat Santali -sr scc srp Serbian + scn scn Sicilian sco sco Scots -hr scr hrv Croatian sel sel Selkup sem sem Semitic (Other) sga sga Irish, Old (to 900) sgn sgn Sign Languages shn shn Shan sid sid Sidamo -si sin sin Sinhalese +si sin sin Sinhala; Sinhalese sio sio Siouan languages sit sit Sino-Tibetan (Other) sla sla Slavic (Other) sk slo slk Slovak sl slv slv Slovenian + sma sma Southern Sami se sme sme Northern Sami smi smi Sami languages (Other) + smj smj Lule Sami + smn smn Inari Sami sm smo smo Samoan + sms sms Skolt Sami sn sna sna Shona sd snd snd Sindhi snk snk Soninke sog sog Sogdian so som som Somali - son son Songhai -st sot sot Sotho, Southern -es spa spa Spanish + son son Songhai languages +st sot sot Sotho, Southern +es spa spa Spanish; Castilian sc srd srd Sardinian + srn srn Sranan Tongo +sr srp srp Serbian srr srr Serer ssa ssa Nilo-Saharan (Other) ss ssw ssw Swati @@ -408,6 +446,7 @@ su sun sun Sundanese sux sux Sumerian sw swa swa Swahili sv swe swe Swedish + syc syc Classical Syriac syr syr Syriac ty tah tah Tahitian tai tai Tai (Other) @@ -426,6 +465,7 @@ ti tir tir Tigrinya tiv tiv Tiv tkl tkl Tokelau tli tli Tlingit + tlh tlh Klingon; tlhIngan-Hol tmh tmh Tamashek tog tog Tonga (Nyasa) to ton ton Tonga (Tonga Islands) @@ -435,20 +475,22 @@ tn tsn tsn Tswana ts tso tso Tsonga tk tuk tuk Turkmen tum tum Tumbuka + tup tup Tupi languages tr tur tur Turkish tut tut Altaic (Other) tvl tvl Tuvalu tw twi twi Twi tyv tyv Tuvinian + udm udm Udmurt uga uga Ugaritic -ug uig uig Uighur +ug uig uig Uighur; Uyghur uk ukr ukr Ukrainian umb umb Umbundu und und Undetermined ur urd urd Urdu uz uzb uzb Uzbek vai vai Vai - ven ven Venda +ve ven ven Venda vi vie vie Vietnamese vo vol vol Volapük vot vot Votic @@ -458,7 +500,9 @@ vo vol vol Volap was was Washo cy wel cym Welsh wen wen Sorbian languages +wa wln wln Walloon wo wol wol Wolof + xal xal Kalmyk; Oirat xh xho xho Xhosa yao yao Yao yap yap Yapese @@ -466,8 +510,11 @@ yi yid yid Yiddish yo yor yor Yoruba ypk ypk Yupik languages zap zap Zapotec + zbl zbl Blissymbols; Blissymbolics; Bliss zen zen Zenaga -za zha zha Zhuang - znd znd Zande +za zha zha Zhuang; Chuang + znd znd Zande languages zu zul zul Zulu zun zun Zuni + zxx zxx No linguistic content; Not applicable + zza zza Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki From f03138a253160c4c9485dff15a7b251acaa34d4e Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sat, 23 May 2009 07:16:17 +0000 Subject: [PATCH 426/544] Update share/misc/iso639 Snapshot was taken on 23 May 2009. Obtained from: http://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt MFC after: 1 week --- share/misc/iso639 | 85 +++++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 40 deletions(-) diff --git a/share/misc/iso639 b/share/misc/iso639 index ffe873c1790a..467add4ac06c 100644 --- a/share/misc/iso639 +++ b/share/misc/iso639 @@ -27,6 +27,12 @@ # # For general discussion about ISO language codes, write to: iso639@dkuug.dk +# +# Download the file http://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt +# and run head/tools/tools/iso/check-iso639.pl to see if everything is up +# to date. +# + # a2: ISO 639-1 Alpha-2 code # bib: ISO 639-2/B bibliographic code # term: ISO 639-2/B terminology code @@ -38,7 +44,7 @@ ab abk abk Abkhazian ach ach Acoli ada ada Adangme ady ady Adyghe; Adygei - afa afa Afro-Asiatic (Other) + afa afa Afro-Asiatic languages afh afh Afrihili af afr afr Afrikaans ain ain Ainu @@ -58,7 +64,7 @@ an arg arg Aragonese hy arm hye Armenian arn arn Mapudungun; Mapuche arp arp Arapaho - art art Artificial (Other) + art art Artificial languages arw arw Arawak as asm asm Assamese ast ast Asturian; Bable; Leonese; Asturleonese @@ -77,12 +83,12 @@ bm bam bam Bambara ban ban Balinese eu baq eus Basque bas bas Basa - bat bat Baltic (Other) + bat bat Baltic languages bej bej Beja; Bedawiyet be bel bel Belarusian bem bem Bemba bn ben ben Bengali - ber ber Berber (Other) + ber ber Berber languages bho bho Bhojpuri bh bih bih Bihari bik bik Bikol @@ -100,12 +106,12 @@ bg bul bul Bulgarian my bur mya Burmese byn byn Blin; Bilin cad cad Caddo - cai cai Central American Indian (Other) + cai cai Central American Indian languages car car Galibi Carib ca cat cat Catalan; Valencian - cau cau Caucasian (Other) + cau cau Caucasian languages ceb ceb Cebuano - cel cel Celtic (Other) + cel cel Celtic languages ch cha cha Chamorro chb chb Chibcha ce che che Chechen @@ -124,14 +130,14 @@ cv chv chv Chuvash cop cop Coptic kw cor cor Cornish co cos cos Corsican - cpe cpe Creoles and pidgins, English based (Other) - cpf cpf Creoles and pidgins, French-based (Other) - cpp cpp Creoles and pidgins, Portuguese-based (Other) + cpe cpe Creoles and pidgins, English based + cpf cpf Creoles and pidgins, French-based + cpp cpp Creoles and pidgins, Portuguese-based cr cre cre Cree crh crh Crimean Tatar; Crimean Turkish - crp crp Creoles and pidgins (Other) + crp crp Creoles and pidgins csb csb Kashubian - cus cus Cushitic (Other) + cus cus Cushitic languages cs cze ces Czech dak dak Dakota da dan dan Danish @@ -143,7 +149,7 @@ da dan dan Danish din din Dinka dv div div Divehi; Dhivehi; Maldivian doi doi Dogri - dra dra Dravidian (Other) + dra dra Dravidian languages dsb dsb Lower Sorbian dua dua Duala dum dum Dutch, Middle (ca.1050-1350) @@ -166,7 +172,7 @@ fo fao fao Faroese fj fij fij Fijian fil fil Filipino; Pilipino fi fin fin Finnish - fiu fiu Finno-Ugrian (Other) + fiu fiu Finno-Ugrian languages fon fon Fon fr fre fra French frm frm French, Middle (ca.1400-1600) @@ -179,7 +185,7 @@ ff ful ful Fulah gaa gaa Ga gay gay Gayo gba gba Gbaya - gem gem Germanic (Other) + gem gem Germanic languages ka geo kat Georgian de ger deu German gez gez Geez @@ -226,12 +232,12 @@ iu iku iku Inuktitut ie ile ile Interlingue; Occidental ilo ilo Iloko ia ina ina Interlingua (International Auxiliary Language Association) - inc inc Indic (Other) + inc inc Indic languages id ind ind Indonesian - ine ine Indo-European (Other) + ine ine Indo-European languages inh inh Ingush ik ipk ipk Inupiaq - ira ira Iranian (Other) + ira ira Iranian languages iro iro Iroquoian languages it ita ita Italian jv jav jav Javanese @@ -252,9 +258,9 @@ kr kau kau Kanuri kk kaz kaz Kazakh kbd kbd Kabardian kha kha Khasi - khi khi Khoisan (Other) + khi khi Khoisan languages km khm khm Central Khmer - kho kho Khotanese + kho kho Khotanese; Sakan ki kik kik Kikuyu; Gikuyu rw kin kin Kinyarwanda ky kir kir Kirghiz; Kyrgyz @@ -302,7 +308,7 @@ mh mah mah Marshallese ml mal mal Malayalam man man Mandingo mi mao mri Maori - map map Austronesian (Other) + map map Austronesian languages mr mar mar Marathi mas mas Masai ms may msa Malay @@ -313,14 +319,13 @@ ms may msa Malay mic mic Mi'kmaq; Micmac min min Minangkabau mis mis Uncoded languages - mkh mkh Mon-Khmer (Other) + mkh mkh Mon-Khmer languages mg mlg mlg Malagasy mt mlt mlt Maltese mnc mnc Manchu mni mni Manipuri mno mno Manobo languages moh moh Mohawk -mo mol mol Moldavian; Moldovan mn mon mon Mongolian mos mos Mossi mul mul Multiple languages @@ -331,7 +336,7 @@ mn mon mon Mongolian myn myn Mayan languages myv myv Erzya nah nah Nahuatl languages - nai nai North American Indian + nai nai North American Indian languages nap nap Neapolitan na nau nau Nauru nv nav nav Navajo; Navaho @@ -342,13 +347,13 @@ ng ndo ndo Ndonga ne nep nep Nepali new new Nepal Bhasa; Newari nia nia Nias - nic nic Niger-Kordofanian (Other) + nic nic Niger-Kordofanian languages niu niu Niuean nog nog Nogai non non Norse, Old no nor nor Norwegian nn nno nno Norwegian Nynorsk; Nynorsk, Norwegian -nb nob nob Bokmål, Norwegian; Norwegian Bokmål +nb nob nob BokmÃ¥l, Norwegian; Norwegian BokmÃ¥l nqo nqo N'Ko nso nso Pedi; Sepedi; Northern Sotho nub nub Nubian languages @@ -358,7 +363,7 @@ ny nya nya Chichewa; Chewa; Nyanja nyn nyn Nyankole nyo nyo Nyoro nzi nzi Nzima -oc oci oci Occitan (post 1500); Provençal +oc oci oci Occitan (post 1500); Provençal oj oji oji Ojibwa or ori ori Oriya om orm orm Oromo @@ -366,7 +371,7 @@ om orm orm Oromo os oss oss Ossetian; Ossetic ota ota Turkish, Ottoman (1500-1928) oto oto Otomian languages - paa paa Papuan (Other) + paa paa Papuan languages pag pag Pangasinan pal pal Pahlavi pam pam Pampanga; Kapampangan @@ -375,24 +380,24 @@ pa pan pan Panjabi; Punjabi pau pau Palauan peo peo Persian, Old (ca.600-400 B.C.) fa per fas Persian - phi phi Philippine (Other) + phi phi Philippine languages phn phn Phoenician pi pli pli Pali pl pol pol Polish pon pon Pohnpeian pt por por Portuguese pra pra Prakrit languages - pro pro Provençal, Old (to 1500) + pro pro Provençal, Old (to 1500) ps pus pus Pushto; Pashto qaa-qtz qaa-qtz Reserved for local use qu que que Quechua raj raj Rajasthani rap rap Rapanui rar rar Rarotongan; Cook Islands Maori - roa roa Romance (Other) + roa roa Romance languages rm roh roh Romansh rom rom Romany -ro rum ron Romanian +ro rum ron Romanian; Moldavian; Moldovan rn run run Rundi rup rup Aromanian; Arumanian; Macedo-Romanian ru rus rus Russian @@ -408,20 +413,20 @@ sa san san Sanskrit scn scn Sicilian sco sco Scots sel sel Selkup - sem sem Semitic (Other) + sem sem Semitic languages sga sga Irish, Old (to 900) sgn sgn Sign Languages shn shn Shan sid sid Sidamo si sin sin Sinhala; Sinhalese sio sio Siouan languages - sit sit Sino-Tibetan (Other) - sla sla Slavic (Other) + sit sit Sino-Tibetan languages + sla sla Slavic languages sk slo slk Slovak sl slv slv Slovenian sma sma Southern Sami se sme sme Northern Sami - smi smi Sami languages (Other) + smi smi Sami languages smj smj Lule Sami smn smn Inari Sami sm smo smo Samoan @@ -438,7 +443,7 @@ sc srd srd Sardinian srn srn Sranan Tongo sr srp srp Serbian srr srr Serer - ssa ssa Nilo-Saharan (Other) + ssa ssa Nilo-Saharan languages ss ssw ssw Swati suk suk Sukuma su sun sun Sundanese @@ -449,7 +454,7 @@ sv swe swe Swedish syc syc Classical Syriac syr syr Syriac ty tah tah Tahitian - tai tai Tai (Other) + tai tai Tai languages ta tam tam Tamil tt tat tat Tatar te tel tel Telugu @@ -477,7 +482,7 @@ tk tuk tuk Turkmen tum tum Tumbuka tup tup Tupi languages tr tur tur Turkish - tut tut Altaic (Other) + tut tut Altaic languages tvl tvl Tuvalu tw twi twi Twi tyv tyv Tuvinian @@ -492,7 +497,7 @@ uz uzb uzb Uzbek vai vai Vai ve ven ven Venda vi vie vie Vietnamese -vo vol vol Volapük +vo vol vol Volapük vot vot Votic wak wak Wakashan languages wal wal Walamo From e420c0cab754ba7cf54134e7499b76b85ecc253a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 23 May 2009 07:58:56 +0000 Subject: [PATCH 427/544] Preset the modified bit in the PTE when pmap_enter() is called during a write fault or while wiring a mapping that must support write access. In general, this change should reduce the number of traps that occur for the purpose of setting the modified bit. More specifically, this change should prevent traps while holding locks in a sysctl handler. See kern/kern_sysctl.c revisions 1.168 and 1.195 (svn r192160) for further details. Tested by: gonzo --- sys/mips/mips/pmap.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 115825c9738d..2188c3695615 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -1849,6 +1849,8 @@ pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t fault_type, vm_page_t m, vm_pr pmap->pm_stats.wired_count++; validate: + if ((access & VM_PROT_WRITE) != 0) + m->md.pv_flags |= PV_TABLE_MOD | PV_TABLE_REF; rw = init_pte_prot(va, m, prot); #ifdef PMAP_DEBUG From 609e2d1b62cd071c1c3ee2738645aa48be5a41af Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sat, 23 May 2009 08:49:55 +0000 Subject: [PATCH 428/544] Rework the text for the import of zic(8) at 20090523. Suggested by Niclas Zeising (and he was absolutely right on it!) --- UPDATING | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/UPDATING b/UPDATING index 8dcc53070b7d..7afffd72b53b 100644 --- a/UPDATING +++ b/UPDATING @@ -24,7 +24,8 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: 20090523: The newly imported zic(8) produces a new format in the - output. Please run tzsetup(8) to install a newly /etc/localtime. + output. Please run tzsetup(8) to install the newly created + data to /etc/localtime. 20090520: The sysctl tree for the usb stack has renamed from hw.usb2.* to From 8c8e796b973ac824006770803db8ccc351e5c152 Mon Sep 17 00:00:00 2001 From: Edwin Groothuis Date: Sat, 23 May 2009 09:01:30 +0000 Subject: [PATCH 429/544] Added two tools to check the contents of /usr/share/misc/iso* with the data from the sources. PR: misc/127430 and misc/misc/127428 --- tools/tools/README | 2 + tools/tools/iso/check-iso3166.pl | 164 +++++++++++++++++++++++++++++++ tools/tools/iso/check-iso639.pl | 98 ++++++++++++++++++ 3 files changed, 264 insertions(+) create mode 100755 tools/tools/iso/check-iso3166.pl create mode 100755 tools/tools/iso/check-iso639.pl diff --git a/tools/tools/README b/tools/tools/README index 9190f6bddde9..de7e80fc9bee 100644 --- a/tools/tools/README +++ b/tools/tools/README @@ -32,6 +32,8 @@ hcomp Compress header files by removing comments and whitespace. html-mv Rename HTML generated filenames to human readable filenames. ifinfo Uses the interface MIB to print out all the information an interface exports in an ugly form. +iso Tool to compare the iso3166 and iso639 files in + /usr/share/misc with the data from the master sites. iwi Tools specific to the Intel PRO/Wireless 2200BG/2225BG/2915ABG support. kdrv KernelDriver; add/list/remove third-party kernel driver diff --git a/tools/tools/iso/check-iso3166.pl b/tools/tools/iso/check-iso3166.pl new file mode 100755 index 000000000000..b85c1883a62d --- /dev/null +++ b/tools/tools/iso/check-iso3166.pl @@ -0,0 +1,164 @@ +#!/usr/bin/perl -w + +# +# $FreeBSD$ +# +# This script compares the file iso3166 (from head/share/misc) with the files +# list-en1-semic-2.txt (from +# http://www.iso.org/iso/list-en1-semic-2.txt) and iso3166-countrycodes.txt +# (from ftp://ftp.ripe.net/) to see if there any differences. +# +# Created by Edwin Groothuis for the FreeBSD project. +# + +use strict; +use Data::Dumper; + +my %old = (); +{ + open(FIN, "iso3166") or die "Cannot open iso3166 (should be in head/share/misc)"; + my @lines = ; + close(FIN); + chomp(@lines); + + foreach my $l (@lines) { + next if ($l =~ /^#/); + next if ($l eq ""); + + die "Bad line: $l\n" + if ($l !~ /^([A-Z\-]*)[ \t]+([A-Z\-]+)[ \t]+(\d+)[ \t]+(.*)/); + my $two = $1; + my $three = $2; + my $number = $3; + my $name = $4; + + $old{$two}{two} = $two; + $old{$two}{three} = $three; + $old{$two}{number} = $number; + $old{$two}{name} = $name; + } +} + +my %new1 = (); +{ + open(FIN, "iso3166-countrycodes.txt") or die "Cannot open iso3166-countrycodes.txt, which can be retrieved from ftp://ftp.ripe.net/"; + my @lines = ; + close(FIN); + chomp(@lines); + + my $noticed = 0; + foreach my $l (@lines) { + if ($l =~ /\-\-\-\-\-\-\-/) { + $noticed = 1; + next; + } + next if (!$noticed); + next if ($l eq ""); + + die "Invalid line: $l\n" + if ($l !~ /^(.+?)[\t ][\t ]+([A-Z]{2})[\t ]+([A-Z]{3})[\t ]+(\d+)[\t ]*$/); + my $two = $2; + my $three = $3; + my $number = $4; + my $name = $1; + + $new1{$two}{two} = $two; + $new1{$two}{three} = $three; + $new1{$two}{number} = $number; + $new1{$two}{name} = $name; + } +} + +my %new2 = (); +{ + open(FIN, "list-en1-semic-2.txt") or die "Cannot open list-en1-semic-2.txt, which can be retrieved from http://www.iso.org/iso/list-en1-semic-2.txt"; + my @lines = ; + close(FIN); + chomp(@lines); + + my $noticed = 0; + foreach my $l (@lines) { + $l =~ s/\x0d//g; + if (!$noticed) { # skip the first line + $noticed = 1; + next; + } + next if ($l eq ""); + + my @a = split(/;/, $l); + die "Invalid line: $l\n" if ($#a != 1); + my $two = $a[1]; + my $name = $a[0]; + + $new2{$two}{two} = $two; + $new2{$two}{name} = $name; + } +} + +{ + my $c = 0; + foreach my $two (sort(keys(%old))) { + if (!defined $new1{$two}) { + print "In old but not new1: $old{$two}{two}\t$old{$two}{three}\t$old{$two}{number}\t$old{$two}{name}\n"; + $c++; + } + if (!defined $new2{$two}) { + print "In old but not new2: $old{$two}{two}\t$old{$two}{name}\n"; + $c++; + } + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $two (sort(keys(%new1))) { + next if (defined $old{$two}); + print "In new1 but not old: $new1{$two}{two}\t$new1{$two}{three}\t$new1{$two}{number}\t$new1{$two}{name}\n"; + $c++; + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $two (sort(keys(%new2))) { + next if (defined $old{$two}); + print "In new2 but not old: $new2{$two}{two}\t$new2{$two}{name}\n"; + $c++; + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $two (sort(keys(%old))) { + if (defined $new1{$two}) { + if ($old{$two}{two} ne $new1{$two}{two} || + $old{$two}{three} ne $new1{$two}{three} || + $old{$two}{number} ne $new1{$two}{number} || + lc($old{$two}{name}) ne lc($new1{$two}{name})) { + print "In old : $old{$two}{two}\t$old{$two}{three}\t$old{$two}{number}\t$old{$two}{name}\n"; + print "In new1: $new1{$two}{two}\t$new1{$two}{three}\t$new1{$two}{number}\t$new1{$two}{name}\n"; + $c++; + } + } + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $two (sort(keys(%old))) { + if (defined $new2{$two}) { + if ($old{$two}{two} ne $new2{$two}{two} || + lc($old{$two}{name}) ne lc($new2{$two}{name})) { + print "In old : $old{$two}{two}\t$old{$two}{name}\n"; + print "In new2: $new2{$two}{two}\t$new2{$two}{name}\n"; + $c++; + } + } + } + print "Found $c issues\n"; +} + diff --git a/tools/tools/iso/check-iso639.pl b/tools/tools/iso/check-iso639.pl new file mode 100755 index 000000000000..9350df09102c --- /dev/null +++ b/tools/tools/iso/check-iso639.pl @@ -0,0 +1,98 @@ +#!/usr/bin/perl -w + +# +# $FreeBSD$ +# +# This script compares the file iso639 (from head/share/misc) with the file +# ISO-639-2_8859-1.txt (from +# http://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt) to see if there +# any differences. +# +# Created by Edwin Groothuis for the FreeBSD project. +# + +use strict; +use Data::Dumper; + +my %old = (); +{ + open(FIN, "iso639") or die "Cannot open iso639 (should be in head/share/misc)"; + my @lines = ; + close(FIN); + chomp(@lines); + + foreach my $l (@lines) { + next if ($l =~ /^#/); + next if ($l eq ""); + + die "Bad line: $l\n" + if ($l !~ /^([a-z\-]*)[ \t]+([a-z\-]+)[ \t]+([a-z\-]+)[ \t]+(.*)/); + my $a2 = $1; + my $bib = $2; + my $term = $3; + my $name = $4; + + $old{$bib}{a2} = $a2; + $old{$bib}{bib} = $bib; + $old{$bib}{term} = $term; + $old{$bib}{name} = $name; + } +} + +my %new = (); +{ + open(FIN, "ISO-639-2_utf-8.txt") or die "Cannot open ISO-639-2_utf-8.txt, which can be retrieved from http://www.loc.gov/standards/iso639-2/ISO-639-2_utf-8.txt"; + my @lines = ; + close(FIN); + chomp(@lines); + + foreach my $l (@lines) { + my @a = split(/\|/, $l); + my $a2 = $a[2]; + my $bib = $a[0]; + my $term = $a[1]; + my $name = $a[3]; + + $term = $bib if ($term eq ""); + + $new{$bib}{a2} = $a2; + $new{$bib}{bib} = $bib; + $new{$bib}{term} = $term; + $new{$bib}{name} = $name; + } +} + +{ + my $c = 0; + foreach my $bib (sort(keys(%old))) { + next if (defined $new{$bib}); + print "In old but not new: $old{$bib}{a2}\t$old{$bib}{bib}\t$old{$bib}{term}\t$old{$bib}{name}\n"; + $c++; + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $bib (sort(keys(%new))) { + next if (defined $old{$bib}); + print "In new but not old: $new{$bib}{a2}\t$new{$bib}{bib}\t$new{$bib}{term}\t$new{$bib}{name}\n"; + $c++; + } + print "Found $c issues\n"; +} + +{ + my $c = 0; + foreach my $bib (sort(keys(%old))) { + next if (!defined $new{$bib}); + next if ($old{$bib}{a2} eq $new{$bib}{a2} && + $old{$bib}{bib} eq $new{$bib}{bib} && + $old{$bib}{term} eq $new{$bib}{term} && + $old{$bib}{name} eq $new{$bib}{name}); + print "In old: $old{$bib}{a2}\t$old{$bib}{bib}\t$old{$bib}{term}\t$old{$bib}{name}\n"; + print "In new: $new{$bib}{a2}\t$new{$bib}{bib}\t$new{$bib}{term}\t$new{$bib}{name}\n"; + $c++; + } + print "Found $c issues\n"; +} From 813bb2c94e9657f306f960f98183ac5de0537e76 Mon Sep 17 00:00:00 2001 From: Joel Dahl Date: Sat, 23 May 2009 09:24:07 +0000 Subject: [PATCH 430/544] Fix minor typo. --- UPDATING | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UPDATING b/UPDATING index 7afffd72b53b..8ef1991cbccf 100644 --- a/UPDATING +++ b/UPDATING @@ -279,7 +279,7 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: memory segment of size > 2 GB on the 64-bit architectures. Due to a limitation of the existing ABI, the shm_segsz member of the struct shmid_ds, returned by shmctl(IPC_STAT) call is - wrong for large segments. Note that limits must be explicitely + wrong for large segments. Note that limits must be explicitly raised to allow such segments to be created. 20090301: From ae184a6a7da0cbe989be569657448e1220839e86 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Sat, 23 May 2009 13:23:46 +0000 Subject: [PATCH 431/544] Fix cryptodev UIO creation. Cryptodev uses UIO structure do get data from userspace and pass it to cryptographic engines. Initially UIO size is equal to size of data passed to engine, but if UIO is prepared for hash calculation an additional small space is created to hold result of operation. While creating space for the result, UIO I/O vector size is correctly extended, but uio_resid field in UIO structure is not modified. As bus_dma code uses uio_resid field to determine size of UIO DMA mapping, resulting mapping hasn't correct size. This leads to a crash if all the following conditions are met: 1. Hardware cryptographic accelerator writes result of hash operation using DMA. 2. Size of input data is less or equal than (n * PAGE_SIZE), 3. Size of input data plus size of hash result is grather than (n * PAGE_SIZE, where n is the same as in point 2. This patch fixes this problem by adding size of the extenstion to uio_resid field in UIO structure. Submitted by: Piotr Ziecik kosmo ! semihalf dot com Reviewed by: philip Obtained from: Semihalf --- sys/opencrypto/cryptodev.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c index 73280ccf079b..5f1331d693ad 100644 --- a/sys/opencrypto/cryptodev.c +++ b/sys/opencrypto/cryptodev.c @@ -409,8 +409,10 @@ cryptodev_op( cse->uio.uio_rw = UIO_WRITE; cse->uio.uio_td = td; cse->uio.uio_iov[0].iov_len = cop->len; - if (cse->thash) + if (cse->thash) { cse->uio.uio_iov[0].iov_len += cse->thash->hashsize; + cse->uio.uio_resid += cse->thash->hashsize; + } cse->uio.uio_iov[0].iov_base = malloc(cse->uio.uio_iov[0].iov_len, M_XDATA, M_WAITOK); From f24f1c51d30bdecbb6af77a10076ddbf7cb6d0ef Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 23 May 2009 13:51:05 +0000 Subject: [PATCH 432/544] Improve API documentation. Reviewed by: rwatson (earlier version) --- lib/libc/posix1e/acl.3 | 2 +- lib/libc/posix1e/acl_add_perm.3 | 8 ++++++++ lib/libc/posix1e/acl_get.3 | 9 +++++++++ lib/libc/posix1e/acl_set.3 | 9 +++++++++ lib/libc/posix1e/acl_set_tag_type.3 | 12 ++++++++++++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/libc/posix1e/acl.3 b/lib/libc/posix1e/acl.3 index 1c824d047e70..43adcdf673bf 100644 --- a/lib/libc/posix1e/acl.3 +++ b/lib/libc/posix1e/acl.3 @@ -48,7 +48,7 @@ The library calls include routines to allocate, duplicate, retrieve, set, and validate ACLs associated with file objects. As well as the POSIX.1e routines, there are a number of non-portable extensions defined that allow for alternative ACL semantics than the -POSIX.1e semantics, such as AFS, NTFS, Coda, and NWFS semantics. +POSIX.1e semantics, such as NFSv4, AFS, NTFS, Coda, and NWFS semantics. Where routines are non-standard, they are suffixed with _np to indicate that they are not portable. .Pp diff --git a/lib/libc/posix1e/acl_add_perm.3 b/lib/libc/posix1e/acl_add_perm.3 index 6a5893e39c27..dd002d121cac 100644 --- a/lib/libc/posix1e/acl_add_perm.3 +++ b/lib/libc/posix1e/acl_add_perm.3 @@ -49,6 +49,14 @@ to the permission set .Pp Note: it is not considered an error to attempt to add permissions that already exist in the permission set. +.Pp +For POSIX.1e ACLs, valid values are: +.Pp +.Bl -column -offset 3n "ACL_EXECUTE" +.It ACL_EXECUTE Execute permission +.It ACL_WRITE Write permission +.It ACL_READ Read permission +.El .Sh RETURN VALUES .Rv -std acl_add_perm .Sh ERRORS diff --git a/lib/libc/posix1e/acl_get.3 b/lib/libc/posix1e/acl_get.3 index fa915df3ec48..344c5958a4af 100644 --- a/lib/libc/posix1e/acl_get.3 +++ b/lib/libc/posix1e/acl_get.3 @@ -91,6 +91,15 @@ with the object referred to by .Va fd . The ACL in the working storage shall not participate in any access control decisions. +.Pp +Valid values for the +.Va type +argument are: +.Pp +.Bl -column -offset 3n "ACL_TYPE_DEFAULT" +.It ACL_TYPE_ACCESS POSIX.1e access ACL +.It ACL_TYPE_DEFAULT POSIX.1e default ACL +.El .Sh IMPLEMENTATION NOTES .Fx Ns 's support for POSIX.1e interfaces and features is still under diff --git a/lib/libc/posix1e/acl_set.3 b/lib/libc/posix1e/acl_set.3 index a2d50b840dde..e906e7922131 100644 --- a/lib/libc/posix1e/acl_set.3 +++ b/lib/libc/posix1e/acl_set.3 @@ -75,6 +75,15 @@ The .Fn acl_set_link_np function acts on a symlink rather than its target, if the target of the path is a symlink. +.Pp +Valid values for the +.Va type +argument are: +.Pp +.Bl -column -offset 3n "ACL_TYPE_DEFAULT" +.It ACL_TYPE_ACCESS POSIX.1e access ACL +.It ACL_TYPE_DEFAULT POSIX.1e default ACL +.El .Sh IMPLEMENTATION NOTES .Fx Ns 's support for POSIX.1e interfaces and features is still under diff --git a/lib/libc/posix1e/acl_set_tag_type.3 b/lib/libc/posix1e/acl_set_tag_type.3 index 7cbca81bec94..113aa22e6871 100644 --- a/lib/libc/posix1e/acl_set_tag_type.3 +++ b/lib/libc/posix1e/acl_set_tag_type.3 @@ -46,6 +46,18 @@ is a POSIX.1e call that sets the ACL tag type of ACL entry .Fa entry_d to the value of .Fa tag_type . +.Pp +Valid values are: +.Pp +.Bl -column -offset 3n "ACL_EVERYONE" +.It ACL_USER_OBJ Permissions apply to file owner +.It ACL_USER Permissions apply to additional user specified by qualifier +.It ACL_GROUP_OBJ Permissions apply to file group +.It ACL_GROUP Permissions apply to additional group specified by qualifier +.It ACL_MASK Permissions specify mask +.It ACL_OTHER Permissions apply to "other" +.It ACL_OTHER_OBJ Same as ACL_OTHER +.El .Sh RETURN VALUES .Rv -std acl_set_tag_type .Sh ERRORS From 6feca53bed90b691cbd4289ba92954900ffc5521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 May 2009 16:00:16 +0000 Subject: [PATCH 433/544] Remove svn:keywords on a file that had fbsd:nokeywords (though I don't understand the reason for the latter) --- sys/cddl/boot/zfs/zfssubr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c index fb4444f242eb..7cde33393246 100644 --- a/sys/cddl/boot/zfs/zfssubr.c +++ b/sys/cddl/boot/zfs/zfssubr.c @@ -24,7 +24,7 @@ */ #include -__FBSDID("$FreeBSD$"); +__FBSDID("$FreeBSD: head/sys/cddl/boot/zfs/zfssubr.c 192599 2009-05-22 20:07:39Z des $"); static uint64_t zfs_crc64_table[256]; From bba5cfd28b94d3fa9a8f0c485e54aa42ec24784a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 May 2009 16:01:58 +0000 Subject: [PATCH 434/544] Unexpand $FreeBSD$. --- sys/cddl/boot/zfs/zfssubr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/boot/zfs/zfssubr.c b/sys/cddl/boot/zfs/zfssubr.c index 7cde33393246..fb4444f242eb 100644 --- a/sys/cddl/boot/zfs/zfssubr.c +++ b/sys/cddl/boot/zfs/zfssubr.c @@ -24,7 +24,7 @@ */ #include -__FBSDID("$FreeBSD: head/sys/cddl/boot/zfs/zfssubr.c 192599 2009-05-22 20:07:39Z des $"); +__FBSDID("$FreeBSD$"); static uint64_t zfs_crc64_table[256]; From 1e2a13e62a4d9bfe1f86c3813eec1c0f163e4fb7 Mon Sep 17 00:00:00 2001 From: Jamie Gritton Date: Sat, 23 May 2009 16:13:26 +0000 Subject: [PATCH 435/544] Delay an error message until the variable it uses gets initialized. Found with: Coverity Prevent(tm) CID: 4316 Reported by: trasz Approved by: bz (mentor) --- sys/kern/kern_jail.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c index 3bc5c10c6765..d0cc440dd7d2 100644 --- a/sys/kern/kern_jail.c +++ b/sys/kern/kern_jail.c @@ -1196,14 +1196,6 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags) if (flags & ~JAIL_GET_MASK) return (EINVAL); - if (jailed(td->td_ucred)) { - /* - * Don't allow a jailed process to see any jails, - * not even its own. - */ - vfs_opterror(opts, "jail not found"); - return (ENOENT); - } /* Get the parameter list. */ error = vfs_buildopts(optuio, &opts); @@ -1211,6 +1203,12 @@ kern_jail_get(struct thread *td, struct uio *optuio, int flags) return (error); errmsg_pos = vfs_getopt_pos(opts, "errmsg"); + /* Don't allow a jailed process to see any jails, not even its own. */ + if (jailed(td->td_ucred)) { + vfs_opterror(opts, "jail not found"); + return (ENOENT); + } + /* * Find the prison specified by one of: lastjid, jid, name. */ From 1849938c8ed341b1362674c9dfaeb29cd7f04c69 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 16:27:42 +0000 Subject: [PATCH 436/544] While r192615 fixed the former problems, make this file VIMAGE compliant now as well initializing local context variables. --- sys/nfsclient/bootp_subr.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sys/nfsclient/bootp_subr.c b/sys/nfsclient/bootp_subr.c index be6a588725fd..b51b38df7e31 100644 --- a/sys/nfsclient/bootp_subr.c +++ b/sys/nfsclient/bootp_subr.c @@ -359,6 +359,7 @@ bootpboot_p_tree(struct radix_node *rn) void bootpboot_p_rtlist(void) { + INIT_VNET_NET(curvnet); printf("Routing table:\n"); RADIX_NODE_HEAD_RLOCK(V_rt_tables[0][AF_INET]); /* could sleep XXX */ @@ -383,6 +384,7 @@ bootpboot_p_if(struct ifnet *ifp, struct ifaddr *ifa) void bootpboot_p_iflist(void) { + INIT_VNET_NET(curvnet); struct ifnet *ifp; struct ifaddr *ifa; @@ -1592,6 +1594,7 @@ bootpc_decode_reply(struct nfsv3_diskless *nd, struct bootpc_ifcontext *ifctx, void bootpc_init(void) { + INIT_VNET_NET(curvnet); struct bootpc_ifcontext *ifctx, *nctx; /* Interface BOOTP contexts */ struct bootpc_globalcontext *gctx; /* Global BOOTP context */ struct ifnet *ifp; From 585823fcf9b3e680af7ca5230c4b2d3772378df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 May 2009 16:36:19 +0000 Subject: [PATCH 437/544] Remove bogus props From b44522f44bfa8e421164f88148eabad75c1921b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 May 2009 16:39:49 +0000 Subject: [PATCH 438/544] Remove bogus prop From db2e47925ece914db7cc01b4b1792535bc65b12b Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 16:42:38 +0000 Subject: [PATCH 439/544] Add sysctls to toggle the behaviour of the (former) IPSEC_FILTERTUNNEL kernel option. This also permits tuning of the option per virtual network stack, as well as separately per inet, inet6. The kernel option is left for a transition period, marked deprecated, and will be removed soon. Initially requested by: phk (1 year 1 day ago) MFC after: 4 weeks --- share/man/man4/ipsec.4 | 12 +++++++----- sys/conf/NOTES | 7 ++++--- sys/netinet/ip_ipsec.c | 11 +++++++++-- sys/netinet6/ip6_ipsec.c | 11 +++++++++-- sys/netipsec/ipsec.c | 16 ++++++++++++++++ sys/netipsec/ipsec.h | 1 + sys/netipsec/ipsec6.h | 1 + sys/netipsec/vipsec.h | 4 ++++ 8 files changed, 51 insertions(+), 12 deletions(-) diff --git a/share/man/man4/ipsec.4 b/share/man/man4/ipsec.4 index 4bc45d6ee28d..47ccdb1082b5 100644 --- a/share/man/man4/ipsec.4 +++ b/share/man/man4/ipsec.4 @@ -29,7 +29,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 5, 2007 +.Dd May 23, 2009 .Dt IPSEC 4 .Os .Sh NAME @@ -37,7 +37,6 @@ .Nd Internet Protocol Security protocol .Sh SYNOPSIS .Cd "options IPSEC" -.Cd "options IPSEC_FILTERTUNNEL" .Cd "device crypto" .Pp .In sys/types.h @@ -88,9 +87,12 @@ inbound. .Pp To properly filter on the inner packets of an .Nm -tunnel with firewalls, add -.Cd "options IPSEC_FILTERTUNNEL" -to the kernel configuration file. +tunnel with firewalls, you can change the values of the following sysctls +.Bl -column net.inet6.ipsec6.filtertunnel default enable +.It Sy "Name Default Enable" +.It net.inet.ipsec.filtertunnel 0 1 +.It net.inet6.ipsec6.filtertunnel 0 1 +.El .\" .Ss Kernel interface .Nm diff --git a/sys/conf/NOTES b/sys/conf/NOTES index 7ba6ac497479..0e5bb44acf46 100644 --- a/sys/conf/NOTES +++ b/sys/conf/NOTES @@ -524,9 +524,10 @@ options ROUTETABLES=2 # max 16. 1 is back compatible. options IPSEC #IP security (requires device crypto) #options IPSEC_DEBUG #debug for IP security # -# Set IPSEC_FILTERTUNNEL to force packets coming through a tunnel -# to be processed by any configured packet filtering twice. -# The default is that packets coming out of a tunnel are _not_ processed; +# #DEPRECATED# +# Set IPSEC_FILTERTUNNEL to change the default of the sysctl to force packets +# coming through a tunnel to be processed by any configured packet filtering +# twice. The default is that packets coming out of a tunnel are _not_ processed; # they are assumed trusted. # # IPSEC history is preserved for such packets, and can be filtered diff --git a/sys/netinet/ip_ipsec.c b/sys/netinet/ip_ipsec.c index 45364a8ae312..ab5d22d88a7f 100644 --- a/sys/netinet/ip_ipsec.c +++ b/sys/netinet/ip_ipsec.c @@ -71,6 +71,10 @@ __FBSDID("$FreeBSD$"); extern struct protosw inetsw[]; +#ifdef VIMAGE_GLOBALS +int ip4_ipsec_filtertunnel; +#endif + /* * Check if we have to jump over firewall processing for this packet. * Called from ip_input(). @@ -79,11 +83,14 @@ extern struct protosw inetsw[]; int ip_ipsec_filtertunnel(struct mbuf *m) { -#if defined(IPSEC) && !defined(IPSEC_FILTERTUNNEL) +#if defined(IPSEC) + INIT_VNET_IPSEC(curvnet); + /* * Bypass packet filtering for packets from a tunnel. */ - if (m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) + if (!V_ip4_ipsec_filtertunnel && + m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) return 1; #endif return 0; diff --git a/sys/netinet6/ip6_ipsec.c b/sys/netinet6/ip6_ipsec.c index a0c1abc3855f..57a504407dc2 100644 --- a/sys/netinet6/ip6_ipsec.c +++ b/sys/netinet6/ip6_ipsec.c @@ -76,6 +76,10 @@ __FBSDID("$FreeBSD$"); extern struct protosw inet6sw[]; +#ifdef VIMAGE_GLOBALS +int ip6_ipsec6_filtertunnel; +#endif + /* * Check if we have to jump over firewall processing for this packet. * Called from ip_input(). @@ -84,11 +88,14 @@ extern struct protosw inet6sw[]; int ip6_ipsec_filtertunnel(struct mbuf *m) { -#if defined(IPSEC) && !defined(IPSEC_FILTERTUNNEL) +#if defined(IPSEC) + INIT_VNET_IPSEC(curvnet); + /* * Bypass packet filtering for packets from a tunnel. */ - if (m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) + if (!V_ip6_ipsec6_filtertunnel && + m_tag_find(m, PACKET_TAG_IPSEC_IN_DONE, NULL) != NULL) return 1; #endif return 0; diff --git a/sys/netipsec/ipsec.c b/sys/netipsec/ipsec.c index 4124d9dc033c..6c42e3227654 100644 --- a/sys/netipsec/ipsec.c +++ b/sys/netipsec/ipsec.c @@ -167,6 +167,9 @@ SYSCTL_V_INT(V_NET, vnet_ipsec, _net_inet_ipsec, OID_AUTO, SYSCTL_V_STRUCT(V_NET, vnet_ipsec, _net_inet_ipsec, OID_AUTO, ipsecstats, CTLFLAG_RD, ipsec4stat, ipsecstat, "IPsec IPv4 statistics."); +SYSCTL_V_INT(V_NET, vnet_ipsec, _net_inet_ipsec, OID_AUTO, + filtertunnel, CTLFLAG_RW, ip4_ipsec_filtertunnel, 0, + "If set filter packets from an IPsec tunnel."); #ifdef REGRESSION #ifdef VIMAGE_GLOBALS @@ -228,6 +231,9 @@ SYSCTL_V_INT(V_NET, vnet_ipsec, _net_inet6_ipsec6, IPSECCTL_DEBUG, SYSCTL_V_STRUCT(V_NET, vnet_ipsec, _net_inet6_ipsec6, IPSECCTL_STATS, ipsecstats, CTLFLAG_RD, ipsec6stat, ipsecstat, "IPsec IPv6 statistics."); +SYSCTL_V_INT(V_NET, vnet_ipsec, _net_inet6_ipsec6, OID_AUTO, + filtertunnel, CTLFLAG_RW, ip6_ipsec6_filtertunnel, 0, + "If set filter packets from an IPsec tunnel."); #endif /* INET6 */ static int ipsec_setspidx_inpcb __P((struct mbuf *, struct inpcb *)); @@ -273,6 +279,11 @@ ipsec_init(void) V_ip4_ah_net_deflev = IPSEC_LEVEL_USE; V_ip4_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ V_ip4_esp_randpad = -1; +#ifdef IPSEC_FILTERTUNNEL + V_ip4_ipsec_filtertunnel = 1; +#else + V_ip4_ipsec_filtertunnel = 0; +#endif V_crypto_support = CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE; @@ -287,6 +298,11 @@ ipsec_init(void) V_ip6_ah_trans_deflev = IPSEC_LEVEL_USE; V_ip6_ah_net_deflev = IPSEC_LEVEL_USE; V_ip6_ipsec_ecn = 0; /* ECN ignore(-1)/forbidden(0)/allowed(1) */ +#ifdef IPSEC_FILTERTUNNEL + V_ip6_ipsec6_filtertunnel = 1; +#else + V_ip6_ipsec6_filtertunnel = 0; +#endif #endif } diff --git a/sys/netipsec/ipsec.h b/sys/netipsec/ipsec.h index d5e7c157cfd7..c869ec85ee8c 100644 --- a/sys/netipsec/ipsec.h +++ b/sys/netipsec/ipsec.h @@ -348,6 +348,7 @@ extern int ip4_ah_cleartos; extern int ip4_ah_offsetmask; extern int ip4_ipsec_dfbit; extern int ip4_ipsec_ecn; +extern int ip4_ipsec_filtertunnel; extern int ip4_esp_randpad; extern int crypto_support; diff --git a/sys/netipsec/ipsec6.h b/sys/netipsec/ipsec6.h index 66124078bd12..2f494632886b 100644 --- a/sys/netipsec/ipsec6.h +++ b/sys/netipsec/ipsec6.h @@ -47,6 +47,7 @@ extern int ip6_esp_net_deflev; extern int ip6_ah_trans_deflev; extern int ip6_ah_net_deflev; extern int ip6_ipsec_ecn; +extern int ip6_ipsec6_filtertunnel; struct inpcb; diff --git a/sys/netipsec/vipsec.h b/sys/netipsec/vipsec.h index 12b37c7cb065..4a643e5e0238 100644 --- a/sys/netipsec/vipsec.h +++ b/sys/netipsec/vipsec.h @@ -57,6 +57,7 @@ struct vnet_ipsec { int _ip4_ah_offsetmask; int _ip4_ipsec_dfbit; int _ip4_ipsec_ecn; + int _ip4_ipsec_filtertunnel; int _ip4_esp_randpad; int _ipsec_replay; @@ -90,6 +91,7 @@ struct vnet_ipsec { int _ip6_ah_trans_deflev; int _ip6_ah_net_deflev; int _ip6_ipsec_ecn; + int _ip6_ipsec6_filtertunnel; int _ah_enable; int _ah_cleartos; @@ -142,12 +144,14 @@ extern struct vnet_ipsec vnet_ipsec_0; #define V_ip4_esp_trans_deflev VNET_IPSEC(ip4_esp_trans_deflev) #define V_ip4_ipsec_dfbit VNET_IPSEC(ip4_ipsec_dfbit) #define V_ip4_ipsec_ecn VNET_IPSEC(ip4_ipsec_ecn) +#define V_ip4_ipsec_filtertunnel VNET_IPSEC(ip4_ipsec_filtertunnel) #define V_ip6_ah_net_deflev VNET_IPSEC(ip6_ah_net_deflev) #define V_ip6_ah_trans_deflev VNET_IPSEC(ip6_ah_trans_deflev) #define V_ip6_esp_net_deflev VNET_IPSEC(ip6_esp_net_deflev) #define V_ip6_esp_randpad VNET_IPSEC(ip6_esp_randpad) #define V_ip6_esp_trans_deflev VNET_IPSEC(ip6_esp_trans_deflev) #define V_ip6_ipsec_ecn VNET_IPSEC(ip6_ipsec_ecn) +#define V_ip6_ipsec6_filtertunnel VNET_IPSEC(ip6_ipsec6_filtertunnel) #define V_ipcomp_enable VNET_IPSEC(ipcomp_enable) #define V_ipcompstat VNET_IPSEC(ipcompstat) #define V_ipip_allow VNET_IPSEC(ipip_allow) From 6a9148fe92fb60453c4e239bdfc2851808fe4f71 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 16:51:13 +0000 Subject: [PATCH 440/544] Implement UDP control block support. So far the udp_tun_func_t had been (ab)using inp_ppcb for udp in kernel tunneling callbacks. Move that into the udpcb and add a field for flags there to be used by upcoming changes instead of sticking udp only flags into in_pcb flags2. Bump __FreeBSD_version for ports to detect it and because of vnet* struct size changes. Submitted by: jhb (7.x version) Reviewed by: rwatson --- sys/netinet/udp_usrreq.c | 102 +++++++++++++++++++++++-------------- sys/netinet/udp_var.h | 18 ++++++- sys/netinet/vinet.h | 2 + sys/netinet6/udp6_usrreq.c | 55 +++++++++++--------- sys/sys/param.h | 2 +- 5 files changed, 114 insertions(+), 65 deletions(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 9aa83dd1f9fc..a49240c14b0c 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -137,6 +137,7 @@ SYSCTL_ULONG(_net_inet_udp, UDPCTL_RECVSPACE, recvspace, CTLFLAG_RW, #ifdef VIMAGE_GLOBALS struct inpcbhead udb; /* from udp_var.h */ struct inpcbinfo udbinfo; +static uma_zone_t udpcb_zone; struct udpstat udpstat; /* from udp_var.h */ #endif @@ -158,6 +159,7 @@ udp_zone_change(void *tag) INIT_VNET_INET(curvnet); uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets); + uma_zone_set_max(V_udpcb_zone, maxsockets); } static int @@ -187,13 +189,39 @@ udp_init(void) &V_udbinfo.ipi_hashmask); V_udbinfo.ipi_porthashbase = hashinit(UDBHASHSIZE, M_PCB, &V_udbinfo.ipi_porthashmask); - V_udbinfo.ipi_zone = uma_zcreate("udpcb", sizeof(struct inpcb), NULL, - NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + V_udbinfo.ipi_zone = uma_zcreate("udp_inpcb", sizeof(struct inpcb), + NULL, NULL, udp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(V_udbinfo.ipi_zone, maxsockets); + + V_udpcb_zone = uma_zcreate("udpcb", sizeof(struct udpcb), + NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); + uma_zone_set_max(V_udpcb_zone, maxsockets); + EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL, EVENTHANDLER_PRI_ANY); } +int +udp_newudpcb(struct inpcb *inp) +{ + INIT_VNET_INET(curvnet); + struct udpcb *up; + + up = uma_zalloc(V_udpcb_zone, M_NOWAIT | M_ZERO); + if (up == NULL) + return (ENOBUFS); + inp->inp_ppcb = up; + return (0); +} + +void +udp_discardcb(struct udpcb *up) +{ + INIT_VNET_INET(curvnet); + + uma_zfree(V_udpcb_zone, up); +} + /* * Subroutine of udp_input(), which appends the provided mbuf chain to the * passed pcb/socket. The caller must provide a sockaddr_in via udp_in that @@ -272,6 +300,7 @@ udp_input(struct mbuf *m, int off) struct udphdr *uh; struct ifnet *ifp; struct inpcb *inp; + struct udpcb *up; int len; struct ip save_ip; struct sockaddr_in udp_in; @@ -455,28 +484,25 @@ udp_input(struct mbuf *m, int off) struct mbuf *n; n = m_copy(m, 0, M_COPYALL); - if (last->inp_ppcb == NULL) { + up = intoudpcb(last); + if (up->u_tun_func == NULL) { if (n != NULL) udp_append(last, ip, n, iphlen + sizeof(struct udphdr), &udp_in); - INP_RUNLOCK(last); } else { /* * Engage the tunneling protocol we * will have to leave the info_lock * up, since we are hunting through * multiple UDP's. - * */ - udp_tun_func_t tunnel_func; - tunnel_func = (udp_tun_func_t)last->inp_ppcb; - tunnel_func(n, iphlen, last); - INP_RUNLOCK(last); + (*up->u_tun_func)(n, iphlen, last); } + INP_RUNLOCK(last); } last = inp; /* @@ -501,22 +527,18 @@ udp_input(struct mbuf *m, int off) UDPSTAT_INC(udps_noportbcast); goto badheadlocked; } - if (last->inp_ppcb == NULL) { + up = intoudpcb(last); + if (up->u_tun_func == NULL) { udp_append(last, ip, m, iphlen + sizeof(struct udphdr), &udp_in); - INP_RUNLOCK(last); - INP_INFO_RUNLOCK(&V_udbinfo); } else { /* * Engage the tunneling protocol. */ - udp_tun_func_t tunnel_func; - - tunnel_func = (udp_tun_func_t)last->inp_ppcb; - tunnel_func(m, iphlen, last); - INP_RUNLOCK(last); - INP_INFO_RUNLOCK(&V_udbinfo); + (*up->u_tun_func)(m, iphlen, last); } + INP_RUNLOCK(last); + INP_INFO_RUNLOCK(&V_udbinfo); return; } @@ -560,18 +582,16 @@ udp_input(struct mbuf *m, int off) INP_RUNLOCK(inp); goto badunlocked; } - if (inp->inp_ppcb != NULL) { + up = intoudpcb(inp); + if (up->u_tun_func == NULL) { + udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in); + } else { /* * Engage the tunneling protocol. */ - udp_tun_func_t tunnel_func; - tunnel_func = (udp_tun_func_t)inp->inp_ppcb; - tunnel_func(m, iphlen, inp); - INP_RUNLOCK(inp); - return; + (*up->u_tun_func)(m, iphlen, inp); } - udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in); INP_RUNLOCK(inp); return; @@ -1142,18 +1162,19 @@ udp_attach(struct socket *so, int proto, struct thread *td) } inp = (struct inpcb *)so->so_pcb; - INP_INFO_WUNLOCK(&V_udbinfo); inp->inp_vflag |= INP_IPV4; inp->inp_ip_ttl = V_ip_defttl; - /* - * UDP does not have a per-protocol pcb (inp->inp_ppcb). - * We use this pointer for kernel tunneling pointer. - * If we ever need to have a protocol block we will - * need to move this function pointer there. Null - * in this pointer means "do the normal thing". - */ - inp->inp_ppcb = NULL; + + error = udp_newudpcb(inp); + if (error) { + in_pcbdetach(inp); + in_pcbfree(inp); + INP_INFO_WUNLOCK(&V_udbinfo); + return (error); + } + INP_WUNLOCK(inp); + INP_INFO_WUNLOCK(&V_udbinfo); return (0); } @@ -1161,24 +1182,26 @@ int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f) { struct inpcb *inp; + struct udpcb *up; - inp = (struct inpcb *)so->so_pcb; KASSERT(so->so_type == SOCK_DGRAM, ("udp_set_kernel_tunneling: !dgram")); KASSERT(so->so_pcb != NULL, ("udp_set_kernel_tunneling: NULL inp")); if (so->so_type != SOCK_DGRAM) { /* Not UDP socket... sorry! */ return (ENOTSUP); } + inp = (struct inpcb *)so->so_pcb; if (inp == NULL) { /* NULL INP? */ return (EINVAL); } INP_WLOCK(inp); - if (inp->inp_ppcb != NULL) { + up = intoudpcb(inp); + if (up->u_tun_func != NULL) { INP_WUNLOCK(inp); return (EBUSY); } - inp->inp_ppcb = f; + up->u_tun_func = f; INP_WUNLOCK(inp); return (0); } @@ -1256,6 +1279,7 @@ udp_detach(struct socket *so) { INIT_VNET_INET(so->so_vnet); struct inpcb *inp; + struct udpcb *up; inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp_detach: inp == NULL")); @@ -1263,9 +1287,13 @@ udp_detach(struct socket *so) ("udp_detach: not disconnected")); INP_INFO_WLOCK(&V_udbinfo); INP_WLOCK(inp); + up = intoudpcb(inp); + KASSERT(up != NULL, ("%s: up == NULL", __func__)); + inp->inp_ppcb = NULL; in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(&V_udbinfo); + udp_discardcb(up); } static int diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index d83f705f58a6..e4298191e090 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -51,6 +51,19 @@ struct udpiphdr { #define ui_ulen ui_u.uh_ulen #define ui_sum ui_u.uh_sum +typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *); + +/* + * UDP control block; one per udp. + */ +struct udpcb { + udp_tun_func_t u_tun_func; /* UDP kernel tunneling callback. */ + u_int u_flags; /* Generic UDP flags. */ +}; + +#define intoudpcb(ip) ((struct udpcb *)(ip)->inp_ppcb) +#define sotoudpcb(so) (intoudpcb(sotoinpcb(so))) + struct udpstat { /* input statistics: */ u_long udps_ipackets; /* total input packets */ @@ -110,14 +123,15 @@ extern u_long udp_sendspace; extern u_long udp_recvspace; extern int udp_log_in_vain; +int udp_newudpcb(struct inpcb *); +void udp_discardcb(struct udpcb *); + void udp_ctlinput(int, struct sockaddr *, void *); void udp_init(void); void udp_input(struct mbuf *, int); struct inpcb *udp_notify(struct inpcb *inp, int errno); int udp_shutdown(struct socket *so); - -typedef void(*udp_tun_func_t)(struct mbuf *, int off, struct inpcb *); int udp_set_kernel_tunneling(struct socket *so, udp_tun_func_t f); #endif diff --git a/sys/netinet/vinet.h b/sys/netinet/vinet.h index 6dcb685b98eb..026869326e28 100644 --- a/sys/netinet/vinet.h +++ b/sys/netinet/vinet.h @@ -149,6 +149,7 @@ struct vnet_inet { struct inpcbhead _udb; struct inpcbinfo _udbinfo; + uma_zone_t _udpcb_zone; struct udpstat _udpstat; int _udp_blackhole; @@ -373,6 +374,7 @@ extern struct vnet_inet vnet_inet_0; #define V_twq_2msl VNET_INET(twq_2msl) #define V_udb VNET_INET(udb) #define V_udbinfo VNET_INET(udbinfo) +#define V_udpcb_zone VNET_INET(udpcb_zone) #define V_udp_blackhole VNET_INET(udp_blackhole) #define V_udpstat VNET_INET(udpstat) #define V_useloopback VNET_INET(useloopback) diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 19cca2c11810..11dcf249db50 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -181,6 +181,7 @@ udp6_input(struct mbuf **mp, int *offp, int proto) struct ip6_hdr *ip6; struct udphdr *uh; struct inpcb *inp; + struct udpcb *up; int off = *offp; int plen, ulen; struct sockaddr_in6 fromsa; @@ -315,7 +316,10 @@ udp6_input(struct mbuf **mp, int *offp, int proto) if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { INP_RLOCK(last); - if (last->inp_ppcb != NULL) { + up = intoudpcb(last); + if (up->u_tun_func == NULL) { + udp6_append(last, n, off, &fromsa); + } else { /* * Engage the tunneling * protocol we will have to @@ -324,15 +328,9 @@ udp6_input(struct mbuf **mp, int *offp, int proto) * through multiple UDP's. * */ - udp_tun_func_t tunnel_func; - - tunnel_func = (udp_tun_func_t)last->inp_ppcb; - tunnel_func(n, off, last); - INP_RUNLOCK(last); - } else { - udp6_append(last, n, off, &fromsa); - INP_RUNLOCK(last); + (*up->u_tun_func)(n, off, last); } + INP_RUNLOCK(last); } } last = inp; @@ -361,18 +359,15 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK(last); INP_INFO_RUNLOCK(&V_udbinfo); - if (last->inp_ppcb != NULL) { + up = intoudpcb(last); + if (up->u_tun_func == NULL) { + udp6_append(last, m, off, &fromsa); + } else { /* * Engage the tunneling protocol. */ - udp_tun_func_t tunnel_func; - - tunnel_func = (udp_tun_func_t)inp->inp_ppcb; - tunnel_func(m, off, last); - INP_RUNLOCK(last); - return (IPPROTO_DONE); + (*up->u_tun_func)(m, off, last); } - udp6_append(last, m, off, &fromsa); INP_RUNLOCK(last); return (IPPROTO_DONE); } @@ -409,18 +404,16 @@ udp6_input(struct mbuf **mp, int *offp, int proto) } INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); - if (inp->inp_ppcb != NULL) { + up = intoudpcb(inp); + if (up->u_tun_func == NULL) { + udp6_append(inp, m, off, &fromsa); + } else { /* * Engage the tunneling protocol. */ - udp_tun_func_t tunnel_func; - tunnel_func = (udp_tun_func_t)inp->inp_ppcb; - tunnel_func(m, off, inp); - INP_RUNLOCK(inp); - return (IPPROTO_DONE); + (*up->u_tun_func)(m, off, inp); } - udp6_append(inp, m, off, &fromsa); INP_RUNLOCK(inp); return (IPPROTO_DONE); @@ -820,7 +813,6 @@ udp6_attach(struct socket *so, int proto, struct thread *td) return (error); } inp = (struct inpcb *)so->so_pcb; - INP_INFO_WUNLOCK(&V_udbinfo); inp->inp_vflag |= INP_IPV6; if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) inp->inp_vflag |= INP_IPV4; @@ -833,7 +825,16 @@ udp6_attach(struct socket *so, int proto, struct thread *td) * which may match an IPv4-mapped IPv6 address. */ inp->inp_ip_ttl = V_ip_defttl; + + error = udp_newudpcb(inp); + if (error) { + in_pcbdetach(inp); + in_pcbfree(inp); + INP_INFO_WUNLOCK(&V_udbinfo); + return (error); + } INP_WUNLOCK(inp); + INP_INFO_WUNLOCK(&V_udbinfo); return (0); } @@ -968,15 +969,19 @@ udp6_detach(struct socket *so) { INIT_VNET_INET(so->so_vnet); struct inpcb *inp; + struct udpcb *up; inp = sotoinpcb(so); KASSERT(inp != NULL, ("udp6_detach: inp == NULL")); INP_INFO_WLOCK(&V_udbinfo); INP_WLOCK(inp); + up = intoudpcb(inp); + KASSERT(up != NULL, ("%s: up == NULL", __func__)); in_pcbdetach(inp); in_pcbfree(inp); INP_INFO_WUNLOCK(&V_udbinfo); + udp_discardcb(up); } static int diff --git a/sys/sys/param.h b/sys/sys/param.h index 4b02e6ad98a4..19dc83eedcda 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800088 /* Master, propagated to newvers */ +#define __FreeBSD_version 800089 /* Master, propagated to newvers */ #ifndef LOCORE #include From dfb31dee8778953dd488c7becf9f323bba71f3f5 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sat, 23 May 2009 16:54:07 +0000 Subject: [PATCH 441/544] Add more obsolete files, old NFSv4 client and legacy USB related. --- ObsoleteFiles.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index ee2e2a95c9ac..899a3febe201 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -18,7 +18,11 @@ OLD_FILES+=etc/rc.d/idmapd OLD_FILES+=sbin/idmapd OLD_FILES+=sbin/mount_nfs4 +OLD_FILES+=usr/share/man/man8/idmapd.8.gz OLD_FILES+=usr/share/man/man8/mount_nfs4.8.gz +# 20090513: removal of legacy versions of USB network interface drivers +OLD_FILES+=usr/include/legacy/dev/usb/if_upgtvar.h +OLD_FILES+=usr/include/legacy/dev/usb/usb_ethersubr.h # 20090417: removal of legacy versions of USB network interface drivers OLD_FILES+=usr/include/legacy/dev/usb/if_auereg.h OLD_FILES+=usr/include/legacy/dev/usb/if_axereg.h From 6d453b1001779dd7d7870f0a939fbc904907ac3d Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 17:02:30 +0000 Subject: [PATCH 442/544] For UDP with introducing the UDP control block, the uma zone had to be named "udp_inpcb" to avoid a naming conflict with tcp[1]. For consistency rename the uma zone for TCP from "inpcb" to "tcp_inpcb". Found by: rwatson [1] Discussed with: rwatson --- sys/netinet/tcp_subr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c index c1dc4b3caac5..3c65a5412998 100644 --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -373,7 +373,7 @@ tcp_init(void) &V_tcbinfo.ipi_hashmask); V_tcbinfo.ipi_porthashbase = hashinit(hashsize, M_PCB, &V_tcbinfo.ipi_porthashmask); - V_tcbinfo.ipi_zone = uma_zcreate("inpcb", sizeof(struct inpcb), + V_tcbinfo.ipi_zone = uma_zcreate("tcp_inpcb", sizeof(struct inpcb), NULL, NULL, tcp_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE); uma_zone_set_max(V_tcbinfo.ipi_zone, maxsockets); /* From 069e32c62d1d9830ba4d7a0d7be7c32b916cc6bb Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sat, 23 May 2009 17:09:47 +0000 Subject: [PATCH 443/544] Add new #defines neccessary to support NFSv4 ACLs. Reviewed by: rwatson --- sys/sys/acl.h | 64 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/sys/sys/acl.h b/sys/sys/acl.h index c14423a554bf..ea4ed3aab190 100644 --- a/sys/sys/acl.h +++ b/sys/sys/acl.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 1999-2001 Robert N. M. Watson + * Copyright (c) 2008 Edward Tomasz NapieraÅ‚a * All rights reserved. * * This software was developed by Robert Watson for the TrustedBSD Project. @@ -29,7 +30,7 @@ */ /* * Developed by the TrustedBSD Project. - * Support for POSIX.1e access control lists. + * Support for POSIX.1e and NFSv4 access control lists. */ #ifndef _SYS_ACL_H_ @@ -40,7 +41,7 @@ #include /* - * POSIX.1e ACL types and related constants. + * POSIX.1e and NFSv4 ACL types and related constants. */ typedef uint32_t acl_tag_t; @@ -53,7 +54,7 @@ typedef uint16_t *acl_flagset_t; /* * With 254 entries, "struct acl_t_struct" is exactly one 4kB page big. - * Note that with NFS4 ACLs, the maximum number of ACL entries one + * Note that with NFSv4 ACLs, the maximum number of ACL entries one * may set on file or directory is about half of ACL_MAX_ENTRIES. * * If you increase this, you might also need to increase @@ -110,7 +111,7 @@ typedef struct acl_entry *acl_entry_t; /* * Internal ACL structure, used in libc, kernel APIs and for on-disk - * storage of NFS4 ACLs. POSIX.1e ACLs use "struct oldacl" for on-disk + * storage of NFSv4 ACLs. POSIX.1e ACLs use "struct oldacl" for on-disk * storage. */ struct acl { @@ -150,6 +151,15 @@ typedef void *acl_t; #define ACL_MASK 0x00000010 #define ACL_OTHER 0x00000020 #define ACL_OTHER_OBJ ACL_OTHER +#define ACL_EVERYONE 0x00000040 + +/* + * Possible valid values for ae_entry_type field, valid only for NFSv4 ACLs. + */ +#define ACL_ENTRY_TYPE_ALLOW 0x0100 +#define ACL_ENTRY_TYPE_DENY 0x0200 +#define ACL_ENTRY_TYPE_AUDIT 0x0400 +#define ACL_ENTRY_TYPE_ALARM 0x0800 /* * Possible valid values for acl_type_t arguments. First two @@ -159,9 +169,10 @@ typedef void *acl_t; #define ACL_TYPE_DEFAULT_OLD 0x00000001 #define ACL_TYPE_ACCESS 0x00000002 #define ACL_TYPE_DEFAULT 0x00000003 +#define ACL_TYPE_NFS4 0x00000004 /* - * Possible flags in ae_perm field for POSIX.1e ACLs. Note + * Possible bits in ae_perm field for POSIX.1e ACLs. Note * that ACL_EXECUTE may be used in both NFSv4 and POSIX.1e ACLs. */ #define ACL_EXECUTE 0x0001 @@ -171,19 +182,60 @@ typedef void *acl_t; #define ACL_PERM_BITS (ACL_EXECUTE | ACL_WRITE | ACL_READ) #define ACL_POSIX1E_BITS (ACL_EXECUTE | ACL_WRITE | ACL_READ) +/* + * Possible bits in ae_perm field for NFSv4 ACLs. + */ +#define ACL_READ_DATA 0x00000008 +#define ACL_LIST_DIRECTORY 0x00000008 +#define ACL_WRITE_DATA 0x00000010 +#define ACL_ADD_FILE 0x00000010 +#define ACL_APPEND_DATA 0x00000020 +#define ACL_ADD_SUBDIRECTORY 0x00000020 +#define ACL_READ_NAMED_ATTRS 0x00000040 +#define ACL_WRITE_NAMED_ATTRS 0x00000080 +/* ACL_EXECUTE is defined above. */ +#define ACL_DELETE_CHILD 0x00000100 +#define ACL_READ_ATTRIBUTES 0x00000200 +#define ACL_WRITE_ATTRIBUTES 0x00000400 +#define ACL_DELETE 0x00000800 +#define ACL_READ_ACL 0x00001000 +#define ACL_WRITE_ACL 0x00002000 +#define ACL_WRITE_OWNER 0x00004000 +#define ACL_SYNCHRONIZE 0x00008000 + +#define ACL_NFS4_PERM_BITS (ACL_READ_DATA | ACL_WRITE_DATA | \ + ACL_APPEND_DATA | ACL_READ_NAMED_ATTRS | ACL_WRITE_NAMED_ATTRS | \ + ACL_EXECUTE | ACL_DELETE_CHILD | ACL_READ_ATTRIBUTES | \ + ACL_WRITE_ATTRIBUTES | ACL_DELETE | ACL_READ_ACL | ACL_WRITE_ACL | \ + ACL_WRITE_OWNER | ACL_SYNCHRONIZE) + /* * Possible entry_id values for acl_get_entry(3). */ #define ACL_FIRST_ENTRY 0 #define ACL_NEXT_ENTRY 1 +/* + * Possible values in ae_flags field; valid only for NFSv4 ACLs. + */ +#define ACL_ENTRY_FILE_INHERIT 0x0001 +#define ACL_ENTRY_DIRECTORY_INHERIT 0x0002 +#define ACL_ENTRY_NO_PROPAGATE_INHERIT 0x0004 +#define ACL_ENTRY_INHERIT_ONLY 0x0008 +#define ACL_ENTRY_SUCCESSFUL_ACCESS 0x0010 +#define ACL_ENTRY_FAILED_ACCESS 0x0020 + +#define ACL_FLAGS_BITS (ACL_ENTRY_FILE_INHERIT | \ + ACL_ENTRY_DIRECTORY_INHERIT | ACL_ENTRY_NO_PROPAGATE_INHERIT | \ + ACL_ENTRY_INHERIT_ONLY | ACL_ENTRY_SUCCESSFUL_ACCESS | \ + ACL_ENTRY_FAILED_ACCESS) + /* * Undefined value in ae_id field. ae_id should be set to this value * iff ae_tag is ACL_USER_OBJ, ACL_GROUP_OBJ, ACL_OTHER or ACL_EVERYONE. */ #define ACL_UNDEFINED_ID ((uid_t)-1) - #ifdef _KERNEL /* From 2b7d3fb503d4fbebca62ea2f61b1e34bcc9012fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dag-Erling=20Sm=C3=B8rgrav?= Date: Sat, 23 May 2009 17:13:35 +0000 Subject: [PATCH 444/544] More bogus props. From 5662349ed5432d36a6977b502cd7b355c300bf5a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 23 May 2009 18:25:11 +0000 Subject: [PATCH 445/544] Eliminate the unnecessary clearing of a page's dirty bits from nwfs_getpages(). --- sys/fs/nwfs/nwfs_io.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/fs/nwfs/nwfs_io.c b/sys/fs/nwfs/nwfs_io.c index e45c2add346a..2f9ac0153466 100644 --- a/sys/fs/nwfs/nwfs_io.c +++ b/sys/fs/nwfs/nwfs_io.c @@ -463,10 +463,13 @@ nwfs_getpages(ap) if (nextoff <= size) { m->valid = VM_PAGE_BITS_ALL; - m->dirty = 0; + KASSERT(m->dirty == 0, + ("nwfs_getpages: page %p is dirty", m)); } else { int nvalid = ((size + DEV_BSIZE - 1) - toff) & ~(DEV_BSIZE - 1); - vm_page_set_validclean(m, 0, nvalid); + vm_page_set_valid(m, 0, nvalid); + KASSERT((m->dirty & vm_page_bits(0, nvalid)) == 0, + ("nwfs_getpages: page %p is dirty", m)); } if (i != ap->a_reqpage) { From b4b264f3e98d138dd4ceea5e4ae2f7c8dc4d9df6 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 23 May 2009 18:33:22 +0000 Subject: [PATCH 446/544] When a page is mapped for write access on a read fault, the PTE should be configured to trap on a write access unless *all* of the page's dirty bits are set. --- sys/mips/mips/pmap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 2188c3695615..c3d6060a35ec 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -3116,7 +3116,8 @@ init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot) */ rw = PTE_RWPAGE; vm_page_dirty(m); - } else if ((m->md.pv_flags & PV_TABLE_MOD) || m->dirty) + } else if ((m->md.pv_flags & PV_TABLE_MOD) || + m->dirty == VM_PAGE_BITS_ALL) rw = PTE_RWPAGE; else rw = PTE_CWPAGE; From 56c4a67ba7c73cfae43a42a1f589129f6381ba15 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 23 May 2009 18:44:26 +0000 Subject: [PATCH 447/544] Give pmap_enter()'s third parameter the same name that it has on amd64 and i386. Otherwise, my next to last commit (r192628) to this file doesn't actually compile. --- sys/mips/mips/pmap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index c3d6060a35ec..229e19874d2f 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -1729,8 +1729,8 @@ pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot) * insert this page into the given map NOW. */ void -pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t fault_type, vm_page_t m, vm_prot_t prot, - boolean_t wired) +pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t m, + vm_prot_t prot, boolean_t wired) { vm_offset_t pa, opa; register pt_entry_t *pte; From e8138981f4f284fe7f52e70f3fb5d3336b5976e7 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 23 May 2009 19:14:20 +0000 Subject: [PATCH 448/544] accumulate npe statistics and expose them through dev.npe.X.stats --- sys/arm/xscale/ixp425/if_npe.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/sys/arm/xscale/ixp425/if_npe.c b/sys/arm/xscale/ixp425/if_npe.c index 5d805d455729..f50a8689130d 100644 --- a/sys/arm/xscale/ixp425/if_npe.c +++ b/sys/arm/xscale/ixp425/if_npe.c @@ -143,6 +143,7 @@ struct npe_softc { struct npestats *sc_stats; bus_dmamap_t sc_stats_map; bus_addr_t sc_stats_phys; /* phys addr of sc_stats */ + struct npestats sc_totals; /* accumulated sc_stats */ }; /* @@ -374,6 +375,8 @@ npe_attach(device_t dev) CTLFLAG_RW, &sc->sc_debug, 0, "control debugging printfs"); SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "tickinterval", CTLFLAG_RW, &sc->sc_tickinterval, 0, "periodic work frequency"); + SYSCTL_ADD_STRUCT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, "stats", + CTLFLAG_RD, &sc->sc_totals, npestats, "onboard stats"); ether_ifattach(ifp, eaddr); return 0; @@ -867,12 +870,24 @@ npe_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr) static void npe_addstats(struct npe_softc *sc) { -#define MIBADD(x) sc->mibdata.x += be32toh(ns->x) +#define NPEADD(x) sc->sc_totals.x += be32toh(ns->x) +#define MIBADD(x) do { sc->mibdata.x += be32toh(ns->x); NPEADD(x); } while (0) struct ifnet *ifp = sc->sc_ifp; struct npestats *ns = sc->sc_stats; MIBADD(dot3StatsAlignmentErrors); MIBADD(dot3StatsFCSErrors); + MIBADD(dot3StatsInternalMacReceiveErrors); + NPEADD(RxOverrunDiscards); + NPEADD(RxLearnedEntryDiscards); + NPEADD(RxLargeFramesDiscards); + NPEADD(RxSTPBlockedDiscards); + NPEADD(RxVLANTypeFilterDiscards); + NPEADD(RxVLANIdFilterDiscards); + NPEADD(RxInvalidSourceDiscards); + NPEADD(RxBlackListDiscards); + NPEADD(RxWhiteListDiscards); + NPEADD(RxUnderflowEntryDiscards); MIBADD(dot3StatsSingleCollisionFrames); MIBADD(dot3StatsMultipleCollisionFrames); MIBADD(dot3StatsDeferredTransmissions); @@ -880,10 +895,12 @@ npe_addstats(struct npe_softc *sc) MIBADD(dot3StatsExcessiveCollisions); MIBADD(dot3StatsInternalMacTransmitErrors); MIBADD(dot3StatsCarrierSenseErrors); + NPEADD(TxLargeFrameDiscards); + NPEADD(TxVLANIdFilterDiscards); + sc->mibdata.dot3StatsFrameTooLongs += be32toh(ns->RxLargeFramesDiscards) + be32toh(ns->TxLargeFrameDiscards); - MIBADD(dot3StatsInternalMacReceiveErrors); sc->mibdata.dot3StatsMissedFrames += be32toh(ns->RxOverrunDiscards) + be32toh(ns->RxUnderflowEntryDiscards); @@ -902,6 +919,7 @@ npe_addstats(struct npe_softc *sc) be32toh(ns->dot3StatsSingleCollisionFrames) + be32toh(ns->dot3StatsMultipleCollisionFrames) ; +#undef NPEADD #undef MIBADD } From fc4c0664997482ff660b6a8f6278449c516ef1e7 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 23 May 2009 19:16:34 +0000 Subject: [PATCH 449/544] add npe tools; first is npestats which reports device statistics --- tools/tools/README | 1 + tools/tools/npe/Makefile | 5 + tools/tools/npe/npestats/Makefile | 8 + tools/tools/npe/npestats/main.c | 143 ++++++++++++++ tools/tools/npe/npestats/npestats.c | 278 ++++++++++++++++++++++++++++ tools/tools/npe/npestats/npestats.h | 50 +++++ tools/tools/npe/npestats/statfoo.c | 192 +++++++++++++++++++ tools/tools/npe/npestats/statfoo.h | 127 +++++++++++++ 8 files changed, 804 insertions(+) create mode 100644 tools/tools/npe/Makefile create mode 100644 tools/tools/npe/npestats/Makefile create mode 100644 tools/tools/npe/npestats/main.c create mode 100644 tools/tools/npe/npestats/npestats.c create mode 100644 tools/tools/npe/npestats/npestats.h create mode 100644 tools/tools/npe/npestats/statfoo.c create mode 100644 tools/tools/npe/npestats/statfoo.h diff --git a/tools/tools/README b/tools/tools/README index de7e80fc9bee..ef934651907c 100644 --- a/tools/tools/README +++ b/tools/tools/README @@ -47,6 +47,7 @@ mfc Merge a directory from HEAD to a branch where it does not already exist and other MFC related script(s). mid Create a Message-ID database for mailing lists. ncpus Count the number of processors +npe Tools specific to the Intel IXP4XXX NPE device nxge A diagnostic tool for the nxge(4) driver pciid Generate src/share/misc/pci_vendors. pciroms A tool for dumping PCI ROM images. WARNING: alpha quality. diff --git a/tools/tools/npe/Makefile b/tools/tools/npe/Makefile new file mode 100644 index 000000000000..4551a4b90d33 --- /dev/null +++ b/tools/tools/npe/Makefile @@ -0,0 +1,5 @@ +# $FreeBSD$ + +SUBDIR= npestats + +.include diff --git a/tools/tools/npe/npestats/Makefile b/tools/tools/npe/npestats/Makefile new file mode 100644 index 000000000000..1683fc9d74c1 --- /dev/null +++ b/tools/tools/npe/npestats/Makefile @@ -0,0 +1,8 @@ +# $FreeBSD$ + +PROG= npestats +SRCS= main.c statfoo.c npestats.c +BINDIR= /usr/local/bin +NO_MAN= true + +.include diff --git a/tools/tools/npe/npestats/main.c b/tools/tools/npe/npestats/main.c new file mode 100644 index 000000000000..3517aabb1f5b --- /dev/null +++ b/tools/tools/npe/npestats/main.c @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +#include +#include +#include +#include +#include +#include + +#include "npestats.h" + +static struct { + const char *tag; + const char *fmt; +} tags[] = { + { "default", + "align,fcs,macrx,overrun,learn,large,stp,badsrc,underflow,collision1,collisionM,deferred,late,excessive,mactx,carrier,toobig" + }, +}; + +static const char * +getfmt(const char *tag) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + int i; + for (i = 0; i < N(tags); i++) + if (strcasecmp(tags[i].tag, tag) == 0) + return tags[i].fmt; + return tag; +#undef N +} + +static int signalled; + +static void +catchalarm(int signo __unused) +{ + signalled = 1; +} + +int +main(int argc, char *argv[]) +{ + struct npestatfoo *wf; + const char *ifname; + int c, banner = 1; + + ifname = getenv("NPE"); + if (ifname == NULL) + ifname = "npe0"; + wf = npestats_new(ifname, getfmt("default")); + while ((c = getopt(argc, argv, "bi:lo:z")) != -1) { + switch (c) { + case 'b': + banner = 0; + break; + case 'i': + wf->setifname(wf, optarg); + break; + case 'l': + wf->print_fields(wf, stdout); + return 0; + case 'o': + wf->setfmt(wf, getfmt(optarg)); + break; + default: + errx(-1, "usage: %s [-a] [-i ifname] [-l] [-o fmt] [interval]\n", argv[0]); + /*NOTREACHED*/ + } + } + argc -= optind; + argv += optind; + + if (argc > 0) { + u_long interval = strtoul(argv[0], NULL, 0); + int line, omask; + + if (interval < 1) + interval = 1; + signal(SIGALRM, catchalarm); + signalled = 0; + alarm(interval); + banner: + if (banner) + wf->print_header(wf, stdout); + line = 0; + loop: + if (line != 0) { + wf->collect_cur(wf); + wf->print_current(wf, stdout); + wf->update_tot(wf); + } else { + wf->collect_tot(wf); + wf->print_total(wf, stdout); + } + fflush(stdout); + omask = sigblock(sigmask(SIGALRM)); + if (!signalled) + sigpause(0); + sigsetmask(omask); + signalled = 0; + alarm(interval); + line++; + if (line == 21) /* XXX tty line count */ + goto banner; + else + goto loop; + /*NOTREACHED*/ + } else { + wf->collect_tot(wf); + wf->print_verbose(wf, stdout); + } + return 0; +} diff --git a/tools/tools/npe/npestats/npestats.c b/tools/tools/npe/npestats/npestats.c new file mode 100644 index 000000000000..3d2a4c209855 --- /dev/null +++ b/tools/tools/npe/npestats/npestats.c @@ -0,0 +1,278 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +/* + * npe statistics class. + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "npestats.h" + +#define AFTER(prev) ((prev)+1) + +static const struct fmt npestats[] = { +#define S_ALIGN 0 + { 7, "align", "align", "alignment errors" }, +#define S_FCS AFTER(S_ALIGN) + { 7, "fcs", "fcs", "FCS errors" }, +#define S_MACRX AFTER(S_FCS) + { 7, "macrx", "macrx", "internal MAC rx errors" }, +#define S_RXORN AFTER(S_MACRX) + { 6, "overrun", "overrun", "rx overrun discards" }, +#define S_LEARN AFTER(S_RXORN) + { 5, "learn", "learn", "rx learned entry discards" }, +#define S_LARGE AFTER(S_LEARN) + { 5, "large", "large", "rx large frame discards" }, +#define S_STP AFTER(S_LARGE) + { 5, "stp", "stp", "rx STP blocked discards" }, +#define S_RX_VLAN_TYPE AFTER(S_STP) + { 5, "rx_vlan_type", "rx_vlant", "rx VLAN type filter discards" }, +#define S_RX_VLAN_ID AFTER(S_RX_VLAN_TYPE) + { 5, "rx_vlan_id", "rx_vlani", "rx VLAN Id filter discards" }, +#define S_BADSRC AFTER(S_RX_VLAN_ID) + { 5, "badsrc", "badsrc", "rx invalid source discards" }, +#define S_BLACKLIST AFTER(S_BADSRC) + { 5, "blacklist", "blacklist", "rx black list discards" }, +#define S_WHITELIST AFTER(S_BLACKLIST) + { 5, "whitelist", "whitelist", "rx white list discards" }, +#define S_UNDERFLOW AFTER(S_WHITELIST) + { 5, "underflow", "underflow", "rx underflow entry discards" }, +#define S_COLL_SINGLE AFTER(S_UNDERFLOW) + { 5, "collision1", "collision1", "single collision frames" }, +#define S_COLL_MULTI AFTER(S_COLL_SINGLE) + { 5, "collisionM", "collisionM", "multiple collision frames" }, +#define S_DEFERRED AFTER(S_COLL_MULTI) + { 5, "deferred", "deferred", "deferred transmissions" }, +#define S_LATE AFTER(S_DEFERRED) + { 5, "late", "late", "late collisions" }, +#define S_EXCESSIVE AFTER(S_LATE) + { 5, "excessive", "excessive", "excessive collisions" }, +#define S_MACTX AFTER(S_EXCESSIVE) + { 7, "mactx", "mactx", "internal MAC tx errors" }, +#define S_CARRIER AFTER(S_MACTX) + { 7, "carrier", "carrier", "carrier sense errors" }, +#define S_TOOBIG AFTER(S_CARRIER) + { 7, "toobig", "toobig", "tx large frame discards" }, +#define S_TX_VLAN_ID AFTER(S_TOOBIG) + { 7, "tx_vlan_id", "tx_vlani", "tx VLAN Id filter discards" }, +}; +#define S_LAST S_TX_VLAN_ID + +/* + * Stat block returned by NPE with NPE_GETSTATS msg. + */ +struct npestats { + uint32_t dot3StatsAlignmentErrors; + uint32_t dot3StatsFCSErrors; + uint32_t dot3StatsInternalMacReceiveErrors; + uint32_t RxOverrunDiscards; + uint32_t RxLearnedEntryDiscards; + uint32_t RxLargeFramesDiscards; + uint32_t RxSTPBlockedDiscards; + uint32_t RxVLANTypeFilterDiscards; + uint32_t RxVLANIdFilterDiscards; + uint32_t RxInvalidSourceDiscards; + uint32_t RxBlackListDiscards; + uint32_t RxWhiteListDiscards; + uint32_t RxUnderflowEntryDiscards; + uint32_t dot3StatsSingleCollisionFrames; + uint32_t dot3StatsMultipleCollisionFrames; + uint32_t dot3StatsDeferredTransmissions; + uint32_t dot3StatsLateCollisions; + uint32_t dot3StatsExcessiveCollisions; + uint32_t dot3StatsInternalMacTransmitErrors; + uint32_t dot3StatsCarrierSenseErrors; + uint32_t TxLargeFrameDiscards; + uint32_t TxVLANIdFilterDiscards; +}; + +struct npestatfoo_p { + struct npestatfoo base; + char oid[80]; + int mib[4]; + struct npestats cur; + struct npestats total; +}; + +static void +npe_setifname(struct npestatfoo *wf0, const char *ifname) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) wf0; + size_t len; + + snprintf(wf->oid, sizeof(wf->oid), "dev.npe.%s.stats", ifname+3); + len = 4; + if (sysctlnametomib(wf->oid, wf->mib, &len) < 0) + err(1, "sysctlnametomib: %s", wf->oid); +} + +static void +npe_collect(struct npestatfoo_p *wf, struct npestats *stats) +{ + size_t len = sizeof(struct npestats); + if (sysctl(wf->mib, 4, stats, &len, NULL, 0) < 0) + err(1, "sysctl: %s", wf->oid); +} + +static void +npe_collect_cur(struct statfoo *sf) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) sf; + + npe_collect(wf, &wf->cur); +} + +static void +npe_collect_tot(struct statfoo *sf) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) sf; + + npe_collect(wf, &wf->total); +} + +static void +npe_update_tot(struct statfoo *sf) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) sf; + + wf->total = wf->cur; +} + +static int +npe_get_curstat(struct statfoo *sf, int s, char b[], size_t bs) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) sf; +#define STAT(x) \ + snprintf(b, bs, "%u", wf->cur.x - wf->total.x); return 1 + + switch (s) { + case S_ALIGN: STAT(dot3StatsAlignmentErrors); + case S_FCS: STAT(dot3StatsFCSErrors); + case S_MACRX: STAT(dot3StatsInternalMacReceiveErrors); + case S_RXORN: STAT(RxOverrunDiscards); + case S_LEARN: STAT(RxLearnedEntryDiscards); + case S_LARGE: STAT(RxLargeFramesDiscards); + case S_STP: STAT(RxSTPBlockedDiscards); + case S_RX_VLAN_TYPE: STAT(RxVLANTypeFilterDiscards); + case S_RX_VLAN_ID: STAT(RxVLANIdFilterDiscards); + case S_BADSRC: STAT(RxInvalidSourceDiscards); + case S_BLACKLIST: STAT(RxBlackListDiscards); + case S_WHITELIST: STAT(RxWhiteListDiscards); + case S_UNDERFLOW: STAT(RxUnderflowEntryDiscards); + case S_COLL_SINGLE: STAT(dot3StatsSingleCollisionFrames); + case S_COLL_MULTI: STAT(dot3StatsMultipleCollisionFrames); + case S_DEFERRED: STAT(dot3StatsDeferredTransmissions); + case S_LATE: STAT(dot3StatsLateCollisions); + case S_EXCESSIVE: STAT(dot3StatsExcessiveCollisions); + case S_MACTX: STAT(dot3StatsInternalMacTransmitErrors); + case S_CARRIER: STAT(dot3StatsCarrierSenseErrors); + case S_TOOBIG: STAT(TxLargeFrameDiscards); + case S_TX_VLAN_ID: STAT(TxVLANIdFilterDiscards); + } + b[0] = '\0'; + return 0; +#undef STAT +} + +static int +npe_get_totstat(struct statfoo *sf, int s, char b[], size_t bs) +{ + struct npestatfoo_p *wf = (struct npestatfoo_p *) sf; +#define STAT(x) \ + snprintf(b, bs, "%u", wf->total.x); return 1 + + switch (s) { + case S_ALIGN: STAT(dot3StatsAlignmentErrors); + case S_FCS: STAT(dot3StatsFCSErrors); + case S_MACRX: STAT(dot3StatsInternalMacReceiveErrors); + case S_RXORN: STAT(RxOverrunDiscards); + case S_LEARN: STAT(RxLearnedEntryDiscards); + case S_LARGE: STAT(RxLargeFramesDiscards); + case S_STP: STAT(RxSTPBlockedDiscards); + case S_RX_VLAN_TYPE: STAT(RxVLANTypeFilterDiscards); + case S_RX_VLAN_ID: STAT(RxVLANIdFilterDiscards); + case S_BADSRC: STAT(RxInvalidSourceDiscards); + case S_BLACKLIST: STAT(RxBlackListDiscards); + case S_WHITELIST: STAT(RxWhiteListDiscards); + case S_UNDERFLOW: STAT(RxUnderflowEntryDiscards); + case S_COLL_SINGLE: STAT(dot3StatsSingleCollisionFrames); + case S_COLL_MULTI: STAT(dot3StatsMultipleCollisionFrames); + case S_DEFERRED: STAT(dot3StatsDeferredTransmissions); + case S_LATE: STAT(dot3StatsLateCollisions); + case S_EXCESSIVE: STAT(dot3StatsExcessiveCollisions); + case S_MACTX: STAT(dot3StatsInternalMacTransmitErrors); + case S_CARRIER: STAT(dot3StatsCarrierSenseErrors); + case S_TOOBIG: STAT(TxLargeFrameDiscards); + case S_TX_VLAN_ID: STAT(TxVLANIdFilterDiscards); + } + b[0] = '\0'; + return 0; +#undef STAT +} + +STATFOO_DEFINE_BOUNCE(npestatfoo) + +struct npestatfoo * +npestats_new(const char *ifname, const char *fmtstring) +{ +#define N(a) (sizeof(a) / sizeof(a[0])) + struct npestatfoo_p *wf; + + wf = calloc(1, sizeof(struct npestatfoo_p)); + if (wf != NULL) { + statfoo_init(&wf->base.base, "npestats", npestats, N(npestats)); + /* override base methods */ + wf->base.base.collect_cur = npe_collect_cur; + wf->base.base.collect_tot = npe_collect_tot; + wf->base.base.get_curstat = npe_get_curstat; + wf->base.base.get_totstat = npe_get_totstat; + wf->base.base.update_tot = npe_update_tot; + + /* setup bounce functions for public methods */ + STATFOO_BOUNCE(wf, npestatfoo); + + /* setup our public methods */ + wf->base.setifname = npe_setifname; + + npe_setifname(&wf->base, ifname); + wf->base.setfmt(&wf->base, fmtstring); + } + return &wf->base; +#undef N +} diff --git a/tools/tools/npe/npestats/npestats.h b/tools/tools/npe/npestats/npestats.h new file mode 100644 index 000000000000..8342ed5381be --- /dev/null +++ b/tools/tools/npe/npestats/npestats.h @@ -0,0 +1,50 @@ +/*- + * Copyright (c) 2009 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +#ifndef _NPESTATS_H_ +#define _NPESTATS_H_ + +#include "statfoo.h" + +/* + * npe statistics class. + */ +struct npestatfoo { + struct statfoo base; + + STATFOO_DECL_METHODS(struct npestatfoo *); + + /* set the network interface name for collection */ + void (*setifname)(struct npestatfoo *, const char *ifname); +}; + +struct npestatfoo *npestats_new(const char *ifname, const char *fmtstring); +#endif /* _NPESTATS_H_ */ diff --git a/tools/tools/npe/npestats/statfoo.c b/tools/tools/npe/npestats/statfoo.c new file mode 100644 index 000000000000..9963ea0495c7 --- /dev/null +++ b/tools/tools/npe/npestats/statfoo.c @@ -0,0 +1,192 @@ +/*- + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +#include +#include + +#include "statfoo.h" + +static void +statfoo_setfmt(struct statfoo *sf, const char *fmt0) +{ +#define N(a) (sizeof(a)/sizeof(a[0])) + char fmt[4096]; + char *fp, *tok; + int i, j; + + j = 0; + strlcpy(fmt, fmt0, sizeof(fmt)); + for (fp = fmt; (tok = strsep(&fp, ", ")) != NULL;) { + for (i = 0; i < sf->nstats; i++) + if (strcasecmp(tok, sf->stats[i].name) == 0) + break; + if (i >= sf->nstats) { + fprintf(stderr, "%s: unknown statistic name \"%s\" " + "skipped\n", sf->name, tok); + continue; + } + if (j+3 > sizeof(sf->fmts)) { + fprintf(stderr, "%s: not enough room for all stats; " + "stopped at %s\n", sf->name, tok); + break; + } + if (j != 0) + sf->fmts[j++] = ' '; + sf->fmts[j++] = 0x80 | i; + } + sf->fmts[j] = '\0'; +#undef N +} + +static void +statfoo_collect(struct statfoo *sf) +{ + fprintf(stderr, "%s: don't know how to collect data\n", sf->name); +} + +static void +statfoo_update_tot(struct statfoo *sf) +{ + fprintf(stderr, "%s: don't know how to update total data\n", sf->name); +} + +static int +statfoo_get(struct statfoo *sf, int s, char b[], size_t bs) +{ + fprintf(stderr, "%s: don't know how to get stat #%u\n", sf->name, s); + return 0; +} + +static void +statfoo_print_header(struct statfoo *sf, FILE *fd) +{ + const unsigned char *cp; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp & 0x80) { + const struct fmt *f = &sf->stats[*cp &~ 0x80]; + fprintf(fd, "%*s", f->width, f->label); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_current(struct statfoo *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp & 0x80) { + const struct fmt *f = &sf->stats[*cp &~ 0x80]; + if (sf->get_curstat(sf, *cp &~ 0x80, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_total(struct statfoo *sf, FILE *fd) +{ + char buf[32]; + const unsigned char *cp; + + for (cp = sf->fmts; *cp != '\0'; cp++) { + if (*cp & 0x80) { + const struct fmt *f = &sf->stats[*cp &~ 0x80]; + if (sf->get_totstat(sf, *cp &~ 0x80, buf, sizeof(buf))) + fprintf(fd, "%*s", f->width, buf); + } else + putc(*cp, fd); + } + putc('\n', fd); +} + +static void +statfoo_print_verbose(struct statfoo *sf, FILE *fd) +{ + const struct fmt *f; + char s[32]; + int i, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (f->width > width) + width = f->width; + } + for (i = 0; i < sf->nstats; i++) { + f = &sf->stats[i]; + if (sf->get_totstat(sf, i, s, sizeof(s)) && strcmp(s, "0")) + fprintf(fd, "%-*s %s\n", width, s, f->desc); + } +} + +static void +statfoo_print_fields(struct statfoo *sf, FILE *fd) +{ + int i, w, width; + + width = 0; + for (i = 0; i < sf->nstats; i++) { + w = strlen(sf->stats[i].name); + if (w > width) + width = w; + } + for (i = 0; i < sf->nstats; i++) { + const struct fmt *f = &sf->stats[i]; + if (f->width != 0) + fprintf(fd, "%-*s %s\n", width, f->name, f->desc); + } +} + +void +statfoo_init(struct statfoo *sf, const char *name, const struct fmt *stats, int nstats) +{ + sf->name = name; + sf->stats = stats; + sf->nstats = nstats; + sf->setfmt = statfoo_setfmt; + sf->collect_cur = statfoo_collect; + sf->collect_tot = statfoo_collect; + sf->update_tot = statfoo_update_tot; + sf->get_curstat = statfoo_get; + sf->get_totstat = statfoo_get; + sf->print_header = statfoo_print_header; + sf->print_current = statfoo_print_current; + sf->print_total = statfoo_print_total; + sf->print_verbose = statfoo_print_verbose; + sf->print_fields = statfoo_print_fields; +} diff --git a/tools/tools/npe/npestats/statfoo.h b/tools/tools/npe/npestats/statfoo.h new file mode 100644 index 000000000000..df7eb7acdcdd --- /dev/null +++ b/tools/tools/npe/npestats/statfoo.h @@ -0,0 +1,127 @@ +/*- + * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification. + * 2. Redistributions in binary form must reproduce at minimum a disclaimer + * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any + * redistribution must be conditioned upon including a substantially + * similar Disclaimer requirement for further binary redistribution. + * + * NO WARRANTY + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER + * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGES. + * + * $FreeBSD$ + */ + +#ifndef _STATFOO_H_ +#define _STATFOO_H_ +/* + * Base class for managing+displaying periodically collected statistics. + */ + +/* + * Statistic definition/description. The are defined + * for stats that correspond 1-1 w/ a collected stat + * and for stats that are calculated indirectly. + */ +struct fmt { + int width; /* printed field width */ + const char* name; /* stat field name referenced by user */ + const char* label; /* printed header label */ + const char* desc; /* verbose description */ +}; + +#define STATFOO_DECL_METHODS(_p) \ + /* set the format of the statistics to display */ \ + void (*setfmt)(_p, const char *); \ + /* collect+store ``current statistics'' */ \ + void (*collect_cur)(_p); \ + /* collect+store ``total statistics'' */ \ + void (*collect_tot)(_p); \ + /* update ``total statistics'' if necessary from current */ \ + void (*update_tot)(_p); \ + /* format a statistic from the current stats */ \ + int (*get_curstat)(_p, int, char [], size_t); \ + /* format a statistic from the total stats */ \ + int (*get_totstat)(_p, int, char [], size_t); \ + /* print field headers terminated by a \n */ \ + void (*print_header)(_p, FILE *); \ + /* print current statistics terminated by a \n */ \ + void (*print_current)(_p, FILE *); \ + /* print total statistics terminated by a \n */ \ + void (*print_total)(_p, FILE *); \ + /* print total statistics in a verbose (1 stat/line) format */ \ + void (*print_verbose)(_p, FILE *); \ + /* print available statistics */ \ + void (*print_fields)(_p, FILE *) + +/* + * Statistics base class. This class is not usable; only + * classes derived from it are useful. + */ +struct statfoo { + const char *name; /* statistics name, e.g. wlanstats */ + const struct fmt *stats; /* statistics in class */ + int nstats; /* number of stats */ + unsigned char fmts[4096]; /* private: compiled stats to display */ + + STATFOO_DECL_METHODS(struct statfoo *); +}; + +void statfoo_init(struct statfoo *, const char *name, + const struct fmt *stats, int nstats); + +#define STATFOO_DEFINE_BOUNCE(_t) \ +static void _t##_setfmt(struct _t *wf, const char *fmt0) \ + { wf->base.setfmt(&wf->base, fmt0); } \ +static void _t##_collect_cur(struct _t *wf) \ + { wf->base.collect_cur(&wf->base); } \ +static void _t##_collect_tot(struct _t *wf) \ + { wf->base.collect_tot(&wf->base); } \ +static void _t##_update_tot(struct _t *wf) \ + { wf->base.update_tot(&wf->base); } \ +static int _t##_get_curstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_curstat(&wf->base, s, b, bs); } \ +static int _t##_get_totstat(struct _t *wf, int s, char b[], size_t bs) \ + { return wf->base.get_totstat(&wf->base, s, b, bs); } \ +static void _t##_print_header(struct _t *wf, FILE *fd) \ + { wf->base.print_header(&wf->base, fd); } \ +static void _t##_print_current(struct _t *wf, FILE *fd) \ + { wf->base.print_current(&wf->base, fd); } \ +static void _t##_print_total(struct _t *wf, FILE *fd) \ + { wf->base.print_total(&wf->base, fd); } \ +static void _t##_print_verbose(struct _t *wf, FILE *fd) \ + { wf->base.print_verbose(&wf->base, fd); } \ +static void _t##_print_fields(struct _t *wf, FILE *fd) \ + { wf->base.print_fields(&wf->base, fd); } + +#define STATFOO_BOUNCE(_p, _t) do { \ + _p->base.setfmt = _t##_setfmt; \ + _p->base.collect_cur = _t##_collect_cur; \ + _p->base.collect_tot = _t##_collect_tot; \ + _p->base.update_tot = _t##_update_tot; \ + _p->base.get_curstat = _t##_get_curstat; \ + _p->base.get_totstat = _t##_get_totstat; \ + _p->base.print_header = _t##_print_header; \ + _p->base.print_current = _t##_print_current; \ + _p->base.print_total = _t##_print_total; \ + _p->base.print_verbose = _t##_print_verbose; \ + _p->base.print_fields = _t##_print_fields; \ +} while (0) +#endif /* _STATFOO_H_ */ From 363b5a9a040879c3841a9e03cc185cfde35710ee Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Sat, 23 May 2009 19:17:05 +0000 Subject: [PATCH 450/544] add npe tools --- tools/tools/nanobsd/gateworks/common | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tools/tools/nanobsd/gateworks/common b/tools/tools/nanobsd/gateworks/common index fe5aafd73ffc..750cd39b1da7 100644 --- a/tools/tools/nanobsd/gateworks/common +++ b/tools/tools/nanobsd/gateworks/common @@ -79,6 +79,22 @@ NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_clean_tools" NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_build_tools" NANO_CUSTOMIZE="$NANO_CUSTOMIZE ath_install_tools" +npe_clean_tools() +{ + echo "cd tools/tools/npe; make clean" | buildenv +} +npe_build_tools() +{ + echo "cd tools/tools/npe; make" | buildenv +} +npe_install_tools() +{ + echo "cd tools/tools/npe; make install" | buildenv +} +NANO_CUSTOMIZE="$NANO_CUSTOMIZE npe_clean_tools" +NANO_CUSTOMIZE="$NANO_CUSTOMIZE npe_build_tools" +NANO_CUSTOMIZE="$NANO_CUSTOMIZE npe_install_tools" + NANO_MAKEFS="makefs -B big \ -o bsize=4096,fsize=512,density=8192,optimization=space" export NANO_MAKEFS From 37f17770e03aae332c6d186042e31ce8f226a0b5 Mon Sep 17 00:00:00 2001 From: Marko Zec Date: Sat, 23 May 2009 21:43:44 +0000 Subject: [PATCH 451/544] V_irtualize the if_clone framework, thus allowing for clonable ifnets to optionally have overlapping unit numbers if attached in different vnets. At this stage if_loop is the only clonable ifnet class that has been extended to allow for such overlapping allocation of unit numbers, i.e. in each vnet it is possible to have a lo0 interface. Other clonable ifnet classes remain to operate with traditional semantics, i.e. each instance of a clonable ifnet will be assigned a globally unique unit number, regardless in which vnet such an ifnet becomes instantiated. While here, garbage collect unused _lo_list field in struct vnet_net, as well as improve indentation for #defines in sys/net/vnet.h. The layout of struct vnet_net has changed, therefore bump __FreeBSD_version. This change has no functional impact on nooptions VIMAGE kernel builds. Reviewed by: bz, brooks Approved by: julian (mentor) --- UPDATING | 5 +++ sys/kern/kern_vimage.c | 5 +++ sys/net/if_clone.c | 84 +++++++++++++++++++++++++++++++++++------- sys/net/if_loop.c | 13 +++++++ sys/net/vnet.h | 37 +++++++++++-------- sys/sys/param.h | 2 +- sys/sys/vimage.h | 2 + 7 files changed, 118 insertions(+), 30 deletions(-) diff --git a/UPDATING b/UPDATING index 8ef1991cbccf..85a005af6cd4 100644 --- a/UPDATING +++ b/UPDATING @@ -22,6 +22,11 @@ NOTE TO PEOPLE WHO THINK THAT FreeBSD 8.x IS SLOW: to maximize performance. (To disable malloc debugging, run ln -s aj /etc/malloc.conf.) +20090523: + The layout of struct vnet_net has changed, therefore modules + need to be rebuilt. + Bump __FreeBSD_version to 800090. + 20090523: The newly imported zic(8) produces a new format in the output. Please run tzsetup(8) to install the newly created diff --git a/sys/kern/kern_vimage.c b/sys/kern/kern_vimage.c index d4c48b5401f1..7cb6d8461f89 100644 --- a/sys/kern/kern_vimage.c +++ b/sys/kern/kern_vimage.c @@ -66,6 +66,10 @@ struct vprocg vprocg_0; #endif #endif +#ifdef VIMAGE +struct vnet *vnet0; +#endif + void vnet_mod_register(const struct vnet_modinfo *vmi) { @@ -331,6 +335,7 @@ vi_init(void *unused) LIST_INSERT_HEAD(&vnet_head, vnet, vnet_le); vnet->vnet_magic_n = VNET_MAGIC_N; vip->v_net = vnet; + vnet0 = vnet; /* We MUST clear curvnet in vi_init_done before going SMP. */ curvnet = LIST_FIRST(&vnet_head); diff --git a/sys/net/if_clone.c b/sys/net/if_clone.c index a0140fca6e59..eaa7397e0423 100644 --- a/sys/net/if_clone.c +++ b/sys/net/if_clone.c @@ -55,10 +55,13 @@ static void if_clone_free(struct if_clone *ifc); static int if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params); +static int vnet_clone_iattach(const void *); static struct mtx if_cloners_mtx; +#ifdef VIMAGE_GLOBALS static int if_cloners_count; -LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); +LIST_HEAD(, if_clone) if_cloners; +#endif #define IF_CLONERS_LOCK_INIT() \ mtx_init(&if_cloners_mtx, "if_cloners lock", NULL, MTX_DEF) @@ -112,10 +115,32 @@ LIST_HEAD(, if_clone) if_cloners = LIST_HEAD_INITIALIZER(if_cloners); static MALLOC_DEFINE(M_CLONE, "clone", "interface cloning framework"); +#ifndef VIMAGE_GLOBALS +static const vnet_modinfo_t vnet_clone_modinfo = { + .vmi_id = VNET_MOD_IF_CLONE, + .vmi_name = "if_clone", + .vmi_iattach = vnet_clone_iattach +}; +#endif /* !VIMAGE_GLOBALS */ + +static int vnet_clone_iattach(const void *unused __unused) +{ + INIT_VNET_NET(curvnet); + + LIST_INIT(&V_if_cloners); + return (0); +} + void if_clone_init(void) { + IF_CLONERS_LOCK_INIT(); +#ifndef VIMAGE_GLOBALS + vnet_mod_register(&vnet_clone_modinfo); +#else + vnet_clone_iattach(NULL); +#endif } /* @@ -124,15 +149,27 @@ if_clone_init(void) int if_clone_create(char *name, size_t len, caddr_t params) { + INIT_VNET_NET(curvnet); struct if_clone *ifc; /* Try to find an applicable cloner for this request */ IF_CLONERS_LOCK(); - LIST_FOREACH(ifc, &if_cloners, ifc_list) { + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { if (ifc->ifc_match(ifc, name)) { break; } } +#ifdef VIMAGE + if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { + CURVNET_SET_QUIET(vnet0); + INIT_VNET_NET(vnet0); + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { + if (ifc->ifc_match(ifc, name)) + break; + } + CURVNET_RESTORE(); + } +#endif IF_CLONERS_UNLOCK(); if (ifc == NULL) @@ -176,6 +213,7 @@ if_clone_createif(struct if_clone *ifc, char *name, size_t len, caddr_t params) int if_clone_destroy(const char *name) { + INIT_VNET_NET(curvnet); struct if_clone *ifc; struct ifnet *ifp; @@ -185,11 +223,22 @@ if_clone_destroy(const char *name) /* Find the cloner for this interface */ IF_CLONERS_LOCK(); - LIST_FOREACH(ifc, &if_cloners, ifc_list) { + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { if (strcmp(ifc->ifc_name, ifp->if_dname) == 0) { break; } } +#ifdef VIMAGE + if (ifc == NULL && !IS_DEFAULT_VNET(curvnet)) { + CURVNET_SET_QUIET(vnet0); + INIT_VNET_NET(vnet0); + LIST_FOREACH(ifc, &V_if_cloners, ifc_list) { + if (ifc->ifc_match(ifc, name)) + break; + } + CURVNET_RESTORE(); + } +#endif IF_CLONERS_UNLOCK(); if (ifc == NULL) return (EINVAL); @@ -208,11 +257,17 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp) if (ifc->ifc_destroy == NULL) return(EOPNOTSUPP); + /* + * Given that the cloned ifnet might be attached to a different + * vnet from where its cloner was registered, we have to + * switch to the vnet context of the target vnet. + */ + CURVNET_SET_QUIET(ifp->if_vnet); + IF_CLONE_LOCK(ifc); IFC_IFLIST_REMOVE(ifc, ifp); IF_CLONE_UNLOCK(ifc); - CURVNET_SET_QUIET(ifp->if_vnet); if_delgroup(ifp, ifc->ifc_name); err = (*ifc->ifc_destroy)(ifc, ifp); @@ -234,6 +289,7 @@ if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp) void if_clone_attach(struct if_clone *ifc) { + INIT_VNET_NET(curvnet); int len, maxclone; /* @@ -249,8 +305,8 @@ if_clone_attach(struct if_clone *ifc) IF_CLONE_ADDREF(ifc); IF_CLONERS_LOCK(); - LIST_INSERT_HEAD(&if_cloners, ifc, ifc_list); - if_cloners_count++; + LIST_INSERT_HEAD(&V_if_cloners, ifc, ifc_list); + V_if_cloners_count++; IF_CLONERS_UNLOCK(); LIST_INIT(&ifc->ifc_iflist); @@ -266,11 +322,12 @@ if_clone_attach(struct if_clone *ifc) void if_clone_detach(struct if_clone *ifc) { + INIT_VNET_NET(curvnet); struct ifc_simple_data *ifcs = ifc->ifc_data; IF_CLONERS_LOCK(); LIST_REMOVE(ifc, ifc_list); - if_cloners_count--; + V_if_cloners_count--; IF_CLONERS_UNLOCK(); /* Allow all simples to be destroyed */ @@ -305,6 +362,7 @@ if_clone_free(struct if_clone *ifc) int if_clone_list(struct if_clonereq *ifcr) { + INIT_VNET_NET(curvnet); char *buf, *dst, *outbuf = NULL; struct if_clone *ifc; int buf_count, count, err = 0; @@ -321,23 +379,23 @@ if_clone_list(struct if_clonereq *ifcr) * could be because that would let arbitrary users cause us to * allocate abritrary amounts of kernel memory. */ - buf_count = (if_cloners_count < ifcr->ifcr_count) ? - if_cloners_count : ifcr->ifcr_count; + buf_count = (V_if_cloners_count < ifcr->ifcr_count) ? + V_if_cloners_count : ifcr->ifcr_count; IF_CLONERS_UNLOCK(); outbuf = malloc(IFNAMSIZ*buf_count, M_CLONE, M_WAITOK | M_ZERO); IF_CLONERS_LOCK(); - ifcr->ifcr_total = if_cloners_count; + ifcr->ifcr_total = V_if_cloners_count; if ((dst = ifcr->ifcr_buffer) == NULL) { /* Just asking how many there are. */ goto done; } - count = (if_cloners_count < buf_count) ? - if_cloners_count : buf_count; + count = (V_if_cloners_count < buf_count) ? + V_if_cloners_count : buf_count; - for (ifc = LIST_FIRST(&if_cloners), buf = outbuf; + for (ifc = LIST_FIRST(&V_if_cloners), buf = outbuf; ifc != NULL && count != 0; ifc = LIST_NEXT(ifc, ifc_list), count--, buf += IFNAMSIZ) { strlcpy(buf, ifc->ifc_name, IFNAMSIZ); diff --git a/sys/net/if_loop.c b/sys/net/if_loop.c index 3319ed89379f..cc9251b1a114 100644 --- a/sys/net/if_loop.c +++ b/sys/net/if_loop.c @@ -111,9 +111,14 @@ static int vnet_loif_iattach(const void *); struct ifnet *loif; /* Used externally */ #endif +#ifdef VIMAGE +MALLOC_DEFINE(M_LO_CLONER, "lo_cloner", "lo_cloner"); +#endif + #ifndef VIMAGE_GLOBALS static const vnet_modinfo_t vnet_loif_modinfo = { .vmi_id = VNET_MOD_LOIF, + .vmi_dependson = VNET_MOD_IF_CLONE, .vmi_name = "loif", .vmi_iattach = vnet_loif_iattach }; @@ -167,7 +172,15 @@ static int vnet_loif_iattach(const void *unused __unused) INIT_VNET_NET(curvnet); V_loif = NULL; + +#ifdef VIMAGE + V_lo_cloner = malloc(sizeof(*V_lo_cloner), M_LO_CLONER, + M_WAITOK | M_ZERO); + bcopy(&lo_cloner, V_lo_cloner, sizeof(*V_lo_cloner)); + if_clone_attach(V_lo_cloner); +#else if_clone_attach(&lo_cloner); +#endif return (0); } diff --git a/sys/net/vnet.h b/sys/net/vnet.h index 662586a0d4cc..bdc466b55a48 100644 --- a/sys/net/vnet.h +++ b/sys/net/vnet.h @@ -31,7 +31,7 @@ */ #ifndef _NET_VNET_H_ -#define _NET_VNET_H_ +#define _NET_VNET_H_ #include @@ -50,10 +50,13 @@ struct vnet_net { uma_zone_t _rtzone; struct ifnet * _loif; - LIST_HEAD(, lo_softc) _lo_list; + struct if_clone * _lo_cloner; LIST_HEAD(, rawcb) _rawcb_list; + LIST_HEAD(, if_clone) _if_cloners; + int _if_cloners_count; + int _ether_ipfw; }; @@ -74,19 +77,21 @@ extern struct vnet_net vnet_net_0; #define VNET_NET(sym) VSYM(vnet_net, sym) -#define V_ether_ipfw VNET_NET(ether_ipfw) -#define V_if_index VNET_NET(if_index) -#define V_if_indexlim VNET_NET(if_indexlim) -#define V_ifg_head VNET_NET(ifg_head) -#define V_ifindex_table VNET_NET(ifindex_table) -#define V_ifklist VNET_NET(ifklist) -#define V_ifnet VNET_NET(ifnet) -#define V_lo_list VNET_NET(lo_list) -#define V_loif VNET_NET(loif) -#define V_rawcb_list VNET_NET(rawcb_list) -#define V_rt_tables VNET_NET(rt_tables) -#define V_rtstat VNET_NET(rtstat) -#define V_rttrash VNET_NET(rttrash) -#define V_rtzone VNET_NET(rtzone) +#define V_ether_ipfw VNET_NET(ether_ipfw) +#define V_if_index VNET_NET(if_index) +#define V_if_indexlim VNET_NET(if_indexlim) +#define V_if_cloners VNET_NET(if_cloners) +#define V_if_cloners_count VNET_NET(if_cloners_count) +#define V_ifg_head VNET_NET(ifg_head) +#define V_ifindex_table VNET_NET(ifindex_table) +#define V_ifklist VNET_NET(ifklist) +#define V_ifnet VNET_NET(ifnet) +#define V_lo_cloner VNET_NET(lo_cloner) +#define V_loif VNET_NET(loif) +#define V_rawcb_list VNET_NET(rawcb_list) +#define V_rt_tables VNET_NET(rt_tables) +#define V_rtstat VNET_NET(rtstat) +#define V_rttrash VNET_NET(rttrash) +#define V_rtzone VNET_NET(rtzone) #endif /* !_NET_VNET_H_ */ diff --git a/sys/sys/param.h b/sys/sys/param.h index 19dc83eedcda..eb8c57f3c3a9 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800089 /* Master, propagated to newvers */ +#define __FreeBSD_version 800090 /* Master, propagated to newvers */ #ifndef LOCORE #include diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index b2c0bc129005..888e1142a0bc 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -95,6 +95,7 @@ struct vnet_modlink { #define VNET_MOD_MLD 13 /* Stateless modules. */ +#define VNET_MOD_IF_CLONE 19 #define VNET_MOD_NG_ETHER 20 #define VNET_MOD_NG_IFACE 21 #define VNET_MOD_NG_EIFACE 22 @@ -271,6 +272,7 @@ extern struct vprocg vprocg_0; #ifdef VIMAGE LIST_HEAD(vnet_list_head, vnet); extern struct vnet_list_head vnet_head; +extern struct vnet *vnet0; #define VNET_ITERATOR_DECL(arg) struct vnet *arg; #define VNET_FOREACH(arg) LIST_FOREACH(arg, &vnet_head, vnet_le) #else From 5760d14d58fa292c1a50b82bef73425e0616207a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Sat, 23 May 2009 22:05:14 +0000 Subject: [PATCH 452/544] pmap_enter() *must* set PG_WRITEABLE on the given page if it creates a mapping that permits write access. Otherwise, pmap_remove_write() will not remove write access from any of the page's mappings. --- sys/mips/mips/pmap.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/mips/mips/pmap.c b/sys/mips/mips/pmap.c index 229e19874d2f..4d7037e91ca8 100644 --- a/sys/mips/mips/pmap.c +++ b/sys/mips/mips/pmap.c @@ -3121,6 +3121,7 @@ init_pte_prot(vm_offset_t va, vm_page_t m, vm_prot_t prot) rw = PTE_RWPAGE; else rw = PTE_CWPAGE; + vm_page_flag_set(m, PG_WRITEABLE); } return rw; } From e17bb250c9e27e4f31bd58f107d1b94163687b70 Mon Sep 17 00:00:00 2001 From: "Bjoern A. Zeeb" Date: Sat, 23 May 2009 22:57:49 +0000 Subject: [PATCH 453/544] Even if not entirely style clean the heavy nesting of the various vimage options along with all the defines made things really hard to read and get right; thus add comments for the #else/#endif cases. Discussed with: zec --- sys/sys/vimage.h | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/sys/sys/vimage.h b/sys/sys/vimage.h index 888e1142a0bc..ddbe7f0970a2 100644 --- a/sys/sys/vimage.h +++ b/sys/sys/vimage.h @@ -138,13 +138,13 @@ void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); #ifdef VIMAGE_GLOBALS #define VSYM(base, sym) (sym) -#else +#else /* !VIMAGE_GLOBALS */ #ifdef VIMAGE #define VSYM(base, sym) ((base)->_ ## sym) -#else +#else /* !VIMAGE */ #define VSYM(base, sym) (base ## _0._ ## sym) -#endif -#endif +#endif /* VIMAGE */ +#endif /* VIMAGE_GLOBALS */ #ifndef VIMAGE_GLOBALS #ifdef VIMAGE @@ -155,11 +155,11 @@ void vnet_mod_deregister_multi(const struct vnet_modinfo *, void *, char *); #define VNET_SYMMAP(mod, name) \ { #name, offsetof(struct vnet_ ## mod, _ ## name), \ sizeof(((struct vnet_ ## mod *) NULL)->_ ## name) } -#else +#else /* !VIMAGE */ #define VNET_SYMMAP(mod, name) \ { #name, (size_t) &(vnet_ ## mod ## _0._ ## name), \ sizeof(vnet_ ## mod ## _0._ ## name) } -#endif +#endif /* VIMAGE */ #define VNET_SYMMAP_END { NULL, 0 } struct vimage { @@ -194,10 +194,10 @@ struct vprocg { #ifdef VIMAGE LIST_HEAD(vimage_list_head, vimage); extern struct vimage_list_head vimage_head; -#else +#else /* !VIMAGE */ extern struct vprocg vprocg_0; -#endif -#endif +#endif /* VIMAGE */ +#endif /* !VIMAGE_GLOBALS */ #define curvnet curthread->td_vnet @@ -245,7 +245,7 @@ extern struct vprocg vprocg_0; #define CURVNET_RESTORE() \ curvnet = saved_vnet; -#endif /* !VNET_DEBUG */ +#endif /* VNET_DEBUG */ #else /* !VIMAGE */ #define VNET_ASSERT(condition) #define CURVNET_SET(arg) @@ -267,7 +267,7 @@ extern struct vprocg vprocg_0; #endif /* !VNET_DEBUG */ #else /* !VIMAGE */ #define INIT_FROM_VNET(vnet, modindex, modtype, sym) -#endif +#endif /* VIMAGE */ #ifdef VIMAGE LIST_HEAD(vnet_list_head, vnet); @@ -303,7 +303,7 @@ extern struct vprocg_list_head vprocg_head; #define P_TO_VIMAGE(p) (p)->p_ucred->cr_vimage #define P_TO_VNET(p) (p)->p_ucred->cr_vimage->v_net #define P_TO_VPROCG(p) (p)->p_ucred->cr_vimage->v_procg -#else +#else /* !VIMAGE */ #define TD_TO_VIMAGE(td) NULL #define TD_TO_VNET(td) NULL #define P_TO_VIMAGE(p) NULL @@ -311,11 +311,11 @@ extern struct vprocg_list_head vprocg_head; #ifdef VIMAGE_GLOBALS #define TD_TO_VPROCG(td) NULL #define P_TO_VPROCG(p) NULL -#else +#else /* !VIMAGE_GLOBALS */ #define TD_TO_VPROCG(td) &vprocg_0 #define P_TO_VPROCG(p) &vprocg_0 -#endif -#endif +#endif /* VIMAGE_GLOBALS */ +#endif /* VIMAGE */ /* Non-VIMAGE null-macros */ #define VNET_LIST_RLOCK() From 20d0a5e544567ca098500d5ed7af8be95d58f488 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 24 May 2009 01:18:56 +0000 Subject: [PATCH 454/544] Modify nfsd.c to add support for the experimental nfs server. This includes the addition of a new flag "-4" that will force use of the experimental server with nfsv4 support in it. This commit also adds two new man pages to the repository that are NFSv4 specific. One describes the file used by the server to restart nfsv4 services safely. The other is a brief overview of nfsv4 and its setup. Reviewed by: dfr Approved by: kib (mentor) --- usr.sbin/nfsd/Makefile | 2 +- usr.sbin/nfsd/nfsd.8 | 36 +++- usr.sbin/nfsd/nfsd.c | 133 ++++++++++++--- usr.sbin/nfsd/nfsv4.4 | 309 ++++++++++++++++++++++++++++++++++ usr.sbin/nfsd/stablerestart.5 | 93 ++++++++++ 5 files changed, 544 insertions(+), 29 deletions(-) create mode 100644 usr.sbin/nfsd/nfsv4.4 create mode 100644 usr.sbin/nfsd/stablerestart.5 diff --git a/usr.sbin/nfsd/Makefile b/usr.sbin/nfsd/Makefile index 21ca3f377a65..3237ce3f9c63 100644 --- a/usr.sbin/nfsd/Makefile +++ b/usr.sbin/nfsd/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PROG= nfsd -MAN= nfsd.8 +MAN= nfsd.8 nfsv4.4 stablerestart.5 WARNS?= 6 diff --git a/usr.sbin/nfsd/nfsd.8 b/usr.sbin/nfsd/nfsd.8 index 64c181e66c9c..3c2dcd4e2f89 100644 --- a/usr.sbin/nfsd/nfsd.8 +++ b/usr.sbin/nfsd/nfsd.8 @@ -38,7 +38,7 @@ server .Sh SYNOPSIS .Nm -.Op Fl ardut +.Op Fl ardut4 .Op Fl n Ar num_servers .Op Fl h Ar bindip .Sh DESCRIPTION @@ -100,6 +100,18 @@ clients. Serve .Tn UDP NFS clients. +.It Fl 4 +Forces +.Nm +to try and start the experimental server that includes NFSv4 support in it. +If this flag isn't specified, the experimental server will only be started +if it is linked into the kernel and the regular one isn't. +.br +ie. The kernel is built with the following: +.Bd -literal -offset indent -compact +# options NFSSERVER +options NFSD +.Ed .El .Pp For example, @@ -120,8 +132,11 @@ utility listens for service requests at the port indicated in the .Tn NFS server specification; see .%T "Network File System Protocol Specification" , -RFC1094 and -.%T "NFS: Network File System Version 3 Protocol Specification" . +RFC1094, +.%T "NFS: Network File System Version 3 Protocol Specification" , +RFC1813 and +.%T "Network File System (NFS) Version 4 Protocol" , +RFC3530. .Pp If .Nm @@ -178,13 +193,28 @@ just do a .Xr nfsstat 1 , .Xr kldload 2 , .Xr nfssvc 2 , +.Xr nfsv4 4 , .Xr exports 5 , +.Xr gssd 8 , .Xr ipfw 8 , .Xr mountd 8 , .Xr nfsiod 8 , +.Xr nfsrevoke 8 , +.Xr nfsuserd 8 , .Xr rpcbind 8 .Sh HISTORY The .Nm utility first appeared in .Bx 4.4 . +.Sh BUGS +If +.Nm +is started when +.Xr gssd 8 +is not running, it will service AUTH_SYS requests only. To fix the problem +you must kill +.Nm +and then restart it, after the +.Xr gssd 8 +is running. diff --git a/usr.sbin/nfsd/nfsd.c b/usr.sbin/nfsd/nfsd.c index 788d1c2af803..9afe62c76c56 100644 --- a/usr.sbin/nfsd/nfsd.c +++ b/usr.sbin/nfsd/nfsd.c @@ -48,6 +48,7 @@ static const char rcsid[] = #include #include #include +#include #include #include @@ -59,6 +60,7 @@ static const char rcsid[] = #include #include #include +#include #include #include @@ -77,11 +79,14 @@ int debug = 1; int debug = 0; #endif +#define NFSD_STABLERESTART "/var/db/nfs-stablerestart" #define MAXNFSDCNT 256 #define DEFNFSDCNT 4 pid_t children[MAXNFSDCNT]; /* PIDs of children */ int nfsdcnt; /* number of children */ int new_syscall; +int run_v4server = 0; /* Force running of nfsv4 server */ +int nfssvc_nfsd; /* Set to correct NFSSVC_xxx flag */ void cleanup(int); void child_cleanup(int); @@ -112,6 +117,7 @@ void usage(void); * -d - unregister with rpcbind * -t - support tcp nfs clients * -u - support udp nfs clients + * -4 - forces it to run a server that supports nfsv4 * followed by "n" which is the number of nfsds' to fork off */ int @@ -131,20 +137,15 @@ main(int argc, char **argv) int tcp6sock, ip6flag, tcpflag, tcpsock; int udpflag, ecode, s, srvcnt; int bindhostc, bindanyflag, rpcbreg, rpcbregcnt; + int stablefd, nfssvc_addsock; char **bindhost = NULL; pid_t pid; - if (modfind("nfsserver") < 0) { - /* Not present in kernel, try loading it */ - if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) - errx(1, "NFS server is not available"); - } - nfsdcnt = DEFNFSDCNT; unregister = reregister = tcpflag = maxsock = 0; bindanyflag = udpflag = connect_type_cnt = bindhostc = 0; -#define GETOPT "ah:n:rdtu" -#define USAGE "[-ardtu] [-n num_servers] [-h bindip]" +#define GETOPT "ah:n:rdtu4" +#define USAGE "[-ardtu4] [-n num_servers] [-h bindip]" while ((ch = getopt(argc, argv, GETOPT)) != -1) switch (ch) { case 'a': @@ -179,6 +180,9 @@ main(int argc, char **argv) case 'u': udpflag = 1; break; + case '4': + run_v4server = 1; + break; default: case '?': usage(); @@ -203,6 +207,25 @@ main(int argc, char **argv) } } + /* + * If the "-4" option was specified OR only the nfsd module is + * found in the server, run "nfsd". + * Otherwise, try and run "nfsserver". + */ + if (run_v4server > 0) { + if (modfind("nfsd") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfsd") < 0 || modfind("nfsd") < 0) + errx(1, "NFS server is not available"); + } + } else if (modfind("nfsserver") < 0 && modfind("nfsd") >= 0) { + run_v4server = 1; + } else if (modfind("nfsserver") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0) + errx(1, "NFS server is not available"); + } + ip6flag = 1; s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); if (s == -1) { @@ -328,15 +351,47 @@ main(int argc, char **argv) openlog("nfsd", LOG_PID, LOG_DAEMON); /* - * Figure out if the kernel supports the new-style - * NFSSVC_NFSD. Old kernels will return ENXIO because they - * don't recognise the flag value, new ones will return EINVAL - * because argp is NULL. + * For V4, we open the stablerestart file and call nfssvc() + * to get it loaded. This is done before the daemons do the + * regular nfssvc() call to service NFS requests. + * (This way the file remains open until the last nfsd is killed + * off.) + * Note that this file is not created by this daemon and can + * only be relocated by recompiling the daemon, in order to + * minimize accidentally starting up with the wrong file. + * If should be created as an empty file Read and Write for + * root before the first time you run NFS v4 and should never + * be re-initialized if at all possible. It should live on a + * local, non-volatile storage device that does not do hardware + * level write-back caching. (See SCSI doc for more information + * on how to prevent write-back caching on SCSI disks.) */ - new_syscall = FALSE; - if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) + if (run_v4server > 0) { + stablefd = open(NFSD_STABLERESTART, O_RDWR, 0); + if (stablefd < 0) { + syslog(LOG_ERR, "Can't open %s\n", NFSD_STABLERESTART); + exit(1); + } + if (nfssvc(NFSSVC_STABLERESTART, (caddr_t)&stablefd) < 0) { + syslog(LOG_ERR, "Can't read stable storage file\n"); + exit(1); + } + nfssvc_addsock = NFSSVC_NFSDADDSOCK; + nfssvc_nfsd = NFSSVC_NFSDNFSD; new_syscall = TRUE; - new_syscall = FALSE; + } else { + nfssvc_addsock = NFSSVC_ADDSOCK; + nfssvc_nfsd = NFSSVC_NFSD; + /* + * Figure out if the kernel supports the new-style + * NFSSVC_NFSD. Old kernels will return ENXIO because they + * don't recognise the flag value, new ones will return EINVAL + * because argp is NULL. + */ + new_syscall = FALSE; + if (nfssvc(NFSSVC_NFSD, NULL) < 0 && errno == EINVAL) + new_syscall = TRUE; + } if (!new_syscall) { /* If we use UDP only, we start the last server below. */ @@ -413,7 +468,7 @@ main(int argc, char **argv) addsockargs.sock = sock; addsockargs.name = NULL; addsockargs.namelen = 0; - if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) { + if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { syslog(LOG_ERR, "can't Add UDP socket"); nfsd_exit(1); } @@ -481,7 +536,7 @@ main(int argc, char **argv) addsockargs.sock = sock; addsockargs.name = NULL; addsockargs.namelen = 0; - if (nfssvc(NFSSVC_ADDSOCK, &addsockargs) < 0) { + if (nfssvc(nfssvc_addsock, &addsockargs) < 0) { syslog(LOG_ERR, "can't add UDP6 socket"); nfsd_exit(1); @@ -711,7 +766,7 @@ main(int argc, char **argv) addsockargs.sock = msgsock; addsockargs.name = (caddr_t)&inetpeer; addsockargs.namelen = len; - nfssvc(NFSSVC_ADDSOCK, &addsockargs); + nfssvc(nfssvc_addsock, &addsockargs); (void)close(msgsock); } else if (FD_ISSET(tcpsock, &v6bits)) { len = sizeof(inet6peer); @@ -733,7 +788,7 @@ main(int argc, char **argv) addsockargs.sock = msgsock; addsockargs.name = (caddr_t)&inet6peer; addsockargs.namelen = len; - nfssvc(NFSSVC_ADDSOCK, &addsockargs); + nfssvc(nfssvc_addsock, &addsockargs); (void)close(msgsock); } } @@ -861,19 +916,47 @@ nfsd_exit(int status) void start_server(int master) { - char principal[128]; - char hostname[128]; + char principal[MAXHOSTNAMELEN + 5]; struct nfsd_nfsd_args nfsdargs; - int status; + int status, error; + char hostname[MAXHOSTNAMELEN + 1], *cp; + struct addrinfo *aip, hints; status = 0; if (new_syscall) { - gethostname(hostname, sizeof(hostname)); - snprintf(principal, sizeof(principal), "nfs@%s", hostname); + gethostname(hostname, sizeof (hostname)); + snprintf(principal, sizeof (principal), "nfs@%s", hostname); + if ((cp = strchr(hostname, '.')) == NULL || + *(cp + 1) == '\0') { + /* If not fully qualified, try getaddrinfo() */ + memset((void *)&hints, 0, sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(hostname, NULL, &hints, &aip); + if (error == 0) { + if (aip->ai_canonname != NULL && + (cp = strchr(aip->ai_canonname, '.')) != + NULL && *(cp + 1) != '\0') + snprintf(principal, sizeof (principal), + "nfs@%s", aip->ai_canonname); + freeaddrinfo(aip); + } + } nfsdargs.principal = principal; nfsdargs.minthreads = nfsdcnt; nfsdargs.maxthreads = nfsdcnt; - if (nfssvc(NFSSVC_NFSD, &nfsdargs) < 0) { + error = nfssvc(nfssvc_nfsd, &nfsdargs); + if (error < 0 && errno == EAUTH) { + /* + * This indicates that it could not register the + * rpcsec_gss credentials, usually because the + * gssd daemon isn't running. + * (only the experimental server with nfsv4) + */ + syslog(LOG_ERR, "No gssd, using AUTH_SYS only"); + principal[0] = '\0'; + error = nfssvc(nfssvc_nfsd, &nfsdargs); + } + if (error < 0) { syslog(LOG_ERR, "nfssvc: %m"); status = 1; } diff --git a/usr.sbin/nfsd/nfsv4.4 b/usr.sbin/nfsd/nfsv4.4 new file mode 100644 index 000000000000..582181d4ef14 --- /dev/null +++ b/usr.sbin/nfsd/nfsv4.4 @@ -0,0 +1,309 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 30, 2009 +.Dt NFSV4 4 +.Os +.Sh NAME +.Nm nfsv4 +.Nd NFS Version 4 Protocol +.Sh SYNOPSIS +experimental client and server with NFSv4 support +.Sh DESCRIPTION +The experimental nfs client and server provides support for the +.Tn NFSv4 +specification; see +.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530" . +The protocol is somewhat similar to NFS Version 3, but differs in significant +ways. It uses a single Compound RPC that concatenates operations to-gether. +Each of these operations are similar to the RPCs of NFS Version 3. +The operations in the compound are performed in order, until one of +them fails (returns an error) and then the RPC terminates at that point. +.Pp +It has +integrated locking support, which implies that the server is no longer +stateless. As such, the +.Tn NFSv4 +server remains in recovery mode for a Grace period (always greater than the +lease duration the server uses) after a reboot. +During this Grace period, clients may recover state but not perform other +open/lock state changing operations. +To provide for correct recovery semantics, a small file described by +.Xr stablerestart 5 +is used by the server during the recovery phase. If this file is missing, +the server will not start. +If this file is lost, it should be recovered from backups, since creating +an empty +.Xr stablerestart 5 +file will result in the server starting without providing a Grace Period +for recovery. +Note that recovery only occurs when the server +machine is rebooted, not when the +.Xr nfsd 8 +are just restarted. +.Pp +It provides several optional features not in NFS Version 3: +.sp +.Bd -literal -offset indent -compact +- NFS Version 4 ACLs +- Referrals, which redirect subtrees to other servers + (not yet implemented) +- Delegations, which allow a client to operate on a file locally +.Ed +.Pp +The +.Tn NFSv4 +protocol does not use a separate mount protocol and assumes that the +server provides a single file system tree structure, rooted at the point +in the local file system tree specified by the +.sp 1 +.Bd -literal -offset indent -compact +V4: +.Ed +.sp 1 +line in +.Xr exports 5 . +The +.Xr nfsd 8 +allows a limited subset of operations to be performed on non-exported subtrees +of the local file system, so that traversal of the tree to the exported +subtrees is possible. +As such, the ``'' can be in a non-exported file system. However, +the entire tree that is rooted at that point must be in local file systems +that are of types that can be NFS exported. +Since the +.Nm +file system is rooted at ``'', setting this to anything other +than ``/'' will result in clients being required to use different mount +paths for +.Nm +than for NFS Version 2 or 3. +Unlike NFS Version 2 and 3, Version 4 allows a client mount to span across +multiple server file systems, although not all clients are capable of doing +this. +.Pp +.Nm +uses names for users and groups instead of numbers. On the wire, they +take the form: +.sp +.Bd -literal -offset indent -compact +@ +.Ed +.sp +where ``'' is not the same as the DNS domain used +for host name lookups, but is usually set to the same string. Most systems set this ``'' +to the domain name part of the machine's +.Xr hostname 1 +by default. However, this can normally be overridden by a command line +option or configuration file for the daemon used to do the name<->number +mapping. +On FreeBSD, the mapping daemon is called +.Xr nfsuserd 8 +and has a command line option that overrides the domain component of the +machine's hostname. +This can be set in +.Xr rc.conf 5 +via the nfsv4_userd_flags variable. +For use of +.Nm , +either client or server, this daemon must be enabled by setting +.sp +.Bd -literal -offset indent -compact +nfsv4_enable="YES" +.Ed +.sp +in +.Xr rc.conf 5 . +If this ``'' is not set correctly or the daemon is not running, ``ls -l'' will typically +report a lot of ``nobody'' and ``nogroup'' ownerships. +.Pp +Although numbers are no longer used in the +.Nm +protocol, they will still be in the RPC authentication fields when running +using AUTH_SYS (sec=sys), which is the default. +As such, in this case both the user/group name and number spaces must +be consistent between the client and server. +.Pp +However, if you run +.Nm +with RPCSEC_GSS (sec=krb5, krb5i, krb5p), only names and KerberosV tickets +will go on the wire. +.Sh SERVER SETUP +.Pp +To set up the experimental nfs server that supports +.Nm +you will need to either build a kernel with: +.sp +.Bd -literal -offset indent -compact +options NFSD +.Ed +and not +.Bd -literal -offset indent -compact +options NFSSERVER +.Ed +.sp +or start +.Xr mountd 8 +and +.Xr nfsd 8 +with the ``-4'' option to force use of the experimental server. +This will occur if +.sp +.Bd -literal -offset indent -compact +nfsv4_enable="YES" +.Ed +.sp +is set in +.Xr rc.conf 5 , +as above. +.Pp +You will also need to add a: +.sp +.Bd -literal -offset indent -compact +V4: +.Ed +.sp +line to the +.Xr exports 5 +file, to tell the server where the +.Nm +tree is rooted. +.Pp +If the file systems you are exporting are only being accessed via +.Nm +there are a couple of +.Xr sysctl 8 +variables that you can change, which might improve performance. +.Bl -tag -width Ds +.It Cm vfs.newnfs.issue_delegations +when set non-zero, allows the server to issue Open Delegations to +clients. These delegations permit the client to manipulate the file +locally on the client. Unfortunately, at this time, client use of +delegations is limited, so performance gains may not be observed. +This can only be enabled when the file systems being exported to +.Nm +clients are not being accessed locally on the server and, if being +accessed via NFS Version 2 or 3 clients, these clients cannot be +using the NLM. +.It Cm vfs.newnfs.enable_locallocks +can be set to 0 to disable acquisition of local byte range locks. +Disabling local locking can only be done if neither local accesses +to the exported file systems nor the NLM is operating on them. +.El +.sp +Note that Samba server access would be considered ``local access'' for the above +discussion. +.Pp +To build a kernel with the experimental +.Nm +linked into it, the +.sp +.Bd -literal -offset indent -compact +options NFSD +.Ed +.sp +must be specified in the kernel's +.Xr config 5 +file. +.Sh CLIENT MOUNTS +.Pp +To do an +.Nm +mount, specify the ``nfsv4'' option on the +.Xr mount_nfs 8 +command line. +This will force use of the experimental client plus set ``tcp'' and +.Nm . +.Pp +If the +.Nm +server that is being mounted on supports delegations, you can set +.sp +.Bd -literal -offset indent -compact +nfsv4_callbackdaemon_enable="YES" +.Ed +.sp +via +.Xr rc.conf 5 +so that the client side callback daemon +.Xr nfscbd 8 +is started upon boot. +Without a functioning callback path, a server will never issue Delegations +to a client. +.sp +By default, the callback address will be set to the IP address acquired via +rtalloc() in the kernel and port# 7745. +To override the default port#, a command line option for +.Xr nfscbd 8 +can be set via the variable +.sp +.Bd -literal -offset indent -compact +nfsv4_callbackdaemon_flag +.Ed +.sp +using +.Xr rc.conf 5 . +.sp +To get callbacks to work when behind a NAT gateway, a port for the callback +service will need to be set up on the NAT gateway and then the address +of the NAT gateway (host IP plus port#) will need to be set by assigning the +.Xr sysctl 8 +variable vfs.newnfs.callback_addr to a string of the form: +.sp +N.N.N.N.N.N +.sp +where the first 4 Ns are the host IP address and the last two are the +port# in network byte order (all decimal #s in the range 0-255). +.Pp +To build a kernel with the experimental +.Nm +client linked into it, the option +.sp +.Bd -literal -offset indent -compact +options NFSCL +.Ed +.sp +must be specified in the kernel's +.Xr config 5 +file. +.Sh FILES +.Bl -tag -width /var/db/nfs-stablerestart -compact +.It Pa /var/db/nfs-stablerestart +NFS V4 stable restart file +.El +.Sh SEE ALSO +.Xr stablerestart 5 +.Xr mountd 8 +.Xr nfscbd 8 +.Xr nfsd 8 +.Xr nfsdumpstate 8 +.Xr nfsrevoke 8 +.Xr nfsuserd 8 +.Sh BUGS +At this time, there is no recall of delegations for local file system +operations. As such, delegations should only be enabled for file systems +that are being used soley as NFS export volumes and are not being accessed +via local system calls nor services such as Samba. diff --git a/usr.sbin/nfsd/stablerestart.5 b/usr.sbin/nfsd/stablerestart.5 new file mode 100644 index 000000000000..c469835fc0db --- /dev/null +++ b/usr.sbin/nfsd/stablerestart.5 @@ -0,0 +1,93 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd Sept 7, 2007 +.Dt STABLERESTART 5 +.Os +.Sh NAME +.Nm nfs-stablerestart +.Nd handles restart edge conditions for the +.Tn NFS +V4 server +.Sh SYNOPSIS +.Nm nfs-stablerestart +.Sh DESCRIPTION +The +.Nm +file holds information that allows the +.Tn NFS +V4 server to restart without always returning the NFSERR_NOGRACE error, as described in the +.Tn NFS V4 +server specification; see +.%T "Network File System (NFS) Version 4 Protocol \\*(tNRFC\\*(sP 3530, Section 8.6.3" . +.Pp +The first record in the file, as defined by struct nfsf_rec in +/usr/include/fs/nfs/nfsrvstate.h, holds the lease duration of the +last incarnation of the server and the number of boot times that follows. +Following this are the number of previous boot times listed in the +first record. +The lease duration is used to set the Grace Period. +The boot times +are used to avoid the unlikely occurrence of a boot time being reused, +due to a TOD clock going backwards. This record and the previous boot times with this boot time added is re-written at the +end of the Grace Period. +.Pp +The rest of the file are appended records, as defined by +struct nfst_rec in /usr/include/fs/nfs/nfsrvstate.h and are used +represent one of two things. There are records which indicate that a +client successfully aquired state and records that indicate a client's state was revoked. +State revoke records indicate that state information +for a client was discarded, due to lease expiry and an otherwise +conflicting open or lock request being made by a different client. +These records can be used +to determine if clients might have done either of the +edge conditions. +.Pp +If a client might have done either edge condition or this file is +empty or corrupted, the server returns NFSERR_NOGRACE for any reclaim +request from the client. +.Pp +For correct operation of the server, it must be ensured that the file +is written to stable storage by the time a write op with IO_SYNC specified +has returned. This might require hardware level caching to be disabled for +a local disk drive that holds the file, or similar. +.Sh FILES +.Bl -tag -width /var/db/nfs-stablerestart -compact +.It Pa /var/db/nfs-stablerestart +NFS V4 stable restart file +.El +.Sh SEE ALSO +.Xr nfsv4 4 +.Xr nfsd 8 +.Sh BUGS +If the file is empty, the NFS V4 server has no choice but to return +NFSERR_NOGRACE for all Reclaim requests. Although correct, this is +a highly undesirable occurrence, so the file should not be lost if +at all possible. Nfsd will not create the file if it does not +exist and will simply log a failure to start, in the hopes that the +file can be recovered from a backup. To move the file, you must edit +the nfsd sources and recompile it. This was done to discourage +accidental relocation of the file. From 63bde62e9a29d3f971a18bc5af1775ddfecb47fc Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 24 May 2009 03:22:49 +0000 Subject: [PATCH 455/544] Fix the experimental nfsv4 client so that it works for the case of a kerberized mount without a host based principal name. This will only work for mounts being done by a user other than root. Support for a host based principal name will not work until proposed changes to the rpcsec_gss part of the krpc are committed. It now builds for "options KGSSAPI". Approved by: kib (mentor) --- sys/fs/nfs/nfs_commonkrpc.c | 51 +++++++++++++++++++++++++-------- sys/fs/nfsclient/nfs_clvfsops.c | 20 ++++++------- 2 files changed, 49 insertions(+), 22 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index 7abff3290667..d487703b6ddf 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -341,7 +341,9 @@ nfs_getauth(struct nfssockreq *nrp, int secflavour, char *clnt_principal, else auth = NULL; #endif - return (auth); + if (auth != NULL) + return (auth); + /* fallthrough */ #endif /* KGSSAPI */ case AUTH_SYS: default: @@ -402,7 +404,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, { u_int32_t *tl; time_t waituntil; - int i, j; + int i, j, set_uid = 0; int trycnt, error = 0, usegssname = 0, secflavour = AUTH_SYS; u_int16_t procnum; u_int trylater_delay = 1; @@ -413,6 +415,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, enum clnt_stat stat; struct nfsreq *rep = NULL; char *srv_principal = NULL; + uid_t saved_uid = (uid_t)-1; if (xidp != NULL) *xidp = 0; @@ -422,6 +425,14 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, return (ESTALE); } + /* + * XXX if not already connected call nfs_connect now. Longer + * term, change nfs_mount to call nfs_connect unconditionally + * and let clnt_reconnect_create handle reconnects. + */ + if (nrp->nr_client == NULL) + newnfs_connect(nmp, nrp, cred, td, 0); + /* * For a client side mount, nmp is != NULL and clp == NULL. For * server calls (callbacks or upcalls), nmp == NULL. @@ -442,8 +453,30 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, nd->nd_procnum != NFSPROC_NULL) { if (NFSHASALLGSSNAME(nmp) && nmp->nm_krbnamelen > 0) nd->nd_flag |= ND_USEGSSNAME; - if ((nd->nd_flag & ND_USEGSSNAME) && nmp->nm_krbnamelen > 0) - usegssname = 1; + if ((nd->nd_flag & ND_USEGSSNAME) != 0) { + /* + * If there is a client side host based credential, + * use that, otherwise use the system uid, if set. + */ + if (nmp->nm_krbnamelen > 0) { + usegssname = 1; + } else if (nmp->nm_uid != (uid_t)-1) { + saved_uid = cred->cr_uid; + cred->cr_uid = nmp->nm_uid; + set_uid = 1; + } + } else if (nmp->nm_krbnamelen == 0 && + nmp->nm_uid != (uid_t)-1 && cred->cr_uid == (uid_t)0) { + /* + * If there is no host based principal name and + * the system uid is set and this is root, use the + * system uid, since root won't have user + * credentials in a credentials cache file. + */ + saved_uid = cred->cr_uid; + cred->cr_uid = nmp->nm_uid; + set_uid = 1; + } if (NFSHASINTEGRITY(nmp)) secflavour = RPCSEC_GSS_KRB5I; else if (NFSHASPRIVACY(nmp)) @@ -462,14 +495,6 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, ((nmp->nm_tprintf_delay)-(nmp->nm_tprintf_initial_delay)); } - /* - * XXX if not already connected call nfs_connect now. Longer - * term, change nfs_mount to call nfs_connect unconditionally - * and let clnt_reconnect_create handle reconnects. - */ - if (nrp->nr_client == NULL) - newnfs_connect(nmp, nrp, cred, td, 0); - if (nd->nd_procnum == NFSPROC_NULL) auth = authnone_create(); else if (usegssname) @@ -478,6 +503,8 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, else auth = nfs_getauth(nrp, secflavour, NULL, srv_principal, NULL, cred); + if (set_uid) + cred->cr_uid = saved_uid; if (auth == NULL) { m_freem(nd->nd_mreq); return (EACCES); diff --git a/sys/fs/nfsclient/nfs_clvfsops.c b/sys/fs/nfsclient/nfs_clvfsops.c index 412ad1db0d84..73fb4e3637f1 100644 --- a/sys/fs/nfsclient/nfs_clvfsops.c +++ b/sys/fs/nfsclient/nfs_clvfsops.c @@ -1062,20 +1062,20 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam, nmp->nm_krbnamelen = argp->krbnamelen; nmp->nm_dirpathlen = argp->dirlen; nmp->nm_srvkrbnamelen = argp->srvkrbnamelen; - if (nmp->nm_dirpathlen > 0) { + if (td->td_ucred->cr_uid != (uid_t)0) { /* - * Since we will be doing dirpath as root, - * set nm_uid to the real uid doing the mount, - * since that is normally the user with a valid TGT. + * nm_uid is used to get KerberosV credentials for + * the nfsv4 state handling operations if there is + * no host based principal set. Use the uid of + * this user if not root, since they are doing the + * mount. I don't think setting this for root will + * work, since root normally does not have user + * credentials in a credentials cache. */ - nmp->nm_uid = td->td_ucred->cr_ruid; + nmp->nm_uid = td->td_ucred->cr_uid; } else { /* - * Just set to -1, so the first Op - * will set it later, to the uid of - * the process doing that (usually - * from a first open in the mount - * point). + * Just set to -1, so it won't be used. */ nmp->nm_uid = (uid_t)-1; } From 3f8cd45f792d9b95289a0733bf3b5e4f7dca8b3b Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 24 May 2009 09:42:53 +0000 Subject: [PATCH 456/544] Add new constants to the acl(9) manual page. --- share/man/man9/acl.9 | 78 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9 index 4ab1e404cbc1..bfd696cba279 100644 --- a/share/man/man9/acl.9 +++ b/share/man/man9/acl.9 @@ -59,7 +59,9 @@ Currently, each ACL is represented in-kernel by a fixed-size structure, defined as follows: .Bd -literal -offset indent struct acl { - int acl_cnt; + unsigned int acl_maxcnt; + unsigned int acl_cnt; + int acl_spare[4]; struct acl_entry acl_entry[ACL_MAX_ENTRIES]; }; .Ed @@ -67,6 +69,10 @@ struct acl { An ACL is constructed from a fixed size array of ACL entries, each of which consists of a set of permissions, principal namespace, and principal identifier. +In this implementation, the +.Vt acl_maxcnt +field is always set to +.Dv ACL_MAX_ENTRIES . .Pp Each individual ACL entry is of the type .Vt acl_entry_t , @@ -97,13 +103,20 @@ match the ACL entry qualifier. .It Dv ACL_MASK The maximum discretionary access rights that can be granted to a process in the file group class. +This is only valid for POSIX.1e ACLs. .It Dv ACL_OTHER Discretionary access rights for processes not covered by any other ACL entry. +This is only valid for POSIX.1e ACLs. .It Dv ACL_OTHER_OBJ Same as .Dv ACL_OTHER . -Each ACL entry must contain exactly one +.It Dv ACL_EVERYONE +Discretionary access rights for all users. +This is only valid for NFSv4 ACLs. +.El +.Pp +Each POSIX.1e ACL must contain exactly one .Dv ACL_USER_OBJ , one .Dv ACL_GROUP_OBJ , @@ -117,13 +130,19 @@ or are present, then exactly one .Dv ACL_MASK entry should be present. -.El .It Vt uid_t Va ae_id The ID of user for whom this ACL describes access permissions. +For entries other than +.Dv ACL_USER +and +.Dv ACL_GROUP , +this field should be set to +.Dv ACL_UNDEFINED_ID . .It Vt acl_perm_t Va ae_perm This field defines what kind of access the process matching this ACL has for accessing the associated file. -.Bl -tag -width ".Dv ACL_POSIX1E_BITS" +For POSIX.1e ACLs, the following are valid: +.Bl -tag -width ".Dv ACL_WRITE_NAMED_ATTRS" .It Dv ACL_EXECUTE The process may execute the associated file. .It Dv ACL_WRITE @@ -134,6 +153,57 @@ The process may read from the associated file. The process has no read, write or execute permissions to the associated file. .El +.Pp +For NFSv4 ACLs, the following are valid: +.Bl -tag -width ".Dv ACL_WRITE_NAMED_ATTRS" +.It Dv ACL_READ_DATA +The process may read from the associated file. +.It Dv ACL_LIST_DIRECTORY +Same as +.Dv ACL_READ_DATA . +.It Dv ACL_WRITE_DATA +The process may write to the associated file. +.It Dv ACL_ADD_FILE +Same as +.Dv ACL_ACL_WRITE_DATA . +.It Dv ACL_APPEND_DATA +.It Dv ACL_ADD_SUBDIRECTORY +Same as +.Dv ACL_APPEND_DATA . +.It Dv ACL_READ_NAMED_ATTRS +Ignored. +.It Dv ACL_WRITE_NAMED_ATTRS +Ignored. +.It Dv ACL_EXECUTE +The process may execute the associated file. +.It Dv ACL_DELETE_CHILD +.It Dv ACL_READ_ATTRIBUTES +.It Dv ACL_WRITE_ATTRIBUTES +.It Dv ACL_DELETE +.It Dv ACL_READ_ACL +.It Dv ACL_WRITE_ACL +.It Dv ACL_WRITE_OWNER +.It Dv ACL_SYNCHRONIZE +Ignored. +.El +.It Vt acl_entry_type_t Va ae_entry_type +This field defines the type of NFSv4 ACL entry. +It is not used with POSIX.1e ACLs. +The following values are valid: +.Bl -tag -width ".Dv ACL_WRITE_NAMED_ATTRS" +.It Dv ACL_ENTRY_TYPE_ALLOW +.It Dv ACL_ENTRY_TYPE_DENY +.El +.It Vt acl_flag_t Va ae_flags +This field defines the inheritance flags of NFSv4 ACL entry. +It is not used with POSIX.1e ACLs. +The following values are valid: +.Bl -tag -width ".Dv ACL_ENTRY_DIRECTORY_INHERIT" +.It Dv ACL_ENTRY_FILE_INHERIT +.It Dv ACL_ENTRY_DIRECTORY_INHERIT +.It Dv ACL_ENRY_NO_PROPAGATE_INHERIT +.It Dv ACL_ENTRY_INHERIT_ONLY +.El .El .Sh SEE ALSO .Xr acl 3 , From 57d8181b40bab5afbb18be5337277395559279c2 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sun, 24 May 2009 11:10:27 +0000 Subject: [PATCH 457/544] Fix build of KGSSAPI bits post-vimage. --- sys/kgssapi/gsstest.c | 9 +++++---- sys/nfsserver/nfs_srvkrpc.c | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/sys/kgssapi/gsstest.c b/sys/kgssapi/gsstest.c index 6d5a0c05d29a..c54fb5d4ea5a 100644 --- a/sys/kgssapi/gsstest.c +++ b/sys/kgssapi/gsstest.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -227,7 +228,7 @@ gsstest_1(void) { static char sbuf[512]; - snprintf(sbuf, sizeof(sbuf), "nfs@%s", hostname); + snprintf(sbuf, sizeof(sbuf), "nfs@%s", V_hostname); name_desc.value = sbuf; } @@ -430,7 +431,7 @@ gsstest_2(int step, const gss_buffer_t input_token, case 1: if (server_context == GSS_C_NO_CONTEXT) { static char sbuf[512]; - snprintf(sbuf, sizeof(sbuf), "nfs@%s", hostname); + snprintf(sbuf, sizeof(sbuf), "nfs@%s", V_hostname); name_desc.value = sbuf; name_desc.length = strlen((const char *) name_desc.value); @@ -811,7 +812,7 @@ gsstest_3(void) return(1); } - snprintf(service, sizeof(service), "host@%s", hostname); + snprintf(service, sizeof(service), "host@%s", V_hostname); auth = rpc_gss_seccreate(client, curthread->td_ucred, service, "kerberosv5", rpc_gss_svc_privacy, @@ -881,7 +882,7 @@ gsstest_4(void) const char **mechs; static rpc_gss_callback_t cb; - snprintf(principal, sizeof(principal), "host@%s", hostname); + snprintf(principal, sizeof(principal), "host@%s", V_hostname); mechs = rpc_gss_get_mechanisms(); while (*mechs) { diff --git a/sys/nfsserver/nfs_srvkrpc.c b/sys/nfsserver/nfs_srvkrpc.c index 77bdec85c62e..030d02abadb1 100644 --- a/sys/nfsserver/nfs_srvkrpc.c +++ b/sys/nfsserver/nfs_srvkrpc.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -488,7 +489,7 @@ nfssvc_nfsd(struct thread *td, struct nfsd_nfsd_args *args) if (error) return (error); } else { - snprintf(principal, sizeof(principal), "nfs@%s", hostname); + snprintf(principal, sizeof(principal), "nfs@%s", V_hostname); } #endif From 3b086f3159bd795c940ead5f973471e7df9d2265 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sun, 24 May 2009 11:37:10 +0000 Subject: [PATCH 458/544] Increase the number of available file descriptors to 64. This fixes the reported zfsboot problems for systems where more than seven drives are part of ZFS pools. --- lib/libstand/stand.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h index 91bfd931ff2e..eae160530ab5 100644 --- a/lib/libstand/stand.h +++ b/lib/libstand/stand.h @@ -167,7 +167,7 @@ struct open_file { #define SOPEN_RASIZE 512 }; -#define SOPEN_MAX 8 +#define SOPEN_MAX 64 extern struct open_file files[]; /* f_flags values */ From 8aec91b5e8ab6a575745ba6d4946d1cfab860489 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 24 May 2009 12:28:38 +0000 Subject: [PATCH 459/544] Replace the while statement with the if for clarity. The loop body cannot be executed more then once. Reviewed by: dfr Tested by: pho MFC after: 1 month --- sys/kern/kern_lockf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c index b8cece625257..aeb6a8cafd2d 100644 --- a/sys/kern/kern_lockf.c +++ b/sys/kern/kern_lockf.c @@ -1361,7 +1361,7 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp, /* * Scan lock list for this file looking for locks that would block us. */ - while (lf_getblock(state, lock)) { + if (lf_getblock(state, lock)) { /* * Free the structure and return if nonblocking. */ From 47e6a3971f01806dda5e4f019db33bcf509ca10c Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Sun, 24 May 2009 12:32:03 +0000 Subject: [PATCH 460/544] Block when initially opening a TTY multiple times. In the original MPSAFE TTY code, I changed the behaviour by returning EBUSY. I thought this made more sense, because it's basically a race to see who gets the TTY first. It turns out this is not a good change, because it also causes EBUSY to be returned when another process is closing the TTY. This can happen during startup, when /etc/rc (or one of its children) is still busy draining its data and /sbin/init is attempting to open the TTY to spawn a getty. Reported by: bz Tested by: bz --- sys/kern/tty.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/sys/kern/tty.c b/sys/kern/tty.c index 2468e8859381..804635ebb540 100644 --- a/sys/kern/tty.c +++ b/sys/kern/tty.c @@ -206,6 +206,7 @@ ttydev_leave(struct tty *tp) ttydevsw_close(tp); tp->t_flags &= ~TF_OPENCLOSE; + cv_broadcast(&tp->t_dcdwait); tty_rel_free(tp); } @@ -231,13 +232,17 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) tty_unlock(tp); return (ENXIO); } + /* - * Prevent the TTY from being opened when being torn down or - * built up by unrelated processes. + * Block when other processes are currently opening or closing + * the TTY. */ - if (tp->t_flags & TF_OPENCLOSE) { - tty_unlock(tp); - return (EBUSY); + while (tp->t_flags & TF_OPENCLOSE) { + error = tty_wait(tp, &tp->t_dcdwait); + if (error != 0) { + tty_unlock(tp); + return (error); + } } tp->t_flags |= TF_OPENCLOSE; @@ -299,6 +304,7 @@ ttydev_open(struct cdev *dev, int oflags, int devtype, struct thread *td) tp->t_flags |= TF_OPENED_IN; done: tp->t_flags &= ~TF_OPENCLOSE; + cv_broadcast(&tp->t_dcdwait); ttydev_leave(tp); return (error); From b33d61771779f7a201667ecad2dd12f7e4a0cfbd Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 24 May 2009 12:33:16 +0000 Subject: [PATCH 461/544] In lf_advlockasync(), recheck for doomed vnode after the state->ls_lock is acquired. In the lf_purgelocks(), assert that vnode is doomed and set *statep to NULL before clearing ls_pending list. Otherwise, we allow for the thread executing lf_advlockasync() to put new pending entry after state->ls_lock is dropped in lf_purgelocks(). Reviewed by: dfr Tested by: pho MFC after: 1 month --- sys/kern/kern_lockf.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c index aeb6a8cafd2d..6a6e966514ee 100644 --- a/sys/kern/kern_lockf.c +++ b/sys/kern/kern_lockf.c @@ -633,7 +633,20 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep, } sx_xlock(&state->ls_lock); - switch(ap->a_op) { + /* + * Recheck the doomed vnode after state->ls_lock is + * locked. lf_purgelocks() requires that no new threads add + * pending locks when vnode is marked by VI_DOOMED flag. + */ + VI_LOCK(vp); + if (vp->v_iflag & VI_DOOMED) { + VI_UNLOCK(vp); + lf_free_lock(lock); + return (ENOENT); + } + VI_UNLOCK(vp); + + switch (ap->a_op) { case F_SETLK: error = lf_setlock(state, lock, vp, ap->a_cookiep); break; @@ -755,8 +768,11 @@ lf_purgelocks(struct vnode *vp, struct lockf **statep) * the remaining locks. */ VI_LOCK(vp); + KASSERT(vp->v_iflag & VI_DOOMED, + ("lf_purgelocks: vp %p has not vgone yet", vp)); state = *statep; if (state) { + *statep = NULL; state->ls_threads++; VI_UNLOCK(vp); @@ -789,7 +805,6 @@ lf_purgelocks(struct vnode *vp, struct lockf **statep) VI_LOCK(vp); while (state->ls_threads > 1) msleep(state, VI_MTX(vp), 0, "purgelocks", 0); - *statep = 0; VI_UNLOCK(vp); /* From 9727972e2c3a530c0443c966e4a3af1c7b8ccc3e Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 24 May 2009 12:37:55 +0000 Subject: [PATCH 462/544] In lf_purgelocks(), assert that state->ls_pending is empty after we weeded out threads, and clean ls_active instead of ls_pending. Reviewed by: dfr Tested by: pho MFC after: 1 month --- sys/kern/kern_lockf.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c index 6a6e966514ee..3f8e9f6c9b12 100644 --- a/sys/kern/kern_lockf.c +++ b/sys/kern/kern_lockf.c @@ -813,7 +813,9 @@ lf_purgelocks(struct vnode *vp, struct lockf **statep) * above). We don't need to bother locking since we * are the last thread using this state structure. */ - LIST_FOREACH_SAFE(lock, &state->ls_pending, lf_link, nlock) { + KASSERT(LIST_EMPTY(&state->ls_pending), + ("lock pending for %p", state)); + LIST_FOREACH_SAFE(lock, &state->ls_active, lf_link, nlock) { LIST_REMOVE(lock, lf_link); lf_free_lock(lock); } From 8af54d4cfc94dd8b52331cbfdcca744cfc69ef15 Mon Sep 17 00:00:00 2001 From: Konstantin Belousov Date: Sun, 24 May 2009 12:39:38 +0000 Subject: [PATCH 463/544] The advisory lock may be activated or activated and removed during the sleep waiting for conditions when the lock may be granted. To prevent lf_setlock() from accessing possibly freed memory, add reference counting to the struct lockf_entry. Bump refcount around the sleep. Make lf_free_lock() return non-zero when structure was freed, and use this after the sleep to return EINTR to the caller. The error code might need a clarification, but we cannot return success to usermode, since the lock is not owned anymore. Reviewed by: dfr Tested by: pho MFC after: 1 month --- sys/kern/kern_lockf.c | 17 +++++++++++++++-- sys/sys/lockf.h | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/sys/kern/kern_lockf.c b/sys/kern/kern_lockf.c index 3f8e9f6c9b12..8862f1e67cac 100644 --- a/sys/kern/kern_lockf.c +++ b/sys/kern/kern_lockf.c @@ -106,7 +106,7 @@ static int lf_owner_matches(struct lock_owner *, caddr_t, struct flock *, int); static struct lockf_entry * lf_alloc_lock(struct lock_owner *); -static void lf_free_lock(struct lockf_entry *); +static int lf_free_lock(struct lockf_entry *); static int lf_clearlock(struct lockf *, struct lockf_entry *); static int lf_overlaps(struct lockf_entry *, struct lockf_entry *); static int lf_blocks(struct lockf_entry *, struct lockf_entry *); @@ -347,9 +347,13 @@ lf_alloc_lock(struct lock_owner *lo) return (lf); } -static void +static int lf_free_lock(struct lockf_entry *lock) { + + KASSERT(lock->lf_refs > 0, ("lockf_entry negative ref count %p", lock)); + if (--lock->lf_refs > 0) + return (0); /* * Adjust the lock_owner reference count and * reclaim the entry if this is the last lock @@ -394,6 +398,7 @@ lf_free_lock(struct lockf_entry *lock) printf("Freed lock %p\n", lock); #endif free(lock, M_LOCKF); + return (1); } /* @@ -540,6 +545,7 @@ lf_advlockasync(struct vop_advlockasync_args *ap, struct lockf **statep, * the lf_lock_owners_lock tax twice. */ lock = lf_alloc_lock(NULL); + lock->lf_refs = 1; lock->lf_start = start; lock->lf_end = end; lock->lf_owner = lo; @@ -1447,7 +1453,13 @@ lf_setlock(struct lockf *state, struct lockf_entry *lock, struct vnode *vp, goto out; } + lock->lf_refs++; error = sx_sleep(lock, &state->ls_lock, priority, lockstr, 0); + if (lf_free_lock(lock)) { + error = EINTR; + goto out; + } + /* * We may have been awakened by a signal and/or by a * debugger continuing us (in which cases we must @@ -1809,6 +1821,7 @@ lf_split(struct lockf *state, struct lockf_entry *lock1, */ splitlock = lf_alloc_lock(lock1->lf_owner); memcpy(splitlock, lock1, sizeof *splitlock); + splitlock->lf_refs = 1; if (splitlock->lf_flags & F_REMOTE) vref(splitlock->lf_vnode); diff --git a/sys/sys/lockf.h b/sys/sys/lockf.h index 323906681184..1235bdba0c4f 100644 --- a/sys/sys/lockf.h +++ b/sys/sys/lockf.h @@ -80,6 +80,7 @@ struct lockf_entry { LIST_ENTRY(lockf_entry) lf_link; /* (s) Linkage for lock lists */ struct lockf_edge_list lf_outedges; /* (s) list of out-edges */ struct lockf_edge_list lf_inedges; /* (s) list of out-edges */ + int lf_refs; /* (s) ref count */ }; LIST_HEAD(lockf_entry_list, lockf_entry); From f435931b4a75365d65f121404d47e6f24331e940 Mon Sep 17 00:00:00 2001 From: Doug Rabson Date: Sun, 24 May 2009 13:22:00 +0000 Subject: [PATCH 464/544] Make sure we feed 32bit align memory to nfsm_dissect otherwise we will fault on platforms with strict alignment requirements. In particular, this fixes the problems with the new RPC transport on the arm platform. Note: this adds yet another copy of nfs_realign(). I will attempt to refactor after NFS_LEGACYRPC is removed. Submitted by: sam --- sys/nfsclient/nfs_krpc.c | 74 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 73 insertions(+), 1 deletion(-) diff --git a/sys/nfsclient/nfs_krpc.c b/sys/nfsclient/nfs_krpc.c index 1aa398ebb5ce..4cd6986494bb 100644 --- a/sys/nfsclient/nfs_krpc.c +++ b/sys/nfsclient/nfs_krpc.c @@ -406,6 +406,65 @@ nfs_feedback(int type, int proc, void *arg) } } +/* + * nfs_realign: + * + * Check for badly aligned mbuf data and realign by copying the unaligned + * portion of the data into a new mbuf chain and freeing the portions + * of the old chain that were replaced. + * + * We cannot simply realign the data within the existing mbuf chain + * because the underlying buffers may contain other rpc commands and + * we cannot afford to overwrite them. + * + * We would prefer to avoid this situation entirely. The situation does + * not occur with NFS/UDP and is supposed to only occassionally occur + * with TCP. Use vfs.nfs.realign_count and realign_test to check this. + * + */ +static int +nfs_realign(struct mbuf **pm, int hsiz) +{ + struct mbuf *m, *n; + int off, space; + + ++nfs_realign_test; + while ((m = *pm) != NULL) { + if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { + /* + * NB: we can't depend on m_pkthdr.len to help us + * decide what to do here. May not be worth doing + * the m_length calculation as m_copyback will + * expand the mbuf chain below as needed. + */ + space = m_length(m, NULL); + if (space >= MINCLSIZE) { + /* NB: m_copyback handles space > MCLBYTES */ + n = m_getcl(M_DONTWAIT, MT_DATA, 0); + } else + n = m_get(M_DONTWAIT, MT_DATA); + if (n == NULL) + return (ENOMEM); + /* + * Align the remainder of the mbuf chain. + */ + n->m_len = 0; + off = 0; + while (m != NULL) { + m_copyback(n, off, m->m_len, mtod(m, caddr_t)); + off += m->m_len; + m = m->m_next; + } + m_freem(*pm); + *pm = n; + ++nfs_realign_count; + break; + } + pm = &m->m_next; + } + return (0); +} + /* * nfs_request - goes something like this * - fill in request struct @@ -525,12 +584,25 @@ nfs_request(struct vnode *vp, struct mbuf *mreq, int procnum, } else { error = EACCES; } - md = mrep; if (error) goto nfsmout; KASSERT(mrep != NULL, ("mrep shouldn't be NULL if no error\n")); + /* + * Search for any mbufs that are not a multiple of 4 bytes long + * or with m_data not longword aligned. + * These could cause pointer alignment problems, so copy them to + * well aligned mbufs. + */ + error = nfs_realign(&mrep, 2 * NFSX_UNSIGNED); + if (error == ENOMEM) { + m_freem(mrep); + AUTH_DESTROY(auth); + return (error); + } + + md = mrep; dpos = mtod(mrep, caddr_t); tl = nfsm_dissect(u_int32_t *, NFSX_UNSIGNED); if (*tl != 0) { From a6412d5d4b560b82b2f6341754584b4c96fad042 Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 24 May 2009 15:27:25 +0000 Subject: [PATCH 465/544] Fix chflags -h in various cases: do not use link target's flags as original. Patch slightly changed to align more with chmod.c. PR: bin/131999 Submitted by: bde Approved by: ed (mentor) MFC after: 3 weeks --- bin/chflags/chflags.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/chflags/chflags.c b/bin/chflags/chflags.c index 053a7a7db4cc..02137eb30c34 100644 --- a/bin/chflags/chflags.c +++ b/bin/chflags/chflags.c @@ -115,7 +115,7 @@ main(int argc, char *argv[]) fts_options |= FTS_LOGICAL; } } else - fts_options = FTS_LOGICAL; + fts_options = hflag ? FTS_PHYSICAL : FTS_LOGICAL; /* XXX: Why don't chflags and lchflags have compatible prototypes? */ if (hflag) From 6dcfa92ee8119665c7e188e6e89160825ce351aa Mon Sep 17 00:00:00 2001 From: Jilles Tjoelker Date: Sun, 24 May 2009 15:32:34 +0000 Subject: [PATCH 466/544] Fix elapsed (etime) field for swapped out processes in ps: show '-' instead of time since the Epoch. PR: bin/123069 Submitted by: Vladimir Kozbin Approved by: ed (mentor) MFC after: 3 weeks --- bin/ps/print.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bin/ps/print.c b/bin/ps/print.c index 1bfce04489e8..aa4f98f2c7bc 100644 --- a/bin/ps/print.c +++ b/bin/ps/print.c @@ -596,6 +596,10 @@ elapsed(KINFO *k, VARENT *ve) char obuff[128]; v = ve->var; + if (!k->ki_valid) { + (void)printf("%-*s", v->width, "-"); + return; + } val = now - k->ki_p->ki_start.tv_sec; days = val / (24 * 60 * 60); val %= 24 * 60 * 60; From 194f4d42def89f85f8cc1259ae8e45bb7a00a195 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 24 May 2009 15:48:48 +0000 Subject: [PATCH 467/544] Fix comment. --- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index d0ddaaa9e6ac..f9b83c29d087 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -3963,7 +3963,7 @@ static int zfs_freebsd_access(ap) struct vop_access_args /* { struct vnode *a_vp; - int a_accmode; + accmode_t a_accmode; struct ucred *a_cred; struct thread *a_td; } */ *ap; From 7070b4fc87fbe52c432714aaad17963fc7bef7d2 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 24 May 2009 17:08:00 +0000 Subject: [PATCH 468/544] Fix typo in the manual page. --- share/man/man9/acl.9 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9 index bfd696cba279..5b35ecd41aad 100644 --- a/share/man/man9/acl.9 +++ b/share/man/man9/acl.9 @@ -201,7 +201,7 @@ The following values are valid: .Bl -tag -width ".Dv ACL_ENTRY_DIRECTORY_INHERIT" .It Dv ACL_ENTRY_FILE_INHERIT .It Dv ACL_ENTRY_DIRECTORY_INHERIT -.It Dv ACL_ENRY_NO_PROPAGATE_INHERIT +.It Dv ACL_ENRTY_NO_PROPAGATE_INHERIT .It Dv ACL_ENTRY_INHERIT_ONLY .El .El From c327ec0021995d2c14d01ba5a7f418e2272bfb0e Mon Sep 17 00:00:00 2001 From: Tom McLaughlin Date: Sun, 24 May 2009 18:34:54 +0000 Subject: [PATCH 469/544] Update man pages after VFS_* changes in r191990. Approved by: brueffer, attilio --- share/man/man9/VFS_MOUNT.9 | 6 ++---- share/man/man9/VFS_QUOTACTL.9 | 4 ++-- share/man/man9/VFS_ROOT.9 | 6 ++---- share/man/man9/VFS_STATFS.9 | 6 ++---- share/man/man9/VFS_SYNC.9 | 6 ++---- share/man/man9/VFS_UNMOUNT.9 | 6 ++---- 6 files changed, 12 insertions(+), 22 deletions(-) diff --git a/share/man/man9/VFS_MOUNT.9 b/share/man/man9/VFS_MOUNT.9 index 97d85faa8d71..4856dc49ea82 100644 --- a/share/man/man9/VFS_MOUNT.9 +++ b/share/man/man9/VFS_MOUNT.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2005 +.Dd May 23, 2009 .Os .Dt VFS_MOUNT 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_MOUNT "struct mount *mp" "struct thread *td" +.Fn VFS_MOUNT "struct mount *mp" .Sh DESCRIPTION The .Fn VFS_MOUNT @@ -50,8 +50,6 @@ The arguments it expects are: .Bl -tag -width data .It Fa mp Structure representing the file system. -.It Fa td -Thread which is mounting the file system. .El .Pp The diff --git a/share/man/man9/VFS_QUOTACTL.9 b/share/man/man9/VFS_QUOTACTL.9 index 4c3620a6e135..48ff866c2117 100644 --- a/share/man/man9/VFS_QUOTACTL.9 +++ b/share/man/man9/VFS_QUOTACTL.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 24, 1996 +.Dd May 23, 2009 .Os .Dt VFS_QUOTACTL 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_QUOTACTL "struct mount *mp" "int cmds" "uid_t uid" "caddr_t arg" "struct thread *td" +.Fn VFS_QUOTACTL "struct mount *mp" "int cmds" "uid_t uid" "caddr_t arg" .Sh DESCRIPTION Implement file system quotas. See diff --git a/share/man/man9/VFS_ROOT.9 b/share/man/man9/VFS_ROOT.9 index 1aa019461c28..2490cfc0bdad 100644 --- a/share/man/man9/VFS_ROOT.9 +++ b/share/man/man9/VFS_ROOT.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 26, 2006 +.Dd May 23, 2009 .Os .Dt VFS_ROOT 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_ROOT "struct mount *mp" "int flags" "struct vnode **vpp" "struct thread *td" +.Fn VFS_ROOT "struct mount *mp" "int flags" "struct vnode **vpp" .Sh DESCRIPTION Return a locked vnode for the root directory of the file system. .Pp @@ -58,8 +58,6 @@ File system is free to ignore the argument and instead acquire an exclusive lock. .It Fa vpp Return parameter for the root vnode. -.It Fa td -The calling thread. .El .Sh SEE ALSO .Xr VFS 9 , diff --git a/share/man/man9/VFS_STATFS.9 b/share/man/man9/VFS_STATFS.9 index dd8dcc7c52f3..80d0d6652a5a 100644 --- a/share/man/man9/VFS_STATFS.9 +++ b/share/man/man9/VFS_STATFS.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2005 +.Dd May 23, 2009 .Os .Dt VFS_STATFS 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_STATFS "struct mount *mp" "struct statfs *sbp" "struct thread *td" +.Fn VFS_STATFS "struct mount *mp" "struct statfs *sbp" .Sh DESCRIPTION The .Fn VFS_STATFS @@ -56,8 +56,6 @@ A structure, as defined by .In sys/mount.h , into which information is placed about the file system. -.It Fa td -The thread which is querying the file system. .El .Pp The fields of diff --git a/share/man/man9/VFS_SYNC.9 b/share/man/man9/VFS_SYNC.9 index 6f603ab8ee14..60947a247095 100644 --- a/share/man/man9/VFS_SYNC.9 +++ b/share/man/man9/VFS_SYNC.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2005 +.Dd May 23, 2009 .Os .Dt VFS_SYNC 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_SYNC "struct mount *mp" "int waitfor" "struct thread *td" +.Fn VFS_SYNC "struct mount *mp" "int waitfor" .Sh DESCRIPTION The .Fn VFS_SYNC @@ -61,8 +61,6 @@ start all I/O, but do not wait for it .It Dv MNT_LAZY push data not written by file system syncer .El -.It Fa td -The calling thread. .El .Pp The diff --git a/share/man/man9/VFS_UNMOUNT.9 b/share/man/man9/VFS_UNMOUNT.9 index 1face4913e1b..676685d4a4b4 100644 --- a/share/man/man9/VFS_UNMOUNT.9 +++ b/share/man/man9/VFS_UNMOUNT.9 @@ -28,7 +28,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 7, 2005 +.Dd May 23, 2009 .Os .Dt VFS_UNMOUNT 9 .Sh NAME @@ -39,7 +39,7 @@ .In sys/mount.h .In sys/vnode.h .Ft int -.Fn VFS_UNMOUNT "struct mount *mp" "int mntflags" "struct thread *td" +.Fn VFS_UNMOUNT "struct mount *mp" "int mntflags" .Sh DESCRIPTION The .Fn VFS_UNMOUNT @@ -58,8 +58,6 @@ are: .It Dv MNT_FORCE Open files are forcibly closed before the file system is unmounted. .El -.It Fa td -Thread which is unmounting the file system. .El .Sh SEE ALSO .Xr vflush 9 , From ad0498a383ee690a65fafd18a2b573004047f731 Mon Sep 17 00:00:00 2001 From: Antoine Brodin Date: Sun, 24 May 2009 18:35:53 +0000 Subject: [PATCH 470/544] Remove an unused variable. --- sys/compat/ndis/kern_ndis.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/compat/ndis/kern_ndis.c b/sys/compat/ndis/kern_ndis.c index 1ccef55efd1f..192f84e87cf5 100644 --- a/sys/compat/ndis/kern_ndis.c +++ b/sys/compat/ndis/kern_ndis.c @@ -543,7 +543,7 @@ ndis_free_bufs(b0) return; } -int in_reset = 0; + void ndis_free_packet(p) ndis_packet *p; From c1edc4480e4e9812cf2359199ba2b8ba0db38f81 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 24 May 2009 18:49:53 +0000 Subject: [PATCH 471/544] Fix the experimental NFSv4 server so that it handles the case where a client is not allowed NFSv4 access correctly. This restriction is specified in the "V4: ..." line(s) in /etc/exports. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdkrpc.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index 18b6d6d797ed..f0b57655dc59 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -286,6 +286,8 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, struct socket *so, cacherep = RC_DROPIT; } else if (nd->nd_repstat) { cacherep = RC_REPLY; + if ((nd->nd_flag & ND_NFSV4) == 0) + panic("nfs_repstat for nfsv2,3"); } else { /* * For NFSv3, play it safe and assume that the client is @@ -313,6 +315,9 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, struct socket *so, else cacherep = RC_REPLY; *rpp = nfsrvd_updatecache(nd, so); + } else if (cacherep == RC_REPLY) { + /* Generate the error reply message for NFSv4 */ + nfsrvd_dorpc(nd, isdgram, td); } return (cacherep); } From 4076aa37dcd44070699f3500ec446eded7ec6ebb Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 24 May 2009 19:21:49 +0000 Subject: [PATCH 472/544] Don't allow non-owner to set SUID bit on a file. It doesn't make any difference now, but in NFSv4 ACLs, there is write_acl permission, which also affects mode changes. Reviewed by: pjd --- sys/cddl/compat/opensolaris/kern/opensolaris_policy.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c index 25c736e53ddd..cedf335257d6 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_policy.c @@ -302,6 +302,14 @@ secpolicy_setid_setsticky_clear(struct vnode *vp, struct vattr *vap, if (error) return (error); } + /* + * Deny setting setuid if we are not the file owner. + */ + if ((vap->va_mode & S_ISUID) && ovap->va_uid != cred->cr_uid) { + error = priv_check_cred(cred, PRIV_VFS_ADMIN, 0); + if (error) + return (error); + } return (0); } From 05c965a221d9486319730b9f31b8f19dc536928a Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 24 May 2009 19:46:12 +0000 Subject: [PATCH 473/544] Crib the realign function out of nfs_krpc.c and add a call to it for the client side reply. Hopefully this fixes the problem with using the new krpc for arm for the experimental nfs client. Approved by: kib (mentor) --- sys/fs/nfs/nfs_commonkrpc.c | 7 +++++ sys/fs/nfs/nfs_commonport.c | 59 +++++++++++++++++++++---------------- 2 files changed, 40 insertions(+), 26 deletions(-) diff --git a/sys/fs/nfs/nfs_commonkrpc.c b/sys/fs/nfs/nfs_commonkrpc.c index d487703b6ddf..1f0cb551700f 100644 --- a/sys/fs/nfs/nfs_commonkrpc.c +++ b/sys/fs/nfs/nfs_commonkrpc.c @@ -603,6 +603,13 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp, KASSERT(nd->nd_mrep != NULL, ("mrep shouldn't be NULL if no error\n")); + /* + * Search for any mbufs that are not a multiple of 4 bytes long + * or with m_data not longword aligned. + * These could cause pointer alignment problems, so copy them to + * well aligned mbufs. + */ + newnfs_realign(&nd->nd_mrep); nd->nd_md = nd->nd_mrep; nd->nd_dpos = NFSMTOD(nd->nd_md, caddr_t); nd->nd_repstat = 0; diff --git a/sys/fs/nfs/nfs_commonport.c b/sys/fs/nfs/nfs_commonport.c index 1c226578bfaf..4c17aee91d6d 100644 --- a/sys/fs/nfs/nfs_commonport.c +++ b/sys/fs/nfs/nfs_commonport.c @@ -70,8 +70,8 @@ static int nfs_realign_test; static int nfs_realign_count; SYSCTL_NODE(_vfs, OID_AUTO, newnfs, CTLFLAG_RW, 0, "New NFS filesystem"); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, realign_test, CTLFLAG_RW, &nfs_realign_test, 0, ""); -SYSCTL_INT(_vfs_newnfs, OID_AUTO, realign_count, CTLFLAG_RW, &nfs_realign_count, 0, ""); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, newnfs_realign_test, CTLFLAG_RW, &nfs_realign_test, 0, ""); +SYSCTL_INT(_vfs_newnfs, OID_AUTO, newnfs_realign_count, CTLFLAG_RW, &nfs_realign_count, 0, ""); SYSCTL_INT(_vfs_newnfs, OID_AUTO, nfs4acl_enable, CTLFLAG_RW, &nfsrv_useacl, 0, ""); SYSCTL_STRING(_vfs_newnfs, OID_AUTO, callback_addr, CTLFLAG_RW, nfsv4_callbackaddr, sizeof(nfsv4_callbackaddr), ""); @@ -129,7 +129,7 @@ newnfs_realign(struct mbuf **pm) } #else /* - * nfs_realign: + * newnfs_realign: * * Check for badly aligned mbuf data and realign by copying the unaligned * portion of the data into a new mbuf chain and freeing the portions @@ -142,43 +142,50 @@ newnfs_realign(struct mbuf **pm) * We would prefer to avoid this situation entirely. The situation does * not occur with NFS/UDP and is supposed to only occassionally occur * with TCP. Use vfs.nfs.realign_count and realign_test to check this. + * */ void newnfs_realign(struct mbuf **pm) { - struct mbuf *m; - struct mbuf *n = NULL; - int off = 0; + struct mbuf *m, *n; + int off, space; ++nfs_realign_test; while ((m = *pm) != NULL) { if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) { - MGET(n, M_WAIT, MT_DATA); - if (m->m_len >= MINCLSIZE) { - MCLGET(n, M_WAIT); - } + /* + * NB: we can't depend on m_pkthdr.len to help us + * decide what to do here. May not be worth doing + * the m_length calculation as m_copyback will + * expand the mbuf chain below as needed. + */ + space = m_length(m, NULL); + if (space >= MINCLSIZE) { + /* NB: m_copyback handles space > MCLBYTES */ + n = m_getcl(M_WAITOK, MT_DATA, 0); + } else + n = m_get(M_WAITOK, MT_DATA); + if (n == NULL) + return; + /* + * Align the remainder of the mbuf chain. + */ n->m_len = 0; + off = 0; + while (m != NULL) { + m_copyback(n, off, m->m_len, mtod(m, caddr_t)); + off += m->m_len; + m = m->m_next; + } + m_freem(*pm); + *pm = n; + ++nfs_realign_count; break; } pm = &m->m_next; } - - /* - * If n is non-NULL, loop on m copying data, then replace the - * portion of the chain that had to be realigned. - */ - if (n != NULL) { - ++nfs_realign_count; - while (m) { - m_copyback(n, off, m->m_len, mtod(m, caddr_t)); - off += m->m_len; - m = m->m_next; - } - m_freem(*pm); - *pm = n; - } } -#endif /* newnfs_realign */ +#endif /* !__i386__ */ #ifdef notdef static void From 4a48670553a650d63c7aad018595103470f5acc3 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Sun, 24 May 2009 20:34:29 +0000 Subject: [PATCH 474/544] There are things too complex to be fixed in one commit. Fix a typo in acl(9) manual page. Submitted by: avg --- share/man/man9/acl.9 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/man/man9/acl.9 b/share/man/man9/acl.9 index 5b35ecd41aad..c7ba84016b3c 100644 --- a/share/man/man9/acl.9 +++ b/share/man/man9/acl.9 @@ -201,7 +201,7 @@ The following values are valid: .Bl -tag -width ".Dv ACL_ENTRY_DIRECTORY_INHERIT" .It Dv ACL_ENTRY_FILE_INHERIT .It Dv ACL_ENTRY_DIRECTORY_INHERIT -.It Dv ACL_ENRTY_NO_PROPAGATE_INHERIT +.It Dv ACL_ENTRY_NO_PROPAGATE_INHERIT .It Dv ACL_ENTRY_INHERIT_ONLY .El .El From 6098ac23c186d0ac542a2a4d1d4d458b9dd20bb4 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Sun, 24 May 2009 23:47:22 +0000 Subject: [PATCH 475/544] Temporarily #undef NFS4_ACL_EXTATTR_NAME, so that the experimental nfs subsystem will build while the NFSv4 ACL support is going into the kernel. Approved by: kib (mentor) --- sys/fs/nfs/nfsport.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index d452927d23d8..c1aa06140fb9 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -71,6 +71,8 @@ #include #include #include +/* until the nfsv4 acl stuff is all committed, undef NFS4_ACL_EXTATTR_NAME */ +#undef NFS4_ACL_EXTATTR_NAME #include #include #include From 767fb36c3aaeac38aabe36f86da71b5f527374cd Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 00:56:01 +0000 Subject: [PATCH 476/544] NVIDIA MCP controllers have no Rx buffer alignment restrictions. Remove PAGE_SIZE alignment used in Rx buffer DMA tag creation. The alignment restriction was used in old local jumbo allocator and nfe(4) switched to UMA backed page allocator for jumbo frame. This change should fix jumbo buffer allocation failure. Reported by: Pascal Braun ( pascal.braun <> continum dot net ) --- sys/dev/nfe/if_nfe.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c index e5a529468c46..cb7a163a9170 100644 --- a/sys/dev/nfe/if_nfe.c +++ b/sys/dev/nfe/if_nfe.c @@ -1153,7 +1153,7 @@ nfe_alloc_jrx_ring(struct nfe_softc *sc, struct nfe_jrx_ring *ring) /* Create DMA tag for jumbo Rx buffers. */ error = bus_dma_tag_create(sc->nfe_parent_tag, - PAGE_SIZE, 0, /* alignment, boundary */ + 1, 0, /* alignment, boundary */ BUS_SPACE_MAXADDR, /* lowaddr */ BUS_SPACE_MAXADDR, /* highaddr */ NULL, NULL, /* filter, filterarg */ From b1cfc0d961f8f898e23e990e7f002acfb2bfddd7 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 25 May 2009 01:00:09 +0000 Subject: [PATCH 477/544] Add NFSv4 root export checks to the DelegPurge, Renew and ReleaseLockOwner operations analagous to what is already in place for SetClientID and SetClientIDConfirm. These are the five NFSv4 operations that do not use file handle(s), so the checks are done using the NFSv4 root export entries in /etc/exports. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdserv.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/sys/fs/nfsserver/nfs_nfsdserv.c b/sys/fs/nfsserver/nfs_nfsdserv.c index f58de7a6b328..55ffb9338be1 100644 --- a/sys/fs/nfsserver/nfs_nfsdserv.c +++ b/sys/fs/nfsserver/nfs_nfsdserv.c @@ -2830,6 +2830,11 @@ nfsrvd_delegpurge(struct nfsrv_descript *nd, __unused int isdgram, int error = 0; nfsquad_t clientid; + if ((!nfs_rootfhset && !nfsv4root_set) || + nfsd_checkrootexp(nd)) { + nd->nd_repstat = NFSERR_WRONGSEC; + return (0); + } NFSM_DISSECT(tl, u_int32_t *, 2 * NFSX_UNSIGNED); clientid.lval[0] = *tl++; clientid.lval[1] = *tl; @@ -3024,6 +3029,11 @@ nfsrvd_renew(struct nfsrv_descript *nd, __unused int isdgram, int error = 0; nfsquad_t clientid; + if ((!nfs_rootfhset && !nfsv4root_set) || + nfsd_checkrootexp(nd)) { + nd->nd_repstat = NFSERR_WRONGSEC; + return (0); + } NFSM_DISSECT(tl, u_int32_t *, NFSX_HYPER); clientid.lval[0] = *tl++; clientid.lval[1] = *tl; @@ -3355,6 +3365,11 @@ nfsrvd_releaselckown(struct nfsrv_descript *nd, __unused int isdgram, int error = 0, len; nfsquad_t clientid; + if ((!nfs_rootfhset && !nfsv4root_set) || + nfsd_checkrootexp(nd)) { + nd->nd_repstat = NFSERR_WRONGSEC; + return (0); + } NFSM_DISSECT(tl, u_int32_t *, 3 * NFSX_UNSIGNED); len = fxdr_unsigned(int, *(tl + 2)); MALLOC(stp, struct nfsstate *, sizeof (struct nfsstate) + len, From f98d7df2371b70763db7eb2ad5455b5af9c47aaf Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 01:41:05 +0000 Subject: [PATCH 478/544] Use mii_phy_add_media() and remove usage of local macro ADD. Also checks extended status register to see whether the PHY is fast ethernet or not. This removes a lot of checks for specific PHY models and it makes easy to add more PHYs to e1000phy(4). While I'm here remove setting mii_anegticks as it is set with mii_phy_add_media(). --- sys/dev/mii/e1000phy.c | 62 ++++++++---------------------------------- 1 file changed, 12 insertions(+), 50 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index f38b4280f34a..5b2247edac1a 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -129,7 +129,6 @@ e1000phy_attach(device_t dev) struct mii_softc *sc; struct mii_attach_args *ma; struct mii_data *mii; - int fast_ether; esc = device_get_softc(dev); sc = &esc->mii_sc; @@ -142,10 +141,8 @@ e1000phy_attach(device_t dev) sc->mii_phy = ma->mii_phyno; sc->mii_service = e1000phy_service; sc->mii_pdata = mii; - sc->mii_anegticks = MII_ANEGTICKS_GIGE; mii->mii_instance++; - fast_ether = 0; esc->mii_model = MII_MODEL(ma->mii_id2); switch (esc->mii_model) { case MII_MODEL_MARVELL_E1011: @@ -167,54 +164,16 @@ e1000phy_attach(device_t dev) */ PHY_WRITE(sc, E1000_EADR, 0); break; - case MII_MODEL_MARVELL_E3082: - /* 88E3082 10/100 Fast Ethernet PHY. */ - sc->mii_anegticks = MII_ANEGTICKS; - fast_ether = 1; - break; } e1000phy_reset(sc); + sc->mii_capabilities = PHY_READ(sc, MII_BMSR) & ma->mii_capmask; + if (sc->mii_capabilities & BMSR_EXTSTAT) + sc->mii_extcapabilities = PHY_READ(sc, MII_EXTSR); device_printf(dev, " "); - -#define ADD(m, c) ifmedia_add(&mii->mii_media, (m), (c), NULL) - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, sc->mii_inst), - E1000_CR_ISOLATE); - if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, sc->mii_inst), - E1000_CR_SPEED_10); - printf("10baseT, "); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_10_T, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_10 | E1000_CR_FULL_DUPLEX); - printf("10baseT-FDX, "); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, sc->mii_inst), - E1000_CR_SPEED_100); - printf("100baseTX, "); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_100 | E1000_CR_FULL_DUPLEX); - printf("100baseTX-FDX, "); - if (fast_ether == 0) { - /* - * 1000BT-simplex not supported; driver must ignore - * this entry, but it must be present in order to - * manually set full-duplex. - */ - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, 0, - sc->mii_inst), E1000_CR_SPEED_1000); - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_T, IFM_FDX, - sc->mii_inst), - E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); - printf("1000baseTX-FDX, "); - } - } else { - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_1000_SX, IFM_FDX, sc->mii_inst), - E1000_CR_SPEED_1000 | E1000_CR_FULL_DUPLEX); - printf("1000baseSX-FDX, "); - } - ADD(IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, sc->mii_inst), 0); - printf("auto\n"); -#undef ADD + mii_phy_add_media(sc); + printf("\n"); MIIBUS_MEDIAINIT(sc->mii_dev); return (0); @@ -339,12 +298,14 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) speed = 0; switch (IFM_SUBTYPE(ife->ifm_media)) { case IFM_1000_T: - if (esc->mii_model == MII_MODEL_MARVELL_E3082) + if ((sc->mii_extcapabilities & + (EXTSR_1000TFDX | EXTSR_1000THDX)) == 0) return (EINVAL); speed = E1000_CR_SPEED_1000; break; case IFM_1000_SX: - if (esc->mii_model == MII_MODEL_MARVELL_E3082) + if ((sc->mii_extcapabilities & + (EXTSR_1000XFDX | EXTSR_1000XHDX)) == 0) return (EINVAL); speed = E1000_CR_SPEED_1000; break; @@ -390,7 +351,8 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) PHY_WRITE(sc, E1000_1GCR, gig | E1000_1GCR_MS_ENABLE); } else { - if (esc->mii_model != MII_MODEL_MARVELL_E3082) + if ((sc->mii_extcapabilities & + (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) PHY_WRITE(sc, E1000_1GCR, 0); } PHY_WRITE(sc, E1000_AR, E1000_AR_SELECTOR_FIELD); @@ -533,7 +495,7 @@ e1000phy_mii_phy_auto(struct e1000phy_softc *esc) else PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE); - if (esc->mii_model != MII_MODEL_MARVELL_E3082) + if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) PHY_WRITE(sc, E1000_1GCR, E1000_1GCR_1000T_FD | E1000_1GCR_1000T); PHY_WRITE(sc, E1000_CR, From 5536a3c5bbcdd0dc1dad1ec6e720157b46a664cd Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 01:45:28 +0000 Subject: [PATCH 479/544] Report current link state while auto-negotiation is in progress. --- sys/dev/mii/e1000phy.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index 5b2247edac1a..e9ac4bb1185b 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -394,7 +394,7 @@ e1000phy_service(struct mii_softc *sc, struct mii_data *mii, int cmd) if (sc->mii_ticks++ == 0) break; if (sc->mii_ticks <= sc->mii_anegticks) - return (0); + break; sc->mii_ticks = 0; e1000phy_reset(sc); From c404d8f55a38017e334f96bceb2685ea4bca0fcf Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 01:56:19 +0000 Subject: [PATCH 480/544] Don't read unnecessary PHY registers. Speed/duplex resolution bit is valid only for auto-negotiation case so check the bit if we know auto-negotiation is active. While I'm here explicitly checks current speed with speed mask and set IFM_NONE if resolved speed is unknown. --- sys/dev/mii/e1000phy.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index e9ac4bb1185b..a6c3763cff35 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -414,18 +414,14 @@ static void e1000phy_status(struct mii_softc *sc) { struct mii_data *mii = sc->mii_pdata; - int bmsr, bmcr, esr, gsr, ssr, isr, ar, lpar; + int bmcr, bmsr, gsr, ssr, ar, lpar; mii->mii_media_status = IFM_AVALID; mii->mii_media_active = IFM_ETHER; bmsr = PHY_READ(sc, E1000_SR) | PHY_READ(sc, E1000_SR); - esr = PHY_READ(sc, E1000_ESR); bmcr = PHY_READ(sc, E1000_CR); ssr = PHY_READ(sc, E1000_SSR); - isr = PHY_READ(sc, E1000_ISR); - ar = PHY_READ(sc, E1000_AR); - lpar = PHY_READ(sc, E1000_LPAR); if (bmsr & E1000_SR_LINK_STATUS) mii->mii_media_status |= IFM_ACTIVE; @@ -433,22 +429,28 @@ e1000phy_status(struct mii_softc *sc) if (bmcr & E1000_CR_LOOPBACK) mii->mii_media_active |= IFM_LOOP; - if ((((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0) && - ((bmsr & E1000_SR_AUTO_NEG_COMPLETE) == 0)) || - ((ssr & E1000_SSR_LINK) == 0) || - ((ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0)) { + if ((bmcr & E1000_CR_AUTO_NEG_ENABLE) != 0 && + (ssr & E1000_SSR_SPD_DPLX_RESOLVED) == 0) { /* Erg, still trying, I guess... */ mii->mii_media_active |= IFM_NONE; return; } if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { - if (ssr & E1000_SSR_1000MBS) + switch (ssr & E1000_SSR_SPEED) { + case E1000_SSR_1000MBS: mii->mii_media_active |= IFM_1000_T; - else if (ssr & E1000_SSR_100MBS) + break; + case E1000_SSR_100MBS: mii->mii_media_active |= IFM_100_TX; - else + break; + case E1000_SSR_10MBS: mii->mii_media_active |= IFM_10_T; + break; + default: + mii->mii_media_active |= IFM_NONE; + return; + } } else { if (ssr & E1000_SSR_1000MBS) mii->mii_media_active |= IFM_1000_SX; @@ -460,6 +462,8 @@ e1000phy_status(struct mii_softc *sc) mii->mii_media_active |= IFM_HDX; if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + ar = PHY_READ(sc, E1000_AR); + lpar = PHY_READ(sc, E1000_LPAR); /* FLAG0==rx-flow-control FLAG1==tx-flow-control */ if ((ar & E1000_AR_PAUSE) && (lpar & E1000_LPAR_PAUSE)) { mii->mii_media_active |= IFM_FLAG0 | IFM_FLAG1; From 2c56cee9e447ba385f9f8d8a7ed6d8d53a5dc4c7 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 02:05:00 +0000 Subject: [PATCH 481/544] Do not ignore NEXT Page capability of auto-negotiation advertisement register. Some PHYs such as 88E3016 requires NEXT Page capability to establish valid link. Also set protocol selector field which is read only but it makes the intention clearer. --- sys/dev/mii/e1000phy.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index a6c3763cff35..0025e76e18c7 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -490,13 +490,16 @@ static int e1000phy_mii_phy_auto(struct e1000phy_softc *esc) { struct mii_softc *sc; + uint16_t reg; sc = &esc->mii_sc; - if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) - PHY_WRITE(sc, E1000_AR, E1000_AR_10T | E1000_AR_10T_FD | + if ((sc->mii_flags & MIIF_HAVEFIBER) == 0) { + reg = PHY_READ(sc, E1000_AR); + reg |= E1000_AR_10T | E1000_AR_10T_FD | E1000_AR_100TX | E1000_AR_100TX_FD | - E1000_AR_PAUSE | E1000_AR_ASM_DIR); - else + E1000_AR_PAUSE | E1000_AR_ASM_DIR; + PHY_WRITE(sc, E1000_AR, reg | E1000_AR_SELECTOR_FIELD); + } else PHY_WRITE(sc, E1000_AR, E1000_FA_1000X_FD | E1000_FA_1000X | E1000_FA_SYM_PAUSE | E1000_FA_ASYM_PAUSE); if ((sc->mii_extcapabilities & (EXTSR_1000TFDX | EXTSR_1000THDX)) != 0) From 745ef56af2bcc07d2f9e9df7618ed95ef904511d Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 02:36:29 +0000 Subject: [PATCH 482/544] Add driver support for 88E3016 PHY which is found on Marvell Yukon FE+ controller. Due to the severe silicon bugs for Yukon FE+, 88E3016 seems to require more workarounds. However I'm not sure whether the workaround is PHY specific or only applicable to Yukon FE+. The datasheet for the PHY is publicly available but it lacks several details for the workaround used in this change. The workaround information was obtained from Linux. Many thanks to Yukon FE+ users who helped me add 88E3016 support. Tested by: bz, Tanguy Bouzeloc ( the.zauron <> gmail dot com ) Bruce Cran ( bruce <> cran dot org dot uk ) Michael Reifenberger ( mike <> reifenberger dot com ) Stephen Montgomery-Smith ( stephen <> missouri dot edu ) --- sys/dev/mii/e1000phy.c | 27 +++++++++++++++++++++++---- sys/dev/mii/e1000phyreg.h | 10 ++++++++++ sys/dev/mii/miidevs | 1 + 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/sys/dev/mii/e1000phy.c b/sys/dev/mii/e1000phy.c index 0025e76e18c7..9f9b9869555f 100644 --- a/sys/dev/mii/e1000phy.c +++ b/sys/dev/mii/e1000phy.c @@ -107,6 +107,7 @@ static const struct mii_phydesc e1000phys[] = { MII_PHY_DESC(MARVELL, E1116), MII_PHY_DESC(MARVELL, E1116R), MII_PHY_DESC(MARVELL, E1118), + MII_PHY_DESC(MARVELL, E3016), MII_PHY_DESC(xxMARVELL, E1000), MII_PHY_DESC(xxMARVELL, E1011), MII_PHY_DESC(xxMARVELL, E1000_3), @@ -212,18 +213,29 @@ e1000phy_reset(struct mii_softc *sc) reg |= E1000_SCR_AUTO_X_MODE; if (esc->mii_model == MII_MODEL_MARVELL_E1116) reg &= ~E1000_SCR_POWER_DOWN; + reg |= E1000_SCR_ASSERT_CRS_ON_TX; break; case MII_MODEL_MARVELL_E3082: reg |= (E1000_SCR_AUTO_X_MODE >> 1); + reg |= E1000_SCR_ASSERT_CRS_ON_TX; + break; + case MII_MODEL_MARVELL_E3016: + reg |= E1000_SCR_AUTO_MDIX; + reg &= ~(E1000_SCR_EN_DETECT | + E1000_SCR_SCRAMBLER_DISABLE); + reg |= E1000_SCR_LPNP; + /* XXX Enable class A driver for Yukon FE+ A0. */ + PHY_WRITE(sc, 0x1C, PHY_READ(sc, 0x1C) | 0x0001); break; default: reg &= ~E1000_SCR_AUTO_X_MODE; + reg |= E1000_SCR_ASSERT_CRS_ON_TX; break; } - /* Enable CRS on TX. */ - reg |= E1000_SCR_ASSERT_CRS_ON_TX; - /* Auto correction for reversed cable polarity. */ - reg &= ~E1000_SCR_POLARITY_REVERSAL; + if (esc->mii_model != MII_MODEL_MARVELL_E3016) { + /* Auto correction for reversed cable polarity. */ + reg &= ~E1000_SCR_POLARITY_REVERSAL; + } PHY_WRITE(sc, E1000_SCR, reg); if (esc->mii_model == MII_MODEL_MARVELL_E1116) { @@ -242,6 +254,13 @@ e1000phy_reset(struct mii_softc *sc) case MII_MODEL_MARVELL_E1118: case MII_MODEL_MARVELL_E1149: break; + case MII_MODEL_MARVELL_E3016: + /* LED2 -> ACT, LED1 -> LINK, LED0 -> SPEED. */ + PHY_WRITE(sc, 0x16, 0x0B << 8 | 0x05 << 4 | 0x04); + /* Integrated register calibration workaround. */ + PHY_WRITE(sc, 0x1D, 17); + PHY_WRITE(sc, 0x1E, 0x3F60); + break; default: /* Force TX_CLK to 25MHz clock. */ reg = PHY_READ(sc, E1000_ESCR); diff --git a/sys/dev/mii/e1000phyreg.h b/sys/dev/mii/e1000phyreg.h index 6f30f5c2996c..0b7222484047 100644 --- a/sys/dev/mii/e1000phyreg.h +++ b/sys/dev/mii/e1000phyreg.h @@ -236,6 +236,16 @@ #define E1000_SCR_TX_FIFO_DEPTH_10 0x8000 #define E1000_SCR_TX_FIFO_DEPTH_12 0xC000 +/* 88E3016 only */ +#define E1000_SCR_AUTO_MDIX 0x0030 +#define E1000_SCR_SIGDET_POLARITY 0x0040 +#define E1000_SCR_EXT_DISTANCE 0x0080 +#define E1000_SCR_FEFI_DISABLE 0x0100 +#define E1000_SCR_NLP_GEN_DISABLE 0x0800 +#define E1000_SCR_LPNP 0x1000 +#define E1000_SCR_NLP_CHK_DISABLE 0x2000 +#define E1000_SCR_EN_DETECT 0x4000 + #define E1000_SCR_EN_DETECT_MASK 0x0300 /* 88E1112 page 2 */ diff --git a/sys/dev/mii/miidevs b/sys/dev/mii/miidevs index 6bc07fa69908..3b62654b68f3 100644 --- a/sys/dev/mii/miidevs +++ b/sys/dev/mii/miidevs @@ -247,6 +247,7 @@ model MARVELL E1111 0x000c Marvell 88E1111 Gigabit PHY model MARVELL E1116 0x0021 Marvell 88E1116 Gigabit PHY model MARVELL E1116R 0x0024 Marvell 88E1116R Gigabit PHY model MARVELL E1118 0x0022 Marvell 88E1118 Gigabit PHY +model MARVELL E3016 0x0026 Marvell 88E3016 10/100 Fast Ethernet PHY model xxMARVELL E1000 0x0005 Marvell 88E1000 Gigabit PHY model xxMARVELL E1011 0x0002 Marvell 88E1011 Gigabit PHY model xxMARVELL E1000_3 0x0003 Marvell 88E1000 Gigabit PHY From 19585f45494529b26139a1764601343990779c88 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 03:24:47 +0000 Subject: [PATCH 483/544] Remove link handling taskqueue and use mii callback directly. While I'm here also checks driver running state. --- sys/dev/msk/if_msk.c | 21 +++------------------ sys/dev/msk/if_mskreg.h | 1 - 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 17bced0adf3f..d15a9028ff60 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -285,7 +285,6 @@ static int msk_phy_writereg(struct msk_if_softc *, int, int, int); static int msk_miibus_readreg(device_t, int, int); static int msk_miibus_writereg(device_t, int, int, int); static void msk_miibus_statchg(device_t); -static void msk_link_task(void *, int); static void msk_rxfilter(struct msk_if_softc *); static void msk_setvlan(struct msk_if_softc *, struct ifnet *); @@ -458,15 +457,6 @@ msk_phy_writereg(struct msk_if_softc *sc_if, int phy, int reg, int val) static void msk_miibus_statchg(device_t dev) -{ - struct msk_if_softc *sc_if; - - sc_if = device_get_softc(dev); - taskqueue_enqueue(taskqueue_swi, &sc_if->msk_link_task); -} - -static void -msk_link_task(void *arg, int pending) { struct msk_softc *sc; struct msk_if_softc *sc_if; @@ -474,17 +464,16 @@ msk_link_task(void *arg, int pending) struct ifnet *ifp; uint32_t gmac; - sc_if = (struct msk_if_softc *)arg; + sc_if = device_get_softc(dev); sc = sc_if->msk_softc; MSK_IF_LOCK(sc_if); mii = device_get_softc(sc_if->msk_miibus); ifp = sc_if->msk_ifp; - if (mii == NULL || ifp == NULL) { - MSK_IF_UNLOCK(sc_if); + if (mii == NULL || ifp == NULL || + (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - } if (mii->mii_media_status & IFM_ACTIVE) { if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) @@ -554,8 +543,6 @@ msk_link_task(void *arg, int pending) /* Read again to ensure writing. */ GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); } - - MSK_IF_UNLOCK(sc_if); } static void @@ -1416,7 +1403,6 @@ msk_attach(device_t dev) } callout_init_mtx(&sc_if->msk_tick_ch, &sc_if->msk_softc->msk_mtx, 0); - TASK_INIT(&sc_if->msk_link_task, 0, msk_link_task, sc_if); msk_sysctl_node(sc_if); /* Disable jumbo frame for Yukon FE. */ @@ -1791,7 +1777,6 @@ msk_detach(device_t dev) MSK_IF_UNLOCK(sc_if); callout_drain(&sc_if->msk_tick_ch); taskqueue_drain(taskqueue_fast, &sc_if->msk_tx_task); - taskqueue_drain(taskqueue_swi, &sc_if->msk_link_task); ether_ifdetach(ifp); MSK_IF_LOCK(sc_if); } diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 09b0d0c4deb4..34ef9d96a23c 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2395,7 +2395,6 @@ struct msk_if_softc { struct msk_ring_data msk_rdata; struct msk_softc *msk_softc; /* parent controller */ struct msk_hw_stats msk_stats; - struct task msk_link_task; struct task msk_tx_task; int msk_if_flags; int msk_detach; From ab7df1e420251dd0f5b4f04f8e4eee0a37fd56c9 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 03:42:33 +0000 Subject: [PATCH 484/544] Use bit definition to represent link state, device suspend instead of using separate variables in softc. --- sys/dev/msk/if_msk.c | 24 +++++++++++++----------- sys/dev/msk/if_mskreg.h | 4 ++-- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index d15a9028ff60..942a7514f8b9 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -477,11 +477,11 @@ msk_miibus_statchg(device_t dev) if (mii->mii_media_status & IFM_ACTIVE) { if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) - sc_if->msk_link = 1; + sc_if->msk_flags |= MSK_FLAG_LINK; } else - sc_if->msk_link = 0; + sc_if->msk_flags &= ~MSK_FLAG_LINK; - if (sc_if->msk_link != 0) { + if ((sc_if->msk_flags & MSK_FLAG_LINK) != 0) { /* Enable Tx FIFO Underrun. */ CSR_WRITE_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_MSK), GM_IS_TX_FF_UR | GM_IS_RX_FF_OR); @@ -2626,7 +2626,7 @@ msk_start(struct ifnet *ifp) MSK_IF_LOCK(sc_if); if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) != - IFF_DRV_RUNNING || sc_if->msk_link == 0) { + IFF_DRV_RUNNING || (sc_if->msk_flags & MSK_FLAG_LINK) == 0) { MSK_IF_UNLOCK(sc_if); return; } @@ -2683,7 +2683,7 @@ msk_watchdog(struct msk_if_softc *sc_if) if (sc_if->msk_watchdog_timer == 0 || --sc_if->msk_watchdog_timer) return; ifp = sc_if->msk_ifp; - if (sc_if->msk_link == 0) { + if ((sc_if->msk_flags & MSK_FLAG_LINK) == 0) { if (bootverbose) if_printf(sc_if->msk_ifp, "watchdog timeout " "(missed link)\n"); @@ -2770,7 +2770,7 @@ mskc_suspend(device_t dev) /* Put hardware reset. */ CSR_WRITE_2(sc, B0_CTST, CS_RST_SET); - sc->msk_suspended = 1; + sc->msk_pflags |= MSK_FLAG_SUSPEND; MSK_UNLOCK(sc); @@ -2793,7 +2793,7 @@ mskc_resume(device_t dev) ((sc->msk_if[i]->msk_ifp->if_flags & IFF_UP) != 0)) msk_init_locked(sc->msk_if[i]); } - sc->msk_suspended = 0; + sc->msk_pflags &= MSK_FLAG_SUSPEND; MSK_UNLOCK(sc); @@ -3306,7 +3306,8 @@ msk_legacy_intr(void *xsc) /* Reading B0_Y2_SP_ISRC2 masks further interrupts. */ status = CSR_READ_4(sc, B0_Y2_SP_ISRC2); - if (status == 0 || status == 0xffffffff || sc->msk_suspended != 0 || + if (status == 0 || status == 0xffffffff || + (sc->msk_pflags & MSK_FLAG_SUSPEND) != 0 || (status & sc->msk_intrmask) == 0) { CSR_WRITE_4(sc, B0_Y2_SP_ICR, 2); return; @@ -3393,7 +3394,8 @@ msk_int_task(void *arg, int pending) /* Get interrupt source. */ status = CSR_READ_4(sc, B0_ISRC); - if (status == 0 || status == 0xffffffff || sc->msk_suspended != 0 || + if (status == 0 || status == 0xffffffff || + (sc->msk_pflags & MSK_FLAG_SUSPEND) != 0 || (status & sc->msk_intrmask) == 0) goto done; @@ -3675,7 +3677,7 @@ msk_init_locked(struct msk_if_softc *sc_if) CSR_WRITE_4(sc, B0_IMSK, sc->msk_intrmask); CSR_READ_4(sc, B0_IMSK); - sc_if->msk_link = 0; + sc_if->msk_flags &= ~MSK_FLAG_LINK; mii_mediachg(mii); ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -3910,7 +3912,7 @@ msk_stop(struct msk_if_softc *sc_if) * Mark the interface down. */ ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - sc_if->msk_link = 0; + sc_if->msk_flags &= ~MSK_FLAG_LINK; } /* diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 34ef9d96a23c..f3c75887a0b4 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2342,7 +2342,6 @@ struct msk_softc { uint32_t msk_intrmask; uint32_t msk_intrhwemask; uint32_t msk_pflags; - int msk_suspended; int msk_clock; int msk_msi; struct msk_if_softc *msk_if[2]; @@ -2382,10 +2381,11 @@ struct msk_if_softc { int msk_framesize; int msk_phytype; int msk_phyaddr; - int msk_link; uint32_t msk_flags; #define MSK_FLAG_RAMBUF 0x0010 #define MSK_FLAG_NOJUMBO 0x0020 +#define MSK_FLAG_SUSPEND 0x2000 +#define MSK_FLAG_LINK 0x8000 struct callout msk_tick_ch; int msk_watchdog_timer; uint32_t msk_txq; /* Tx. Async Queue offset */ From 7a76e8a4899fcdbe6345b67fd472600970e8e799 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 03:49:43 +0000 Subject: [PATCH 485/544] Use bit definition to represent MSI and detach state instead of using separate variables in softc. --- sys/dev/msk/if_msk.c | 8 ++++---- sys/dev/msk/if_mskreg.h | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 942a7514f8b9..30cd67c4c60f 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -923,7 +923,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) & (IFF_PROMISC | IFF_ALLMULTI)) != 0) msk_rxfilter(sc_if); } else { - if (sc_if->msk_detach == 0) + if ((sc_if->msk_flags & MSK_FLAG_DETACH) == 0) msk_init_locked(sc_if); } } else { @@ -1645,7 +1645,7 @@ mskc_attach(device_t dev) if (sc->msk_num_port == 1 && pci_alloc_msi(dev, &msir) == 0) { if (msic == msir) { - sc->msk_msi = 1; + sc->msk_pflags |= MSK_FLAG_MSI; sc->msk_irq_spec = msic == 2 ? msk_irq_spec_msi2 : msk_irq_spec_msi; @@ -1771,7 +1771,7 @@ msk_detach(device_t dev) ifp = sc_if->msk_ifp; if (device_is_attached(dev)) { /* XXX */ - sc_if->msk_detach = 1; + sc_if->msk_flags |= MSK_FLAG_DETACH; msk_stop(sc_if); /* Can't hold locks while calling detach. */ MSK_IF_UNLOCK(sc_if); @@ -1855,7 +1855,7 @@ mskc_detach(device_t dev) sc->msk_intrhand[1] = NULL; } bus_release_resources(dev, sc->msk_irq_spec, sc->msk_irq); - if (sc->msk_msi) + if ((sc->msk_pflags & MSK_FLAG_MSI) != 0) pci_release_msi(dev); bus_release_resources(dev, sc->msk_res_spec, sc->msk_res); mtx_destroy(&sc->msk_mtx); diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index f3c75887a0b4..0416e0d3d8db 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2343,7 +2343,6 @@ struct msk_softc { uint32_t msk_intrhwemask; uint32_t msk_pflags; int msk_clock; - int msk_msi; struct msk_if_softc *msk_if[2]; device_t msk_devs[2]; int msk_txqsize; @@ -2382,9 +2381,11 @@ struct msk_if_softc { int msk_phytype; int msk_phyaddr; uint32_t msk_flags; +#define MSK_FLAG_MSI 0x0001 #define MSK_FLAG_RAMBUF 0x0010 #define MSK_FLAG_NOJUMBO 0x0020 #define MSK_FLAG_SUSPEND 0x2000 +#define MSK_FLAG_DETACH 0x4000 #define MSK_FLAG_LINK 0x8000 struct callout msk_tick_ch; int msk_watchdog_timer; @@ -2397,7 +2398,6 @@ struct msk_if_softc { struct msk_hw_stats msk_stats; struct task msk_tx_task; int msk_if_flags; - int msk_detach; uint16_t msk_vtag; /* VLAN tag id. */ }; From 325c534e4a7986fda6fe429fcf4fff5f08a4eb00 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 03:53:12 +0000 Subject: [PATCH 486/544] Correctly return the result of mii_mediachg(). Previously it always used to return success. --- sys/dev/msk/if_msk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 30cd67c4c60f..9e84d8262d6d 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -856,15 +856,16 @@ msk_mediachange(struct ifnet *ifp) { struct msk_if_softc *sc_if; struct mii_data *mii; + int error; sc_if = ifp->if_softc; MSK_IF_LOCK(sc_if); mii = device_get_softc(sc_if->msk_miibus); - mii_mediachg(mii); + error = mii_mediachg(mii); MSK_IF_UNLOCK(sc_if); - return (0); + return (error); } /* From e2b166039a1f29838d7dbcece1d7164307847617 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 04:22:27 +0000 Subject: [PATCH 487/544] Rather than checking every chip revision, introduce more flags to mark controller's capability. Controllers that have jumbo frame support sets MSK_FLAG_JUMBO, and controllers that does not support checksum offloading for jumbo frames will set MSK_FLAG_JUMBO_NOCSUM. For Fast Ethernet controllers it will set MSK_FLAG_FASTETHER and it would be used in link state handling. While here, disable Tx checksum offloading if jumbo frame is used on controllers that does not have Tx checksum offloading capability for jumbo frame(e.g. Yukon EC Ultra). --- sys/dev/msk/if_msk.c | 56 +++++++++++++++++++++-------------------- sys/dev/msk/if_mskreg.h | 6 +++-- 2 files changed, 33 insertions(+), 29 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 9e84d8262d6d..362a61640cbf 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -901,20 +901,29 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) switch(command) { case SIOCSIFMTU: + MSK_IF_LOCK(sc_if); if (ifr->ifr_mtu > MSK_JUMBO_MTU || ifr->ifr_mtu < ETHERMIN) error = EINVAL; else if (ifp->if_mtu != ifr->ifr_mtu) { - if ((sc_if->msk_flags & MSK_FLAG_NOJUMBO) != 0 && - ifr->ifr_mtu > ETHERMTU) - error = EINVAL; - else { - MSK_IF_LOCK(sc_if); - ifp->if_mtu = ifr->ifr_mtu; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - msk_init_locked(sc_if); - MSK_IF_UNLOCK(sc_if); + if (ifr->ifr_mtu > ETHERMTU) { + if ((sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) { + error = EINVAL; + MSK_IF_UNLOCK(sc_if); + break; + } + if ((sc_if->msk_flags & + MSK_FLAG_JUMBO_NOCSUM) != 0) { + ifp->if_hwassist &= + ~(MSK_CSUM_FEATURES | CSUM_TSO); + ifp->if_capenable &= + ~(IFCAP_TSO4 | IFCAP_TXCSUM); + VLAN_CAPABILITIES(ifp); + } } + ifp->if_mtu = ifr->ifr_mtu; + msk_init_locked(sc_if); } + MSK_IF_UNLOCK(sc_if); break; case SIOCSIFFLAGS: MSK_IF_LOCK(sc_if); @@ -971,11 +980,7 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) ifp->if_hwassist &= ~CSUM_TSO; } if (ifp->if_mtu > ETHERMTU && - sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) { - /* - * In Yukon EC Ultra, TSO & checksum offload is not - * supported for jumbo frame. - */ + (sc_if->msk_flags & MSK_FLAG_JUMBO_NOCSUM) != 0) { ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO); ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM); } @@ -1406,10 +1411,6 @@ msk_attach(device_t dev) callout_init_mtx(&sc_if->msk_tick_ch, &sc_if->msk_softc->msk_mtx, 0); msk_sysctl_node(sc_if); - /* Disable jumbo frame for Yukon FE. */ - if (sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_FE) - sc_if->msk_flags |= MSK_FLAG_NOJUMBO; - if ((error = msk_txrx_dma_alloc(sc_if) != 0)) goto fail; msk_rx_dma_jalloc(sc_if); @@ -1609,14 +1610,20 @@ mskc_attach(device_t dev) switch (sc->msk_hw_id) { case CHIP_ID_YUKON_EC: + sc->msk_clock = 125; /* 125 Mhz */ + sc->msk_pflags |= MSK_FLAG_JUMBO; + break; case CHIP_ID_YUKON_EC_U: sc->msk_clock = 125; /* 125 Mhz */ + sc->msk_pflags |= MSK_FLAG_JUMBO | MSK_FLAG_JUMBO_NOCSUM; break; case CHIP_ID_YUKON_FE: sc->msk_clock = 100; /* 100 Mhz */ + sc->msk_pflags |= MSK_FLAG_FASTETHER; break; case CHIP_ID_YUKON_XL: sc->msk_clock = 156; /* 156 Mhz */ + sc->msk_pflags |= MSK_FLAG_JUMBO; break; default: sc->msk_clock = 156; /* 156 Mhz */ @@ -2158,11 +2165,10 @@ msk_rx_dma_jalloc(struct msk_if_softc *sc_if) bus_size_t rxalign; int error, i; - if (jumbo_disable != 0 || (sc_if->msk_flags & MSK_FLAG_NOJUMBO) != 0) { - sc_if->msk_flags |= MSK_FLAG_NOJUMBO; + if (jumbo_disable != 0 || (sc_if->msk_flags & MSK_FLAG_JUMBO) == 0) { + sc_if->msk_flags &= ~MSK_FLAG_JUMBO; device_printf(sc_if->msk_if_dev, "disabling jumbo frame support\n"); - sc_if->msk_flags |= MSK_FLAG_NOJUMBO; return (0); } /* Create tag for jumbo Rx ring. */ @@ -2257,7 +2263,7 @@ msk_rx_dma_jalloc(struct msk_if_softc *sc_if) msk_rx_dma_jfree(sc_if); device_printf(sc_if->msk_if_dev, "disabling jumbo frame support " "due to resource shortage\n"); - sc_if->msk_flags |= MSK_FLAG_NOJUMBO; + sc_if->msk_flags &= ~MSK_FLAG_JUMBO; return (error); } @@ -3490,11 +3496,7 @@ msk_init_locked(struct msk_if_softc *sc_if) sc_if->msk_framesize = ifp->if_mtu; sc_if->msk_framesize += ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN; if (ifp->if_mtu > ETHERMTU && - sc_if->msk_softc->msk_hw_id == CHIP_ID_YUKON_EC_U) { - /* - * In Yukon EC Ultra, TSO & checksum offload is not - * supported for jumbo frame. - */ + (sc_if->msk_flags & MSK_FLAG_JUMBO_NOCSUM) != 0) { ifp->if_hwassist &= ~(MSK_CSUM_FEATURES | CSUM_TSO); ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM); } diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 0416e0d3d8db..660c7676d5c4 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2382,8 +2382,10 @@ struct msk_if_softc { int msk_phyaddr; uint32_t msk_flags; #define MSK_FLAG_MSI 0x0001 -#define MSK_FLAG_RAMBUF 0x0010 -#define MSK_FLAG_NOJUMBO 0x0020 +#define MSK_FLAG_FASTETHER 0x0004 +#define MSK_FLAG_JUMBO 0x0008 +#define MSK_FLAG_JUMBO_NOCSUM 0x0010 +#define MSK_FLAG_RAMBUF 0x0020 #define MSK_FLAG_SUSPEND 0x2000 #define MSK_FLAG_DETACH 0x4000 #define MSK_FLAG_LINK 0x8000 From 4b76fe63d9ed65ea7bd0751bba51e9b31e549383 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 04:25:08 +0000 Subject: [PATCH 488/544] Caller already hold a driver lock in mii callback, assert it. --- sys/dev/msk/if_msk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 362a61640cbf..778973f2bd1f 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -467,7 +467,7 @@ msk_miibus_statchg(device_t dev) sc_if = device_get_softc(dev); sc = sc_if->msk_softc; - MSK_IF_LOCK(sc_if); + MSK_IF_LOCK_ASSERT(sc_if); mii = device_get_softc(sc_if->msk_miibus); ifp = sc_if->msk_ifp; From 40d6bed8a77f26b0aff57adfabd77354abcde414 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 04:27:12 +0000 Subject: [PATCH 489/544] Oops, add missing ~ operator. --- sys/dev/msk/if_msk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 778973f2bd1f..3ab8722d6645 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -2800,7 +2800,7 @@ mskc_resume(device_t dev) ((sc->msk_if[i]->msk_ifp->if_flags & IFF_UP) != 0)) msk_init_locked(sc->msk_if[i]); } - sc->msk_pflags &= MSK_FLAG_SUSPEND; + sc->msk_pflags &= ~MSK_FLAG_SUSPEND; MSK_UNLOCK(sc); From 262e9dcf36460d10194cc4d63e6cd615704b2c19 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 06:09:18 +0000 Subject: [PATCH 490/544] Add support for newer descriptor format. This format is used on Yukon FE+, Yukon Extreme and Yukon Supreme. --- sys/dev/msk/if_msk.c | 38 ++++++++++++++++++++++++++------------ sys/dev/msk/if_mskreg.h | 3 +++ 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 3ab8722d6645..f067247df8ee 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -2399,7 +2399,8 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head) tcp_offset = offset = 0; m = *m_head; - if ((m->m_pkthdr.csum_flags & (MSK_CSUM_FEATURES | CSUM_TSO)) != 0) { + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) == 0 && + (m->m_pkthdr.csum_flags & (MSK_CSUM_FEATURES | CSUM_TSO)) != 0) { /* * Since mbuf has no protocol specific structure information * in it we have to inspect protocol information here to @@ -2526,11 +2527,18 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head) /* Check TSO support. */ if ((m->m_pkthdr.csum_flags & CSUM_TSO) != 0) { - tso_mtu = offset + m->m_pkthdr.tso_segsz; + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0) + tso_mtu = m->m_pkthdr.tso_segsz; + else + tso_mtu = offset + m->m_pkthdr.tso_segsz; if (tso_mtu != sc_if->msk_cdata.msk_tso_mtu) { tx_le = &sc_if->msk_rdata.msk_tx_ring[prod]; tx_le->msk_addr = htole32(tso_mtu); - tx_le->msk_control = htole32(OP_LRGLEN | HW_OWNER); + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0) + tx_le->msk_control = htole32(OP_MSS | HW_OWNER); + else + tx_le->msk_control = + htole32(OP_LRGLEN | HW_OWNER); sc_if->msk_cdata.msk_tx_cnt++; MSK_INC(prod, MSK_TX_RING_CNT); sc_if->msk_cdata.msk_tso_mtu = tso_mtu; @@ -2554,15 +2562,21 @@ msk_encap(struct msk_if_softc *sc_if, struct mbuf **m_head) } /* Check if we have to handle checksum offload. */ if (tso == 0 && (m->m_pkthdr.csum_flags & MSK_CSUM_FEATURES) != 0) { - tx_le = &sc_if->msk_rdata.msk_tx_ring[prod]; - tx_le->msk_addr = htole32(((tcp_offset + m->m_pkthdr.csum_data) - & 0xffff) | ((uint32_t)tcp_offset << 16)); - tx_le->msk_control = htole32(1 << 16 | (OP_TCPLISW | HW_OWNER)); - control = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; - if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0) - control |= UDPTCP; - sc_if->msk_cdata.msk_tx_cnt++; - MSK_INC(prod, MSK_TX_RING_CNT); + if ((sc_if->msk_flags & MSK_FLAG_DESCV2) != 0) + control |= CALSUM; + else { + tx_le = &sc_if->msk_rdata.msk_tx_ring[prod]; + tx_le->msk_addr = htole32(((tcp_offset + + m->m_pkthdr.csum_data) & 0xffff) | + ((uint32_t)tcp_offset << 16)); + tx_le->msk_control = htole32(1 << 16 | + (OP_TCPLISW | HW_OWNER)); + control = CALSUM | WR_SUM | INIT_SUM | LOCK_SUM; + if ((m->m_pkthdr.csum_flags & CSUM_UDP) != 0) + control |= UDPTCP; + sc_if->msk_cdata.msk_tx_cnt++; + MSK_INC(prod, MSK_TX_RING_CNT); + } } si = prod; diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index 660c7676d5c4..d32013c15cc0 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2122,6 +2122,8 @@ struct msk_stat_desc { #define OP_ADDR64VLAN (OP_ADDR64 | OP_VLAN) #define OP_LRGLEN 0x24000000 #define OP_LRGLENVLAN (OP_LRGLEN | OP_VLAN) +#define OP_MSS 0x28000000 +#define OP_MSSVLAN (OP_MSS | OP_VLAN) #define OP_BUFFER 0x40000000 #define OP_PACKET 0x41000000 #define OP_LARGESEND 0x43000000 @@ -2386,6 +2388,7 @@ struct msk_if_softc { #define MSK_FLAG_JUMBO 0x0008 #define MSK_FLAG_JUMBO_NOCSUM 0x0010 #define MSK_FLAG_RAMBUF 0x0020 +#define MSK_FLAG_DESCV2 0x0040 #define MSK_FLAG_SUSPEND 0x2000 #define MSK_FLAG_DETACH 0x4000 #define MSK_FLAG_LINK 0x8000 From 6c4d62e1d6ef01410f04aea6b3fe45180d8c2a1a Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 06:19:36 +0000 Subject: [PATCH 491/544] Explicitly check resolved speed/duplex. Just checking IFM_ACTIVE does not guarantee established link. Also 1000baseT link report for fast ethernet controller is not valid one so make sure gigabit link is allowed for this controller. Whenever we lost link, check whether Rx/Tx MACs were enabled. If both MAC are not active, do not try to disable it again. --- sys/dev/msk/if_msk.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index f067247df8ee..41084e802a1b 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -475,11 +475,25 @@ msk_miibus_statchg(device_t dev) (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - if (mii->mii_media_status & IFM_ACTIVE) { - if (IFM_SUBTYPE(mii->mii_media_active) != IFM_NONE) + sc_if->msk_flags &= ~MSK_FLAG_LINK; + if ((mii->mii_media_status & (IFM_AVALID | IFM_ACTIVE)) == + (IFM_AVALID | IFM_ACTIVE)) { + switch (IFM_SUBTYPE(mii->mii_media_active)) { + case IFM_10_T: + case IFM_100_TX: sc_if->msk_flags |= MSK_FLAG_LINK; - } else - sc_if->msk_flags &= ~MSK_FLAG_LINK; + break; + case IFM_1000_T: + case IFM_1000_SX: + case IFM_1000_LX: + case IFM_1000_CX: + if ((sc_if->msk_flags & MSK_FLAG_FASTETHER) == 0) + sc_if->msk_flags |= MSK_FLAG_LINK; + break; + default: + break; + } + } if ((sc_if->msk_flags & MSK_FLAG_LINK) != 0) { /* Enable Tx FIFO Underrun. */ @@ -538,10 +552,12 @@ msk_miibus_statchg(device_t dev) msk_phy_writereg(sc_if, PHY_ADDR_MARV, PHY_MARV_INT_MASK, 0); /* Disable Rx/Tx MAC. */ gmac = GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); - gmac &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); - GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac); - /* Read again to ensure writing. */ - GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); + if ((GM_GPCR_RX_ENA | GM_GPCR_TX_ENA) != 0) { + gmac &= ~(GM_GPCR_RX_ENA | GM_GPCR_TX_ENA); + GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac); + /* Read again to ensure writing. */ + GMAC_READ_2(sc, sc_if->msk_port, GM_GP_CTRL); + } } } From 846e6d79e53963d61a075a60412663d9b5d4cdf3 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 06:29:02 +0000 Subject: [PATCH 492/544] Disable HW WOL for Yukon EC Ultra. While I'm here use switch statement over if-else statement. This change will make it easy to add newer Yukon controllers. --- sys/dev/msk/if_msk.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 41084e802a1b..3356d1d01821 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1080,7 +1080,7 @@ mskc_setup_rambuffer(struct msk_softc *sc) static void msk_phy_power(struct msk_softc *sc, int mode) { - uint32_t val; + uint32_t our, val; int i; switch (mode) { @@ -1106,16 +1106,17 @@ msk_phy_power(struct msk_softc *sc, int mode) val = pci_read_config(sc->msk_dev, PCI_OUR_REG_1, 4); val &= ~(PCI_Y2_PHY1_POWD | PCI_Y2_PHY2_POWD); - if (sc->msk_hw_id == CHIP_ID_YUKON_XL && - sc->msk_hw_rev > CHIP_REV_YU_XL_A1) { - /* Deassert Low Power for 1st PHY. */ - val |= PCI_Y2_PHY1_COMA; - if (sc->msk_num_port > 1) - val |= PCI_Y2_PHY2_COMA; - } else if (sc->msk_hw_id == CHIP_ID_YUKON_EC_U) { - uint32_t our; - - CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_ON); + switch (sc->msk_hw_id) { + case CHIP_ID_YUKON_XL: + if (sc->msk_hw_rev > CHIP_REV_YU_XL_A1) { + /* Deassert Low Power for 1st PHY. */ + val |= PCI_Y2_PHY1_COMA; + if (sc->msk_num_port > 1) + val |= PCI_Y2_PHY2_COMA; + } + break; + case CHIP_ID_YUKON_EC_U: + CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF); /* Enable all clocks. */ pci_write_config(sc->msk_dev, PCI_OUR_REG_3, 0, 4); @@ -1126,6 +1127,9 @@ msk_phy_power(struct msk_softc *sc, int mode) pci_write_config(sc->msk_dev, PCI_OUR_REG_4, our, 4); /* Set to default value. */ pci_write_config(sc->msk_dev, PCI_OUR_REG_5, 0, 4); + break; + default: + break; } /* Release PHY from PowerDown/COMA mode. */ pci_write_config(sc->msk_dev, PCI_OUR_REG_1, val, 4); From e6e23ffecb19a2cd490a0fd8bfcd670a07767d34 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 06:39:48 +0000 Subject: [PATCH 493/544] Explicitly reset GMAC Controls and initialize GM_GP_CTRL register. The GM_GP_CTRL register may have stale content from previous link information so clearing it will make hardware update the register correctly when it established a valid link. While I'm here remove stale comment. --- sys/dev/msk/if_msk.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 3356d1d01821..f6334882c106 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -3535,18 +3535,16 @@ msk_init_locked(struct msk_if_softc *sc_if) ifp->if_capenable &= ~(IFCAP_TSO4 | IFCAP_TXCSUM); } + /* GMAC Control reset. */ + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_SET); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_RST_CLR); + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, GMAC_CTRL), GMC_F_LOOPB_OFF); + /* - * Initialize GMAC first. - * Without this initialization, Rx MAC did not work as expected - * and Rx MAC garbled status LEs and it resulted in out-of-order - * or duplicated frame delivery which in turn showed very poor - * Rx performance.(I had to write a packet analysis code that - * could be embeded in driver to diagnose this issue.) - * I've spent almost 2 months to fix this issue. If I have had - * datasheet for Yukon II I wouldn't have encountered this. :-( + * Initialize GMAC first such that speed/duplex/flow-control + * parameters are renegotiated when interface is brought up. */ - gmac = GM_GPCR_SPEED_100 | GM_GPCR_SPEED_1000 | GM_GPCR_DUP_FULL; - GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, gmac); + GMAC_WRITE_2(sc, sc_if->msk_port, GM_GP_CTRL, 0); /* Dummy read the Interrupt Source Register. */ CSR_READ_1(sc, MR_ADDR(sc_if->msk_port, GMAC_IRQ_SRC)); From f879e8d923c1e491ef4446719df747367e06f3d5 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 25 May 2009 06:45:33 +0000 Subject: [PATCH 494/544] Implement "addr1,+N" ranges - not dissimilar to grep's -A switch. PR: 134856 Submitted by: Jeremie Le Hen - jeremie at le-hen dot org --- usr.bin/sed/compile.c | 11 +++++++++-- usr.bin/sed/defs.h | 5 +++-- usr.bin/sed/process.c | 33 ++++++++++++++++++++------------- usr.bin/sed/sed.1 | 8 +++++++- 4 files changed, 39 insertions(+), 18 deletions(-) diff --git a/usr.bin/sed/compile.c b/usr.bin/sed/compile.c index 39250a3278a6..53e2af76df77 100644 --- a/usr.bin/sed/compile.c +++ b/usr.bin/sed/compile.c @@ -181,7 +181,7 @@ semicolon: EATSPACE(); if ((*link = cmd = malloc(sizeof(struct s_command))) == NULL) err(1, "malloc"); link = &cmd->next; - cmd->nonsel = cmd->inrange = 0; + cmd->startline = cmd->nonsel = 0; /* First parse the addresses */ naddr = 0; @@ -775,6 +775,7 @@ compile_addr(char *p, struct s_addr *a) icase = 0; + a->type = 0; switch (*p) { case '\\': /* Context address */ ++p; @@ -798,10 +799,16 @@ compile_addr(char *p, struct s_addr *a) case '$': /* Last line */ a->type = AT_LAST; return (p + 1); + + case '+': /* Relative line number */ + a->type = AT_RELLINE; + p++; + /* FALLTHROUGH */ /* Line number */ case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - a->type = AT_LINE; + if (a->type == 0) + a->type = AT_LINE; a->u.l = strtol(p, &end, 10); return (end); default: diff --git a/usr.bin/sed/defs.h b/usr.bin/sed/defs.h index 895e719d47b0..d4f434ee84eb 100644 --- a/usr.bin/sed/defs.h +++ b/usr.bin/sed/defs.h @@ -38,8 +38,9 @@ * Types of address specifications */ enum e_atype { - AT_RE, /* Line that match RE */ + AT_RE = 1, /* Line that match RE */ AT_LINE, /* Specific line */ + AT_RELLINE, /* Relative line */ AT_LAST, /* Last line */ }; @@ -91,6 +92,7 @@ struct s_tr { struct s_command { struct s_command *next; /* Pointer to next command */ struct s_addr *a1, *a2; /* Start and end address */ + u_long startline; /* Start line number or zero */ char *t; /* Text for : a c i r w */ union { struct s_command *c; /* Command(s) for b t { */ @@ -100,7 +102,6 @@ struct s_command { } u; char code; /* Command code */ u_int nonsel:1; /* True if ! */ - u_int inrange:1; /* True if in range */ }; /* diff --git a/usr.bin/sed/process.c b/usr.bin/sed/process.c index a29fe0ea8c7a..5e2618ae98fd 100644 --- a/usr.bin/sed/process.c +++ b/usr.bin/sed/process.c @@ -275,8 +275,8 @@ new: if (!nflag && !pd) (a)->type == AT_LINE ? linenum == (a)->u.l : lastline()) /* - * Return TRUE if the command applies to the current line. Sets the inrange - * flag to process ranges. Interprets the non-select (``!'') flag. + * Return TRUE if the command applies to the current line. Sets the start + * line for process ranges. Interprets the non-select (``!'') flag. */ static __inline int applies(struct s_command *cp) @@ -287,18 +287,22 @@ applies(struct s_command *cp) if (cp->a1 == NULL && cp->a2 == NULL) r = 1; else if (cp->a2) - if (cp->inrange) { + if (cp->startline > 0) { if (MATCH(cp->a2)) { - cp->inrange = 0; + cp->startline = 0; lastaddr = 1; r = 1; - } else if (cp->a2->type == AT_LINE && - linenum > cp->a2->u.l) { + } else if (linenum - cp->startline <= cp->a2->u.l) + r = 1; + else if ((cp->a2->type == AT_LINE && + linenum > cp->a2->u.l) || + (cp->a2->type == AT_RELLINE && + linenum - cp->startline > cp->a2->u.l)) { /* * We missed the 2nd address due to a branch, * so just close the range and return false. */ - cp->inrange = 0; + cp->startline = 0; r = 0; } else r = 1; @@ -308,12 +312,15 @@ applies(struct s_command *cp) * equal to the line number first selected, only * one line shall be selected. * -- POSIX 1003.2 + * Likewise if the relative second line address is zero. */ - if (cp->a2->type == AT_LINE && - linenum >= cp->a2->u.l) + if ((cp->a2->type == AT_LINE && + linenum >= cp->a2->u.l) || + (cp->a2->type == AT_RELLINE && cp->a2->u.l == 0)) lastaddr = 1; - else - cp->inrange = 1; + else { + cp->startline = linenum; + } r = 1; } else r = 0; @@ -331,11 +338,11 @@ resetstate(void) struct s_command *cp; /* - * Reset all inrange markers. + * Reset all in-range markers. */ for (cp = prog; cp; cp = cp->code == '{' ? cp->u.c : cp->next) if (cp->a2) - cp->inrange = 0; + cp->startline = 0; /* * Clear out the hold space. diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1 index f694f40c059f..2481ac2719e2 100644 --- a/usr.bin/sed/sed.1 +++ b/usr.bin/sed/sed.1 @@ -211,6 +211,9 @@ that matches the second address. If the second address is a number less than or equal to the line number first selected, only that line is selected. +The number in the second address may be prefixed with a +.Pq Dq \&+ +to specify the number of lines to match after the first pattern. In the case when the second address is a context address, .Nm @@ -594,7 +597,10 @@ The .Fl E , I , a and .Fl i -options, as well as the +options, the prefixing +.Dq \&+ +in the second member of an address range, +as well as the .Dq I flag to the address regular expression and substitution command are non-standard From 258f721bc9289cf20e9c2b612ab41accbc623bfc Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 25 May 2009 06:58:42 +0000 Subject: [PATCH 495/544] Regression test the 'addr1,+N' feature added in r192732 --- tools/regression/usr.bin/sed/multitest.t | 2 ++ tools/regression/usr.bin/sed/regress.multitest.out/40_2.21 | 5 +++++ tools/regression/usr.bin/sed/regress.multitest.out/41_2.22 | 3 +++ 3 files changed, 10 insertions(+) create mode 100644 tools/regression/usr.bin/sed/regress.multitest.out/40_2.21 create mode 100644 tools/regression/usr.bin/sed/regress.multitest.out/41_2.22 diff --git a/tools/regression/usr.bin/sed/multitest.t b/tools/regression/usr.bin/sed/multitest.t index b5c6bfaa78b2..f3a42e26d86a 100644 --- a/tools/regression/usr.bin/sed/multitest.t +++ b/tools/regression/usr.bin/sed/multitest.t @@ -180,6 +180,8 @@ hello' /dev/null mark '2.18' ; $SED -n '/l2_3/,/l1_8/p' lines1 lines2 mark '2.19' ; $SED -n '12,3p' lines1 lines2 mark '2.20' ; $SED -n '/l1_7/,3p' lines1 lines2 + mark '2.21' ; $SED -n '13,+4p' lines1 lines2 + mark '2.22' ; $SED -n '/l1_6/,+2p' lines1 lines2 } test_group() diff --git a/tools/regression/usr.bin/sed/regress.multitest.out/40_2.21 b/tools/regression/usr.bin/sed/regress.multitest.out/40_2.21 new file mode 100644 index 000000000000..1a9e0660615a --- /dev/null +++ b/tools/regression/usr.bin/sed/regress.multitest.out/40_2.21 @@ -0,0 +1,5 @@ +l1_13 +l1_14 +l2_1 +l2_2 +l2_3 diff --git a/tools/regression/usr.bin/sed/regress.multitest.out/41_2.22 b/tools/regression/usr.bin/sed/regress.multitest.out/41_2.22 new file mode 100644 index 000000000000..b1827918b488 --- /dev/null +++ b/tools/regression/usr.bin/sed/regress.multitest.out/41_2.22 @@ -0,0 +1,3 @@ +l1_6 +l1_7 +l1_8 From 61708f4cb2d8ca0cc5f83b093eb087dfba8a9510 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:06:10 +0000 Subject: [PATCH 496/544] Add preliminary Yukon FE+ support and register definitions. Yukon FE+ is fast ethernet controller and uses new descriptor format. Since I don't have this controller, the support code was written from guess and various feedback from enthusiastic users. Thanks to all users who patiently tested my initial patches. Special thanks to Tanguy Bouzeloc who fixed critical bug of initial patch. Tested by: bz, Tanguy Bouzeloc ( the.zauron <> gmail dot com ) Bruce Cran ( bruce <> cran dot org dot uk ) Michael Reifenberger ( mike <> reifenberger dot com ) Stephen Montgomery-Smith ( stephen <> missouri dot edu ) --- sys/dev/msk/if_msk.c | 17 +++++++++++++---- sys/dev/msk/if_mskreg.h | 7 +++++++ 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index f6334882c106..81dfa06d609b 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -220,7 +220,8 @@ static const char *model_name[] = { "Yukon EC Ultra", "Yukon Unknown", "Yukon EC", - "Yukon FE" + "Yukon FE", + "Yukon FE+" }; static int mskc_probe(device_t); @@ -1116,6 +1117,7 @@ msk_phy_power(struct msk_softc *sc, int mode) } break; case CHIP_ID_YUKON_EC_U: + case CHIP_ID_YUKON_FE_P: CSR_WRITE_2(sc, B0_CTST, Y2_HW_WOL_OFF); /* Enable all clocks. */ @@ -1579,7 +1581,7 @@ mskc_attach(device_t dev) sc->msk_hw_rev = (CSR_READ_1(sc, B2_MAC_CFG) >> 4) & 0x0f; /* Bail out if chip is not recognized. */ if (sc->msk_hw_id < CHIP_ID_YUKON_XL || - sc->msk_hw_id > CHIP_ID_YUKON_FE) { + sc->msk_hw_id > CHIP_ID_YUKON_FE_P) { device_printf(dev, "unknown device: id=0x%02x, rev=0x%02x\n", sc->msk_hw_id, sc->msk_hw_rev); mtx_destroy(&sc->msk_mtx); @@ -1641,6 +1643,10 @@ mskc_attach(device_t dev) sc->msk_clock = 100; /* 100 Mhz */ sc->msk_pflags |= MSK_FLAG_FASTETHER; break; + case CHIP_ID_YUKON_FE_P: + sc->msk_clock = 50; /* 50 Mhz */ + sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2; + break; case CHIP_ID_YUKON_XL: sc->msk_clock = 156; /* 156 Mhz */ sc->msk_pflags |= MSK_FLAG_JUMBO; @@ -3512,6 +3518,7 @@ msk_init_locked(struct msk_if_softc *sc_if) struct mii_data *mii; uint16_t eaddr[ETHER_ADDR_LEN / 2]; uint16_t gmac; + uint32_t reg; int error, i; MSK_IF_LOCK_ASSERT(sc_if); @@ -3590,8 +3597,10 @@ msk_init_locked(struct msk_if_softc *sc_if) /* Configure Rx MAC FIFO. */ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_SET); CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), GMF_RST_CLR); - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), - GMF_OPER_ON | GMF_RX_F_FL_ON); + reg = GMF_OPER_ON | GMF_RX_F_FL_ON; + if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P) + reg |= GMF_RX_OVER_ON; + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_CTRL_T), reg); /* Set receive filter. */ msk_rxfilter(sc_if); diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index d32013c15cc0..c4d9030a56a7 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -828,6 +828,7 @@ #define CHIP_ID_YUKON_EC_U 0xb4 /* Chip ID for YUKON-2 EC Ultra */ #define CHIP_ID_YUKON_EC 0xb6 /* Chip ID for YUKON-2 EC */ #define CHIP_ID_YUKON_FE 0xb7 /* Chip ID for YUKON-2 FE */ +#define CHIP_ID_YUKON_FE_P 0xb8 /* Chip ID for YUKON-2 FE+ */ #define CHIP_REV_YU_XL_A0 0 /* Chip Rev. for Yukon-2 A0 */ #define CHIP_REV_YU_XL_A1 1 /* Chip Rev. for Yukon-2 A1 */ @@ -841,6 +842,8 @@ #define CHIP_REV_YU_EC_U_A0 1 #define CHIP_REV_YU_EC_U_A1 2 +#define CHIP_REV_YU_FE_P_A0 0 /* Chip Rev. for Yukon-2 FE+ A0 */ + /* B2_Y2_CLK_GATE 8 bit Clock Gating (Yukon-2 only) */ #define Y2_STATUS_LNK2_INAC BIT_7 /* Status Link 2 inactiv (0 = activ) */ #define Y2_CLK_GAT_LNK2_DIS BIT_6 /* Disable clock gating Link 2 */ @@ -1855,6 +1858,10 @@ #define RX_TRUNC_OFF BIT_26 /* disable packet truncation */ #define RX_VLAN_STRIP_ON BIT_25 /* enable VLAN stripping */ #define RX_VLAN_STRIP_OFF BIT_24 /* disable VLAN stripping */ +#define GMF_RX_OVER_ON BIT_19 /* enable flushing on receive overrun */ +#define GMF_RX_OVER_OFF BIT_18 /* disable flushing on receive overrun */ +#define GMF_ASF_RX_OVER_ON BIT_17 /* enable flushing of ASF when overrun */ +#define GMF_ASF_RX_OVER_OFF BIT_16 /* disable flushing of ASF when overrun */ #define GMF_WP_TST_ON BIT_14 /* Write Pointer Test On */ #define GMF_WP_TST_OFF BIT_13 /* Write Pointer Test Off */ #define GMF_WP_STEP BIT_12 /* Write Pointer Step/Increment */ From 224003b7bad6a7326d117607011164d27f8f417d Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:31:18 +0000 Subject: [PATCH 497/544] Add workaround for Yukon FE+ A0. This controller is known to have severe silicon bugs that can't handle VLAN hardware tagging as well as status LE writeback bug. The status LE writeback bug is so critical we can't trust status word of received frame. To accept frames on Yukon FE+ A0 msk(4) just do minimal check for received frames and pass them to upper stack. This means msk(4) can pass corrupted frames to upper layer. You have been warned! Also I supposed RX_GMF_FL_THR to be 32bits register but Linux driver treated it as 16bit register so follow their leads. At least this does not seem to break msk(4) on Yukon FE+. Tested by: bz, Tanguy Bouzeloc ( the.zauron <> gmail dot com ) Bruce Cran ( bruce <> cran dot org dot uk ) Michael Reifenberger ( mike <> reifenberger dot com ) Stephen Montgomery-Smith ( stephen <> missouri dot edu ) --- sys/dev/msk/if_msk.c | 61 +++++++++++++++++++++++++++++++++-------- sys/dev/msk/if_mskreg.h | 2 ++ 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 81dfa06d609b..c3e3e4aac69d 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -1493,14 +1493,17 @@ msk_attach(device_t dev) ether_ifattach(ifp, eaddr); MSK_IF_LOCK(sc_if); - /* - * VLAN capability setup - * Due to Tx checksum offload hardware bugs, msk(4) manually - * computes checksum for short frames. For VLAN tagged frames - * this workaround does not work so disable checksum offload - * for VLAN interface. - */ - ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING; + /* VLAN capability setup */ + ifp->if_capabilities |= IFCAP_VLAN_MTU; + if ((sc_if->msk_flags & MSK_FLAG_NOHWVLAN) == 0) { + /* + * Due to Tx checksum offload hardware bugs, msk(4) manually + * computes checksum for short frames. For VLAN tagged frames + * this workaround does not work so disable checksum offload + * for VLAN interface. + */ + ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; + } ifp->if_capenable = ifp->if_capabilities; /* @@ -1646,6 +1649,19 @@ mskc_attach(device_t dev) case CHIP_ID_YUKON_FE_P: sc->msk_clock = 50; /* 50 Mhz */ sc->msk_pflags |= MSK_FLAG_FASTETHER | MSK_FLAG_DESCV2; + if (sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { + /* + * XXX + * FE+ A0 has status LE writeback bug so msk(4) + * does not rely on status word of received frame + * in msk_rxeof() which in turn disables all + * hardware assistance bits reported by the status + * word as well as validity of the recevied frame. + * Just pass received frames to upper stack with + * minimal test and let upper stack handle them. + */ + sc->msk_pflags |= MSK_FLAG_NOHWVLAN | MSK_FLAG_NORXCHK; + } break; case CHIP_ID_YUKON_XL: sc->msk_clock = 156; /* 156 Mhz */ @@ -2882,7 +2898,18 @@ msk_rxeof(struct msk_if_softc *sc_if, uint32_t status, int len) if ((status & GMR_FS_VLAN) != 0 && (ifp->if_capenable & IFCAP_VLAN_HWTAGGING) != 0) rxlen -= ETHER_VLAN_ENCAP_LEN; - if (len > sc_if->msk_framesize || + if ((sc_if->msk_flags & MSK_FLAG_NORXCHK) != 0) { + /* + * For controllers that returns bogus status code + * just do minimal check and let upper stack + * handle this frame. + */ + if (len > MSK_MAX_FRAMELEN || len < ETHER_HDR_LEN) { + ifp->if_ierrors++; + msk_discard_rxbuf(sc_if, cons); + break; + } + } else if (len > sc_if->msk_framesize || ((status & GMR_FS_ANY_ERR) != 0) || ((status & GMR_FS_RX_OK) == 0) || (rxlen != len)) { /* Don't count flow-control packet as errors. */ @@ -3613,8 +3640,12 @@ msk_init_locked(struct msk_if_softc *sc_if) * Set Rx FIFO flush threshold to 64 bytes + 1 FIFO word * due to hardware hang on receipt of pause frames. */ - CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_THR), - RX_GMF_FL_THR_DEF + 1); + reg = RX_GMF_FL_THR_DEF + 1; + /* Another magic for Yukon FE+ - From Linux. */ + if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P && + sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) + reg = 0x178; + CSR_WRITE_2(sc, MR_ADDR(sc_if->msk_port, RX_GMF_FL_THR), reg); /* Configure Tx MAC FIFO. */ CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_CTRL_T), GMF_RST_SET); @@ -3646,6 +3677,14 @@ msk_init_locked(struct msk_if_softc *sc_if) } } + if (sc->msk_hw_id == CHIP_ID_YUKON_FE_P && + sc->msk_hw_rev == CHIP_REV_YU_FE_P_A0) { + /* Disable dynamic watermark - from Linux. */ + reg = CSR_READ_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA)); + reg &= ~0x03; + CSR_WRITE_4(sc, MR_ADDR(sc_if->msk_port, TX_GMF_EA), reg); + } + /* * Disable Force Sync bit and Alloc bit in Tx RAM interface * arbiter as we don't use Sync Tx queue. diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index c4d9030a56a7..d979419db0a8 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -2396,6 +2396,8 @@ struct msk_if_softc { #define MSK_FLAG_JUMBO_NOCSUM 0x0010 #define MSK_FLAG_RAMBUF 0x0020 #define MSK_FLAG_DESCV2 0x0040 +#define MSK_FLAG_NOHWVLAN 0x0080 +#define MSK_FLAG_NORXCHK 0x0100 #define MSK_FLAG_SUSPEND 0x2000 #define MSK_FLAG_DETACH 0x4000 #define MSK_FLAG_LINK 0x8000 From 1290998502696923e23fcaaf404cc8b5c7fd6646 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:48:00 +0000 Subject: [PATCH 498/544] Add device ids for Yukon FE+(88E8040, 88E8040T, 88E8048 and 88E8070). --- sys/dev/msk/if_msk.c | 8 ++++++++ sys/dev/msk/if_mskreg.h | 6 +++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index c3e3e4aac69d..67e82ece91c3 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -197,6 +197,14 @@ static struct msk_product { "Marvell Yukon 88E8038 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8039, "Marvell Yukon 88E8039 Gigabit Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_8040, + "Marvell Yukon 88E8040 Fast Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_8040T, + "Marvell Yukon 88E8040T Fast Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_8048, + "Marvell Yukon 88E8048 Fast Ethernet" }, + { VENDORID_MARVELL, DEVICEID_MRVL_8070, + "Marvell Yukon 88E8070 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_4361, "Marvell Yukon 88E8050 Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_4360, diff --git a/sys/dev/msk/if_mskreg.h b/sys/dev/msk/if_mskreg.h index d979419db0a8..24a2376f5052 100644 --- a/sys/dev/msk/if_mskreg.h +++ b/sys/dev/msk/if_mskreg.h @@ -130,12 +130,16 @@ #define DEVICEID_MRVL_8035 0x4350 #define DEVICEID_MRVL_8036 0x4351 #define DEVICEID_MRVL_8038 0x4352 -#define DEVICEID_MRVL_8039 0X4353 +#define DEVICEID_MRVL_8039 0x4353 +#define DEVICEID_MRVL_8040 0x4354 +#define DEVICEID_MRVL_8040T 0x4355 +#define DEVICEID_MRVL_8048 0x435A #define DEVICEID_MRVL_4360 0x4360 #define DEVICEID_MRVL_4361 0x4361 #define DEVICEID_MRVL_4362 0x4362 #define DEVICEID_MRVL_4363 0x4363 #define DEVICEID_MRVL_4364 0x4364 +#define DEVICEID_MRVL_8070 0x4365 #define DEVICEID_MRVL_436A 0x436A /* From 6f5a0d1f39d6889be793b518c4aab050dc39e102 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:50:14 +0000 Subject: [PATCH 499/544] If interface is not UP, don't return media status. --- sys/dev/msk/if_msk.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 67e82ece91c3..02e03e33f85b 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -904,6 +904,10 @@ msk_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) sc_if = ifp->if_softc; MSK_IF_LOCK(sc_if); + if ((ifp->if_flags & IFF_UP) == 0) { + MSK_IF_UNLOCK(sc_if); + return; + } mii = device_get_softc(sc_if->msk_miibus); mii_pollstat(mii); From 89e226665157b662df6b55f90060296ae7c003ed Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:56:14 +0000 Subject: [PATCH 500/544] Don't reinitialize controller when interface is already running. --- sys/dev/msk/if_msk.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 02e03e33f85b..5b379563cb45 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -2763,6 +2763,7 @@ msk_watchdog(struct msk_if_softc *sc_if) if_printf(sc_if->msk_ifp, "watchdog timeout " "(missed link)\n"); ifp->if_oerrors++; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; msk_init_locked(sc_if); return; } @@ -2787,6 +2788,7 @@ msk_watchdog(struct msk_if_softc *sc_if) if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; + ifp->if_drv_flags &= ~IFF_DRV_RUNNING; msk_init_locked(sc_if); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue(taskqueue_fast, &sc_if->msk_tx_task); @@ -2865,8 +2867,11 @@ mskc_resume(device_t dev) mskc_reset(sc); for (i = 0; i < sc->msk_num_port; i++) { if (sc->msk_if[i] != NULL && sc->msk_if[i]->msk_ifp != NULL && - ((sc->msk_if[i]->msk_ifp->if_flags & IFF_UP) != 0)) + ((sc->msk_if[i]->msk_ifp->if_flags & IFF_UP) != 0)) { + sc->msk_if[i]->msk_ifp->if_drv_flags &= + ~IFF_DRV_RUNNING; msk_init_locked(sc->msk_if[i]); + } } sc->msk_pflags &= ~MSK_FLAG_SUSPEND; @@ -3566,6 +3571,9 @@ msk_init_locked(struct msk_if_softc *sc_if) sc = sc_if->msk_softc; mii = device_get_softc(sc_if->msk_miibus); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + return; + error = 0; /* Cancel pending I/O and free all Rx/Tx buffers. */ msk_stop(sc_if); From 98e02aebefd0cfbbe1daf67c65b952d37d098022 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 07:59:30 +0000 Subject: [PATCH 501/544] Be consistent with other capability checking. --- sys/dev/msk/if_msk.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 5b379563cb45..45c42fb019aa 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -987,23 +987,24 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFCAP: MSK_IF_LOCK(sc_if); mask = ifr->ifr_reqcap ^ ifp->if_capenable; - if ((mask & IFCAP_TXCSUM) != 0) { + if ((mask & IFCAP_TXCSUM) != 0 && + (IFCAP_TXCSUM & ifp->if_capabilities) != 0) { ifp->if_capenable ^= IFCAP_TXCSUM; - if ((IFCAP_TXCSUM & ifp->if_capenable) != 0 && - (IFCAP_TXCSUM & ifp->if_capabilities) != 0) + if ((IFCAP_TXCSUM & ifp->if_capenable) != 0) ifp->if_hwassist |= MSK_CSUM_FEATURES; else ifp->if_hwassist &= ~MSK_CSUM_FEATURES; } - if ((mask & IFCAP_VLAN_HWTAGGING) != 0) { + if ((mask & IFCAP_VLAN_HWTAGGING) != 0 && + (IFCAP_VLAN_HWTAGGING & ifp->if_capabilities) != 0) { ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING; msk_setvlan(sc_if, ifp); } - if ((mask & IFCAP_TSO4) != 0) { + if ((mask & IFCAP_TSO4) != 0 && + (IFCAP_TSO4 & ifp->if_capabilities) != 0) { ifp->if_capenable ^= IFCAP_TSO4; - if ((IFCAP_TSO4 & ifp->if_capenable) != 0 && - (IFCAP_TSO4 & ifp->if_capabilities) != 0) + if ((IFCAP_TSO4 & ifp->if_capenable) != 0) ifp->if_hwassist |= CSUM_TSO; else ifp->if_hwassist &= ~CSUM_TSO; From b7e1e144e9253ff7504f8f94286b2959c124ee5c Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 08:02:05 +0000 Subject: [PATCH 502/544] Simplify SIOCSIFFLAGS handler. --- sys/dev/msk/if_msk.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 45c42fb019aa..112b97004174 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -957,18 +957,14 @@ msk_ioctl(struct ifnet *ifp, u_long command, caddr_t data) case SIOCSIFFLAGS: MSK_IF_LOCK(sc_if); if ((ifp->if_flags & IFF_UP) != 0) { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) { - if (((ifp->if_flags ^ sc_if->msk_if_flags) - & (IFF_PROMISC | IFF_ALLMULTI)) != 0) - msk_rxfilter(sc_if); - } else { - if ((sc_if->msk_flags & MSK_FLAG_DETACH) == 0) - msk_init_locked(sc_if); - } - } else { - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - msk_stop(sc_if); - } + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0 && + ((ifp->if_flags ^ sc_if->msk_if_flags) & + (IFF_PROMISC | IFF_ALLMULTI)) != 0) + msk_rxfilter(sc_if); + else if ((sc_if->msk_flags & MSK_FLAG_DETACH) == 0) + msk_init_locked(sc_if); + } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) + msk_stop(sc_if); sc_if->msk_if_flags = ifp->if_flags; MSK_IF_UNLOCK(sc_if); break; From 004f62de561b1a623d160431fc86e3b91ae6109f Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 08:11:03 +0000 Subject: [PATCH 503/544] msk(4) now supports Yukon FE+. Specifically 88E8040, 88E8040T, 88E8048 and 88E8070 are supported. Bump .Dd --- share/man/man4/msk.4 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4 index 1d9c9bbf9299..b4d1589281a6 100644 --- a/share/man/man4/msk.4 +++ b/share/man/man4/msk.4 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd December 5, 2007 +.Dd May 25, 2009 .Dt MSK 4 .Os .Sh NAME @@ -184,6 +184,12 @@ Marvell Yukon 88E8038 Gigabit Ethernet .It Marvell Yukon 88E8039 Gigabit Ethernet .It +Marvell Yukon 88E8040 Fast Ethernet +.It +Marvell Yukon 88E8040T Fast Ethernet +.It +Marvell Yukon 88E8048 Fast Ethernet +.It Marvell Yukon 88E8050 Gigabit Ethernet .It Marvell Yukon 88E8052 Gigabit Ethernet @@ -196,6 +202,8 @@ Marvell Yukon 88E8056 Gigabit Ethernet .It Marvell Yukon 88E8058 Gigabit Ethernet .It +Marvell Yukon 88E8070 Fast Ethernet +.It SysKonnect SK-9Sxx Gigabit Ethernet .It SysKonnect SK-9Exx Gigabit Ethernet From f972d4c6fb411de1cca52cf3804404aadfb30a8e Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 08:26:39 +0000 Subject: [PATCH 504/544] Correct controller description for 88E8035, 88E8036, 88E8038 and 88E8039. These are fast ethernet controllers. --- sys/dev/msk/if_msk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sys/dev/msk/if_msk.c b/sys/dev/msk/if_msk.c index 112b97004174..93575cf85a95 100644 --- a/sys/dev/msk/if_msk.c +++ b/sys/dev/msk/if_msk.c @@ -190,13 +190,13 @@ static struct msk_product { { VENDORID_MARVELL, DEVICEID_MRVL_8062X, "Marvell Yukon 88E8062 SX/LX Gigabit Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8035, - "Marvell Yukon 88E8035 Gigabit Ethernet" }, + "Marvell Yukon 88E8035 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8036, - "Marvell Yukon 88E8036 Gigabit Ethernet" }, + "Marvell Yukon 88E8036 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8038, - "Marvell Yukon 88E8038 Gigabit Ethernet" }, + "Marvell Yukon 88E8038 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8039, - "Marvell Yukon 88E8039 Gigabit Ethernet" }, + "Marvell Yukon 88E8039 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8040, "Marvell Yukon 88E8040 Fast Ethernet" }, { VENDORID_MARVELL, DEVICEID_MRVL_8040T, From 4f9b2cb23318f26b0e70f33034613f759bfc3c19 Mon Sep 17 00:00:00 2001 From: Pyun YongHyeon Date: Mon, 25 May 2009 08:27:52 +0000 Subject: [PATCH 505/544] Correct controller description for 88E8035, 88E8036, 88E8038 and 88E8039. These are fast ethernet controllers. --- share/man/man4/msk.4 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/share/man/man4/msk.4 b/share/man/man4/msk.4 index b4d1589281a6..095a2c8fd47e 100644 --- a/share/man/man4/msk.4 +++ b/share/man/man4/msk.4 @@ -176,13 +176,13 @@ Marvell Yukon 88E8062CU Gigabit Ethernet .It Marvell Yukon 88E8062 SX/LX Gigabit Ethernet .It -Marvell Yukon 88E8035 Gigabit Ethernet +Marvell Yukon 88E8035 Fast Ethernet .It -Marvell Yukon 88E8036 Gigabit Ethernet +Marvell Yukon 88E8036 Fast Ethernet .It -Marvell Yukon 88E8038 Gigabit Ethernet +Marvell Yukon 88E8038 Fast Ethernet .It -Marvell Yukon 88E8039 Gigabit Ethernet +Marvell Yukon 88E8039 Fast Ethernet .It Marvell Yukon 88E8040 Fast Ethernet .It From 3f33fa335e6145e044e74e50e6b84102deef0da1 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 09:09:43 +0000 Subject: [PATCH 506/544] Copy spx_usrreq.c to spx_reass.c in order to apply similar file layout changes to IPX/SPX that were applied to TCP/IP in the creation of tcp_reass.c. MFC after: 1 month --- sys/netipx/spx_reass.c | 2132 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2132 insertions(+) create mode 100644 sys/netipx/spx_reass.c diff --git a/sys/netipx/spx_reass.c b/sys/netipx/spx_reass.c new file mode 100644 index 000000000000..7bfa88ebc536 --- /dev/null +++ b/sys/netipx/spx_reass.c @@ -0,0 +1,2132 @@ +/*- + * Copyright (c) 1984, 1985, 1986, 1987, 1993 + * The Regents of the University of California. + * Copyright (c) 2004-2006 Robert N. M. Watson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Copyright (c) 1995, Mike Mitchell + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)spx_usrreq.h + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +/* + * SPX protocol implementation. + */ +static struct mtx spx_mtx; /* Protects only spx_iss. */ +static u_short spx_iss; +static u_short spx_newchecks[50]; +static int spx_hardnosed; +static int spx_use_delack = 0; +static int traceallspxs = 0; +static struct spx_istat spx_istat; +static int spxrexmtthresh = 3; + +#define SPX_LOCK_INIT() mtx_init(&spx_mtx, "spx_mtx", NULL, MTX_DEF) +#define SPX_LOCK() mtx_lock(&spx_mtx) +#define SPX_UNLOCK() mtx_unlock(&spx_mtx) + +/* Following was struct spxstat spxstat; */ +#ifndef spxstat +#define spxstat spx_istat.newstats +#endif + +static const int spx_backoff[SPX_MAXRXTSHIFT+1] = + { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; + +static void spx_close(struct spxpcb *cb); +static void spx_disconnect(struct spxpcb *cb); +static void spx_drop(struct spxpcb *cb, int errno); +static int spx_output(struct spxpcb *cb, struct mbuf *m0); +static int spx_reass(struct spxpcb *cb, struct spx *si); +static void spx_setpersist(struct spxpcb *cb); +static void spx_template(struct spxpcb *cb); +static void spx_timers(struct spxpcb *cb, int timer); +static void spx_usrclosed(struct spxpcb *cb); + +static void spx_usr_abort(struct socket *so); +static int spx_accept(struct socket *so, struct sockaddr **nam); +static int spx_attach(struct socket *so, int proto, struct thread *td); +static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td); +static void spx_usr_close(struct socket *so); +static int spx_connect(struct socket *so, struct sockaddr *nam, + struct thread *td); +static void spx_detach(struct socket *so); +static void spx_pcbdetach(struct ipxpcb *ipxp); +static int spx_usr_disconnect(struct socket *so); +static int spx_listen(struct socket *so, int backlog, struct thread *td); +static int spx_rcvd(struct socket *so, int flags); +static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags); +static int spx_send(struct socket *so, int flags, struct mbuf *m, + struct sockaddr *addr, struct mbuf *control, + struct thread *td); +static int spx_shutdown(struct socket *so); +static int spx_sp_attach(struct socket *so, int proto, struct thread *td); + +struct pr_usrreqs spx_usrreqs = { + .pru_abort = spx_usr_abort, + .pru_accept = spx_accept, + .pru_attach = spx_attach, + .pru_bind = spx_bind, + .pru_connect = spx_connect, + .pru_control = ipx_control, + .pru_detach = spx_detach, + .pru_disconnect = spx_usr_disconnect, + .pru_listen = spx_listen, + .pru_peeraddr = ipx_peeraddr, + .pru_rcvd = spx_rcvd, + .pru_rcvoob = spx_rcvoob, + .pru_send = spx_send, + .pru_shutdown = spx_shutdown, + .pru_sockaddr = ipx_sockaddr, + .pru_close = spx_usr_close, +}; + +struct pr_usrreqs spx_usrreq_sps = { + .pru_abort = spx_usr_abort, + .pru_accept = spx_accept, + .pru_attach = spx_sp_attach, + .pru_bind = spx_bind, + .pru_connect = spx_connect, + .pru_control = ipx_control, + .pru_detach = spx_detach, + .pru_disconnect = spx_usr_disconnect, + .pru_listen = spx_listen, + .pru_peeraddr = ipx_peeraddr, + .pru_rcvd = spx_rcvd, + .pru_rcvoob = spx_rcvoob, + .pru_send = spx_send, + .pru_shutdown = spx_shutdown, + .pru_sockaddr = ipx_sockaddr, + .pru_close = spx_usr_close, +}; + +static __inline void +spx_insque(struct spx_q *element, struct spx_q *head) +{ + + element->si_next = head->si_next; + element->si_prev = head; + head->si_next = element; + element->si_next->si_prev = element; +} + +static __inline void +spx_remque(struct spx_q *element) +{ + + element->si_next->si_prev = element->si_prev; + element->si_prev->si_next = element->si_next; + element->si_prev = NULL; +} + +void +spx_init(void) +{ + + SPX_LOCK_INIT(); + spx_iss = 1; /* WRONG !! should fish it out of TODR */ +} + +void +spx_input(struct mbuf *m, struct ipxpcb *ipxp) +{ + struct spxpcb *cb; + struct spx *si = mtod(m, struct spx *); + struct socket *so; + struct spx spx_savesi; + int dropsocket = 0; + short ostate = 0; + + spxstat.spxs_rcvtotal++; + KASSERT(ipxp != NULL, ("spx_input: ipxpcb == NULL")); + + /* + * spx_input() assumes that the caller will hold both the pcb list + * lock and also the ipxp lock. spx_input() will release both before + * returning, and may in fact trade in the ipxp lock for another pcb + * lock following sonewconn(). + */ + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_input: cb == NULL")); + + if (ipxp->ipxp_flags & IPXP_DROPPED) + goto drop; + + if (m->m_len < sizeof(*si)) { + if ((m = m_pullup(m, sizeof(*si))) == NULL) { + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + spxstat.spxs_rcvshort++; + return; + } + si = mtod(m, struct spx *); + } + si->si_seq = ntohs(si->si_seq); + si->si_ack = ntohs(si->si_ack); + si->si_alo = ntohs(si->si_alo); + + so = ipxp->ipxp_socket; + KASSERT(so != NULL, ("spx_input: so == NULL")); + + if (so->so_options & SO_DEBUG || traceallspxs) { + ostate = cb->s_state; + spx_savesi = *si; + } + if (so->so_options & SO_ACCEPTCONN) { + struct spxpcb *ocb = cb; + + so = sonewconn(so, 0); + if (so == NULL) + goto drop; + + /* + * This is ugly, but .... + * + * Mark socket as temporary until we're committed to keeping + * it. The code at ``drop'' and ``dropwithreset'' check the + * flag dropsocket to see if the temporary socket created + * here should be discarded. We mark the socket as + * discardable until we're committed to it below in + * TCPS_LISTEN. + * + * XXXRW: In the new world order of real kernel parallelism, + * temporarily allocating the socket when we're "not sure" + * seems like a bad idea, as we might race to remove it if + * the listen socket is closed...? + * + * We drop the lock of the listen socket ipxp, and acquire + * the lock of the new socket ippx. + */ + dropsocket++; + IPX_UNLOCK(ipxp); + ipxp = (struct ipxpcb *)so->so_pcb; + IPX_LOCK(ipxp); + ipxp->ipxp_laddr = si->si_dna; + cb = ipxtospxpcb(ipxp); + cb->s_mtu = ocb->s_mtu; /* preserve sockopts */ + cb->s_flags = ocb->s_flags; /* preserve sockopts */ + cb->s_flags2 = ocb->s_flags2; /* preserve sockopts */ + cb->s_state = TCPS_LISTEN; + } + IPX_LOCK_ASSERT(ipxp); + + /* + * Packet received on connection. Reset idle time and keep-alive + * timer. + */ + cb->s_idle = 0; + cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; + + switch (cb->s_state) { + case TCPS_LISTEN:{ + struct sockaddr_ipx *sipx, ssipx; + struct ipx_addr laddr; + + /* + * If somebody here was carying on a conversation and went + * away, and his pen pal thinks he can still talk, we get the + * misdirected packet. + */ + if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) { + spx_istat.gonawy++; + goto dropwithreset; + } + sipx = &ssipx; + bzero(sipx, sizeof *sipx); + sipx->sipx_len = sizeof(*sipx); + sipx->sipx_family = AF_IPX; + sipx->sipx_addr = si->si_sna; + laddr = ipxp->ipxp_laddr; + if (ipx_nullhost(laddr)) + ipxp->ipxp_laddr = si->si_dna; + if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, &thread0)) { + ipxp->ipxp_laddr = laddr; + spx_istat.noconn++; + goto drop; + } + spx_template(cb); + dropsocket = 0; /* committed to socket */ + cb->s_did = si->si_sid; + cb->s_rack = si->si_ack; + cb->s_ralo = si->si_alo; +#define THREEWAYSHAKE +#ifdef THREEWAYSHAKE + cb->s_state = TCPS_SYN_RECEIVED; + cb->s_force = 1 + SPXT_KEEP; + spxstat.spxs_accepts++; + cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; + } + break; + + case TCPS_SYN_RECEIVED: { + /* + * This state means that we have heard a response to our + * acceptance of their connection. It is probably logically + * unnecessary in this implementation. + */ + if (si->si_did != cb->s_sid) { + spx_istat.wrncon++; + goto drop; + } +#endif + ipxp->ipxp_fport = si->si_sport; + cb->s_timer[SPXT_REXMT] = 0; + cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; + soisconnected(so); + cb->s_state = TCPS_ESTABLISHED; + spxstat.spxs_accepts++; + } + break; + + case TCPS_SYN_SENT: + /* + * This state means that we have gotten a response to our + * attempt to establish a connection. We fill in the data + * from the other side, telling us which port to respond to, + * instead of the well-known one we might have sent to in the + * first place. We also require that this is a response to + * our connection id. + */ + if (si->si_did != cb->s_sid) { + spx_istat.notme++; + goto drop; + } + spxstat.spxs_connects++; + cb->s_did = si->si_sid; + cb->s_rack = si->si_ack; + cb->s_ralo = si->si_alo; + cb->s_dport = ipxp->ipxp_fport = si->si_sport; + cb->s_timer[SPXT_REXMT] = 0; + cb->s_flags |= SF_ACKNOW; + soisconnected(so); + cb->s_state = TCPS_ESTABLISHED; + + /* + * Use roundtrip time of connection request for initial rtt. + */ + if (cb->s_rtt) { + cb->s_srtt = cb->s_rtt << 3; + cb->s_rttvar = cb->s_rtt << 1; + SPXT_RANGESET(cb->s_rxtcur, + ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, + SPXTV_MIN, SPXTV_REXMTMAX); + cb->s_rtt = 0; + } + } + + if (so->so_options & SO_DEBUG || traceallspxs) + spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0); + + m->m_len -= sizeof(struct ipx); + m->m_pkthdr.len -= sizeof(struct ipx); + m->m_data += sizeof(struct ipx); + + if (spx_reass(cb, si)) + m_freem(m); + if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT))) + spx_output(cb, NULL); + cb->s_flags &= ~(SF_WIN|SF_RXT); + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return; + +dropwithreset: + IPX_LOCK_ASSERT(ipxp); + if (cb == NULL || (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || + traceallspxs)) + spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); + IPX_UNLOCK(ipxp); + if (dropsocket) { + struct socket *head; + ACCEPT_LOCK(); + KASSERT((so->so_qstate & SQ_INCOMP) != 0, + ("spx_input: nascent socket not SQ_INCOMP on soabort()")); + head = so->so_head; + TAILQ_REMOVE(&head->so_incomp, so, so_list); + head->so_incqlen--; + so->so_qstate &= ~SQ_INCOMP; + so->so_head = NULL; + ACCEPT_UNLOCK(); + soabort(so); + } + IPX_LIST_UNLOCK(); + m_freem(m); + return; + +drop: + IPX_LOCK_ASSERT(ipxp); + if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs) + spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + m_freem(m); +} + +/* + * This is structurally similar to the tcp reassembly routine but its + * function is somewhat different: it merely queues packets up, and + * suppresses duplicates. + */ +static int +spx_reass(struct spxpcb *cb, struct spx *si) +{ + struct spx_q *q; + struct mbuf *m; + struct socket *so = cb->s_ipxpcb->ipxp_socket; + char packetp = cb->s_flags & SF_HI; + int incr; + char wakeup = 0; + + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + if (si == SI(0)) + goto present; + + /* + * Update our news from them. + */ + if (si->si_cc & SPX_SA) + cb->s_flags |= (spx_use_delack ? SF_DELACK : SF_ACKNOW); + if (SSEQ_GT(si->si_alo, cb->s_ralo)) + cb->s_flags |= SF_WIN; + if (SSEQ_LEQ(si->si_ack, cb->s_rack)) { + if ((si->si_cc & SPX_SP) && cb->s_rack != (cb->s_smax + 1)) { + spxstat.spxs_rcvdupack++; + + /* + * If this is a completely duplicate ack and other + * conditions hold, we assume a packet has been + * dropped and retransmit it exactly as in + * tcp_input(). + */ + if (si->si_ack != cb->s_rack || + si->si_alo != cb->s_ralo) + cb->s_dupacks = 0; + else if (++cb->s_dupacks == spxrexmtthresh) { + u_short onxt = cb->s_snxt; + int cwnd = cb->s_cwnd; + + cb->s_snxt = si->si_ack; + cb->s_cwnd = CUNIT; + cb->s_force = 1 + SPXT_REXMT; + spx_output(cb, NULL); + cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; + cb->s_rtt = 0; + if (cwnd >= 4 * CUNIT) + cb->s_cwnd = cwnd / 2; + if (SSEQ_GT(onxt, cb->s_snxt)) + cb->s_snxt = onxt; + return (1); + } + } else + cb->s_dupacks = 0; + goto update_window; + } + cb->s_dupacks = 0; + + /* + * If our correspondent acknowledges data we haven't sent TCP would + * drop the packet after acking. We'll be a little more permissive. + */ + if (SSEQ_GT(si->si_ack, (cb->s_smax + 1))) { + spxstat.spxs_rcvacktoomuch++; + si->si_ack = cb->s_smax + 1; + } + spxstat.spxs_rcvackpack++; + + /* + * If transmit timer is running and timed sequence number was acked, + * update smoothed round trip time. See discussion of algorithm in + * tcp_input.c + */ + if (cb->s_rtt && SSEQ_GT(si->si_ack, cb->s_rtseq)) { + spxstat.spxs_rttupdated++; + if (cb->s_srtt != 0) { + short delta; + delta = cb->s_rtt - (cb->s_srtt >> 3); + if ((cb->s_srtt += delta) <= 0) + cb->s_srtt = 1; + if (delta < 0) + delta = -delta; + delta -= (cb->s_rttvar >> 2); + if ((cb->s_rttvar += delta) <= 0) + cb->s_rttvar = 1; + } else { + /* + * No rtt measurement yet. + */ + cb->s_srtt = cb->s_rtt << 3; + cb->s_rttvar = cb->s_rtt << 1; + } + cb->s_rtt = 0; + cb->s_rxtshift = 0; + SPXT_RANGESET(cb->s_rxtcur, + ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, + SPXTV_MIN, SPXTV_REXMTMAX); + } + + /* + * If all outstanding data is acked, stop retransmit timer and + * remember to restart (more output or persist). If there is more + * data to be acked, restart retransmit timer, using current + * (possibly backed-off) value; + */ + if (si->si_ack == cb->s_smax + 1) { + cb->s_timer[SPXT_REXMT] = 0; + cb->s_flags |= SF_RXT; + } else if (cb->s_timer[SPXT_PERSIST] == 0) + cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; + + /* + * When new data is acked, open the congestion window. If the window + * gives us less than ssthresh packets in flight, open exponentially + * (maxseg at a time). Otherwise open linearly (maxseg^2 / cwnd at a + * time). + */ + incr = CUNIT; + if (cb->s_cwnd > cb->s_ssthresh) + incr = max(incr * incr / cb->s_cwnd, 1); + cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx); + + /* + * Trim Acked data from output queue. + */ + SOCKBUF_LOCK(&so->so_snd); + while ((m = so->so_snd.sb_mb) != NULL) { + if (SSEQ_LT((mtod(m, struct spx *))->si_seq, si->si_ack)) + sbdroprecord_locked(&so->so_snd); + else + break; + } + sowwakeup_locked(so); + cb->s_rack = si->si_ack; +update_window: + if (SSEQ_LT(cb->s_snxt, cb->s_rack)) + cb->s_snxt = cb->s_rack; + if (SSEQ_LT(cb->s_swl1, si->si_seq) || ((cb->s_swl1 == si->si_seq && + (SSEQ_LT(cb->s_swl2, si->si_ack))) || + (cb->s_swl2 == si->si_ack && SSEQ_LT(cb->s_ralo, si->si_alo)))) { + /* keep track of pure window updates */ + if ((si->si_cc & SPX_SP) && cb->s_swl2 == si->si_ack + && SSEQ_LT(cb->s_ralo, si->si_alo)) { + spxstat.spxs_rcvwinupd++; + spxstat.spxs_rcvdupack--; + } + cb->s_ralo = si->si_alo; + cb->s_swl1 = si->si_seq; + cb->s_swl2 = si->si_ack; + cb->s_swnd = (1 + si->si_alo - si->si_ack); + if (cb->s_swnd > cb->s_smxw) + cb->s_smxw = cb->s_swnd; + cb->s_flags |= SF_WIN; + } + + /* + * If this packet number is higher than that which we have allocated + * refuse it, unless urgent. + */ + if (SSEQ_GT(si->si_seq, cb->s_alo)) { + if (si->si_cc & SPX_SP) { + spxstat.spxs_rcvwinprobe++; + return (1); + } else + spxstat.spxs_rcvpackafterwin++; + if (si->si_cc & SPX_OB) { + if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) + return (1); /* else queue this packet; */ + } else { +#ifdef BROKEN + /* + * XXXRW: This is broken on at least one count: + * spx_close() will free the ipxp and related parts, + * which are then touched by spx_input() after the + * return from spx_reass(). + */ + /*struct socket *so = cb->s_ipxpcb->ipxp_socket; + if (so->so_state && SS_NOFDREF) { + spx_close(cb); + } else + would crash system*/ +#endif + spx_istat.notyet++; + return (1); + } + } + + /* + * If this is a system packet, we don't need to queue it up, and + * won't update acknowledge #. + */ + if (si->si_cc & SPX_SP) + return (1); + + /* + * We have already seen this packet, so drop. + */ + if (SSEQ_LT(si->si_seq, cb->s_ack)) { + spx_istat.bdreas++; + spxstat.spxs_rcvduppack++; + if (si->si_seq == cb->s_ack - 1) + spx_istat.lstdup++; + return (1); + } + + /* + * Loop through all packets queued up to insert in appropriate + * sequence. + */ + for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) { + if (si->si_seq == SI(q)->si_seq) { + spxstat.spxs_rcvduppack++; + return (1); + } + if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) { + spxstat.spxs_rcvoopack++; + break; + } + } + spx_insque((struct spx_q *)si, q->si_prev); + + /* + * If this packet is urgent, inform process + */ + if (si->si_cc & SPX_OB) { + cb->s_iobc = ((char *)si)[1 + sizeof(*si)]; + sohasoutofband(so); + cb->s_oobflags |= SF_IOOB; + } +present: +#define SPINC sizeof(struct spxhdr) + SOCKBUF_LOCK(&so->so_rcv); + + /* + * Loop through all packets queued up to update acknowledge number, + * and present all acknowledged data to user; if in packet interface + * mode, show packet headers. + */ + for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) { + if (SI(q)->si_seq == cb->s_ack) { + cb->s_ack++; + m = dtom(q); + if (SI(q)->si_cc & SPX_OB) { + cb->s_oobflags &= ~SF_IOOB; + if (so->so_rcv.sb_cc) + so->so_oobmark = so->so_rcv.sb_cc; + else + so->so_rcv.sb_state |= SBS_RCVATMARK; + } + q = q->si_prev; + spx_remque(q->si_next); + wakeup = 1; + spxstat.spxs_rcvpack++; +#ifdef SF_NEWCALL + if (cb->s_flags2 & SF_NEWCALL) { + struct spxhdr *sp = mtod(m, struct spxhdr *); + u_char dt = sp->spx_dt; + spx_newchecks[4]++; + if (dt != cb->s_rhdr.spx_dt) { + struct mbuf *mm = + m_getclr(M_DONTWAIT, MT_CONTROL); + spx_newchecks[0]++; + if (mm != NULL) { + u_short *s = + mtod(mm, u_short *); + cb->s_rhdr.spx_dt = dt; + mm->m_len = 5; /*XXX*/ + s[0] = 5; + s[1] = 1; + *(u_char *)(&s[2]) = dt; + sbappend_locked(&so->so_rcv, mm); + } + } + if (sp->spx_cc & SPX_OB) { + MCHTYPE(m, MT_OOBDATA); + spx_newchecks[1]++; + so->so_oobmark = 0; + so->so_rcv.sb_state &= ~SBS_RCVATMARK; + } + if (packetp == 0) { + m->m_data += SPINC; + m->m_len -= SPINC; + m->m_pkthdr.len -= SPINC; + } + if ((sp->spx_cc & SPX_EM) || packetp) { + sbappendrecord_locked(&so->so_rcv, m); + spx_newchecks[9]++; + } else + sbappend_locked(&so->so_rcv, m); + } else +#endif + if (packetp) + sbappendrecord_locked(&so->so_rcv, m); + else { + cb->s_rhdr = *mtod(m, struct spxhdr *); + m->m_data += SPINC; + m->m_len -= SPINC; + m->m_pkthdr.len -= SPINC; + sbappend_locked(&so->so_rcv, m); + } + } else + break; + } + if (wakeup) + sorwakeup_locked(so); + else + SOCKBUF_UNLOCK(&so->so_rcv); + return (0); +} + +void +spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy) +{ + + /* Currently, nothing. */ +} + +static int +spx_output(struct spxpcb *cb, struct mbuf *m0) +{ + struct socket *so = cb->s_ipxpcb->ipxp_socket; + struct mbuf *m; + struct spx *si = NULL; + struct sockbuf *sb = &so->so_snd; + int len = 0, win, rcv_win; + short span, off, recordp = 0; + u_short alo; + int error = 0, sendalot; +#ifdef notdef + int idle; +#endif + struct mbuf *mprev; + + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + if (m0 != NULL) { + int mtu = cb->s_mtu; + int datalen; + + /* + * Make sure that packet isn't too big. + */ + for (m = m0; m != NULL; m = m->m_next) { + mprev = m; + len += m->m_len; + if (m->m_flags & M_EOR) + recordp = 1; + } + datalen = (cb->s_flags & SF_HO) ? + len - sizeof(struct spxhdr) : len; + if (datalen > mtu) { + if (cb->s_flags & SF_PI) { + m_freem(m0); + return (EMSGSIZE); + } else { + int oldEM = cb->s_cc & SPX_EM; + + cb->s_cc &= ~SPX_EM; + while (len > mtu) { + m = m_copym(m0, 0, mtu, M_DONTWAIT); + if (m == NULL) { + cb->s_cc |= oldEM; + m_freem(m0); + return (ENOBUFS); + } + if (cb->s_flags & SF_NEWCALL) { + struct mbuf *mm = m; + spx_newchecks[7]++; + while (mm != NULL) { + mm->m_flags &= ~M_EOR; + mm = mm->m_next; + } + } + error = spx_output(cb, m); + if (error) { + cb->s_cc |= oldEM; + m_freem(m0); + return (error); + } + m_adj(m0, mtu); + len -= mtu; + } + cb->s_cc |= oldEM; + } + } + + /* + * Force length even, by adding a "garbage byte" if + * necessary. + */ + if (len & 1) { + m = mprev; + if (M_TRAILINGSPACE(m) >= 1) + m->m_len++; + else { + struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA); + + if (m1 == NULL) { + m_freem(m0); + return (ENOBUFS); + } + m1->m_len = 1; + *(mtod(m1, u_char *)) = 0; + m->m_next = m1; + } + } + m = m_gethdr(M_DONTWAIT, MT_DATA); + if (m == NULL) { + m_freem(m0); + return (ENOBUFS); + } + + /* + * Fill in mbuf with extended SP header and addresses and + * length put into network format. + */ + MH_ALIGN(m, sizeof(struct spx)); + m->m_len = sizeof(struct spx); + m->m_next = m0; + si = mtod(m, struct spx *); + si->si_i = *cb->s_ipx; + si->si_s = cb->s_shdr; + if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) { + struct spxhdr *sh; + if (m0->m_len < sizeof(*sh)) { + if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) { + m_free(m); + m_freem(m0); + return (EINVAL); + } + m->m_next = m0; + } + sh = mtod(m0, struct spxhdr *); + si->si_dt = sh->spx_dt; + si->si_cc |= sh->spx_cc & SPX_EM; + m0->m_len -= sizeof(*sh); + m0->m_data += sizeof(*sh); + len -= sizeof(*sh); + } + len += sizeof(*si); + if ((cb->s_flags2 & SF_NEWCALL) && recordp) { + si->si_cc |= SPX_EM; + spx_newchecks[8]++; + } + if (cb->s_oobflags & SF_SOOB) { + /* + * Per jqj@cornell: Make sure OB packets convey + * exactly 1 byte. If the packet is 1 byte or + * larger, we have already guaranted there to be at + * least one garbage byte for the checksum, and extra + * bytes shouldn't hurt! + */ + if (len > sizeof(*si)) { + si->si_cc |= SPX_OB; + len = (1 + sizeof(*si)); + } + } + si->si_len = htons((u_short)len); + m->m_pkthdr.len = ((len - 1) | 1) + 1; + + /* + * Queue stuff up for output. + */ + sbappendrecord(sb, m); + cb->s_seq++; + } +#ifdef notdef + idle = (cb->s_smax == (cb->s_rack - 1)); +#endif +again: + sendalot = 0; + off = cb->s_snxt - cb->s_rack; + win = min(cb->s_swnd, (cb->s_cwnd / CUNIT)); + + /* + * If in persist timeout with window of 0, send a probe. Otherwise, + * if window is small but non-zero and timer expired, send what we + * can and go into transmit state. + */ + if (cb->s_force == 1 + SPXT_PERSIST) { + if (win != 0) { + cb->s_timer[SPXT_PERSIST] = 0; + cb->s_rxtshift = 0; + } + } + span = cb->s_seq - cb->s_rack; + len = min(span, win) - off; + + if (len < 0) { + /* + * Window shrank after we went into it. If window shrank to + * 0, cancel pending restransmission and pull s_snxt back to + * (closed) window. We will enter persist state below. If + * the widndow didn't close completely, just wait for an ACK. + */ + len = 0; + if (win == 0) { + cb->s_timer[SPXT_REXMT] = 0; + cb->s_snxt = cb->s_rack; + } + } + if (len > 1) + sendalot = 1; + rcv_win = sbspace(&so->so_rcv); + + /* + * Send if we owe peer an ACK. + */ + if (cb->s_oobflags & SF_SOOB) { + /* + * Must transmit this out of band packet. + */ + cb->s_oobflags &= ~ SF_SOOB; + sendalot = 1; + spxstat.spxs_sndurg++; + goto found; + } + if (cb->s_flags & SF_ACKNOW) + goto send; + if (cb->s_state < TCPS_ESTABLISHED) + goto send; + + /* + * Silly window can't happen in spx. Code from TCP deleted. + */ + if (len) + goto send; + + /* + * Compare available window to amount of window known to peer (as + * advertised window less next expected input.) If the difference is + * at least two packets or at least 35% of the mximum possible + * window, then want to send a window update to peer. + */ + if (rcv_win > 0) { + u_short delta = 1 + cb->s_alo - cb->s_ack; + int adv = rcv_win - (delta * cb->s_mtu); + + if ((so->so_rcv.sb_cc == 0 && adv >= (2 * cb->s_mtu)) || + (100 * adv / so->so_rcv.sb_hiwat >= 35)) { + spxstat.spxs_sndwinup++; + cb->s_flags |= SF_ACKNOW; + goto send; + } + + } + + /* + * Many comments from tcp_output.c are appropriate here including ... + * If send window is too small, there is data to transmit, and no + * retransmit or persist is pending, then go to persist state. If + * nothing happens soon, send when timer expires: if window is + * non-zero, transmit what we can, otherwise send a probe. + */ + if (so->so_snd.sb_cc && cb->s_timer[SPXT_REXMT] == 0 && + cb->s_timer[SPXT_PERSIST] == 0) { + cb->s_rxtshift = 0; + spx_setpersist(cb); + } + + /* + * No reason to send a packet, just return. + */ + cb->s_outx = 1; + return (0); + +send: + /* + * Find requested packet. + */ + si = 0; + if (len > 0) { + cb->s_want = cb->s_snxt; + for (m = sb->sb_mb; m != NULL; m = m->m_act) { + si = mtod(m, struct spx *); + if (SSEQ_LEQ(cb->s_snxt, si->si_seq)) + break; + } + found: + if (si != NULL) { + if (si->si_seq == cb->s_snxt) + cb->s_snxt++; + else + spxstat.spxs_sndvoid++, si = 0; + } + } + + /* + * Update window. + */ + if (rcv_win < 0) + rcv_win = 0; + alo = cb->s_ack - 1 + (rcv_win / ((short)cb->s_mtu)); + if (SSEQ_LT(alo, cb->s_alo)) + alo = cb->s_alo; + + if (si != NULL) { + /* + * Must make a copy of this packet for ipx_output to monkey + * with. + */ + m = m_copy(dtom(si), 0, (int)M_COPYALL); + if (m == NULL) + return (ENOBUFS); + si = mtod(m, struct spx *); + if (SSEQ_LT(si->si_seq, cb->s_smax)) + spxstat.spxs_sndrexmitpack++; + else + spxstat.spxs_sndpack++; + } else if (cb->s_force || cb->s_flags & SF_ACKNOW) { + /* + * Must send an acknowledgement or a probe. + */ + if (cb->s_force) + spxstat.spxs_sndprobe++; + if (cb->s_flags & SF_ACKNOW) + spxstat.spxs_sndacks++; + m = m_gethdr(M_DONTWAIT, MT_DATA); + if (m == NULL) + return (ENOBUFS); + + /* + * Fill in mbuf with extended SP header and addresses and + * length put into network format. + */ + MH_ALIGN(m, sizeof(struct spx)); + m->m_len = sizeof(*si); + m->m_pkthdr.len = sizeof(*si); + si = mtod(m, struct spx *); + si->si_i = *cb->s_ipx; + si->si_s = cb->s_shdr; + si->si_seq = cb->s_smax + 1; + si->si_len = htons(sizeof(*si)); + si->si_cc |= SPX_SP; + } else { + cb->s_outx = 3; + if (so->so_options & SO_DEBUG || traceallspxs) + spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); + return (0); + } + + /* + * Stuff checksum and output datagram. + */ + if ((si->si_cc & SPX_SP) == 0) { + if (cb->s_force != (1 + SPXT_PERSIST) || + cb->s_timer[SPXT_PERSIST] == 0) { + /* + * If this is a new packet and we are not currently + * timing anything, time this one. + */ + if (SSEQ_LT(cb->s_smax, si->si_seq)) { + cb->s_smax = si->si_seq; + if (cb->s_rtt == 0) { + spxstat.spxs_segstimed++; + cb->s_rtseq = si->si_seq; + cb->s_rtt = 1; + } + } + + /* + * Set rexmt timer if not currently set, initial + * value for retransmit timer is smoothed round-trip + * time + 2 * round-trip time variance. Initialize + * shift counter which is used for backoff of + * retransmit time. + */ + if (cb->s_timer[SPXT_REXMT] == 0 && + cb->s_snxt != cb->s_rack) { + cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; + if (cb->s_timer[SPXT_PERSIST]) { + cb->s_timer[SPXT_PERSIST] = 0; + cb->s_rxtshift = 0; + } + } + } else if (SSEQ_LT(cb->s_smax, si->si_seq)) + cb->s_smax = si->si_seq; + } else if (cb->s_state < TCPS_ESTABLISHED) { + if (cb->s_rtt == 0) + cb->s_rtt = 1; /* Time initial handshake */ + if (cb->s_timer[SPXT_REXMT] == 0) + cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; + } + + /* + * Do not request acks when we ack their data packets or when we do a + * gratuitous window update. + */ + if (((si->si_cc & SPX_SP) == 0) || cb->s_force) + si->si_cc |= SPX_SA; + si->si_seq = htons(si->si_seq); + si->si_alo = htons(alo); + si->si_ack = htons(cb->s_ack); + + if (ipxcksum) + si->si_sum = ipx_cksum(m, ntohs(si->si_len)); + else + si->si_sum = 0xffff; + + cb->s_outx = 4; + if (so->so_options & SO_DEBUG || traceallspxs) + spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); + + if (so->so_options & SO_DONTROUTE) + error = ipx_outputfl(m, NULL, IPX_ROUTETOIF); + else + error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0); + if (error) + return (error); + spxstat.spxs_sndtotal++; + + /* + * Data sent (as far as we can tell). If this advertises a larger + * window than any other segment, then remember the size of the + * advertized window. Any pending ACK has now been sent. + */ + cb->s_force = 0; + cb->s_flags &= ~(SF_ACKNOW|SF_DELACK); + if (SSEQ_GT(alo, cb->s_alo)) + cb->s_alo = alo; + if (sendalot) + goto again; + cb->s_outx = 5; + return (0); +} + +static int spx_do_persist_panics = 0; + +static void +spx_setpersist(struct spxpcb *cb) +{ + int t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; + + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics) + panic("spx_output REXMT"); + + /* + * Start/restart persistance timer. + */ + SPXT_RANGESET(cb->s_timer[SPXT_PERSIST], + t*spx_backoff[cb->s_rxtshift], + SPXTV_PERSMIN, SPXTV_PERSMAX); + if (cb->s_rxtshift < SPX_MAXRXTSHIFT) + cb->s_rxtshift++; +} + +int +spx_ctloutput(struct socket *so, struct sockopt *sopt) +{ + struct spxhdr spxhdr; + struct ipxpcb *ipxp; + struct spxpcb *cb; + int mask, error; + short soptval; + u_short usoptval; + int optval; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_ctloutput: ipxp == NULL")); + + /* + * This will have to be changed when we do more general stacking of + * protocols. + */ + if (sopt->sopt_level != IPXPROTO_SPX) + return (ipx_ctloutput(so, sopt)); + + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + IPX_UNLOCK(ipxp); + return (ECONNRESET); + } + + IPX_LOCK(ipxp); + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_ctloutput: cb == NULL")); + + error = 0; + switch (sopt->sopt_dir) { + case SOPT_GET: + switch (sopt->sopt_name) { + case SO_HEADERS_ON_INPUT: + mask = SF_HI; + goto get_flags; + + case SO_HEADERS_ON_OUTPUT: + mask = SF_HO; + get_flags: + soptval = cb->s_flags & mask; + IPX_UNLOCK(ipxp); + error = sooptcopyout(sopt, &soptval, + sizeof(soptval)); + break; + + case SO_MTU: + usoptval = cb->s_mtu; + IPX_UNLOCK(ipxp); + error = sooptcopyout(sopt, &usoptval, + sizeof(usoptval)); + break; + + case SO_LAST_HEADER: + spxhdr = cb->s_rhdr; + IPX_UNLOCK(ipxp); + error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); + break; + + case SO_DEFAULT_HEADERS: + spxhdr = cb->s_shdr; + IPX_UNLOCK(ipxp); + error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); + break; + + default: + IPX_UNLOCK(ipxp); + error = ENOPROTOOPT; + } + break; + + case SOPT_SET: + /* + * XXX Why are these shorts on get and ints on set? That + * doesn't make any sense... + * + * XXXRW: Note, when we re-acquire the ipxp lock, we should + * re-check that it's not dropped. + */ + IPX_UNLOCK(ipxp); + switch (sopt->sopt_name) { + case SO_HEADERS_ON_INPUT: + mask = SF_HI; + goto set_head; + + case SO_HEADERS_ON_OUTPUT: + mask = SF_HO; + set_head: + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + break; + + IPX_LOCK(ipxp); + if (cb->s_flags & SF_PI) { + if (optval) + cb->s_flags |= mask; + else + cb->s_flags &= ~mask; + } else error = EINVAL; + IPX_UNLOCK(ipxp); + break; + + case SO_MTU: + error = sooptcopyin(sopt, &usoptval, sizeof usoptval, + sizeof usoptval); + if (error) + break; + /* Unlocked write. */ + cb->s_mtu = usoptval; + break; + +#ifdef SF_NEWCALL + case SO_NEWCALL: + error = sooptcopyin(sopt, &optval, sizeof optval, + sizeof optval); + if (error) + break; + IPX_LOCK(ipxp); + if (optval) { + cb->s_flags2 |= SF_NEWCALL; + spx_newchecks[5]++; + } else { + cb->s_flags2 &= ~SF_NEWCALL; + spx_newchecks[6]++; + } + IPX_UNLOCK(ipxp); + break; +#endif + + case SO_DEFAULT_HEADERS: + { + struct spxhdr sp; + + error = sooptcopyin(sopt, &sp, sizeof sp, + sizeof sp); + if (error) + break; + IPX_LOCK(ipxp); + cb->s_dt = sp.spx_dt; + cb->s_cc = sp.spx_cc & SPX_EM; + IPX_UNLOCK(ipxp); + } + break; + + default: + error = ENOPROTOOPT; + } + break; + + default: + panic("spx_ctloutput: bad socket option direction"); + } + return (error); +} + +static void +spx_usr_abort(struct socket *so) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_usr_abort: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_usr_abort: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + spx_drop(cb, ECONNABORTED); + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); +} + +/* + * Accept a connection. Essentially all the work is done at higher levels; + * just return the address of the peer, storing through addr. + */ +static int +spx_accept(struct socket *so, struct sockaddr **nam) +{ + struct ipxpcb *ipxp; + struct sockaddr_ipx *sipx, ssipx; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_accept: ipxp == NULL")); + + sipx = &ssipx; + bzero(sipx, sizeof *sipx); + sipx->sipx_len = sizeof *sipx; + sipx->sipx_family = AF_IPX; + IPX_LOCK(ipxp); + sipx->sipx_addr = ipxp->ipxp_faddr; + IPX_UNLOCK(ipxp); + *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); + return (0); +} + +static int +spx_attach(struct socket *so, int proto, struct thread *td) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + struct mbuf *mm; + struct sockbuf *sb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL")); + + if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { + error = soreserve(so, (u_long) 3072, (u_long) 3072); + if (error) + return (error); + } + + cb = malloc(sizeof *cb, M_PCB, M_NOWAIT | M_ZERO); + if (cb == NULL) + return (ENOBUFS); + mm = m_getclr(M_DONTWAIT, MT_DATA); + if (mm == NULL) { + free(cb, M_PCB); + return (ENOBUFS); + } + + IPX_LIST_LOCK(); + error = ipx_pcballoc(so, &ipxpcb_list, td); + if (error) { + IPX_LIST_UNLOCK(); + m_free(mm); + free(cb, M_PCB); + return (error); + } + ipxp = sotoipxpcb(so); + ipxp->ipxp_flags |= IPXP_SPX; + + cb->s_ipx = mtod(mm, struct ipx *); + cb->s_state = TCPS_LISTEN; + cb->s_smax = -1; + cb->s_swl1 = -1; + cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q; + cb->s_ipxpcb = ipxp; + cb->s_mtu = 576 - sizeof(struct spx); + sb = &so->so_snd; + cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu; + cb->s_ssthresh = cb->s_cwnd; + cb->s_cwmx = sbspace(sb) * CUNIT / (2 * sizeof(struct spx)); + + /* + * Above is recomputed when connecting to account for changed + * buffering or mtu's. + */ + cb->s_rtt = SPXTV_SRTTBASE; + cb->s_rttvar = SPXTV_SRTTDFLT << 2; + SPXT_RANGESET(cb->s_rxtcur, + ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1, + SPXTV_MIN, SPXTV_REXMTMAX); + ipxp->ipxp_pcb = (caddr_t)cb; + IPX_LIST_UNLOCK(); + return (0); +} + +static void +spx_pcbdetach(struct ipxpcb *ipxp) +{ + struct spxpcb *cb; + struct spx_q *s; + struct mbuf *m; + + IPX_LOCK_ASSERT(ipxp); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL")); + + s = cb->s_q.si_next; + while (s != &(cb->s_q)) { + s = s->si_next; + spx_remque(s); + m = dtom(s); + m_freem(m); + } + m_free(dtom(cb->s_ipx)); + free(cb, M_PCB); + ipxp->ipxp_pcb = NULL; +} + +static int +spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td) +{ + struct ipxpcb *ipxp; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_bind: ipxp == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + error = ipx_pcbbind(ipxp, nam, td); +out: + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return (error); +} + +static void +spx_usr_close(struct socket *so) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_usr_close: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_usr_close: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (cb->s_state > TCPS_LISTEN) + spx_disconnect(cb); + else + spx_close(cb); + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); +} + +/* + * Initiate connection to peer. Enter SYN_SENT state, and mark socket as + * connecting. Start keep-alive timer, setup prototype header, send initial + * system packet requesting connection. + */ +static int +spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_connect: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_connect: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto spx_connect_end; + } + if (ipxp->ipxp_lport == 0) { + error = ipx_pcbbind(ipxp, NULL, td); + if (error) + goto spx_connect_end; + } + error = ipx_pcbconnect(ipxp, nam, td); + if (error) + goto spx_connect_end; + soisconnecting(so); + spxstat.spxs_connattempt++; + cb->s_state = TCPS_SYN_SENT; + cb->s_did = 0; + spx_template(cb); + cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; + cb->s_force = 1 + SPXTV_KEEP; + + /* + * Other party is required to respond to the port I send from, but he + * is not required to answer from where I am sending to, so allow + * wildcarding. Original port I am sending to is still saved in + * cb->s_dport. + */ + ipxp->ipxp_fport = 0; + error = spx_output(cb, NULL); +spx_connect_end: + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return (error); +} + +static void +spx_detach(struct socket *so) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + + /* + * XXXRW: Should assert appropriately detached. + */ + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_detach: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_detach: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + spx_pcbdetach(ipxp); + ipx_pcbfree(ipxp); + IPX_LIST_UNLOCK(); +} + +/* + * We may decide later to implement connection closing handshaking at the spx + * level optionally. Here is the hook to do it: + */ +static int +spx_usr_disconnect(struct socket *so) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_usr_disconnect: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_usr_disconnect: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + spx_disconnect(cb); + error = 0; +out: + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return (error); +} + +static int +spx_listen(struct socket *so, int backlog, struct thread *td) +{ + int error; + struct ipxpcb *ipxp; + struct spxpcb *cb; + + error = 0; + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_listen: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_listen: cb == NULL")); + + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + SOCK_LOCK(so); + error = solisten_proto_check(so); + if (error == 0 && ipxp->ipxp_lport == 0) + error = ipx_pcbbind(ipxp, NULL, td); + if (error == 0) { + cb->s_state = TCPS_LISTEN; + solisten_proto(so, backlog); + } + SOCK_UNLOCK(so); +out: + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return (error); +} + +/* + * After a receive, possibly send acknowledgment updating allocation. + */ +static int +spx_rcvd(struct socket *so, int flags) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_rcvd: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_rcvd: cb == NULL")); + + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + cb->s_flags |= SF_RVD; + spx_output(cb, NULL); + cb->s_flags &= ~SF_RVD; + error = 0; +out: + IPX_UNLOCK(ipxp); + return (error); +} + +static int +spx_rcvoob(struct socket *so, struct mbuf *m, int flags) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_rcvoob: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_rcvoob: cb == NULL")); + + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + SOCKBUF_LOCK(&so->so_rcv); + if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark || + (so->so_rcv.sb_state & SBS_RCVATMARK)) { + SOCKBUF_UNLOCK(&so->so_rcv); + m->m_len = 1; + *mtod(m, caddr_t) = cb->s_iobc; + error = 0; + goto out; + } + SOCKBUF_UNLOCK(&so->so_rcv); + error = EINVAL; +out: + IPX_UNLOCK(ipxp); + return (error); +} + +static int +spx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, + struct mbuf *controlp, struct thread *td) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_send: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_send: cb == NULL")); + + error = 0; + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = ECONNRESET; + goto spx_send_end; + } + if (flags & PRUS_OOB) { + if (sbspace(&so->so_snd) < -512) { + error = ENOBUFS; + goto spx_send_end; + } + cb->s_oobflags |= SF_SOOB; + } + if (controlp != NULL) { + u_short *p = mtod(controlp, u_short *); + spx_newchecks[2]++; + if ((p[0] == 5) && (p[1] == 1)) { /* XXXX, for testing */ + cb->s_shdr.spx_dt = *(u_char *)(&p[2]); + spx_newchecks[3]++; + } + m_freem(controlp); + } + controlp = NULL; + error = spx_output(cb, m); + m = NULL; +spx_send_end: + IPX_UNLOCK(ipxp); + if (controlp != NULL) + m_freem(controlp); + if (m != NULL) + m_freem(m); + return (error); +} + +static int +spx_shutdown(struct socket *so) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_shutdown: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_shutdown: cb == NULL")); + + socantsendmore(so); + IPX_LIST_LOCK(); + IPX_LOCK(ipxp); + if (ipxp->ipxp_flags & IPXP_DROPPED) { + error = EINVAL; + goto out; + } + spx_usrclosed(cb); + error = 0; +out: + IPX_UNLOCK(ipxp); + IPX_LIST_UNLOCK(); + return (error); +} + +static int +spx_sp_attach(struct socket *so, int proto, struct thread *td) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int error; + + KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL")); + + error = spx_attach(so, proto, td); + if (error) + return (error); + + ipxp = sotoipxpcb(so); + KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL")); + + cb = ipxtospxpcb(ipxp); + KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL")); + + IPX_LOCK(ipxp); + cb->s_flags |= (SF_HI | SF_HO | SF_PI); + IPX_UNLOCK(ipxp); + return (0); +} + +/* + * Create template to be used to send spx packets on a connection. Called + * after host entry created, fills in a skeletal spx header (choosing + * connection id), minimizing the amount of work necessary when the + * connection is used. + */ +static void +spx_template(struct spxpcb *cb) +{ + struct ipxpcb *ipxp = cb->s_ipxpcb; + struct ipx *ipx = cb->s_ipx; + struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd); + + IPX_LOCK_ASSERT(ipxp); + + ipx->ipx_pt = IPXPROTO_SPX; + ipx->ipx_sna = ipxp->ipxp_laddr; + ipx->ipx_dna = ipxp->ipxp_faddr; + SPX_LOCK(); + cb->s_sid = htons(spx_iss); + spx_iss += SPX_ISSINCR/2; + SPX_UNLOCK(); + cb->s_alo = 1; + cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu; + + /* + * Try to expand fast to full complement of large packets. + */ + cb->s_ssthresh = cb->s_cwnd; + cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spx)); + + /* + * But allow for lots of little packets as well. + */ + cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd); +} + +/* + * Close a SPIP control block. Wake up any sleepers. We used to free any + * queued packets and cb->s_ipx here, but now we defer that until the pcb is + * discarded. + */ +void +spx_close(struct spxpcb *cb) +{ + struct ipxpcb *ipxp = cb->s_ipxpcb; + struct socket *so = ipxp->ipxp_socket; + + KASSERT(ipxp != NULL, ("spx_close: ipxp == NULL")); + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(ipxp); + + ipxp->ipxp_flags |= IPXP_DROPPED; + soisdisconnected(so); + spxstat.spxs_closed++; +} + +/* + * Someday we may do level 3 handshaking to close a connection or send a + * xerox style error. For now, just close. cb will always be invalid after + * this call. + */ +static void +spx_usrclosed(struct spxpcb *cb) +{ + + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + spx_close(cb); +} + +/* + * cb will always be invalid after this call. + */ +static void +spx_disconnect(struct spxpcb *cb) +{ + + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + spx_close(cb); +} + +/* + * Drop connection, reporting the specified error. cb will always be invalid + * after this call. + */ +static void +spx_drop(struct spxpcb *cb, int errno) +{ + struct socket *so = cb->s_ipxpcb->ipxp_socket; + + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + /* + * Someday, in the xerox world we will generate error protocol + * packets announcing that the socket has gone away. + */ + if (TCPS_HAVERCVDSYN(cb->s_state)) { + spxstat.spxs_drops++; + cb->s_state = TCPS_CLOSED; + /*tcp_output(cb);*/ + } else + spxstat.spxs_conndrops++; + so->so_error = errno; + spx_close(cb); +} + +/* + * Fast timeout routine for processing delayed acks. + */ +void +spx_fasttimo(void) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + + IPX_LIST_LOCK(); + LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { + IPX_LOCK(ipxp); + if (!(ipxp->ipxp_flags & IPXP_SPX) || + (ipxp->ipxp_flags & IPXP_DROPPED)) { + IPX_UNLOCK(ipxp); + continue; + } + cb = ipxtospxpcb(ipxp); + if (cb->s_flags & SF_DELACK) { + cb->s_flags &= ~SF_DELACK; + cb->s_flags |= SF_ACKNOW; + spxstat.spxs_delack++; + spx_output(cb, NULL); + } + IPX_UNLOCK(ipxp); + } + IPX_LIST_UNLOCK(); +} + +/* + * spx protocol timeout routine called every 500 ms. Updates the timers in + * all active pcb's and causes finite state machine actions if timers expire. + */ +void +spx_slowtimo(void) +{ + struct ipxpcb *ipxp; + struct spxpcb *cb; + int i; + + /* + * Search through tcb's and update active timers. Once, timers could + * free ipxp's, but now we do that only when detaching a socket. + */ + IPX_LIST_LOCK(); + LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { + IPX_LOCK(ipxp); + if (!(ipxp->ipxp_flags & IPXP_SPX) || + (ipxp->ipxp_flags & IPXP_DROPPED)) { + IPX_UNLOCK(ipxp); + continue; + } + + cb = (struct spxpcb *)ipxp->ipxp_pcb; + KASSERT(cb != NULL, ("spx_slowtimo: cb == NULL")); + for (i = 0; i < SPXT_NTIMERS; i++) { + if (cb->s_timer[i] && --cb->s_timer[i] == 0) { + spx_timers(cb, i); + if (ipxp->ipxp_flags & IPXP_DROPPED) + break; + } + } + if (!(ipxp->ipxp_flags & IPXP_DROPPED)) { + cb->s_idle++; + if (cb->s_rtt) + cb->s_rtt++; + } + IPX_UNLOCK(ipxp); + } + IPX_LIST_UNLOCK(); + SPX_LOCK(); + spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */ + SPX_UNLOCK(); +} + +/* + * SPX timer processing. + */ +static void +spx_timers(struct spxpcb *cb, int timer) +{ + long rexmt; + int win; + + IPX_LIST_LOCK_ASSERT(); + IPX_LOCK_ASSERT(cb->s_ipxpcb); + + cb->s_force = 1 + timer; + switch (timer) { + case SPXT_2MSL: + /* + * 2 MSL timeout in shutdown went off. TCP deletes + * connection control block. + */ + printf("spx: SPXT_2MSL went off for no reason\n"); + cb->s_timer[timer] = 0; + break; + + case SPXT_REXMT: + /* + * Retransmission timer went off. Message has not been acked + * within retransmit interval. Back off to a longer + * retransmit interval and retransmit one packet. + */ + if (++cb->s_rxtshift > SPX_MAXRXTSHIFT) { + cb->s_rxtshift = SPX_MAXRXTSHIFT; + spxstat.spxs_timeoutdrop++; + spx_drop(cb, ETIMEDOUT); + break; + } + spxstat.spxs_rexmttimeo++; + rexmt = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; + rexmt *= spx_backoff[cb->s_rxtshift]; + SPXT_RANGESET(cb->s_rxtcur, rexmt, SPXTV_MIN, SPXTV_REXMTMAX); + cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; + + /* + * If we have backed off fairly far, our srtt estimate is + * probably bogus. Clobber it so we'll take the next rtt + * measurement as our srtt; move the current srtt into rttvar + * to keep the current retransmit times until then. + */ + if (cb->s_rxtshift > SPX_MAXRXTSHIFT / 4 ) { + cb->s_rttvar += (cb->s_srtt >> 2); + cb->s_srtt = 0; + } + cb->s_snxt = cb->s_rack; + + /* + * If timing a packet, stop the timer. + */ + cb->s_rtt = 0; + + /* + * See very long discussion in tcp_timer.c about congestion + * window and sstrhesh. + */ + win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2; + if (win < 2) + win = 2; + cb->s_cwnd = CUNIT; + cb->s_ssthresh = win * CUNIT; + spx_output(cb, NULL); + break; + + case SPXT_PERSIST: + /* + * Persistance timer into zero window. Force a probe to be + * sent. + */ + spxstat.spxs_persisttimeo++; + spx_setpersist(cb); + spx_output(cb, NULL); + break; + + case SPXT_KEEP: + /* + * Keep-alive timer went off; send something or drop + * connection if idle for too long. + */ + spxstat.spxs_keeptimeo++; + if (cb->s_state < TCPS_ESTABLISHED) + goto dropit; + if (cb->s_ipxpcb->ipxp_socket->so_options & SO_KEEPALIVE) { + if (cb->s_idle >= SPXTV_MAXIDLE) + goto dropit; + spxstat.spxs_keepprobe++; + spx_output(cb, NULL); + } else + cb->s_idle = 0; + cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; + break; + + dropit: + spxstat.spxs_keepdrops++; + spx_drop(cb, ETIMEDOUT); + break; + + default: + panic("spx_timers: unknown timer %d", timer); + } +} From d1c77156d875caa3e7971413c141a1b26a0c07f3 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 25 May 2009 09:23:26 +0000 Subject: [PATCH 507/544] Enhance the 'p' command so that it understands size qualifiers (K/M/G) and so that it understands '*' as 'DTRT'. PR: 68312 Submitted by: Rene de Vries - rene at tunix dot nl (mostly) MFC after: 3 weeks --- sbin/fdisk/fdisk.8 | 36 +++++++++++++++++++ sbin/fdisk/fdisk.c | 88 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 118 insertions(+), 6 deletions(-) diff --git a/sbin/fdisk/fdisk.8 b/sbin/fdisk/fdisk.8 index 1537266a9798..0ffdeff9b937 100644 --- a/sbin/fdisk/fdisk.8 +++ b/sbin/fdisk/fdisk.8 @@ -372,6 +372,31 @@ starting at sector for .Ar length sectors. +If the +.Ar start +or +.Ar length +is suffixed with a +.Em K , +.Em M +or +.Em G , +it is taken as a +.Em Kilobyte , +.Em Megabyte +or +.Em Gigabyte +measurement respectively. +If the +.Ar start +is given as +.Qq * +it is set to the value of the previous partition end. +If the +.Ar length +is given as +.Qq * +the partition end is set to the end of the disk. .Pp Only those slices explicitly mentioned by these lines are modified; any slice not referenced by a @@ -421,6 +446,17 @@ for 2503871 sectors (note: these numbers will be rounded upwards and downwards to correspond to head and cylinder boundaries): .Pp .Dl "p 1 165 1 2503871" +.Pp +Example: to set slices 1, 2 and 4 to +.Fx +slices, the first being 2 Gigabytes, the second being 10 Gigabytes and the +forth being the remainder of the disk (again, numbers will be rounded +appropriately): +.Pp +.Dl "p 1 165 63 2G" +.Dl "p 2 165 * 10G" +.Dl "p 3 0 0 0" +.Dl "p 4 165 * *" .It Ic a Ar slice Make .Ar slice diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index c500d03d6c9d..1e121bb6450d 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$"); int iotest; +#define NOSECTORS ((u_int32_t)-1) #define LBUF 100 static char lbuf[LBUF]; @@ -106,6 +107,7 @@ typedef struct cmd { struct arg { char argtype; int arg_val; + char *arg_str; } args[MAX_ARGS]; } CMD; @@ -970,16 +972,23 @@ parse_config_line(char *line, CMD *command) */ while (1) { while (isspace(*cp)) ++cp; + if (*cp == '\0') + break; /* eol */ if (*cp == '#') break; /* found comment */ if (isalpha(*cp)) command->args[command->n_args].argtype = *cp++; - if (!isdigit(*cp)) - break; /* assume end of line */ end = NULL; command->args[command->n_args].arg_val = strtol(cp, &end, 0); - if (cp == end) - break; /* couldn't parse number */ + if (cp == end || (!isspace(*end) && *end != '\0')) { + char ch; + end = cp; + while (!isspace(*end) && *end != '\0') ++end; + ch = *end; *end = '\0'; + command->args[command->n_args].arg_str = strdup(cp); + *end = ch; + } else + command->args[command->n_args].arg_str = NULL; cp = end; command->n_args++; } @@ -1078,6 +1087,33 @@ process_geometry(CMD *command) return (status); } +static u_int32_t +str2sectors(const char *str) +{ + char *end; + unsigned long val; + + val = strtoul(str, &end, 0); + if (str == end || *end == '\0') { + warnx("ERROR line %d: unexpected size: \'%s\'", + current_line_number, str); + return NOSECTORS; + } + + if (*end == 'K') + val *= 1024UL / secsize; + else if (*end == 'M') + val *= 1024UL * 1024UL / secsize; + else if (*end == 'G') + val *= 1024UL * 1024UL * 1024UL / secsize; + else { + warnx("ERROR line %d: unexpected modifier: %c " + "(not K/M/G)", current_line_number, *end); + return NOSECTORS; + } + + return val; +} static int process_partition(CMD *command) @@ -1103,8 +1139,48 @@ process_partition(CMD *command) partp = &mboot.parts[partition - 1]; bzero(partp, sizeof (*partp)); partp->dp_typ = command->args[1].arg_val; - partp->dp_start = command->args[2].arg_val; - partp->dp_size = command->args[3].arg_val; + if (command->args[2].arg_str != NULL) { + if (strcmp(command->args[2].arg_str, "*") == 0) { + int i; + partp->dp_start = dos_sectors; + for (i = 1; i < partition; i++) { + struct dos_partition *prev_partp; + prev_partp = ((struct dos_partition *) + &mboot.parts) + i - 1; + if (prev_partp->dp_typ != 0) + partp->dp_start = prev_partp->dp_start + + prev_partp->dp_size; + } + if (partp->dp_start % dos_sectors != 0) { + prev_head_boundary = partp->dp_start / + dos_sectors * dos_sectors; + partp->dp_start = prev_head_boundary + + dos_sectors; + } + } else { + partp->dp_start = str2sectors(command->args[2].arg_str); + if (partp->dp_start == NOSECTORS) + break; + } + } else + partp->dp_start = command->args[2].arg_val; + + if (command->args[3].arg_str != NULL) { + if (strcmp(command->args[3].arg_str, "*") == 0) + partp->dp_size = ((disksecs / dos_cylsecs) * + dos_cylsecs) - partp->dp_start; + else { + partp->dp_size = str2sectors(command->args[3].arg_str); + if (partp->dp_size == NOSECTORS) + break; + } + prev_cyl_boundary = ((partp->dp_start + partp->dp_size) / + dos_cylsecs) * dos_cylsecs; + if (prev_cyl_boundary > partp->dp_start) + partp->dp_size = prev_cyl_boundary - partp->dp_start; + } else + partp->dp_size = command->args[3].arg_val; + max_end = partp->dp_start + partp->dp_size; if (partp->dp_typ == 0) { From cf5320bd29d6649d54875eb0fc62628de42d700c Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 09:28:54 +0000 Subject: [PATCH 508/544] Complete move of SPX reassembly from spx_usrreq.c to spx_reass.c. MFC after: 1 month --- sys/conf/files | 1 + sys/netipx/spx_reass.c | 1712 +-------------------------------------- sys/netipx/spx_usrreq.c | 355 +------- sys/netipx/spx_var.h | 13 + 4 files changed, 20 insertions(+), 2061 deletions(-) diff --git a/sys/conf/files b/sys/conf/files index a3bd42f252bd..a8cf11bd9232 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2427,6 +2427,7 @@ netipx/ipx_pcb.c optional ipx netipx/ipx_proto.c optional ipx netipx/ipx_usrreq.c optional ipx netipx/spx_debug.c optional ipx +netipx/spx_reass.c optional ipx netipx/spx_usrreq.c optional ipx netnatm/natm.c optional natm netnatm/natm_pcb.c optional natm diff --git a/sys/netipx/spx_reass.c b/sys/netipx/spx_reass.c index 7bfa88ebc536..2e69f5e0343e 100644 --- a/sys/netipx/spx_reass.c +++ b/sys/netipx/spx_reass.c @@ -89,97 +89,9 @@ __FBSDID("$FreeBSD$"); #include #include -/* - * SPX protocol implementation. - */ -static struct mtx spx_mtx; /* Protects only spx_iss. */ -static u_short spx_iss; -static u_short spx_newchecks[50]; -static int spx_hardnosed; static int spx_use_delack = 0; -static int traceallspxs = 0; -static struct spx_istat spx_istat; static int spxrexmtthresh = 3; -#define SPX_LOCK_INIT() mtx_init(&spx_mtx, "spx_mtx", NULL, MTX_DEF) -#define SPX_LOCK() mtx_lock(&spx_mtx) -#define SPX_UNLOCK() mtx_unlock(&spx_mtx) - -/* Following was struct spxstat spxstat; */ -#ifndef spxstat -#define spxstat spx_istat.newstats -#endif - -static const int spx_backoff[SPX_MAXRXTSHIFT+1] = - { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; - -static void spx_close(struct spxpcb *cb); -static void spx_disconnect(struct spxpcb *cb); -static void spx_drop(struct spxpcb *cb, int errno); -static int spx_output(struct spxpcb *cb, struct mbuf *m0); -static int spx_reass(struct spxpcb *cb, struct spx *si); -static void spx_setpersist(struct spxpcb *cb); -static void spx_template(struct spxpcb *cb); -static void spx_timers(struct spxpcb *cb, int timer); -static void spx_usrclosed(struct spxpcb *cb); - -static void spx_usr_abort(struct socket *so); -static int spx_accept(struct socket *so, struct sockaddr **nam); -static int spx_attach(struct socket *so, int proto, struct thread *td); -static int spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td); -static void spx_usr_close(struct socket *so); -static int spx_connect(struct socket *so, struct sockaddr *nam, - struct thread *td); -static void spx_detach(struct socket *so); -static void spx_pcbdetach(struct ipxpcb *ipxp); -static int spx_usr_disconnect(struct socket *so); -static int spx_listen(struct socket *so, int backlog, struct thread *td); -static int spx_rcvd(struct socket *so, int flags); -static int spx_rcvoob(struct socket *so, struct mbuf *m, int flags); -static int spx_send(struct socket *so, int flags, struct mbuf *m, - struct sockaddr *addr, struct mbuf *control, - struct thread *td); -static int spx_shutdown(struct socket *so); -static int spx_sp_attach(struct socket *so, int proto, struct thread *td); - -struct pr_usrreqs spx_usrreqs = { - .pru_abort = spx_usr_abort, - .pru_accept = spx_accept, - .pru_attach = spx_attach, - .pru_bind = spx_bind, - .pru_connect = spx_connect, - .pru_control = ipx_control, - .pru_detach = spx_detach, - .pru_disconnect = spx_usr_disconnect, - .pru_listen = spx_listen, - .pru_peeraddr = ipx_peeraddr, - .pru_rcvd = spx_rcvd, - .pru_rcvoob = spx_rcvoob, - .pru_send = spx_send, - .pru_shutdown = spx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = spx_usr_close, -}; - -struct pr_usrreqs spx_usrreq_sps = { - .pru_abort = spx_usr_abort, - .pru_accept = spx_accept, - .pru_attach = spx_sp_attach, - .pru_bind = spx_bind, - .pru_connect = spx_connect, - .pru_control = ipx_control, - .pru_detach = spx_detach, - .pru_disconnect = spx_usr_disconnect, - .pru_listen = spx_listen, - .pru_peeraddr = ipx_peeraddr, - .pru_rcvd = spx_rcvd, - .pru_rcvoob = spx_rcvoob, - .pru_send = spx_send, - .pru_shutdown = spx_shutdown, - .pru_sockaddr = ipx_sockaddr, - .pru_close = spx_usr_close, -}; - static __inline void spx_insque(struct spx_q *element, struct spx_q *head) { @@ -189,8 +101,8 @@ spx_insque(struct spx_q *element, struct spx_q *head) head->si_next = element; element->si_next->si_prev = element; } - -static __inline void + +void spx_remque(struct spx_q *element) { @@ -199,258 +111,12 @@ spx_remque(struct spx_q *element) element->si_prev = NULL; } -void -spx_init(void) -{ - - SPX_LOCK_INIT(); - spx_iss = 1; /* WRONG !! should fish it out of TODR */ -} - -void -spx_input(struct mbuf *m, struct ipxpcb *ipxp) -{ - struct spxpcb *cb; - struct spx *si = mtod(m, struct spx *); - struct socket *so; - struct spx spx_savesi; - int dropsocket = 0; - short ostate = 0; - - spxstat.spxs_rcvtotal++; - KASSERT(ipxp != NULL, ("spx_input: ipxpcb == NULL")); - - /* - * spx_input() assumes that the caller will hold both the pcb list - * lock and also the ipxp lock. spx_input() will release both before - * returning, and may in fact trade in the ipxp lock for another pcb - * lock following sonewconn(). - */ - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_input: cb == NULL")); - - if (ipxp->ipxp_flags & IPXP_DROPPED) - goto drop; - - if (m->m_len < sizeof(*si)) { - if ((m = m_pullup(m, sizeof(*si))) == NULL) { - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - spxstat.spxs_rcvshort++; - return; - } - si = mtod(m, struct spx *); - } - si->si_seq = ntohs(si->si_seq); - si->si_ack = ntohs(si->si_ack); - si->si_alo = ntohs(si->si_alo); - - so = ipxp->ipxp_socket; - KASSERT(so != NULL, ("spx_input: so == NULL")); - - if (so->so_options & SO_DEBUG || traceallspxs) { - ostate = cb->s_state; - spx_savesi = *si; - } - if (so->so_options & SO_ACCEPTCONN) { - struct spxpcb *ocb = cb; - - so = sonewconn(so, 0); - if (so == NULL) - goto drop; - - /* - * This is ugly, but .... - * - * Mark socket as temporary until we're committed to keeping - * it. The code at ``drop'' and ``dropwithreset'' check the - * flag dropsocket to see if the temporary socket created - * here should be discarded. We mark the socket as - * discardable until we're committed to it below in - * TCPS_LISTEN. - * - * XXXRW: In the new world order of real kernel parallelism, - * temporarily allocating the socket when we're "not sure" - * seems like a bad idea, as we might race to remove it if - * the listen socket is closed...? - * - * We drop the lock of the listen socket ipxp, and acquire - * the lock of the new socket ippx. - */ - dropsocket++; - IPX_UNLOCK(ipxp); - ipxp = (struct ipxpcb *)so->so_pcb; - IPX_LOCK(ipxp); - ipxp->ipxp_laddr = si->si_dna; - cb = ipxtospxpcb(ipxp); - cb->s_mtu = ocb->s_mtu; /* preserve sockopts */ - cb->s_flags = ocb->s_flags; /* preserve sockopts */ - cb->s_flags2 = ocb->s_flags2; /* preserve sockopts */ - cb->s_state = TCPS_LISTEN; - } - IPX_LOCK_ASSERT(ipxp); - - /* - * Packet received on connection. Reset idle time and keep-alive - * timer. - */ - cb->s_idle = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - - switch (cb->s_state) { - case TCPS_LISTEN:{ - struct sockaddr_ipx *sipx, ssipx; - struct ipx_addr laddr; - - /* - * If somebody here was carying on a conversation and went - * away, and his pen pal thinks he can still talk, we get the - * misdirected packet. - */ - if (spx_hardnosed && (si->si_did != 0 || si->si_seq != 0)) { - spx_istat.gonawy++; - goto dropwithreset; - } - sipx = &ssipx; - bzero(sipx, sizeof *sipx); - sipx->sipx_len = sizeof(*sipx); - sipx->sipx_family = AF_IPX; - sipx->sipx_addr = si->si_sna; - laddr = ipxp->ipxp_laddr; - if (ipx_nullhost(laddr)) - ipxp->ipxp_laddr = si->si_dna; - if (ipx_pcbconnect(ipxp, (struct sockaddr *)sipx, &thread0)) { - ipxp->ipxp_laddr = laddr; - spx_istat.noconn++; - goto drop; - } - spx_template(cb); - dropsocket = 0; /* committed to socket */ - cb->s_did = si->si_sid; - cb->s_rack = si->si_ack; - cb->s_ralo = si->si_alo; -#define THREEWAYSHAKE -#ifdef THREEWAYSHAKE - cb->s_state = TCPS_SYN_RECEIVED; - cb->s_force = 1 + SPXT_KEEP; - spxstat.spxs_accepts++; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - } - break; - - case TCPS_SYN_RECEIVED: { - /* - * This state means that we have heard a response to our - * acceptance of their connection. It is probably logically - * unnecessary in this implementation. - */ - if (si->si_did != cb->s_sid) { - spx_istat.wrncon++; - goto drop; - } -#endif - ipxp->ipxp_fport = si->si_sport; - cb->s_timer[SPXT_REXMT] = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - soisconnected(so); - cb->s_state = TCPS_ESTABLISHED; - spxstat.spxs_accepts++; - } - break; - - case TCPS_SYN_SENT: - /* - * This state means that we have gotten a response to our - * attempt to establish a connection. We fill in the data - * from the other side, telling us which port to respond to, - * instead of the well-known one we might have sent to in the - * first place. We also require that this is a response to - * our connection id. - */ - if (si->si_did != cb->s_sid) { - spx_istat.notme++; - goto drop; - } - spxstat.spxs_connects++; - cb->s_did = si->si_sid; - cb->s_rack = si->si_ack; - cb->s_ralo = si->si_alo; - cb->s_dport = ipxp->ipxp_fport = si->si_sport; - cb->s_timer[SPXT_REXMT] = 0; - cb->s_flags |= SF_ACKNOW; - soisconnected(so); - cb->s_state = TCPS_ESTABLISHED; - - /* - * Use roundtrip time of connection request for initial rtt. - */ - if (cb->s_rtt) { - cb->s_srtt = cb->s_rtt << 3; - cb->s_rttvar = cb->s_rtt << 1; - SPXT_RANGESET(cb->s_rxtcur, - ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - cb->s_rtt = 0; - } - } - - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_INPUT, (u_char)ostate, cb, &spx_savesi, 0); - - m->m_len -= sizeof(struct ipx); - m->m_pkthdr.len -= sizeof(struct ipx); - m->m_data += sizeof(struct ipx); - - if (spx_reass(cb, si)) - m_freem(m); - if (cb->s_force || (cb->s_flags & (SF_ACKNOW|SF_WIN|SF_RXT))) - spx_output(cb, NULL); - cb->s_flags &= ~(SF_WIN|SF_RXT); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return; - -dropwithreset: - IPX_LOCK_ASSERT(ipxp); - if (cb == NULL || (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || - traceallspxs)) - spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); - IPX_UNLOCK(ipxp); - if (dropsocket) { - struct socket *head; - ACCEPT_LOCK(); - KASSERT((so->so_qstate & SQ_INCOMP) != 0, - ("spx_input: nascent socket not SQ_INCOMP on soabort()")); - head = so->so_head; - TAILQ_REMOVE(&head->so_incomp, so, so_list); - head->so_incqlen--; - so->so_qstate &= ~SQ_INCOMP; - so->so_head = NULL; - ACCEPT_UNLOCK(); - soabort(so); - } - IPX_LIST_UNLOCK(); - m_freem(m); - return; - -drop: - IPX_LOCK_ASSERT(ipxp); - if (cb->s_ipxpcb->ipxp_socket->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_DROP, (u_char)ostate, cb, &spx_savesi, 0); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - m_freem(m); -} - /* * This is structurally similar to the tcp reassembly routine but its * function is somewhat different: it merely queues packets up, and * suppresses duplicates. */ -static int +int spx_reass(struct spxpcb *cb, struct spx *si) { struct spx_q *q; @@ -758,1375 +424,3 @@ spx_reass(struct spxpcb *cb, struct spx *si) SOCKBUF_UNLOCK(&so->so_rcv); return (0); } - -void -spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy) -{ - - /* Currently, nothing. */ -} - -static int -spx_output(struct spxpcb *cb, struct mbuf *m0) -{ - struct socket *so = cb->s_ipxpcb->ipxp_socket; - struct mbuf *m; - struct spx *si = NULL; - struct sockbuf *sb = &so->so_snd; - int len = 0, win, rcv_win; - short span, off, recordp = 0; - u_short alo; - int error = 0, sendalot; -#ifdef notdef - int idle; -#endif - struct mbuf *mprev; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (m0 != NULL) { - int mtu = cb->s_mtu; - int datalen; - - /* - * Make sure that packet isn't too big. - */ - for (m = m0; m != NULL; m = m->m_next) { - mprev = m; - len += m->m_len; - if (m->m_flags & M_EOR) - recordp = 1; - } - datalen = (cb->s_flags & SF_HO) ? - len - sizeof(struct spxhdr) : len; - if (datalen > mtu) { - if (cb->s_flags & SF_PI) { - m_freem(m0); - return (EMSGSIZE); - } else { - int oldEM = cb->s_cc & SPX_EM; - - cb->s_cc &= ~SPX_EM; - while (len > mtu) { - m = m_copym(m0, 0, mtu, M_DONTWAIT); - if (m == NULL) { - cb->s_cc |= oldEM; - m_freem(m0); - return (ENOBUFS); - } - if (cb->s_flags & SF_NEWCALL) { - struct mbuf *mm = m; - spx_newchecks[7]++; - while (mm != NULL) { - mm->m_flags &= ~M_EOR; - mm = mm->m_next; - } - } - error = spx_output(cb, m); - if (error) { - cb->s_cc |= oldEM; - m_freem(m0); - return (error); - } - m_adj(m0, mtu); - len -= mtu; - } - cb->s_cc |= oldEM; - } - } - - /* - * Force length even, by adding a "garbage byte" if - * necessary. - */ - if (len & 1) { - m = mprev; - if (M_TRAILINGSPACE(m) >= 1) - m->m_len++; - else { - struct mbuf *m1 = m_get(M_DONTWAIT, MT_DATA); - - if (m1 == NULL) { - m_freem(m0); - return (ENOBUFS); - } - m1->m_len = 1; - *(mtod(m1, u_char *)) = 0; - m->m_next = m1; - } - } - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(m0); - return (ENOBUFS); - } - - /* - * Fill in mbuf with extended SP header and addresses and - * length put into network format. - */ - MH_ALIGN(m, sizeof(struct spx)); - m->m_len = sizeof(struct spx); - m->m_next = m0; - si = mtod(m, struct spx *); - si->si_i = *cb->s_ipx; - si->si_s = cb->s_shdr; - if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) { - struct spxhdr *sh; - if (m0->m_len < sizeof(*sh)) { - if((m0 = m_pullup(m0, sizeof(*sh))) == NULL) { - m_free(m); - m_freem(m0); - return (EINVAL); - } - m->m_next = m0; - } - sh = mtod(m0, struct spxhdr *); - si->si_dt = sh->spx_dt; - si->si_cc |= sh->spx_cc & SPX_EM; - m0->m_len -= sizeof(*sh); - m0->m_data += sizeof(*sh); - len -= sizeof(*sh); - } - len += sizeof(*si); - if ((cb->s_flags2 & SF_NEWCALL) && recordp) { - si->si_cc |= SPX_EM; - spx_newchecks[8]++; - } - if (cb->s_oobflags & SF_SOOB) { - /* - * Per jqj@cornell: Make sure OB packets convey - * exactly 1 byte. If the packet is 1 byte or - * larger, we have already guaranted there to be at - * least one garbage byte for the checksum, and extra - * bytes shouldn't hurt! - */ - if (len > sizeof(*si)) { - si->si_cc |= SPX_OB; - len = (1 + sizeof(*si)); - } - } - si->si_len = htons((u_short)len); - m->m_pkthdr.len = ((len - 1) | 1) + 1; - - /* - * Queue stuff up for output. - */ - sbappendrecord(sb, m); - cb->s_seq++; - } -#ifdef notdef - idle = (cb->s_smax == (cb->s_rack - 1)); -#endif -again: - sendalot = 0; - off = cb->s_snxt - cb->s_rack; - win = min(cb->s_swnd, (cb->s_cwnd / CUNIT)); - - /* - * If in persist timeout with window of 0, send a probe. Otherwise, - * if window is small but non-zero and timer expired, send what we - * can and go into transmit state. - */ - if (cb->s_force == 1 + SPXT_PERSIST) { - if (win != 0) { - cb->s_timer[SPXT_PERSIST] = 0; - cb->s_rxtshift = 0; - } - } - span = cb->s_seq - cb->s_rack; - len = min(span, win) - off; - - if (len < 0) { - /* - * Window shrank after we went into it. If window shrank to - * 0, cancel pending restransmission and pull s_snxt back to - * (closed) window. We will enter persist state below. If - * the widndow didn't close completely, just wait for an ACK. - */ - len = 0; - if (win == 0) { - cb->s_timer[SPXT_REXMT] = 0; - cb->s_snxt = cb->s_rack; - } - } - if (len > 1) - sendalot = 1; - rcv_win = sbspace(&so->so_rcv); - - /* - * Send if we owe peer an ACK. - */ - if (cb->s_oobflags & SF_SOOB) { - /* - * Must transmit this out of band packet. - */ - cb->s_oobflags &= ~ SF_SOOB; - sendalot = 1; - spxstat.spxs_sndurg++; - goto found; - } - if (cb->s_flags & SF_ACKNOW) - goto send; - if (cb->s_state < TCPS_ESTABLISHED) - goto send; - - /* - * Silly window can't happen in spx. Code from TCP deleted. - */ - if (len) - goto send; - - /* - * Compare available window to amount of window known to peer (as - * advertised window less next expected input.) If the difference is - * at least two packets or at least 35% of the mximum possible - * window, then want to send a window update to peer. - */ - if (rcv_win > 0) { - u_short delta = 1 + cb->s_alo - cb->s_ack; - int adv = rcv_win - (delta * cb->s_mtu); - - if ((so->so_rcv.sb_cc == 0 && adv >= (2 * cb->s_mtu)) || - (100 * adv / so->so_rcv.sb_hiwat >= 35)) { - spxstat.spxs_sndwinup++; - cb->s_flags |= SF_ACKNOW; - goto send; - } - - } - - /* - * Many comments from tcp_output.c are appropriate here including ... - * If send window is too small, there is data to transmit, and no - * retransmit or persist is pending, then go to persist state. If - * nothing happens soon, send when timer expires: if window is - * non-zero, transmit what we can, otherwise send a probe. - */ - if (so->so_snd.sb_cc && cb->s_timer[SPXT_REXMT] == 0 && - cb->s_timer[SPXT_PERSIST] == 0) { - cb->s_rxtshift = 0; - spx_setpersist(cb); - } - - /* - * No reason to send a packet, just return. - */ - cb->s_outx = 1; - return (0); - -send: - /* - * Find requested packet. - */ - si = 0; - if (len > 0) { - cb->s_want = cb->s_snxt; - for (m = sb->sb_mb; m != NULL; m = m->m_act) { - si = mtod(m, struct spx *); - if (SSEQ_LEQ(cb->s_snxt, si->si_seq)) - break; - } - found: - if (si != NULL) { - if (si->si_seq == cb->s_snxt) - cb->s_snxt++; - else - spxstat.spxs_sndvoid++, si = 0; - } - } - - /* - * Update window. - */ - if (rcv_win < 0) - rcv_win = 0; - alo = cb->s_ack - 1 + (rcv_win / ((short)cb->s_mtu)); - if (SSEQ_LT(alo, cb->s_alo)) - alo = cb->s_alo; - - if (si != NULL) { - /* - * Must make a copy of this packet for ipx_output to monkey - * with. - */ - m = m_copy(dtom(si), 0, (int)M_COPYALL); - if (m == NULL) - return (ENOBUFS); - si = mtod(m, struct spx *); - if (SSEQ_LT(si->si_seq, cb->s_smax)) - spxstat.spxs_sndrexmitpack++; - else - spxstat.spxs_sndpack++; - } else if (cb->s_force || cb->s_flags & SF_ACKNOW) { - /* - * Must send an acknowledgement or a probe. - */ - if (cb->s_force) - spxstat.spxs_sndprobe++; - if (cb->s_flags & SF_ACKNOW) - spxstat.spxs_sndacks++; - m = m_gethdr(M_DONTWAIT, MT_DATA); - if (m == NULL) - return (ENOBUFS); - - /* - * Fill in mbuf with extended SP header and addresses and - * length put into network format. - */ - MH_ALIGN(m, sizeof(struct spx)); - m->m_len = sizeof(*si); - m->m_pkthdr.len = sizeof(*si); - si = mtod(m, struct spx *); - si->si_i = *cb->s_ipx; - si->si_s = cb->s_shdr; - si->si_seq = cb->s_smax + 1; - si->si_len = htons(sizeof(*si)); - si->si_cc |= SPX_SP; - } else { - cb->s_outx = 3; - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); - return (0); - } - - /* - * Stuff checksum and output datagram. - */ - if ((si->si_cc & SPX_SP) == 0) { - if (cb->s_force != (1 + SPXT_PERSIST) || - cb->s_timer[SPXT_PERSIST] == 0) { - /* - * If this is a new packet and we are not currently - * timing anything, time this one. - */ - if (SSEQ_LT(cb->s_smax, si->si_seq)) { - cb->s_smax = si->si_seq; - if (cb->s_rtt == 0) { - spxstat.spxs_segstimed++; - cb->s_rtseq = si->si_seq; - cb->s_rtt = 1; - } - } - - /* - * Set rexmt timer if not currently set, initial - * value for retransmit timer is smoothed round-trip - * time + 2 * round-trip time variance. Initialize - * shift counter which is used for backoff of - * retransmit time. - */ - if (cb->s_timer[SPXT_REXMT] == 0 && - cb->s_snxt != cb->s_rack) { - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - if (cb->s_timer[SPXT_PERSIST]) { - cb->s_timer[SPXT_PERSIST] = 0; - cb->s_rxtshift = 0; - } - } - } else if (SSEQ_LT(cb->s_smax, si->si_seq)) - cb->s_smax = si->si_seq; - } else if (cb->s_state < TCPS_ESTABLISHED) { - if (cb->s_rtt == 0) - cb->s_rtt = 1; /* Time initial handshake */ - if (cb->s_timer[SPXT_REXMT] == 0) - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - } - - /* - * Do not request acks when we ack their data packets or when we do a - * gratuitous window update. - */ - if (((si->si_cc & SPX_SP) == 0) || cb->s_force) - si->si_cc |= SPX_SA; - si->si_seq = htons(si->si_seq); - si->si_alo = htons(alo); - si->si_ack = htons(cb->s_ack); - - if (ipxcksum) - si->si_sum = ipx_cksum(m, ntohs(si->si_len)); - else - si->si_sum = 0xffff; - - cb->s_outx = 4; - if (so->so_options & SO_DEBUG || traceallspxs) - spx_trace(SA_OUTPUT, cb->s_state, cb, si, 0); - - if (so->so_options & SO_DONTROUTE) - error = ipx_outputfl(m, NULL, IPX_ROUTETOIF); - else - error = ipx_outputfl(m, &cb->s_ipxpcb->ipxp_route, 0); - if (error) - return (error); - spxstat.spxs_sndtotal++; - - /* - * Data sent (as far as we can tell). If this advertises a larger - * window than any other segment, then remember the size of the - * advertized window. Any pending ACK has now been sent. - */ - cb->s_force = 0; - cb->s_flags &= ~(SF_ACKNOW|SF_DELACK); - if (SSEQ_GT(alo, cb->s_alo)) - cb->s_alo = alo; - if (sendalot) - goto again; - cb->s_outx = 5; - return (0); -} - -static int spx_do_persist_panics = 0; - -static void -spx_setpersist(struct spxpcb *cb) -{ - int t = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (cb->s_timer[SPXT_REXMT] && spx_do_persist_panics) - panic("spx_output REXMT"); - - /* - * Start/restart persistance timer. - */ - SPXT_RANGESET(cb->s_timer[SPXT_PERSIST], - t*spx_backoff[cb->s_rxtshift], - SPXTV_PERSMIN, SPXTV_PERSMAX); - if (cb->s_rxtshift < SPX_MAXRXTSHIFT) - cb->s_rxtshift++; -} - -int -spx_ctloutput(struct socket *so, struct sockopt *sopt) -{ - struct spxhdr spxhdr; - struct ipxpcb *ipxp; - struct spxpcb *cb; - int mask, error; - short soptval; - u_short usoptval; - int optval; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_ctloutput: ipxp == NULL")); - - /* - * This will have to be changed when we do more general stacking of - * protocols. - */ - if (sopt->sopt_level != IPXPROTO_SPX) - return (ipx_ctloutput(so, sopt)); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - IPX_UNLOCK(ipxp); - return (ECONNRESET); - } - - IPX_LOCK(ipxp); - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_ctloutput: cb == NULL")); - - error = 0; - switch (sopt->sopt_dir) { - case SOPT_GET: - switch (sopt->sopt_name) { - case SO_HEADERS_ON_INPUT: - mask = SF_HI; - goto get_flags; - - case SO_HEADERS_ON_OUTPUT: - mask = SF_HO; - get_flags: - soptval = cb->s_flags & mask; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &soptval, - sizeof(soptval)); - break; - - case SO_MTU: - usoptval = cb->s_mtu; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &usoptval, - sizeof(usoptval)); - break; - - case SO_LAST_HEADER: - spxhdr = cb->s_rhdr; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); - break; - - case SO_DEFAULT_HEADERS: - spxhdr = cb->s_shdr; - IPX_UNLOCK(ipxp); - error = sooptcopyout(sopt, &spxhdr, sizeof(spxhdr)); - break; - - default: - IPX_UNLOCK(ipxp); - error = ENOPROTOOPT; - } - break; - - case SOPT_SET: - /* - * XXX Why are these shorts on get and ints on set? That - * doesn't make any sense... - * - * XXXRW: Note, when we re-acquire the ipxp lock, we should - * re-check that it's not dropped. - */ - IPX_UNLOCK(ipxp); - switch (sopt->sopt_name) { - case SO_HEADERS_ON_INPUT: - mask = SF_HI; - goto set_head; - - case SO_HEADERS_ON_OUTPUT: - mask = SF_HO; - set_head: - error = sooptcopyin(sopt, &optval, sizeof optval, - sizeof optval); - if (error) - break; - - IPX_LOCK(ipxp); - if (cb->s_flags & SF_PI) { - if (optval) - cb->s_flags |= mask; - else - cb->s_flags &= ~mask; - } else error = EINVAL; - IPX_UNLOCK(ipxp); - break; - - case SO_MTU: - error = sooptcopyin(sopt, &usoptval, sizeof usoptval, - sizeof usoptval); - if (error) - break; - /* Unlocked write. */ - cb->s_mtu = usoptval; - break; - -#ifdef SF_NEWCALL - case SO_NEWCALL: - error = sooptcopyin(sopt, &optval, sizeof optval, - sizeof optval); - if (error) - break; - IPX_LOCK(ipxp); - if (optval) { - cb->s_flags2 |= SF_NEWCALL; - spx_newchecks[5]++; - } else { - cb->s_flags2 &= ~SF_NEWCALL; - spx_newchecks[6]++; - } - IPX_UNLOCK(ipxp); - break; -#endif - - case SO_DEFAULT_HEADERS: - { - struct spxhdr sp; - - error = sooptcopyin(sopt, &sp, sizeof sp, - sizeof sp); - if (error) - break; - IPX_LOCK(ipxp); - cb->s_dt = sp.spx_dt; - cb->s_cc = sp.spx_cc & SPX_EM; - IPX_UNLOCK(ipxp); - } - break; - - default: - error = ENOPROTOOPT; - } - break; - - default: - panic("spx_ctloutput: bad socket option direction"); - } - return (error); -} - -static void -spx_usr_abort(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_abort: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_abort: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - spx_drop(cb, ECONNABORTED); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * Accept a connection. Essentially all the work is done at higher levels; - * just return the address of the peer, storing through addr. - */ -static int -spx_accept(struct socket *so, struct sockaddr **nam) -{ - struct ipxpcb *ipxp; - struct sockaddr_ipx *sipx, ssipx; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_accept: ipxp == NULL")); - - sipx = &ssipx; - bzero(sipx, sizeof *sipx); - sipx->sipx_len = sizeof *sipx; - sipx->sipx_family = AF_IPX; - IPX_LOCK(ipxp); - sipx->sipx_addr = ipxp->ipxp_faddr; - IPX_UNLOCK(ipxp); - *nam = sodupsockaddr((struct sockaddr *)sipx, M_WAITOK); - return (0); -} - -static int -spx_attach(struct socket *so, int proto, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - struct mbuf *mm; - struct sockbuf *sb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp == NULL, ("spx_attach: ipxp != NULL")); - - if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) { - error = soreserve(so, (u_long) 3072, (u_long) 3072); - if (error) - return (error); - } - - cb = malloc(sizeof *cb, M_PCB, M_NOWAIT | M_ZERO); - if (cb == NULL) - return (ENOBUFS); - mm = m_getclr(M_DONTWAIT, MT_DATA); - if (mm == NULL) { - free(cb, M_PCB); - return (ENOBUFS); - } - - IPX_LIST_LOCK(); - error = ipx_pcballoc(so, &ipxpcb_list, td); - if (error) { - IPX_LIST_UNLOCK(); - m_free(mm); - free(cb, M_PCB); - return (error); - } - ipxp = sotoipxpcb(so); - ipxp->ipxp_flags |= IPXP_SPX; - - cb->s_ipx = mtod(mm, struct ipx *); - cb->s_state = TCPS_LISTEN; - cb->s_smax = -1; - cb->s_swl1 = -1; - cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q; - cb->s_ipxpcb = ipxp; - cb->s_mtu = 576 - sizeof(struct spx); - sb = &so->so_snd; - cb->s_cwnd = sbspace(sb) * CUNIT / cb->s_mtu; - cb->s_ssthresh = cb->s_cwnd; - cb->s_cwmx = sbspace(sb) * CUNIT / (2 * sizeof(struct spx)); - - /* - * Above is recomputed when connecting to account for changed - * buffering or mtu's. - */ - cb->s_rtt = SPXTV_SRTTBASE; - cb->s_rttvar = SPXTV_SRTTDFLT << 2; - SPXT_RANGESET(cb->s_rxtcur, - ((SPXTV_SRTTBASE >> 2) + (SPXTV_SRTTDFLT << 2)) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - ipxp->ipxp_pcb = (caddr_t)cb; - IPX_LIST_UNLOCK(); - return (0); -} - -static void -spx_pcbdetach(struct ipxpcb *ipxp) -{ - struct spxpcb *cb; - struct spx_q *s; - struct mbuf *m; - - IPX_LOCK_ASSERT(ipxp); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL")); - - s = cb->s_q.si_next; - while (s != &(cb->s_q)) { - s = s->si_next; - spx_remque(s); - m = dtom(s); - m_freem(m); - } - m_free(dtom(cb->s_ipx)); - free(cb, M_PCB); - ipxp->ipxp_pcb = NULL; -} - -static int -spx_bind(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_bind: ipxp == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - error = ipx_pcbbind(ipxp, nam, td); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -spx_usr_close(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_close: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_close: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (cb->s_state > TCPS_LISTEN) - spx_disconnect(cb); - else - spx_close(cb); - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * Initiate connection to peer. Enter SYN_SENT state, and mark socket as - * connecting. Start keep-alive timer, setup prototype header, send initial - * system packet requesting connection. - */ -static int -spx_connect(struct socket *so, struct sockaddr *nam, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_connect: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_connect: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto spx_connect_end; - } - if (ipxp->ipxp_lport == 0) { - error = ipx_pcbbind(ipxp, NULL, td); - if (error) - goto spx_connect_end; - } - error = ipx_pcbconnect(ipxp, nam, td); - if (error) - goto spx_connect_end; - soisconnecting(so); - spxstat.spxs_connattempt++; - cb->s_state = TCPS_SYN_SENT; - cb->s_did = 0; - spx_template(cb); - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - cb->s_force = 1 + SPXTV_KEEP; - - /* - * Other party is required to respond to the port I send from, but he - * is not required to answer from where I am sending to, so allow - * wildcarding. Original port I am sending to is still saved in - * cb->s_dport. - */ - ipxp->ipxp_fport = 0; - error = spx_output(cb, NULL); -spx_connect_end: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static void -spx_detach(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - /* - * XXXRW: Should assert appropriately detached. - */ - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_detach: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_detach: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - spx_pcbdetach(ipxp); - ipx_pcbfree(ipxp); - IPX_LIST_UNLOCK(); -} - -/* - * We may decide later to implement connection closing handshaking at the spx - * level optionally. Here is the hook to do it: - */ -static int -spx_usr_disconnect(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_usr_disconnect: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_usr_disconnect: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - spx_disconnect(cb); - error = 0; -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static int -spx_listen(struct socket *so, int backlog, struct thread *td) -{ - int error; - struct ipxpcb *ipxp; - struct spxpcb *cb; - - error = 0; - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_listen: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_listen: cb == NULL")); - - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - SOCK_LOCK(so); - error = solisten_proto_check(so); - if (error == 0 && ipxp->ipxp_lport == 0) - error = ipx_pcbbind(ipxp, NULL, td); - if (error == 0) { - cb->s_state = TCPS_LISTEN; - solisten_proto(so, backlog); - } - SOCK_UNLOCK(so); -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -/* - * After a receive, possibly send acknowledgment updating allocation. - */ -static int -spx_rcvd(struct socket *so, int flags) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_rcvd: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_rcvd: cb == NULL")); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - cb->s_flags |= SF_RVD; - spx_output(cb, NULL); - cb->s_flags &= ~SF_RVD; - error = 0; -out: - IPX_UNLOCK(ipxp); - return (error); -} - -static int -spx_rcvoob(struct socket *so, struct mbuf *m, int flags) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_rcvoob: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_rcvoob: cb == NULL")); - - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - SOCKBUF_LOCK(&so->so_rcv); - if ((cb->s_oobflags & SF_IOOB) || so->so_oobmark || - (so->so_rcv.sb_state & SBS_RCVATMARK)) { - SOCKBUF_UNLOCK(&so->so_rcv); - m->m_len = 1; - *mtod(m, caddr_t) = cb->s_iobc; - error = 0; - goto out; - } - SOCKBUF_UNLOCK(&so->so_rcv); - error = EINVAL; -out: - IPX_UNLOCK(ipxp); - return (error); -} - -static int -spx_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, - struct mbuf *controlp, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_send: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_send: cb == NULL")); - - error = 0; - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = ECONNRESET; - goto spx_send_end; - } - if (flags & PRUS_OOB) { - if (sbspace(&so->so_snd) < -512) { - error = ENOBUFS; - goto spx_send_end; - } - cb->s_oobflags |= SF_SOOB; - } - if (controlp != NULL) { - u_short *p = mtod(controlp, u_short *); - spx_newchecks[2]++; - if ((p[0] == 5) && (p[1] == 1)) { /* XXXX, for testing */ - cb->s_shdr.spx_dt = *(u_char *)(&p[2]); - spx_newchecks[3]++; - } - m_freem(controlp); - } - controlp = NULL; - error = spx_output(cb, m); - m = NULL; -spx_send_end: - IPX_UNLOCK(ipxp); - if (controlp != NULL) - m_freem(controlp); - if (m != NULL) - m_freem(m); - return (error); -} - -static int -spx_shutdown(struct socket *so) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_shutdown: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_shutdown: cb == NULL")); - - socantsendmore(so); - IPX_LIST_LOCK(); - IPX_LOCK(ipxp); - if (ipxp->ipxp_flags & IPXP_DROPPED) { - error = EINVAL; - goto out; - } - spx_usrclosed(cb); - error = 0; -out: - IPX_UNLOCK(ipxp); - IPX_LIST_UNLOCK(); - return (error); -} - -static int -spx_sp_attach(struct socket *so, int proto, struct thread *td) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int error; - - KASSERT(so->so_pcb == NULL, ("spx_sp_attach: so_pcb != NULL")); - - error = spx_attach(so, proto, td); - if (error) - return (error); - - ipxp = sotoipxpcb(so); - KASSERT(ipxp != NULL, ("spx_sp_attach: ipxp == NULL")); - - cb = ipxtospxpcb(ipxp); - KASSERT(cb != NULL, ("spx_sp_attach: cb == NULL")); - - IPX_LOCK(ipxp); - cb->s_flags |= (SF_HI | SF_HO | SF_PI); - IPX_UNLOCK(ipxp); - return (0); -} - -/* - * Create template to be used to send spx packets on a connection. Called - * after host entry created, fills in a skeletal spx header (choosing - * connection id), minimizing the amount of work necessary when the - * connection is used. - */ -static void -spx_template(struct spxpcb *cb) -{ - struct ipxpcb *ipxp = cb->s_ipxpcb; - struct ipx *ipx = cb->s_ipx; - struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd); - - IPX_LOCK_ASSERT(ipxp); - - ipx->ipx_pt = IPXPROTO_SPX; - ipx->ipx_sna = ipxp->ipxp_laddr; - ipx->ipx_dna = ipxp->ipxp_faddr; - SPX_LOCK(); - cb->s_sid = htons(spx_iss); - spx_iss += SPX_ISSINCR/2; - SPX_UNLOCK(); - cb->s_alo = 1; - cb->s_cwnd = (sbspace(sb) * CUNIT) / cb->s_mtu; - - /* - * Try to expand fast to full complement of large packets. - */ - cb->s_ssthresh = cb->s_cwnd; - cb->s_cwmx = (sbspace(sb) * CUNIT) / (2 * sizeof(struct spx)); - - /* - * But allow for lots of little packets as well. - */ - cb->s_cwmx = max(cb->s_cwmx, cb->s_cwnd); -} - -/* - * Close a SPIP control block. Wake up any sleepers. We used to free any - * queued packets and cb->s_ipx here, but now we defer that until the pcb is - * discarded. - */ -void -spx_close(struct spxpcb *cb) -{ - struct ipxpcb *ipxp = cb->s_ipxpcb; - struct socket *so = ipxp->ipxp_socket; - - KASSERT(ipxp != NULL, ("spx_close: ipxp == NULL")); - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(ipxp); - - ipxp->ipxp_flags |= IPXP_DROPPED; - soisdisconnected(so); - spxstat.spxs_closed++; -} - -/* - * Someday we may do level 3 handshaking to close a connection or send a - * xerox style error. For now, just close. cb will always be invalid after - * this call. - */ -static void -spx_usrclosed(struct spxpcb *cb) -{ - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - spx_close(cb); -} - -/* - * cb will always be invalid after this call. - */ -static void -spx_disconnect(struct spxpcb *cb) -{ - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - spx_close(cb); -} - -/* - * Drop connection, reporting the specified error. cb will always be invalid - * after this call. - */ -static void -spx_drop(struct spxpcb *cb, int errno) -{ - struct socket *so = cb->s_ipxpcb->ipxp_socket; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - /* - * Someday, in the xerox world we will generate error protocol - * packets announcing that the socket has gone away. - */ - if (TCPS_HAVERCVDSYN(cb->s_state)) { - spxstat.spxs_drops++; - cb->s_state = TCPS_CLOSED; - /*tcp_output(cb);*/ - } else - spxstat.spxs_conndrops++; - so->so_error = errno; - spx_close(cb); -} - -/* - * Fast timeout routine for processing delayed acks. - */ -void -spx_fasttimo(void) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - - IPX_LIST_LOCK(); - LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { - IPX_LOCK(ipxp); - if (!(ipxp->ipxp_flags & IPXP_SPX) || - (ipxp->ipxp_flags & IPXP_DROPPED)) { - IPX_UNLOCK(ipxp); - continue; - } - cb = ipxtospxpcb(ipxp); - if (cb->s_flags & SF_DELACK) { - cb->s_flags &= ~SF_DELACK; - cb->s_flags |= SF_ACKNOW; - spxstat.spxs_delack++; - spx_output(cb, NULL); - } - IPX_UNLOCK(ipxp); - } - IPX_LIST_UNLOCK(); -} - -/* - * spx protocol timeout routine called every 500 ms. Updates the timers in - * all active pcb's and causes finite state machine actions if timers expire. - */ -void -spx_slowtimo(void) -{ - struct ipxpcb *ipxp; - struct spxpcb *cb; - int i; - - /* - * Search through tcb's and update active timers. Once, timers could - * free ipxp's, but now we do that only when detaching a socket. - */ - IPX_LIST_LOCK(); - LIST_FOREACH(ipxp, &ipxpcb_list, ipxp_list) { - IPX_LOCK(ipxp); - if (!(ipxp->ipxp_flags & IPXP_SPX) || - (ipxp->ipxp_flags & IPXP_DROPPED)) { - IPX_UNLOCK(ipxp); - continue; - } - - cb = (struct spxpcb *)ipxp->ipxp_pcb; - KASSERT(cb != NULL, ("spx_slowtimo: cb == NULL")); - for (i = 0; i < SPXT_NTIMERS; i++) { - if (cb->s_timer[i] && --cb->s_timer[i] == 0) { - spx_timers(cb, i); - if (ipxp->ipxp_flags & IPXP_DROPPED) - break; - } - } - if (!(ipxp->ipxp_flags & IPXP_DROPPED)) { - cb->s_idle++; - if (cb->s_rtt) - cb->s_rtt++; - } - IPX_UNLOCK(ipxp); - } - IPX_LIST_UNLOCK(); - SPX_LOCK(); - spx_iss += SPX_ISSINCR/PR_SLOWHZ; /* increment iss */ - SPX_UNLOCK(); -} - -/* - * SPX timer processing. - */ -static void -spx_timers(struct spxpcb *cb, int timer) -{ - long rexmt; - int win; - - IPX_LIST_LOCK_ASSERT(); - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - cb->s_force = 1 + timer; - switch (timer) { - case SPXT_2MSL: - /* - * 2 MSL timeout in shutdown went off. TCP deletes - * connection control block. - */ - printf("spx: SPXT_2MSL went off for no reason\n"); - cb->s_timer[timer] = 0; - break; - - case SPXT_REXMT: - /* - * Retransmission timer went off. Message has not been acked - * within retransmit interval. Back off to a longer - * retransmit interval and retransmit one packet. - */ - if (++cb->s_rxtshift > SPX_MAXRXTSHIFT) { - cb->s_rxtshift = SPX_MAXRXTSHIFT; - spxstat.spxs_timeoutdrop++; - spx_drop(cb, ETIMEDOUT); - break; - } - spxstat.spxs_rexmttimeo++; - rexmt = ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1; - rexmt *= spx_backoff[cb->s_rxtshift]; - SPXT_RANGESET(cb->s_rxtcur, rexmt, SPXTV_MIN, SPXTV_REXMTMAX); - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - - /* - * If we have backed off fairly far, our srtt estimate is - * probably bogus. Clobber it so we'll take the next rtt - * measurement as our srtt; move the current srtt into rttvar - * to keep the current retransmit times until then. - */ - if (cb->s_rxtshift > SPX_MAXRXTSHIFT / 4 ) { - cb->s_rttvar += (cb->s_srtt >> 2); - cb->s_srtt = 0; - } - cb->s_snxt = cb->s_rack; - - /* - * If timing a packet, stop the timer. - */ - cb->s_rtt = 0; - - /* - * See very long discussion in tcp_timer.c about congestion - * window and sstrhesh. - */ - win = min(cb->s_swnd, (cb->s_cwnd/CUNIT)) / 2; - if (win < 2) - win = 2; - cb->s_cwnd = CUNIT; - cb->s_ssthresh = win * CUNIT; - spx_output(cb, NULL); - break; - - case SPXT_PERSIST: - /* - * Persistance timer into zero window. Force a probe to be - * sent. - */ - spxstat.spxs_persisttimeo++; - spx_setpersist(cb); - spx_output(cb, NULL); - break; - - case SPXT_KEEP: - /* - * Keep-alive timer went off; send something or drop - * connection if idle for too long. - */ - spxstat.spxs_keeptimeo++; - if (cb->s_state < TCPS_ESTABLISHED) - goto dropit; - if (cb->s_ipxpcb->ipxp_socket->so_options & SO_KEEPALIVE) { - if (cb->s_idle >= SPXTV_MAXIDLE) - goto dropit; - spxstat.spxs_keepprobe++; - spx_output(cb, NULL); - } else - cb->s_idle = 0; - cb->s_timer[SPXT_KEEP] = SPXTV_KEEP; - break; - - dropit: - spxstat.spxs_keepdrops++; - spx_drop(cb, ETIMEDOUT); - break; - - default: - panic("spx_timers: unknown timer %d", timer); - } -} diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 7bfa88ebc536..8ca3ce480180 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -94,30 +94,21 @@ __FBSDID("$FreeBSD$"); */ static struct mtx spx_mtx; /* Protects only spx_iss. */ static u_short spx_iss; -static u_short spx_newchecks[50]; +u_short spx_newchecks[50]; static int spx_hardnosed; -static int spx_use_delack = 0; static int traceallspxs = 0; -static struct spx_istat spx_istat; -static int spxrexmtthresh = 3; +struct spx_istat spx_istat; #define SPX_LOCK_INIT() mtx_init(&spx_mtx, "spx_mtx", NULL, MTX_DEF) #define SPX_LOCK() mtx_lock(&spx_mtx) #define SPX_UNLOCK() mtx_unlock(&spx_mtx) -/* Following was struct spxstat spxstat; */ -#ifndef spxstat -#define spxstat spx_istat.newstats -#endif - static const int spx_backoff[SPX_MAXRXTSHIFT+1] = { 1, 2, 4, 8, 16, 32, 64, 64, 64, 64, 64, 64, 64 }; static void spx_close(struct spxpcb *cb); static void spx_disconnect(struct spxpcb *cb); static void spx_drop(struct spxpcb *cb, int errno); -static int spx_output(struct spxpcb *cb, struct mbuf *m0); -static int spx_reass(struct spxpcb *cb, struct spx *si); static void spx_setpersist(struct spxpcb *cb); static void spx_template(struct spxpcb *cb); static void spx_timers(struct spxpcb *cb, int timer); @@ -180,25 +171,6 @@ struct pr_usrreqs spx_usrreq_sps = { .pru_close = spx_usr_close, }; -static __inline void -spx_insque(struct spx_q *element, struct spx_q *head) -{ - - element->si_next = head->si_next; - element->si_prev = head; - head->si_next = element; - element->si_next->si_prev = element; -} - -static __inline void -spx_remque(struct spx_q *element) -{ - - element->si_next->si_prev = element->si_prev; - element->si_prev->si_next = element->si_next; - element->si_prev = NULL; -} - void spx_init(void) { @@ -445,328 +417,7 @@ spx_input(struct mbuf *m, struct ipxpcb *ipxp) m_freem(m); } -/* - * This is structurally similar to the tcp reassembly routine but its - * function is somewhat different: it merely queues packets up, and - * suppresses duplicates. - */ -static int -spx_reass(struct spxpcb *cb, struct spx *si) -{ - struct spx_q *q; - struct mbuf *m; - struct socket *so = cb->s_ipxpcb->ipxp_socket; - char packetp = cb->s_flags & SF_HI; - int incr; - char wakeup = 0; - - IPX_LOCK_ASSERT(cb->s_ipxpcb); - - if (si == SI(0)) - goto present; - - /* - * Update our news from them. - */ - if (si->si_cc & SPX_SA) - cb->s_flags |= (spx_use_delack ? SF_DELACK : SF_ACKNOW); - if (SSEQ_GT(si->si_alo, cb->s_ralo)) - cb->s_flags |= SF_WIN; - if (SSEQ_LEQ(si->si_ack, cb->s_rack)) { - if ((si->si_cc & SPX_SP) && cb->s_rack != (cb->s_smax + 1)) { - spxstat.spxs_rcvdupack++; - - /* - * If this is a completely duplicate ack and other - * conditions hold, we assume a packet has been - * dropped and retransmit it exactly as in - * tcp_input(). - */ - if (si->si_ack != cb->s_rack || - si->si_alo != cb->s_ralo) - cb->s_dupacks = 0; - else if (++cb->s_dupacks == spxrexmtthresh) { - u_short onxt = cb->s_snxt; - int cwnd = cb->s_cwnd; - - cb->s_snxt = si->si_ack; - cb->s_cwnd = CUNIT; - cb->s_force = 1 + SPXT_REXMT; - spx_output(cb, NULL); - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - cb->s_rtt = 0; - if (cwnd >= 4 * CUNIT) - cb->s_cwnd = cwnd / 2; - if (SSEQ_GT(onxt, cb->s_snxt)) - cb->s_snxt = onxt; - return (1); - } - } else - cb->s_dupacks = 0; - goto update_window; - } - cb->s_dupacks = 0; - - /* - * If our correspondent acknowledges data we haven't sent TCP would - * drop the packet after acking. We'll be a little more permissive. - */ - if (SSEQ_GT(si->si_ack, (cb->s_smax + 1))) { - spxstat.spxs_rcvacktoomuch++; - si->si_ack = cb->s_smax + 1; - } - spxstat.spxs_rcvackpack++; - - /* - * If transmit timer is running and timed sequence number was acked, - * update smoothed round trip time. See discussion of algorithm in - * tcp_input.c - */ - if (cb->s_rtt && SSEQ_GT(si->si_ack, cb->s_rtseq)) { - spxstat.spxs_rttupdated++; - if (cb->s_srtt != 0) { - short delta; - delta = cb->s_rtt - (cb->s_srtt >> 3); - if ((cb->s_srtt += delta) <= 0) - cb->s_srtt = 1; - if (delta < 0) - delta = -delta; - delta -= (cb->s_rttvar >> 2); - if ((cb->s_rttvar += delta) <= 0) - cb->s_rttvar = 1; - } else { - /* - * No rtt measurement yet. - */ - cb->s_srtt = cb->s_rtt << 3; - cb->s_rttvar = cb->s_rtt << 1; - } - cb->s_rtt = 0; - cb->s_rxtshift = 0; - SPXT_RANGESET(cb->s_rxtcur, - ((cb->s_srtt >> 2) + cb->s_rttvar) >> 1, - SPXTV_MIN, SPXTV_REXMTMAX); - } - - /* - * If all outstanding data is acked, stop retransmit timer and - * remember to restart (more output or persist). If there is more - * data to be acked, restart retransmit timer, using current - * (possibly backed-off) value; - */ - if (si->si_ack == cb->s_smax + 1) { - cb->s_timer[SPXT_REXMT] = 0; - cb->s_flags |= SF_RXT; - } else if (cb->s_timer[SPXT_PERSIST] == 0) - cb->s_timer[SPXT_REXMT] = cb->s_rxtcur; - - /* - * When new data is acked, open the congestion window. If the window - * gives us less than ssthresh packets in flight, open exponentially - * (maxseg at a time). Otherwise open linearly (maxseg^2 / cwnd at a - * time). - */ - incr = CUNIT; - if (cb->s_cwnd > cb->s_ssthresh) - incr = max(incr * incr / cb->s_cwnd, 1); - cb->s_cwnd = min(cb->s_cwnd + incr, cb->s_cwmx); - - /* - * Trim Acked data from output queue. - */ - SOCKBUF_LOCK(&so->so_snd); - while ((m = so->so_snd.sb_mb) != NULL) { - if (SSEQ_LT((mtod(m, struct spx *))->si_seq, si->si_ack)) - sbdroprecord_locked(&so->so_snd); - else - break; - } - sowwakeup_locked(so); - cb->s_rack = si->si_ack; -update_window: - if (SSEQ_LT(cb->s_snxt, cb->s_rack)) - cb->s_snxt = cb->s_rack; - if (SSEQ_LT(cb->s_swl1, si->si_seq) || ((cb->s_swl1 == si->si_seq && - (SSEQ_LT(cb->s_swl2, si->si_ack))) || - (cb->s_swl2 == si->si_ack && SSEQ_LT(cb->s_ralo, si->si_alo)))) { - /* keep track of pure window updates */ - if ((si->si_cc & SPX_SP) && cb->s_swl2 == si->si_ack - && SSEQ_LT(cb->s_ralo, si->si_alo)) { - spxstat.spxs_rcvwinupd++; - spxstat.spxs_rcvdupack--; - } - cb->s_ralo = si->si_alo; - cb->s_swl1 = si->si_seq; - cb->s_swl2 = si->si_ack; - cb->s_swnd = (1 + si->si_alo - si->si_ack); - if (cb->s_swnd > cb->s_smxw) - cb->s_smxw = cb->s_swnd; - cb->s_flags |= SF_WIN; - } - - /* - * If this packet number is higher than that which we have allocated - * refuse it, unless urgent. - */ - if (SSEQ_GT(si->si_seq, cb->s_alo)) { - if (si->si_cc & SPX_SP) { - spxstat.spxs_rcvwinprobe++; - return (1); - } else - spxstat.spxs_rcvpackafterwin++; - if (si->si_cc & SPX_OB) { - if (SSEQ_GT(si->si_seq, cb->s_alo + 60)) - return (1); /* else queue this packet; */ - } else { -#ifdef BROKEN - /* - * XXXRW: This is broken on at least one count: - * spx_close() will free the ipxp and related parts, - * which are then touched by spx_input() after the - * return from spx_reass(). - */ - /*struct socket *so = cb->s_ipxpcb->ipxp_socket; - if (so->so_state && SS_NOFDREF) { - spx_close(cb); - } else - would crash system*/ -#endif - spx_istat.notyet++; - return (1); - } - } - - /* - * If this is a system packet, we don't need to queue it up, and - * won't update acknowledge #. - */ - if (si->si_cc & SPX_SP) - return (1); - - /* - * We have already seen this packet, so drop. - */ - if (SSEQ_LT(si->si_seq, cb->s_ack)) { - spx_istat.bdreas++; - spxstat.spxs_rcvduppack++; - if (si->si_seq == cb->s_ack - 1) - spx_istat.lstdup++; - return (1); - } - - /* - * Loop through all packets queued up to insert in appropriate - * sequence. - */ - for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) { - if (si->si_seq == SI(q)->si_seq) { - spxstat.spxs_rcvduppack++; - return (1); - } - if (SSEQ_LT(si->si_seq, SI(q)->si_seq)) { - spxstat.spxs_rcvoopack++; - break; - } - } - spx_insque((struct spx_q *)si, q->si_prev); - - /* - * If this packet is urgent, inform process - */ - if (si->si_cc & SPX_OB) { - cb->s_iobc = ((char *)si)[1 + sizeof(*si)]; - sohasoutofband(so); - cb->s_oobflags |= SF_IOOB; - } -present: -#define SPINC sizeof(struct spxhdr) - SOCKBUF_LOCK(&so->so_rcv); - - /* - * Loop through all packets queued up to update acknowledge number, - * and present all acknowledged data to user; if in packet interface - * mode, show packet headers. - */ - for (q = cb->s_q.si_next; q != &cb->s_q; q = q->si_next) { - if (SI(q)->si_seq == cb->s_ack) { - cb->s_ack++; - m = dtom(q); - if (SI(q)->si_cc & SPX_OB) { - cb->s_oobflags &= ~SF_IOOB; - if (so->so_rcv.sb_cc) - so->so_oobmark = so->so_rcv.sb_cc; - else - so->so_rcv.sb_state |= SBS_RCVATMARK; - } - q = q->si_prev; - spx_remque(q->si_next); - wakeup = 1; - spxstat.spxs_rcvpack++; -#ifdef SF_NEWCALL - if (cb->s_flags2 & SF_NEWCALL) { - struct spxhdr *sp = mtod(m, struct spxhdr *); - u_char dt = sp->spx_dt; - spx_newchecks[4]++; - if (dt != cb->s_rhdr.spx_dt) { - struct mbuf *mm = - m_getclr(M_DONTWAIT, MT_CONTROL); - spx_newchecks[0]++; - if (mm != NULL) { - u_short *s = - mtod(mm, u_short *); - cb->s_rhdr.spx_dt = dt; - mm->m_len = 5; /*XXX*/ - s[0] = 5; - s[1] = 1; - *(u_char *)(&s[2]) = dt; - sbappend_locked(&so->so_rcv, mm); - } - } - if (sp->spx_cc & SPX_OB) { - MCHTYPE(m, MT_OOBDATA); - spx_newchecks[1]++; - so->so_oobmark = 0; - so->so_rcv.sb_state &= ~SBS_RCVATMARK; - } - if (packetp == 0) { - m->m_data += SPINC; - m->m_len -= SPINC; - m->m_pkthdr.len -= SPINC; - } - if ((sp->spx_cc & SPX_EM) || packetp) { - sbappendrecord_locked(&so->so_rcv, m); - spx_newchecks[9]++; - } else - sbappend_locked(&so->so_rcv, m); - } else -#endif - if (packetp) - sbappendrecord_locked(&so->so_rcv, m); - else { - cb->s_rhdr = *mtod(m, struct spxhdr *); - m->m_data += SPINC; - m->m_len -= SPINC; - m->m_pkthdr.len -= SPINC; - sbappend_locked(&so->so_rcv, m); - } - } else - break; - } - if (wakeup) - sorwakeup_locked(so); - else - SOCKBUF_UNLOCK(&so->so_rcv); - return (0); -} - -void -spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy) -{ - - /* Currently, nothing. */ -} - -static int +int spx_output(struct spxpcb *cb, struct mbuf *m0) { struct socket *so = cb->s_ipxpcb->ipxp_socket; diff --git a/sys/netipx/spx_var.h b/sys/netipx/spx_var.h index 47be027041e7..be6714e953f5 100644 --- a/sys/netipx/spx_var.h +++ b/sys/netipx/spx_var.h @@ -143,4 +143,17 @@ struct spx_istat { #define SSEQ_GT(a,b) (((short)((a)-(b))) > 0) #define SSEQ_GEQ(a,b) (((short)((a)-(b))) >= 0) +#ifdef _KERNEL +/* Following was struct spxstat spxstat; */ +#ifndef spxstat +#define spxstat spx_istat.newstats +#endif +extern struct spx_istat spx_istat; +extern u_short spx_newchecks[50]; + +int spx_output(struct spxpcb *cb, struct mbuf *m0); +int spx_reass(struct spxpcb *cb, struct spx *si); +void spx_remque(struct spx_q *element); +#endif + #endif /* !_NETIPX_SPX_VAR_H_ */ From da3ea50434a4c0841e721c2869e58c1511b28354 Mon Sep 17 00:00:00 2001 From: Maxim Konovalov Date: Mon, 25 May 2009 09:52:58 +0000 Subject: [PATCH 509/544] o Fix typo in the example. PR: docs/134930 Submitted by: Alex Keda MFC after: 1 week --- sbin/geom/class/journal/gjournal.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/geom/class/journal/gjournal.8 b/sbin/geom/class/journal/gjournal.8 index 319b90244076..0aad6ae31cdb 100644 --- a/sbin/geom/class/journal/gjournal.8 +++ b/sbin/geom/class/journal/gjournal.8 @@ -220,7 +220,7 @@ allows this (i.e., if the last sector is not already used by the file system): .Bd -literal -offset indent umount /dev/da0s1d gjournal label da0s1d da0s1e && \e - tunefs -J enable -n disable da01sd.journal && \e + tunefs -J enable -n disable da0s1d.journal && \e mount -o async /dev/da0s1d.journal /mnt || \e mount /dev/da0s1d /mnt .Ed From d4299409327fb3b307eeaf26fdce1ead7583e05a Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 09:57:18 +0000 Subject: [PATCH 510/544] Prefer m_nextpkt to m_act when iterating mbuf queues. MFC after: 1 month --- sys/netipx/spx_usrreq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 8ca3ce480180..1b084a1ac276 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -673,7 +673,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) si = 0; if (len > 0) { cb->s_want = cb->s_snxt; - for (m = sb->sb_mb; m != NULL; m = m->m_act) { + for (m = sb->sb_mb; m != NULL; m = m->m_nextpkt) { si = mtod(m, struct spx *); if (SSEQ_LEQ(cb->s_snxt, si->si_seq)) break; From 040eca7b0448d76144600bb716f46ac83d2ea2b8 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 10:25:41 +0000 Subject: [PATCH 511/544] Pull SPX reassembly queue init and flush into spx_reass.c. MFC after: 1 month --- sys/netipx/spx_reass.c | 30 +++++++++++++++++++++++++++++- sys/netipx/spx_usrreq.c | 14 +++----------- sys/netipx/spx_var.h | 2 ++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/sys/netipx/spx_reass.c b/sys/netipx/spx_reass.c index 2e69f5e0343e..05961053fab5 100644 --- a/sys/netipx/spx_reass.c +++ b/sys/netipx/spx_reass.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. - * Copyright (c) 2004-2006 Robert N. M. Watson + * Copyright (c) 2004-2009 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -111,6 +111,34 @@ spx_remque(struct spx_q *element) element->si_prev = NULL; } +/* + * Flesh pending queued segments on SPX close. + */ +void +spx_reass_flush(struct spxpcb *cb) +{ + struct spx_q *s; + struct mbuf *m; + + s = cb->s_q.si_next; + while (s != &(cb->s_q)) { + s = s->si_next; + spx_remque(s); + m = dtom(s); + m_freem(m); + } +} + +/* + * Initialize SPX segment reassembly queue on SPX socket open. + */ +void +spx_reass_init(struct spxpcb *cb) +{ + + cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q; +} + /* * This is structurally similar to the tcp reassembly routine but its * function is somewhat different: it merely queues packets up, and diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 1b084a1ac276..67612f94b3fa 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -1,7 +1,7 @@ /*- * Copyright (c) 1984, 1985, 1986, 1987, 1993 * The Regents of the University of California. - * Copyright (c) 2004-2006 Robert N. M. Watson + * Copyright (c) 2004-2009 Robert N. M. Watson * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -1091,7 +1091,7 @@ spx_attach(struct socket *so, int proto, struct thread *td) cb->s_state = TCPS_LISTEN; cb->s_smax = -1; cb->s_swl1 = -1; - cb->s_q.si_next = cb->s_q.si_prev = &cb->s_q; + spx_reass_init(cb); cb->s_ipxpcb = ipxp; cb->s_mtu = 576 - sizeof(struct spx); sb = &so->so_snd; @@ -1117,21 +1117,13 @@ static void spx_pcbdetach(struct ipxpcb *ipxp) { struct spxpcb *cb; - struct spx_q *s; - struct mbuf *m; IPX_LOCK_ASSERT(ipxp); cb = ipxtospxpcb(ipxp); KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL")); - s = cb->s_q.si_next; - while (s != &(cb->s_q)) { - s = s->si_next; - spx_remque(s); - m = dtom(s); - m_freem(m); - } + spx_reass_flush(cb); m_free(dtom(cb->s_ipx)); free(cb, M_PCB); ipxp->ipxp_pcb = NULL; diff --git a/sys/netipx/spx_var.h b/sys/netipx/spx_var.h index be6714e953f5..cf599fac9b9c 100644 --- a/sys/netipx/spx_var.h +++ b/sys/netipx/spx_var.h @@ -153,6 +153,8 @@ extern u_short spx_newchecks[50]; int spx_output(struct spxpcb *cb, struct mbuf *m0); int spx_reass(struct spxpcb *cb, struct spx *si); +void spx_reass_flush(struct spxpcb *cb); +void spx_reass_init(struct spxpcb *cb); void spx_remque(struct spx_q *element); #endif From 905220d58e98031c4b9ff3aa41a680fede046876 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 11:50:58 +0000 Subject: [PATCH 512/544] Rather than store a skeleton IPX header in an mbuf hung off the SPX PCB, simply embed it in the PCB, avoiding additional memory overhead, memory allocation overhead, and removing one of the few remaining uses of dtom() in the network stack. Restore misplaced spx_ctlinput() from an earlier commit. MFC after: 1 month --- sys/netipx/spx.h | 4 ++-- sys/netipx/spx_usrreq.c | 23 +++++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/sys/netipx/spx.h b/sys/netipx/spx.h index 044b6d4e8df5..2f4d21088312 100644 --- a/sys/netipx/spx.h +++ b/sys/netipx/spx.h @@ -129,7 +129,7 @@ struct spxpcb { u_short s_mtu; /* Max packet size for this stream */ /* use sequence fields in headers to store sequence numbers for this connection */ - struct ipx *s_ipx; + struct ipx s_ipx; struct spxhdr s_shdr; /* prototype header to transmit */ #define s_cc s_shdr.spx_cc /* connection control (for EM bit) */ #define s_dt s_shdr.spx_dt /* datastream type */ @@ -138,7 +138,7 @@ struct spxpcb { #define s_seq s_shdr.spx_seq /* sequence number */ #define s_ack s_shdr.spx_ack /* acknowledge number */ #define s_alo s_shdr.spx_alo /* allocation number */ -#define s_dport s_ipx->ipx_dna.x_port /* where we are sending */ +#define s_dport s_ipx.ipx_dna.x_port /* where we are sending */ struct spxhdr s_rhdr; /* last received header (in effect!)*/ u_short s_rack; /* their acknowledge number */ u_short s_ralo; /* their allocation number */ diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 67612f94b3fa..8717a2d131c7 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -417,6 +417,13 @@ spx_input(struct mbuf *m, struct ipxpcb *ipxp) m_freem(m); } +void +spx_ctlinput(int cmd, struct sockaddr *arg_as_sa, void *dummy) +{ + + /* Currently, nothing. */ +} + int spx_output(struct spxpcb *cb, struct mbuf *m0) { @@ -520,7 +527,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) m->m_len = sizeof(struct spx); m->m_next = m0; si = mtod(m, struct spx *); - si->si_i = *cb->s_ipx; + si->si_i = cb->s_ipx; si->si_s = cb->s_shdr; if ((cb->s_flags & SF_PI) && (cb->s_flags & SF_HO)) { struct spxhdr *sh; @@ -729,7 +736,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) m->m_len = sizeof(*si); m->m_pkthdr.len = sizeof(*si); si = mtod(m, struct spx *); - si->si_i = *cb->s_ipx; + si->si_i = cb->s_ipx; si->si_s = cb->s_shdr; si->si_seq = cb->s_smax + 1; si->si_len = htons(sizeof(*si)); @@ -1087,7 +1094,6 @@ spx_attach(struct socket *so, int proto, struct thread *td) ipxp = sotoipxpcb(so); ipxp->ipxp_flags |= IPXP_SPX; - cb->s_ipx = mtod(mm, struct ipx *); cb->s_state = TCPS_LISTEN; cb->s_smax = -1; cb->s_swl1 = -1; @@ -1124,7 +1130,6 @@ spx_pcbdetach(struct ipxpcb *ipxp) KASSERT(cb != NULL, ("spx_pcbdetach: cb == NULL")); spx_reass_flush(cb); - m_free(dtom(cb->s_ipx)); free(cb, M_PCB); ipxp->ipxp_pcb = NULL; } @@ -1490,14 +1495,13 @@ static void spx_template(struct spxpcb *cb) { struct ipxpcb *ipxp = cb->s_ipxpcb; - struct ipx *ipx = cb->s_ipx; struct sockbuf *sb = &(ipxp->ipxp_socket->so_snd); IPX_LOCK_ASSERT(ipxp); - ipx->ipx_pt = IPXPROTO_SPX; - ipx->ipx_sna = ipxp->ipxp_laddr; - ipx->ipx_dna = ipxp->ipxp_faddr; + cb->s_ipx.ipx_pt = IPXPROTO_SPX; + cb->s_ipx.ipx_sna = ipxp->ipxp_laddr; + cb->s_ipx.ipx_dna = ipxp->ipxp_faddr; SPX_LOCK(); cb->s_sid = htons(spx_iss); spx_iss += SPX_ISSINCR/2; @@ -1519,8 +1523,7 @@ spx_template(struct spxpcb *cb) /* * Close a SPIP control block. Wake up any sleepers. We used to free any - * queued packets and cb->s_ipx here, but now we defer that until the pcb is - * discarded. + * queued packets, but now we defer that until the pcb is discarded. */ void spx_close(struct spxpcb *cb) From fc2c3e84bc70d830f22d1779b8e77bd5b78a5c87 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 11:52:33 +0000 Subject: [PATCH 513/544] Prefer NULL to 0 for pointer assignments. MFC after: 1 month --- sys/netipx/spx_usrreq.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 8717a2d131c7..10f84c1726b9 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -677,7 +677,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) /* * Find requested packet. */ - si = 0; + si = NULL; if (len > 0) { cb->s_want = cb->s_snxt; for (m = sb->sb_mb; m != NULL; m = m->m_nextpkt) { @@ -690,7 +690,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) if (si->si_seq == cb->s_snxt) cb->s_snxt++; else - spxstat.spxs_sndvoid++, si = 0; + spxstat.spxs_sndvoid++, si = NULL; } } From e098e5f03284d903f8c22c2eae2b76fe8e16bd31 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 13:32:54 +0000 Subject: [PATCH 514/544] Eliminate use of dtom() in spx_output() by fixing up tracking of the containing mbuf for 'si' in local variable 'm'. MFC after: 1 month --- sys/netipx/spx_usrreq.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 10f84c1726b9..3e8e81d492f7 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -428,7 +428,7 @@ int spx_output(struct spxpcb *cb, struct mbuf *m0) { struct socket *so = cb->s_ipxpcb->ipxp_socket; - struct mbuf *m; + struct mbuf *m = NULL; struct spx *si = NULL; struct sockbuf *sb = &so->so_snd; int len = 0, win, rcv_win; @@ -678,6 +678,7 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) * Find requested packet. */ si = NULL; + m = NULL; if (len > 0) { cb->s_want = cb->s_snxt; for (m = sb->sb_mb; m != NULL; m = m->m_nextpkt) { @@ -687,10 +688,12 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) } found: if (si != NULL) { - if (si->si_seq == cb->s_snxt) - cb->s_snxt++; - else - spxstat.spxs_sndvoid++, si = NULL; + if (si->si_seq != cb->s_snxt) { + spxstat.spxs_sndvoid++; + si = NULL; + m = NULL; + } else + cb->s_snxt++; } } @@ -703,12 +706,12 @@ spx_output(struct spxpcb *cb, struct mbuf *m0) if (SSEQ_LT(alo, cb->s_alo)) alo = cb->s_alo; - if (si != NULL) { + if (m != NULL) { /* * Must make a copy of this packet for ipx_output to monkey * with. */ - m = m_copy(dtom(si), 0, (int)M_COPYALL); + m = m_copy(m, 0, M_COPYALL); if (m == NULL) return (ENOBUFS); si = mtod(m, struct spx *); From 37516046a2c1bff38c4d5878996c08df0a018dfa Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 13:34:03 +0000 Subject: [PATCH 515/544] Add missing call to ipx_pcbdetach() during SPX socket tear-down: not harmful in practice if running without INVARIANTS, but will panic with KASSERT enabled when SPX sockets are closed. MFC after: 3 days --- sys/netipx/spx_usrreq.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sys/netipx/spx_usrreq.c b/sys/netipx/spx_usrreq.c index 3e8e81d492f7..97c0a1959ddd 100644 --- a/sys/netipx/spx_usrreq.c +++ b/sys/netipx/spx_usrreq.c @@ -1253,6 +1253,7 @@ spx_detach(struct socket *so) IPX_LIST_LOCK(); IPX_LOCK(ipxp); spx_pcbdetach(ipxp); + ipx_pcbdetach(ipxp); ipx_pcbfree(ipxp); IPX_LIST_UNLOCK(); } From 5265bc60138160bd8ac706a89335a79167e5d4b4 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 13:52:51 +0000 Subject: [PATCH 516/544] Staticize spx_remque() now that it's only used from spx_reass.c. --- sys/netipx/spx_reass.c | 2 +- sys/netipx/spx_var.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/netipx/spx_reass.c b/sys/netipx/spx_reass.c index 05961053fab5..05b2912f6be5 100644 --- a/sys/netipx/spx_reass.c +++ b/sys/netipx/spx_reass.c @@ -102,7 +102,7 @@ spx_insque(struct spx_q *element, struct spx_q *head) element->si_next->si_prev = element; } -void +static void spx_remque(struct spx_q *element) { diff --git a/sys/netipx/spx_var.h b/sys/netipx/spx_var.h index cf599fac9b9c..8325b7f92084 100644 --- a/sys/netipx/spx_var.h +++ b/sys/netipx/spx_var.h @@ -155,7 +155,6 @@ int spx_output(struct spxpcb *cb, struct mbuf *m0); int spx_reass(struct spxpcb *cb, struct spx *si); void spx_reass_flush(struct spxpcb *cb); void spx_reass_init(struct spxpcb *cb); -void spx_remque(struct spx_q *element); #endif #endif /* !_NETIPX_SPX_VAR_H_ */ From 9235ed71993ec615fd4675e2b0e37afc1c346f48 Mon Sep 17 00:00:00 2001 From: Attilio Rao Date: Mon, 25 May 2009 14:37:10 +0000 Subject: [PATCH 517/544] Use, in uncovered part, the END() macro in order to improve debugging. In this specific case, Valgrind won't get confused when analyzing such functions. Sponsored by: Sandvine Incorporated Tested by: emaste MFC: 3 days --- lib/libc_r/arch/amd64/_atomic_lock.S | 1 + lib/libc_r/arch/i386/_atomic_lock.S | 1 + lib/libstand/i386/_setjmp.S | 2 ++ lib/msun/amd64/e_sqrt.S | 1 + lib/msun/amd64/e_sqrtf.S | 1 + lib/msun/amd64/s_lrint.S | 1 + lib/msun/amd64/s_lrintf.S | 1 + lib/msun/amd64/s_remquo.S | 1 + lib/msun/amd64/s_remquof.S | 1 + lib/msun/amd64/s_scalbn.S | 1 + lib/msun/amd64/s_scalbnf.S | 1 + lib/msun/amd64/s_scalbnl.S | 1 + lib/msun/i387/e_exp.S | 1 + lib/msun/i387/e_fmod.S | 1 + lib/msun/i387/e_log.S | 1 + lib/msun/i387/e_log10.S | 1 + lib/msun/i387/e_log10f.S | 1 + lib/msun/i387/e_remainder.S | 1 + lib/msun/i387/e_remainderf.S | 1 + lib/msun/i387/e_sqrt.S | 1 + lib/msun/i387/e_sqrtf.S | 1 + lib/msun/i387/s_ceil.S | 1 + lib/msun/i387/s_ceilf.S | 1 + lib/msun/i387/s_ceill.S | 1 + lib/msun/i387/s_copysign.S | 1 + lib/msun/i387/s_copysignf.S | 1 + lib/msun/i387/s_copysignl.S | 1 + lib/msun/i387/s_cos.S | 1 + lib/msun/i387/s_finite.S | 1 + lib/msun/i387/s_floor.S | 1 + lib/msun/i387/s_floorf.S | 1 + lib/msun/i387/s_floorl.S | 1 + lib/msun/i387/s_llrint.S | 1 + lib/msun/i387/s_llrintf.S | 1 + lib/msun/i387/s_logb.S | 1 + lib/msun/i387/s_logbf.S | 1 + lib/msun/i387/s_lrint.S | 1 + lib/msun/i387/s_lrintf.S | 1 + lib/msun/i387/s_remquo.S | 1 + lib/msun/i387/s_remquof.S | 1 + lib/msun/i387/s_rint.S | 1 + lib/msun/i387/s_rintf.S | 1 + lib/msun/i387/s_scalbn.S | 1 + lib/msun/i387/s_scalbnf.S | 1 + lib/msun/i387/s_scalbnl.S | 1 + lib/msun/i387/s_significand.S | 1 + lib/msun/i387/s_significandf.S | 1 + lib/msun/i387/s_sin.S | 1 + lib/msun/i387/s_tan.S | 1 + lib/msun/i387/s_trunc.S | 1 + lib/msun/i387/s_truncf.S | 1 + lib/msun/i387/s_truncl.S | 1 + lib/msun/ia64/s_fma.S | 1 + lib/msun/ia64/s_fmaf.S | 1 + lib/msun/ia64/s_fmal.S | 1 + tools/KSE/ksetest/kse_asm.S | 2 ++ tools/KSE/rr/kse_asm.S | 2 ++ 57 files changed, 60 insertions(+) diff --git a/lib/libc_r/arch/amd64/_atomic_lock.S b/lib/libc_r/arch/amd64/_atomic_lock.S index aaab0814d8c3..0a9070988cd6 100644 --- a/lib/libc_r/arch/amd64/_atomic_lock.S +++ b/lib/libc_r/arch/amd64/_atomic_lock.S @@ -38,4 +38,5 @@ ENTRY(_atomic_lock) movl $1, %eax xchgq %rax, (%rdi) ret +END(_atomic_lock) diff --git a/lib/libc_r/arch/i386/_atomic_lock.S b/lib/libc_r/arch/i386/_atomic_lock.S index af49aff68f03..7dba53cf499e 100644 --- a/lib/libc_r/arch/i386/_atomic_lock.S +++ b/lib/libc_r/arch/i386/_atomic_lock.S @@ -39,4 +39,5 @@ ENTRY(_atomic_lock) movl $1, %eax xchg %eax, (%ecx) ret +END(_atomic_lock) diff --git a/lib/libstand/i386/_setjmp.S b/lib/libstand/i386/_setjmp.S index 84df89e891c1..cc9de5cdb88e 100644 --- a/lib/libstand/i386/_setjmp.S +++ b/lib/libstand/i386/_setjmp.S @@ -58,6 +58,7 @@ ENTRY(_setjmp) movl %edi,20(%eax) xorl %eax,%eax ret +END(_setjmp) ENTRY(_longjmp) movl 4(%esp),%edx @@ -73,3 +74,4 @@ ENTRY(_longjmp) incl %eax 1: movl %ecx,0(%esp) ret +END(_longjmp) diff --git a/lib/msun/amd64/e_sqrt.S b/lib/msun/amd64/e_sqrt.S index f4b4f62b5ce0..41293204feaf 100644 --- a/lib/msun/amd64/e_sqrt.S +++ b/lib/msun/amd64/e_sqrt.S @@ -30,4 +30,5 @@ __FBSDID("$FreeBSD$") ENTRY(sqrt) sqrtsd %xmm0, %xmm0 ret +END(sqrt) diff --git a/lib/msun/amd64/e_sqrtf.S b/lib/msun/amd64/e_sqrtf.S index 25f4dfc5bf84..4dc2eb39ba05 100644 --- a/lib/msun/amd64/e_sqrtf.S +++ b/lib/msun/amd64/e_sqrtf.S @@ -30,3 +30,4 @@ __FBSDID("$FreeBSD$") ENTRY(sqrtf) sqrtss %xmm0, %xmm0 ret +END(sqrtf) diff --git a/lib/msun/amd64/s_lrint.S b/lib/msun/amd64/s_lrint.S index 9059a38f84de..975ab9e15d6b 100644 --- a/lib/msun/amd64/s_lrint.S +++ b/lib/msun/amd64/s_lrint.S @@ -34,3 +34,4 @@ __FBSDID("$FreeBSD$") ENTRY(fn) cvtsd2si %xmm0, %rax ret +END(fn) diff --git a/lib/msun/amd64/s_lrintf.S b/lib/msun/amd64/s_lrintf.S index cc27d208ae4a..f55126ceb60f 100644 --- a/lib/msun/amd64/s_lrintf.S +++ b/lib/msun/amd64/s_lrintf.S @@ -34,3 +34,4 @@ __FBSDID("$FreeBSD$") ENTRY(fn) cvtss2si %xmm0, %rax ret +END(fn) diff --git a/lib/msun/amd64/s_remquo.S b/lib/msun/amd64/s_remquo.S index eb113d718e86..6d821d9a9873 100644 --- a/lib/msun/amd64/s_remquo.S +++ b/lib/msun/amd64/s_remquo.S @@ -63,3 +63,4 @@ ENTRY(remquo) fstpl -8(%rsp) movsd -8(%rsp),%xmm0 ret +END(remquo) diff --git a/lib/msun/amd64/s_remquof.S b/lib/msun/amd64/s_remquof.S index 0833f5b984b5..24d728cc4101 100644 --- a/lib/msun/amd64/s_remquof.S +++ b/lib/msun/amd64/s_remquof.S @@ -63,3 +63,4 @@ ENTRY(remquof) fstps -4(%rsp) movss -4(%rsp),%xmm0 ret +END(remquof) diff --git a/lib/msun/amd64/s_scalbn.S b/lib/msun/amd64/s_scalbn.S index c9ac808b9b03..5275ba719ba8 100644 --- a/lib/msun/amd64/s_scalbn.S +++ b/lib/msun/amd64/s_scalbn.S @@ -37,3 +37,4 @@ ENTRY(scalbn) fstpl -8(%rsp) movsd -8(%rsp),%xmm0 ret +END(scalbn) diff --git a/lib/msun/amd64/s_scalbnf.S b/lib/msun/amd64/s_scalbnf.S index a9b9f803bdaf..2a794da7c802 100644 --- a/lib/msun/amd64/s_scalbnf.S +++ b/lib/msun/amd64/s_scalbnf.S @@ -37,6 +37,7 @@ ENTRY(scalbnf) fstps -8(%rsp) movss -8(%rsp),%xmm0 ret +END(scalbnf) .globl CNAME(ldexpf) .set CNAME(ldexpf),CNAME(scalbnf) diff --git a/lib/msun/amd64/s_scalbnl.S b/lib/msun/amd64/s_scalbnl.S index 8dfa810757af..95bbe9f08b30 100644 --- a/lib/msun/amd64/s_scalbnl.S +++ b/lib/msun/amd64/s_scalbnl.S @@ -14,6 +14,7 @@ ENTRY(scalbnl) fscale fstp %st(1) ret +END(scalbnl) .globl CNAME(ldexpl) .set CNAME(ldexpl),CNAME(scalbnl) diff --git a/lib/msun/i387/e_exp.S b/lib/msun/i387/e_exp.S index 9c8740700d36..7aeb0c314ec7 100644 --- a/lib/msun/i387/e_exp.S +++ b/lib/msun/i387/e_exp.S @@ -96,3 +96,4 @@ x_Inf_or_NaN: x_not_minus_Inf: fldl 4(%esp) ret +END(exp) diff --git a/lib/msun/i387/e_fmod.S b/lib/msun/i387/e_fmod.S index 71c4c3062ee5..ffa1300e6fe5 100644 --- a/lib/msun/i387/e_fmod.S +++ b/lib/msun/i387/e_fmod.S @@ -46,3 +46,4 @@ ENTRY(fmod) jp 1b fstp %st(1) ret +END(fmod) diff --git a/lib/msun/i387/e_log.S b/lib/msun/i387/e_log.S index 0d06940a670b..3fac5eed4982 100644 --- a/lib/msun/i387/e_log.S +++ b/lib/msun/i387/e_log.S @@ -42,3 +42,4 @@ ENTRY(log) fldl 4(%esp) fyl2x ret +END(log) diff --git a/lib/msun/i387/e_log10.S b/lib/msun/i387/e_log10.S index edc13ffb8bd2..2688fe921f96 100644 --- a/lib/msun/i387/e_log10.S +++ b/lib/msun/i387/e_log10.S @@ -42,3 +42,4 @@ ENTRY(log10) fldl 4(%esp) fyl2x ret +END(log10) diff --git a/lib/msun/i387/e_log10f.S b/lib/msun/i387/e_log10f.S index 44410bc2b8ec..3c3271f0bef3 100644 --- a/lib/msun/i387/e_log10f.S +++ b/lib/msun/i387/e_log10f.S @@ -13,3 +13,4 @@ ENTRY(log10f) flds 4(%esp) fyl2x ret +END(log10f) diff --git a/lib/msun/i387/e_remainder.S b/lib/msun/i387/e_remainder.S index ff2f1426ec14..b8a5409506f4 100644 --- a/lib/msun/i387/e_remainder.S +++ b/lib/msun/i387/e_remainder.S @@ -46,3 +46,4 @@ ENTRY(remainder) jp 1b fstp %st(1) ret +END(remainder) diff --git a/lib/msun/i387/e_remainderf.S b/lib/msun/i387/e_remainderf.S index 4093c8a289b5..9d760d54e73d 100644 --- a/lib/msun/i387/e_remainderf.S +++ b/lib/msun/i387/e_remainderf.S @@ -17,3 +17,4 @@ ENTRY(remainderf) jp 1b fstp %st(1) ret +END(remainderf) diff --git a/lib/msun/i387/e_sqrt.S b/lib/msun/i387/e_sqrt.S index 554beb706eb1..1c1bf6b33b43 100644 --- a/lib/msun/i387/e_sqrt.S +++ b/lib/msun/i387/e_sqrt.S @@ -41,3 +41,4 @@ ENTRY(sqrt) fldl 4(%esp) fsqrt ret +END(sqrt) diff --git a/lib/msun/i387/e_sqrtf.S b/lib/msun/i387/e_sqrtf.S index 9d78725030cd..dbb64f687a4d 100644 --- a/lib/msun/i387/e_sqrtf.S +++ b/lib/msun/i387/e_sqrtf.S @@ -12,3 +12,4 @@ ENTRY(sqrtf) flds 4(%esp) fsqrt ret +END(sqrtf) diff --git a/lib/msun/i387/s_ceil.S b/lib/msun/i387/s_ceil.S index e805d8524bb9..32fcf9ce634c 100644 --- a/lib/msun/i387/s_ceil.S +++ b/lib/msun/i387/s_ceil.S @@ -56,3 +56,4 @@ ENTRY(ceil) leave ret +END(ceil) diff --git a/lib/msun/i387/s_ceilf.S b/lib/msun/i387/s_ceilf.S index 473d30951d2b..846028f6e37d 100644 --- a/lib/msun/i387/s_ceilf.S +++ b/lib/msun/i387/s_ceilf.S @@ -27,3 +27,4 @@ ENTRY(ceilf) leave ret +END(ceilf) diff --git a/lib/msun/i387/s_ceill.S b/lib/msun/i387/s_ceill.S index ae64abfecaf8..9466a3ebe09f 100644 --- a/lib/msun/i387/s_ceill.S +++ b/lib/msun/i387/s_ceill.S @@ -25,3 +25,4 @@ ENTRY(ceill) leave ret +END(ceill) diff --git a/lib/msun/i387/s_copysign.S b/lib/msun/i387/s_copysign.S index ec28b452bfa7..4842c532867e 100644 --- a/lib/msun/i387/s_copysign.S +++ b/lib/msun/i387/s_copysign.S @@ -46,3 +46,4 @@ ENTRY(copysign) movl %eax,8(%esp) fldl 4(%esp) ret +END(copysign) diff --git a/lib/msun/i387/s_copysignf.S b/lib/msun/i387/s_copysignf.S index e78ad24b71d3..0be7a6560870 100644 --- a/lib/msun/i387/s_copysignf.S +++ b/lib/msun/i387/s_copysignf.S @@ -17,3 +17,4 @@ ENTRY(copysignf) movl %eax,4(%esp) flds 4(%esp) ret +END(copysignf) diff --git a/lib/msun/i387/s_copysignl.S b/lib/msun/i387/s_copysignl.S index 7878591d387e..5256628e0032 100644 --- a/lib/msun/i387/s_copysignl.S +++ b/lib/msun/i387/s_copysignl.S @@ -15,3 +15,4 @@ ENTRY(copysignl) movl %eax,12(%esp) fldt 4(%esp) ret +END(copysignl) diff --git a/lib/msun/i387/s_cos.S b/lib/msun/i387/s_cos.S index a73ba0621229..900a987ff8d6 100644 --- a/lib/msun/i387/s_cos.S +++ b/lib/msun/i387/s_cos.S @@ -54,3 +54,4 @@ ENTRY(cos) fstp %st(1) fcos ret +END(cos) diff --git a/lib/msun/i387/s_finite.S b/lib/msun/i387/s_finite.S index b27b7d1149df..a2e407f4a3f9 100644 --- a/lib/msun/i387/s_finite.S +++ b/lib/msun/i387/s_finite.S @@ -44,3 +44,4 @@ ENTRY(finite) setneb %al andl $0x000000ff, %eax ret +END(finite) diff --git a/lib/msun/i387/s_floor.S b/lib/msun/i387/s_floor.S index 66c1d9f9d0f5..005f873578cd 100644 --- a/lib/msun/i387/s_floor.S +++ b/lib/msun/i387/s_floor.S @@ -56,3 +56,4 @@ ENTRY(floor) leave ret +END(floor) diff --git a/lib/msun/i387/s_floorf.S b/lib/msun/i387/s_floorf.S index f1000fef7659..14d3b85d2a53 100644 --- a/lib/msun/i387/s_floorf.S +++ b/lib/msun/i387/s_floorf.S @@ -27,3 +27,4 @@ ENTRY(floorf) leave ret +END(floorf) diff --git a/lib/msun/i387/s_floorl.S b/lib/msun/i387/s_floorl.S index a0bb048e4a7d..bec03a7a3e49 100644 --- a/lib/msun/i387/s_floorl.S +++ b/lib/msun/i387/s_floorl.S @@ -25,3 +25,4 @@ ENTRY(floorl) leave ret +END(floorl) diff --git a/lib/msun/i387/s_llrint.S b/lib/msun/i387/s_llrint.S index 1b8a63826679..2bf1342a0a0a 100644 --- a/lib/msun/i387/s_llrint.S +++ b/lib/msun/i387/s_llrint.S @@ -34,3 +34,4 @@ ENTRY(llrint) popl %eax popl %edx ret +END(llrint) diff --git a/lib/msun/i387/s_llrintf.S b/lib/msun/i387/s_llrintf.S index 4f398b6dd1b8..465e4079f07d 100644 --- a/lib/msun/i387/s_llrintf.S +++ b/lib/msun/i387/s_llrintf.S @@ -34,3 +34,4 @@ ENTRY(llrintf) popl %eax popl %edx ret +END(llrintf) diff --git a/lib/msun/i387/s_logb.S b/lib/msun/i387/s_logb.S index 9e09f840c40c..7156f952a33d 100644 --- a/lib/msun/i387/s_logb.S +++ b/lib/msun/i387/s_logb.S @@ -42,3 +42,4 @@ ENTRY(logb) fxtract fstp %st ret +END(logb) diff --git a/lib/msun/i387/s_logbf.S b/lib/msun/i387/s_logbf.S index 4cfa02b86f7d..ddd5eba8cc62 100644 --- a/lib/msun/i387/s_logbf.S +++ b/lib/msun/i387/s_logbf.S @@ -13,3 +13,4 @@ ENTRY(logbf) fxtract fstp %st ret +END(logbf) diff --git a/lib/msun/i387/s_lrint.S b/lib/msun/i387/s_lrint.S index 82269c884d53..10db3333033d 100644 --- a/lib/msun/i387/s_lrint.S +++ b/lib/msun/i387/s_lrint.S @@ -33,3 +33,4 @@ ENTRY(lrint) fistpl (%esp) popl %eax ret +END(lrint) diff --git a/lib/msun/i387/s_lrintf.S b/lib/msun/i387/s_lrintf.S index b9915fa5d071..ee97206f99e4 100644 --- a/lib/msun/i387/s_lrintf.S +++ b/lib/msun/i387/s_lrintf.S @@ -33,3 +33,4 @@ ENTRY(lrintf) fistpl (%esp) popl %eax ret +END(lrintf) diff --git a/lib/msun/i387/s_remquo.S b/lib/msun/i387/s_remquo.S index fd8af5ef8b3c..b71dd6f0b525 100644 --- a/lib/msun/i387/s_remquo.S +++ b/lib/msun/i387/s_remquo.S @@ -60,3 +60,4 @@ ENTRY(remquo) movl 20(%esp),%ecx movl %eax,(%ecx) ret +END(remquo) diff --git a/lib/msun/i387/s_remquof.S b/lib/msun/i387/s_remquof.S index 70a43f4b4b39..c0b37fc6ce61 100644 --- a/lib/msun/i387/s_remquof.S +++ b/lib/msun/i387/s_remquof.S @@ -60,3 +60,4 @@ ENTRY(remquof) movl 12(%esp),%ecx movl %eax,(%ecx) ret +END(remquof) diff --git a/lib/msun/i387/s_rint.S b/lib/msun/i387/s_rint.S index 79da080d7110..70532e7fd3bf 100644 --- a/lib/msun/i387/s_rint.S +++ b/lib/msun/i387/s_rint.S @@ -41,3 +41,4 @@ ENTRY(rint) fldl 4(%esp) frndint ret +END(rint) diff --git a/lib/msun/i387/s_rintf.S b/lib/msun/i387/s_rintf.S index 646dcb516cee..2f175200d945 100644 --- a/lib/msun/i387/s_rintf.S +++ b/lib/msun/i387/s_rintf.S @@ -12,3 +12,4 @@ ENTRY(rintf) flds 4(%esp) frndint ret +END(rintf) diff --git a/lib/msun/i387/s_scalbn.S b/lib/msun/i387/s_scalbn.S index c00e1fb137e0..5e87159cc436 100644 --- a/lib/msun/i387/s_scalbn.S +++ b/lib/msun/i387/s_scalbn.S @@ -43,3 +43,4 @@ ENTRY(scalbn) fscale fstp %st(1) ret +END(scalbn) diff --git a/lib/msun/i387/s_scalbnf.S b/lib/msun/i387/s_scalbnf.S index 3c84749b6c42..df21521520e1 100644 --- a/lib/msun/i387/s_scalbnf.S +++ b/lib/msun/i387/s_scalbnf.S @@ -14,6 +14,7 @@ ENTRY(scalbnf) fscale fstp %st(1) /* bug fix for fp stack overflow */ ret +END(scalbnf) .globl CNAME(ldexpf) .set CNAME(ldexpf),CNAME(scalbnf) diff --git a/lib/msun/i387/s_scalbnl.S b/lib/msun/i387/s_scalbnl.S index c166326b6d16..4ac6877c891a 100644 --- a/lib/msun/i387/s_scalbnl.S +++ b/lib/msun/i387/s_scalbnl.S @@ -14,6 +14,7 @@ ENTRY(scalbnl) fscale fstp %st(1) ret +END(scalbnl) .globl CNAME(ldexpl) .set CNAME(ldexpl),CNAME(scalbnl) diff --git a/lib/msun/i387/s_significand.S b/lib/msun/i387/s_significand.S index 13f1f3e76282..1427924e5e8b 100644 --- a/lib/msun/i387/s_significand.S +++ b/lib/msun/i387/s_significand.S @@ -42,3 +42,4 @@ ENTRY(significand) fxtract fstp %st(1) ret +END(significand) diff --git a/lib/msun/i387/s_significandf.S b/lib/msun/i387/s_significandf.S index 99299814353b..e8f8b9ad8b9a 100644 --- a/lib/msun/i387/s_significandf.S +++ b/lib/msun/i387/s_significandf.S @@ -13,3 +13,4 @@ ENTRY(significandf) fxtract fstp %st(1) ret +END(significandf) diff --git a/lib/msun/i387/s_sin.S b/lib/msun/i387/s_sin.S index d152352abf2f..250327e90614 100644 --- a/lib/msun/i387/s_sin.S +++ b/lib/msun/i387/s_sin.S @@ -54,3 +54,4 @@ ENTRY(sin) fstp %st(1) fsin ret +END(sin) diff --git a/lib/msun/i387/s_tan.S b/lib/msun/i387/s_tan.S index d0cbc0aabd97..e6fc90ab9582 100644 --- a/lib/msun/i387/s_tan.S +++ b/lib/msun/i387/s_tan.S @@ -56,3 +56,4 @@ ENTRY(tan) fptan fstp %st(0) ret +END(tan) diff --git a/lib/msun/i387/s_trunc.S b/lib/msun/i387/s_trunc.S index 91926d7373c4..ac16e696d064 100644 --- a/lib/msun/i387/s_trunc.S +++ b/lib/msun/i387/s_trunc.S @@ -24,3 +24,4 @@ ENTRY(trunc) leave ret +END(trunc) diff --git a/lib/msun/i387/s_truncf.S b/lib/msun/i387/s_truncf.S index 000136738dfc..ccc84ae02fae 100644 --- a/lib/msun/i387/s_truncf.S +++ b/lib/msun/i387/s_truncf.S @@ -24,3 +24,4 @@ ENTRY(truncf) leave ret +END(truncf) diff --git a/lib/msun/i387/s_truncl.S b/lib/msun/i387/s_truncl.S index b20b06ebcfc4..abbca8f80a81 100644 --- a/lib/msun/i387/s_truncl.S +++ b/lib/msun/i387/s_truncl.S @@ -24,3 +24,4 @@ ENTRY(truncl) leave ret +END(truncl) diff --git a/lib/msun/ia64/s_fma.S b/lib/msun/ia64/s_fma.S index 3e693592fce8..3fed3868bbe1 100644 --- a/lib/msun/ia64/s_fma.S +++ b/lib/msun/ia64/s_fma.S @@ -32,3 +32,4 @@ ENTRY(fma, 3) fma.d f8 = f8, f9, f10 br.ret.sptk b0 } +END(fma) diff --git a/lib/msun/ia64/s_fmaf.S b/lib/msun/ia64/s_fmaf.S index 1e122bb525eb..c12fb03e87ed 100644 --- a/lib/msun/ia64/s_fmaf.S +++ b/lib/msun/ia64/s_fmaf.S @@ -32,3 +32,4 @@ ENTRY(fmaf, 3) fma.s f8 = f8, f9, f10 br.ret.sptk b0 } +END(fmaf) diff --git a/lib/msun/ia64/s_fmal.S b/lib/msun/ia64/s_fmal.S index c24a1dee62a0..4ae01cc00cac 100644 --- a/lib/msun/ia64/s_fmal.S +++ b/lib/msun/ia64/s_fmal.S @@ -32,3 +32,4 @@ ENTRY(fmal, 3) fma f8 = f8, f9, f10 br.ret.sptk b0 } +END(fmal) diff --git a/tools/KSE/ksetest/kse_asm.S b/tools/KSE/ksetest/kse_asm.S index 20dc1dbba258..ac571f7f1aee 100644 --- a/tools/KSE/ksetest/kse_asm.S +++ b/tools/KSE/ksetest/kse_asm.S @@ -99,6 +99,7 @@ ENTRY(uts_to_thread) pop %ebx /* %ebx off stack */ popf /* flags off stack */ 5: ret /* %eip off stack */ +END(uts_to_thread) /* * int thread_to_uts(struct kse_thr_mailbox *tm, struct kse_mailbox *km); @@ -154,4 +155,5 @@ ENTRY(thread_to_uts) pushl KM_FUNC_OFFSET(%edx) /* .. the uts can return to itself */ pushl KM_FUNC_OFFSET(%edx) /* push the address of the uts func */ 2: ret +END(thread_to_uts) diff --git a/tools/KSE/rr/kse_asm.S b/tools/KSE/rr/kse_asm.S index 20dc1dbba258..ac571f7f1aee 100644 --- a/tools/KSE/rr/kse_asm.S +++ b/tools/KSE/rr/kse_asm.S @@ -99,6 +99,7 @@ ENTRY(uts_to_thread) pop %ebx /* %ebx off stack */ popf /* flags off stack */ 5: ret /* %eip off stack */ +END(uts_to_thread) /* * int thread_to_uts(struct kse_thr_mailbox *tm, struct kse_mailbox *km); @@ -154,4 +155,5 @@ ENTRY(thread_to_uts) pushl KM_FUNC_OFFSET(%edx) /* .. the uts can return to itself */ pushl KM_FUNC_OFFSET(%edx) /* push the address of the uts func */ 2: ret +END(thread_to_uts) From cce6e15556cf6198ceacb93915e1d00bf49989e2 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Mon, 25 May 2009 14:51:47 +0000 Subject: [PATCH 518/544] Remove comment about moving tcp_reass() to its own file named tcp_reass.c, that happened a while ago. MFC after: 3 days --- sys/netinet/tcp_reass.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sys/netinet/tcp_reass.c b/sys/netinet/tcp_reass.c index 080bb02c40bf..0849c25161c3 100644 --- a/sys/netinet/tcp_reass.c +++ b/sys/netinet/tcp_reass.c @@ -150,8 +150,7 @@ tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m) /* * XXX: tcp_reass() is rather inefficient with its data structures - * and should be rewritten (see NetBSD for optimizations). While - * doing that it should move to its own file tcp_reass.c. + * and should be rewritten (see NetBSD for optimizations). */ /* From bcdaa850691d8e4b402a3ba1bbb970287f673838 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Mon, 25 May 2009 15:48:10 +0000 Subject: [PATCH 519/544] Add the "-4" option to nfsstat, so that it will reports stats for the experimental nfs subsystem when that option is specified. Approved by: kib (mentor) --- usr.bin/nfsstat/nfsstat.1 | 7 +- usr.bin/nfsstat/nfsstat.c | 369 +++++++++++++++++++++++++++++++++++++- 2 files changed, 369 insertions(+), 7 deletions(-) diff --git a/usr.bin/nfsstat/nfsstat.1 b/usr.bin/nfsstat/nfsstat.1 index a7c2a13cd21f..990ae990fd91 100644 --- a/usr.bin/nfsstat/nfsstat.1 +++ b/usr.bin/nfsstat/nfsstat.1 @@ -42,7 +42,7 @@ statistics .Sh SYNOPSIS .Nm -.Op Fl cszW +.Op Fl cszW4 .Op Fl M Ar core .Op Fl N Ar system .Op Fl w Ar wait @@ -82,6 +82,10 @@ activity for both the client and server at second intervals. .It Fl z Reset statistics after displaying them. +(Not currently supported by the experimental nfs subsystem.) +.It Fl 4 +Gather statistics from the experimental nfs subsystem that includes +support for NFSv4 instead of the regular nfs subsystem. .El .Sh FILES .Bl -tag -width ".Pa /boot/kernel/kernel" -compact @@ -97,6 +101,7 @@ default memory file .Xr systat 1 , .Xr sysctl 3 , .Xr iostat 8 , +.Xr nfsdumpstate 8 , .Xr pstat 8 , .Xr vmstat 8 .Sh HISTORY diff --git a/usr.bin/nfsstat/nfsstat.c b/usr.bin/nfsstat/nfsstat.c index 5a1495a1f528..508ec09a52df 100644 --- a/usr.bin/nfsstat/nfsstat.c +++ b/usr.bin/nfsstat/nfsstat.c @@ -56,6 +56,10 @@ static const char rcsid[] = #include #include #include +#include + +#include + #include #include #include @@ -82,6 +86,9 @@ kvm_t *kd; static int deadkernel = 0; static int widemode = 0; static int zflag = 0; +static int run_v4 = 0; +static int printtitle = 1; +static struct ext_nfsstats ext_nfsstats; void intpr(int, int); void printhdr(int, int); @@ -89,6 +96,8 @@ void sidewaysintpr(u_int, int, int); void usage(void); char *sperc1(int, int); char *sperc2(int, int); +void exp_intpr(int, int); +void exp_sidewaysintpr(u_int, int, int); #define DELTA(field) (nfsstats.field - lastst.field) @@ -104,7 +113,7 @@ main(int argc, char **argv) interval = 0; memf = nlistf = NULL; - while ((ch = getopt(argc, argv, "csWM:N:w:z")) != -1) + while ((ch = getopt(argc, argv, "csWM:N:w:z4")) != -1) switch(ch) { case 'M': memf = optarg; @@ -131,6 +140,9 @@ main(int argc, char **argv) case 'z': zflag = 1; break; + case '4': + run_v4 = 1; + break; case '?': default: usage(); @@ -149,7 +161,13 @@ main(int argc, char **argv) } } #endif - if (nlistf != NULL || memf != NULL) { + if (run_v4 != 0 && modfind("nfscommon") < 0) + errx(1, "experimental client/server not loaded"); + + if (run_v4 != 0) { + if (nfssvc(NFSSVC_GETSTATS, &ext_nfsstats) < 0) + err(1, "Can't get stats"); + } else if (nlistf != NULL || memf != NULL) { deadkernel = 1; if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY, @@ -161,10 +179,17 @@ main(int argc, char **argv) } } - if (interval) - sidewaysintpr(interval, clientOnly, serverOnly); - else - intpr(clientOnly, serverOnly); + if (interval) { + if (run_v4 > 0) + exp_sidewaysintpr(interval, clientOnly, serverOnly); + else + sidewaysintpr(interval, clientOnly, serverOnly); + } else { + if (run_v4 > 0) + exp_intpr(clientOnly, serverOnly); + else + intpr(clientOnly, serverOnly); + } exit(0); } @@ -517,3 +542,335 @@ sperc2(int ttl, int misses) return(p); } +/* + * Print a description of the nfs stats for the experimental client/server. + */ +void +exp_intpr(int clientOnly, int serverOnly) +{ + + if (clientOnly != 0) { + if (printtitle) { + printf("Client Info:\n"); + printf("Rpc Counts:\n"); + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Getattr", "Setattr", "Lookup", "Readlink", + "Read", "Write", "Create", "Remove"); + } + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.rpccnt[NFSPROC_GETATTR], + ext_nfsstats.rpccnt[NFSPROC_SETATTR], + ext_nfsstats.rpccnt[NFSPROC_LOOKUP], + ext_nfsstats.rpccnt[NFSPROC_READLINK], + ext_nfsstats.rpccnt[NFSPROC_READ], + ext_nfsstats.rpccnt[NFSPROC_WRITE], + ext_nfsstats.rpccnt[NFSPROC_CREATE], + ext_nfsstats.rpccnt[NFSPROC_REMOVE]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", + "Readdir", "RdirPlus", "Access"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.rpccnt[NFSPROC_RENAME], + ext_nfsstats.rpccnt[NFSPROC_LINK], + ext_nfsstats.rpccnt[NFSPROC_SYMLINK], + ext_nfsstats.rpccnt[NFSPROC_MKDIR], + ext_nfsstats.rpccnt[NFSPROC_RMDIR], + ext_nfsstats.rpccnt[NFSPROC_READDIR], + ext_nfsstats.rpccnt[NFSPROC_READDIRPLUS], + ext_nfsstats.rpccnt[NFSPROC_ACCESS]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Mknod", "Fsstat", "Fsinfo", "PathConf", + "Commit", "SetClId", "SetClIdCf", "Lock"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.rpccnt[NFSPROC_MKNOD], + ext_nfsstats.rpccnt[NFSPROC_FSSTAT], + ext_nfsstats.rpccnt[NFSPROC_FSINFO], + ext_nfsstats.rpccnt[NFSPROC_PATHCONF], + ext_nfsstats.rpccnt[NFSPROC_COMMIT], + ext_nfsstats.rpccnt[NFSPROC_SETCLIENTID], + ext_nfsstats.rpccnt[NFSPROC_SETCLIENTIDCFRM], + ext_nfsstats.rpccnt[NFSPROC_LOCK]); + if (printtitle) + printf("%9.9s %9.9s %9.9s %9.9s\n", + "LockT", "LockU", "Open", "OpenCfr"); + printf("%9d %9d %9d %9d\n", + ext_nfsstats.rpccnt[NFSPROC_LOCKT], + ext_nfsstats.rpccnt[NFSPROC_LOCKU], + ext_nfsstats.rpccnt[NFSPROC_OPEN], + ext_nfsstats.rpccnt[NFSPROC_OPENCONFIRM]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "OpenOwner", "Opens", "LockOwner", + "Locks", "Delegs", "LocalOwn", + "LocalOpen", "LocalLOwn"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.clopenowners, + ext_nfsstats.clopens, + ext_nfsstats.cllockowners, + ext_nfsstats.cllocks, + ext_nfsstats.cldelegates, + ext_nfsstats.cllocalopenowners, + ext_nfsstats.cllocalopens, + ext_nfsstats.cllocallockowners); + if (printtitle) + printf("%9.9s\n", "LocalLock"); + printf("%9d\n", ext_nfsstats.cllocallocks); + if (printtitle) { + printf("Rpc Info:\n"); + printf("%9.9s %9.9s %9.9s %9.9s %9.9s\n", + "TimedOut", "Invalid", "X Replies", "Retries", + "Requests"); + } + printf("%9d %9d %9d %9d %9d\n", + ext_nfsstats.rpctimeouts, + ext_nfsstats.rpcinvalid, + ext_nfsstats.rpcunexpected, + ext_nfsstats.rpcretries, + ext_nfsstats.rpcrequests); + if (printtitle) { + printf("Cache Info:\n"); + printf("%9.9s %9.9s %9.9s %9.9s", + "Attr Hits", "Misses", "Lkup Hits", "Misses"); + printf(" %9.9s %9.9s %9.9s %9.9s\n", + "BioR Hits", "Misses", "BioW Hits", "Misses"); + } + printf("%9d %9d %9d %9d", + ext_nfsstats.attrcache_hits, + ext_nfsstats.attrcache_misses, + ext_nfsstats.lookupcache_hits, + ext_nfsstats.lookupcache_misses); + printf(" %9d %9d %9d %9d\n", + ext_nfsstats.biocache_reads, + ext_nfsstats.read_bios, + ext_nfsstats.biocache_writes, + ext_nfsstats.write_bios); + if (printtitle) { + printf("%9.9s %9.9s %9.9s %9.9s", + "BioRLHits", "Misses", "BioD Hits", "Misses"); + printf(" %9.9s %9.9s\n", "DirE Hits", "Misses"); + } + printf("%9d %9d %9d %9d", + ext_nfsstats.biocache_readlinks, + ext_nfsstats.readlink_bios, + ext_nfsstats.biocache_readdirs, + ext_nfsstats.readdir_bios); + printf(" %9d %9d\n", + ext_nfsstats.direofcache_hits, + ext_nfsstats.direofcache_misses); + } + if (serverOnly != 0) { + if (printtitle) { + printf("\nServer Info:\n"); + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Getattr", "Setattr", "Lookup", "Readlink", + "Read", "Write", "Create", "Remove"); + } + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_GETATTR], + ext_nfsstats.srvrpccnt[NFSV4OP_SETATTR], + ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUP], + ext_nfsstats.srvrpccnt[NFSV4OP_READLINK], + ext_nfsstats.srvrpccnt[NFSV4OP_READ], + ext_nfsstats.srvrpccnt[NFSV4OP_WRITE], + ext_nfsstats.srvrpccnt[NFSV4OP_V3CREATE], + ext_nfsstats.srvrpccnt[NFSV4OP_REMOVE]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Rename", "Link", "Symlink", "Mkdir", "Rmdir", + "Readdir", "RdirPlus", "Access"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_RENAME], + ext_nfsstats.srvrpccnt[NFSV4OP_LINK], + ext_nfsstats.srvrpccnt[NFSV4OP_SYMLINK], + ext_nfsstats.srvrpccnt[NFSV4OP_MKDIR], + ext_nfsstats.srvrpccnt[NFSV4OP_RMDIR], + ext_nfsstats.srvrpccnt[NFSV4OP_READDIR], + ext_nfsstats.srvrpccnt[NFSV4OP_READDIRPLUS], + ext_nfsstats.srvrpccnt[NFSV4OP_ACCESS]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Mknod", "Fsstat", "Fsinfo", "PathConf", + "Commit", "LookupP", "SetClId", "SetClIdCf"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_MKNOD], + ext_nfsstats.srvrpccnt[NFSV4OP_FSSTAT], + ext_nfsstats.srvrpccnt[NFSV4OP_FSINFO], + ext_nfsstats.srvrpccnt[NFSV4OP_PATHCONF], + ext_nfsstats.srvrpccnt[NFSV4OP_COMMIT], + ext_nfsstats.srvrpccnt[NFSV4OP_LOOKUPP], + ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTID], + ext_nfsstats.srvrpccnt[NFSV4OP_SETCLIENTIDCFRM]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "Open", "OpenAttr", "OpenDwnGr", "OpenCfrm", + "DelePurge", "DeleRet", "GetFH", "Lock"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_OPEN], + ext_nfsstats.srvrpccnt[NFSV4OP_OPENATTR], + ext_nfsstats.srvrpccnt[NFSV4OP_OPENDOWNGRADE], + ext_nfsstats.srvrpccnt[NFSV4OP_OPENCONFIRM], + ext_nfsstats.srvrpccnt[NFSV4OP_DELEGPURGE], + ext_nfsstats.srvrpccnt[NFSV4OP_DELEGRETURN], + ext_nfsstats.srvrpccnt[NFSV4OP_GETFH], + ext_nfsstats.srvrpccnt[NFSV4OP_LOCK]); + if (printtitle) + printf( + "%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n" + , "LockT", "LockU", "Close", "Verify", "NVerify", + "PutFH", "PutPubFH", "PutRootFH"); + printf("%9d %9d %9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_LOCKT], + ext_nfsstats.srvrpccnt[NFSV4OP_LOCKU], + ext_nfsstats.srvrpccnt[NFSV4OP_CLOSE], + ext_nfsstats.srvrpccnt[NFSV4OP_VERIFY], + ext_nfsstats.srvrpccnt[NFSV4OP_NVERIFY], + ext_nfsstats.srvrpccnt[NFSV4OP_PUTFH], + ext_nfsstats.srvrpccnt[NFSV4OP_PUTPUBFH], + ext_nfsstats.srvrpccnt[NFSV4OP_PUTROOTFH]); + if (printtitle) + printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", + "Renew", "RestoreFH", "SaveFH", "Secinfo", + "RelLckOwn", "V4Create"); + printf("%9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvrpccnt[NFSV4OP_RENEW], + ext_nfsstats.srvrpccnt[NFSV4OP_RESTOREFH], + ext_nfsstats.srvrpccnt[NFSV4OP_SAVEFH], + ext_nfsstats.srvrpccnt[NFSV4OP_SECINFO], + ext_nfsstats.srvrpccnt[NFSV4OP_RELEASELCKOWN], + ext_nfsstats.srvrpccnt[NFSV4OP_CREATE]); + if (printtitle) { + printf("Server:\n"); + printf("%9.9s %9.9s %9.9s\n", + "Retfailed", "Faults", "Clients"); + } + printf("%9d %9d %9d\n", + ext_nfsstats.srv_errs, ext_nfsstats.srvrpc_errs, + ext_nfsstats.srvclients); + if (printtitle) + printf("%9.9s %9.9s %9.9s %9.9s %9.9s \n", + "OpenOwner", "Opens", "LockOwner", + "Locks", "Delegs"); + printf("%9d %9d %9d %9d %9d \n", + ext_nfsstats.srvopenowners, + ext_nfsstats.srvopens, + ext_nfsstats.srvlockowners, + ext_nfsstats.srvlocks, + ext_nfsstats.srvdelegates); + if (printtitle) { + printf("Server Cache Stats:\n"); + printf("%9.9s %9.9s %9.9s %9.9s %9.9s %9.9s\n", + "Inprog", "Idem", "Non-idem", "Misses", + "CacheSize", "TCPPeak"); + } + printf("%9d %9d %9d %9d %9d %9d\n", + ext_nfsstats.srvcache_inproghits, + ext_nfsstats.srvcache_idemdonehits, + ext_nfsstats.srvcache_nonidemdonehits, + ext_nfsstats.srvcache_misses, + ext_nfsstats.srvcache_size, + ext_nfsstats.srvcache_tcppeak); + } +} + +/* + * Print a running summary of nfs statistics for the experimental client and/or + * server. + * Repeat display every interval seconds, showing statistics + * collected over that interval. Assumes that interval is non-zero. + * First line printed at top of screen is always cumulative. + */ +void +exp_sidewaysintpr(u_int interval, int clientOnly, int serverOnly) +{ + struct ext_nfsstats nfsstats, lastst, *ext_nfsstatsp; + int hdrcnt = 1; + + ext_nfsstatsp = &lastst; + if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) + err(1, "Can't get stats"); + sleep(interval); + + for (;;) { + ext_nfsstatsp = &nfsstats; + if (nfssvc(NFSSVC_GETSTATS, ext_nfsstatsp) < 0) + err(1, "Can't get stats"); + + if (--hdrcnt == 0) { + printhdr(clientOnly, serverOnly); + if (clientOnly && serverOnly) + hdrcnt = 10; + else + hdrcnt = 20; + } + if (clientOnly) { + printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", + ((clientOnly && serverOnly) ? "Client:" : ""), + DELTA(attrcache_hits) + DELTA(attrcache_misses), + DELTA(lookupcache_hits) + DELTA(lookupcache_misses), + DELTA(biocache_readlinks), + DELTA(biocache_reads), + DELTA(biocache_writes), + nfsstats.rpccnt[NFSPROC_RENAME] - + lastst.rpccnt[NFSPROC_RENAME], + DELTA(accesscache_hits) + DELTA(accesscache_misses), + DELTA(biocache_readdirs) + ); + if (widemode) { + printf(" %s %s %s %s %s %s", + sperc1(DELTA(attrcache_hits), + DELTA(attrcache_misses)), + sperc1(DELTA(lookupcache_hits), + DELTA(lookupcache_misses)), + sperc2(DELTA(biocache_reads), + DELTA(read_bios)), + sperc2(DELTA(biocache_writes), + DELTA(write_bios)), + sperc1(DELTA(accesscache_hits), + DELTA(accesscache_misses)), + sperc2(DELTA(biocache_readdirs), + DELTA(readdir_bios)) + ); + } + printf("\n"); + lastst = nfsstats; + } + if (serverOnly) { + printf("%s %6d %6d %6d %6d %6d %6d %6d %6d", + ((clientOnly && serverOnly) ? "Server:" : ""), + nfsstats.srvrpccnt[NFSPROC_GETATTR] - + lastst.srvrpccnt[NFSPROC_GETATTR], + nfsstats.srvrpccnt[NFSPROC_LOOKUP] - + lastst.srvrpccnt[NFSPROC_LOOKUP], + nfsstats.srvrpccnt[NFSPROC_READLINK] - + lastst.srvrpccnt[NFSPROC_READLINK], + nfsstats.srvrpccnt[NFSPROC_READ] - + lastst.srvrpccnt[NFSPROC_READ], + nfsstats.srvrpccnt[NFSPROC_WRITE] - + lastst.srvrpccnt[NFSPROC_WRITE], + nfsstats.srvrpccnt[NFSPROC_RENAME] - + lastst.srvrpccnt[NFSPROC_RENAME], + nfsstats.srvrpccnt[NFSPROC_ACCESS] - + lastst.srvrpccnt[NFSPROC_ACCESS], + (nfsstats.srvrpccnt[NFSPROC_READDIR] - + lastst.srvrpccnt[NFSPROC_READDIR]) + + (nfsstats.srvrpccnt[NFSPROC_READDIRPLUS] - + lastst.srvrpccnt[NFSPROC_READDIRPLUS])); + printf("\n"); + lastst = nfsstats; + } + fflush(stdout); + sleep(interval); + } + /*NOTREACHED*/ +} + From 5ce8d9708ccd142bcda5020225400a775eae9758 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 25 May 2009 16:34:35 +0000 Subject: [PATCH 520/544] rev bpf attach/detach event api to include the dlt --- sys/net/bpf.c | 4 ++-- sys/sys/eventhandler.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/sys/net/bpf.c b/sys/net/bpf.c index 5bca0eb27787..b944e2902cb0 100644 --- a/sys/net/bpf.c +++ b/sys/net/bpf.c @@ -535,7 +535,7 @@ bpf_attachd(struct bpf_d *d, struct bpf_if *bp) bpf_bpfd_cnt++; BPFIF_UNLOCK(bp); - EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, 1); + EVENTHANDLER_INVOKE(bpf_track, bp->bif_ifp, bp->bif_dlt, 1); } /* @@ -563,7 +563,7 @@ bpf_detachd(struct bpf_d *d) BPFD_UNLOCK(d); BPFIF_UNLOCK(bp); - EVENTHANDLER_INVOKE(bpf_track, ifp, 0); + EVENTHANDLER_INVOKE(bpf_track, ifp, bp->bif_dlt, 0); /* * Check if this descriptor had requested promiscuous mode. diff --git a/sys/sys/eventhandler.h b/sys/sys/eventhandler.h index de787afc627f..1f26d48f6581 100644 --- a/sys/sys/eventhandler.h +++ b/sys/sys/eventhandler.h @@ -184,7 +184,8 @@ EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); /* BPF attach/detach events */ struct ifnet; -typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* 1 =>'s attach */); +typedef void (*bpf_track_fn)(void *, struct ifnet *, int /* dlt */, + int /* 1 =>'s attach */); EVENTHANDLER_DECLARE(bpf_track, bpf_track_fn); /* From ac86de8587935d6c75035c001afebfdb6f39538f Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 25 May 2009 16:35:31 +0000 Subject: [PATCH 521/544] do internal bpf tracking only for radiotap DLT's --- sys/net80211/ieee80211_freebsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sys/net80211/ieee80211_freebsd.c b/sys/net80211/ieee80211_freebsd.c index 3caf79079a26..15170c79fdbb 100644 --- a/sys/net80211/ieee80211_freebsd.c +++ b/sys/net80211/ieee80211_freebsd.c @@ -730,10 +730,10 @@ ieee80211_load_module(const char *modname) static eventhandler_tag wlan_bpfevent; static void -bpf_track(void *arg, struct ifnet *ifp, int attach) +bpf_track(void *arg, struct ifnet *ifp, int dlt, int attach) { /* NB: identify vap's by if_start */ - if (ifp->if_start == ieee80211_start) { + if (dlt == DLT_IEEE802_11_RADIO && ifp->if_start == ieee80211_start) { struct ieee80211vap *vap = ifp->if_softc; /* * Track bpf radiotap listener state. We mark the vap From a6c3cf3eca414028017fa8362c2d4e21797794f3 Mon Sep 17 00:00:00 2001 From: Sam Leffler Date: Mon, 25 May 2009 16:38:47 +0000 Subject: [PATCH 522/544] Fix handling of devices w/o radiotap support: o do not attach DLT_IEEE802_11_RADIO unless both tx and rx headers are present; this is assumed in the capture code paths o verify the above with asserts in ieee80211_radiotap_{rx,tx} o add missing checks for active taps before calling ieee80211_radiotap_rx --- sys/net80211/ieee80211_adhoc.c | 2 +- sys/net80211/ieee80211_hostap.c | 2 +- sys/net80211/ieee80211_monitor.c | 3 ++- sys/net80211/ieee80211_radiotap.c | 14 ++++++++------ sys/net80211/ieee80211_sta.c | 2 +- sys/net80211/ieee80211_wds.c | 2 +- 6 files changed, 14 insertions(+), 11 deletions(-) diff --git a/sys/net80211/ieee80211_adhoc.c b/sys/net80211/ieee80211_adhoc.c index 8f3780899ff4..ed3f6f8fa4c3 100644 --- a/sys/net80211/ieee80211_adhoc.c +++ b/sys/net80211/ieee80211_adhoc.c @@ -656,7 +656,7 @@ adhoc_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap) + if (need_tap && ieee80211_radiotap_active_vap(vap)) ieee80211_radiotap_rx(vap, m); m_freem(m); } diff --git a/sys/net80211/ieee80211_hostap.c b/sys/net80211/ieee80211_hostap.c index 9264a71a3970..ee83eacef112 100644 --- a/sys/net80211/ieee80211_hostap.c +++ b/sys/net80211/ieee80211_hostap.c @@ -850,7 +850,7 @@ hostap_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap) + if (need_tap && ieee80211_radiotap_active_vap(vap)) ieee80211_radiotap_rx(vap, m); m_freem(m); } diff --git a/sys/net80211/ieee80211_monitor.c b/sys/net80211/ieee80211_monitor.c index 119c87d0dff8..3f2c847e26bd 100644 --- a/sys/net80211/ieee80211_monitor.c +++ b/sys/net80211/ieee80211_monitor.c @@ -128,7 +128,8 @@ monitor_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) { struct ieee80211vap *vap = ni->ni_vap; - ieee80211_radiotap_rx(vap, m); + if (ieee80211_radiotap_active_vap(vap)) + ieee80211_radiotap_rx(vap, m); m_freem(m); return -1; } diff --git a/sys/net80211/ieee80211_radiotap.c b/sys/net80211/ieee80211_radiotap.c index 2c4482f716e7..9c8dc4dcdd0b 100644 --- a/sys/net80211/ieee80211_radiotap.c +++ b/sys/net80211/ieee80211_radiotap.c @@ -102,12 +102,12 @@ ieee80211_radiotap_vattach(struct ieee80211vap *vap) struct ieee80211com *ic = vap->iv_ic; struct ieee80211_radiotap_header *th = ic->ic_th; - KASSERT(th != NULL, ("no radiotap setup")); - - /* radiotap DLT for raw 802.11 frames */ - bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + le16toh(th->it_len), - &vap->iv_rawbpf); + if (th != NULL && ic->ic_rh != NULL) { + /* radiotap DLT for raw 802.11 frames */ + bpfattach2(vap->iv_ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + le16toh(th->it_len), + &vap->iv_rawbpf); + } } void @@ -193,6 +193,7 @@ dispatch_radiotap(struct ieee80211vap *vap0, struct mbuf *m, void ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m) { + KASSERT(vap0->iv_ic->ic_th != NULL, ("no tx radiotap header")); dispatch_radiotap(vap0, m, vap0->iv_ic->ic_th); } @@ -202,6 +203,7 @@ ieee80211_radiotap_tx(struct ieee80211vap *vap0, struct mbuf *m) void ieee80211_radiotap_rx(struct ieee80211vap *vap0, struct mbuf *m) { + KASSERT(vap0->iv_ic->ic_rh != NULL, ("no rx radiotap header")); dispatch_radiotap(vap0, m, vap0->iv_ic->ic_rh); } diff --git a/sys/net80211/ieee80211_sta.c b/sys/net80211/ieee80211_sta.c index 9a529172ef04..0dee283c217d 100644 --- a/sys/net80211/ieee80211_sta.c +++ b/sys/net80211/ieee80211_sta.c @@ -885,7 +885,7 @@ sta_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap) + if (need_tap && ieee80211_radiotap_active_vap(vap)) ieee80211_radiotap_rx(vap, m); m_freem(m); } diff --git a/sys/net80211/ieee80211_wds.c b/sys/net80211/ieee80211_wds.c index 85ab5448814b..fb2ada9915d6 100644 --- a/sys/net80211/ieee80211_wds.c +++ b/sys/net80211/ieee80211_wds.c @@ -797,7 +797,7 @@ wds_input(struct ieee80211_node *ni, struct mbuf *m, int rssi, int nf) ifp->if_ierrors++; out: if (m != NULL) { - if (need_tap) + if (need_tap && ieee80211_radiotap_active_vap(vap)) ieee80211_radiotap_rx(vap, m); m_freem(m); } From 09c398cabf201f7374ca50d01fe246d4cf8bfc89 Mon Sep 17 00:00:00 2001 From: Mark Murray Date: Mon, 25 May 2009 17:06:24 +0000 Subject: [PATCH 523/544] Euro is missing With this I shall see it fixed Thank you for your time --- share/syscons/keymaps/uk.iso-ctrl.kbd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/share/syscons/keymaps/uk.iso-ctrl.kbd b/share/syscons/keymaps/uk.iso-ctrl.kbd index 986ec754c60a..2225c30e228f 100644 --- a/share/syscons/keymaps/uk.iso-ctrl.kbd +++ b/share/syscons/keymaps/uk.iso-ctrl.kbd @@ -8,7 +8,7 @@ 002 '1' '!' nop nop '`' '`' nop nop O 003 '2' '"' nul nul '@' '@' nul nul O 004 '3' 163 nop nop '#' '#' nop nop O - 005 '4' '$' nop nop '4' '$' nop nop O + 005 '4' '$' 164 164 '4' '$' nop nop O 006 '5' '%' nop nop '5' '%' nop nop O 007 '6' '^' rs rs '^' '^' rs rs O 008 '7' '&' nop nop '[' '[' esc esc O From 4b54fa116c2285a61518456b6ad57d306fc373a3 Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Mon, 25 May 2009 20:07:41 +0000 Subject: [PATCH 524/544] Fix kdump build when building it by hand. I don't entirely like this approach, but it will only be temporarily, namely until we get rid of COMPAT_43TTY. I do want to cause a compiler error when included, because it's just there for binary compatibility. Reported by: Andrzej Tobola --- usr.bin/kdump/mkioctls | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/kdump/mkioctls b/usr.bin/kdump/mkioctls index 1f99c5a23c08..9c7e9342017c 100644 --- a/usr.bin/kdump/mkioctls +++ b/usr.bin/kdump/mkioctls @@ -32,7 +32,7 @@ ioctl_includes=` ` awk -v x="$ioctl_includes" 'BEGIN {print x}' | - gcc -E -I$1 -dM - | + gcc -E -I$1 -dM -DCOMPAT_43TTY - | awk -v ioctl_includes="$ioctl_includes" -v use_switch="$use_switch" ' BEGIN { print "/* XXX obnoxious prerequisites. */" From 1496abde066c452449caeb3e0e67b69999e4f812 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 25 May 2009 21:27:31 +0000 Subject: [PATCH 525/544] Bump the document date to reflect the 'p' command enhancements. Suggested by: trhodes --- sbin/fdisk/fdisk.8 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sbin/fdisk/fdisk.8 b/sbin/fdisk/fdisk.8 index 0ffdeff9b937..1d042397cd76 100644 --- a/sbin/fdisk/fdisk.8 +++ b/sbin/fdisk/fdisk.8 @@ -1,6 +1,6 @@ .\" $FreeBSD$ .\" -.Dd April 30, 2007 +.Dd May 24, 2009 .Dt FDISK 8 .Os .Sh NAME From f1b746f92da39e7a80c18963389c3addf55a77e0 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Mon, 25 May 2009 21:29:06 +0000 Subject: [PATCH 526/544] Bump the document date to reflect the recent address range enhancements. Suggested by: throdes --- usr.bin/sed/sed.1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr.bin/sed/sed.1 b/usr.bin/sed/sed.1 index 2481ac2719e2..d5858ffc82f1 100644 --- a/usr.bin/sed/sed.1 +++ b/usr.bin/sed/sed.1 @@ -31,7 +31,7 @@ .\" @(#)sed.1 8.2 (Berkeley) 12/30/93 .\" $FreeBSD$ .\" -.Dd August 24, 2008 +.Dd May 24, 2009 .Dt SED 1 .Os .Sh NAME From 84e17f8297aa45ffff75e858e5a51238c8d6c9de Mon Sep 17 00:00:00 2001 From: Mark Murray Date: Mon, 25 May 2009 22:50:11 +0000 Subject: [PATCH 527/544] There is rubbish here It is time to take it out Now it is cleaner --- sys/dev/random/nehemiah.c | 2 +- sys/dev/random/randomdev_soft.c | 17 +++++++---------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/sys/dev/random/nehemiah.c b/sys/dev/random/nehemiah.c index 3001b2030e11..e34cdfa03ba1 100644 --- a/sys/dev/random/nehemiah.c +++ b/sys/dev/random/nehemiah.c @@ -129,7 +129,7 @@ random_nehemiah_init(void) { acw.raw = 0ULL; acw.field.round_count = 12; - + mtx_init(&random_nehemiah_mtx, "random nehemiah", NULL, MTX_DEF); } diff --git a/sys/dev/random/randomdev_soft.c b/sys/dev/random/randomdev_soft.c index dfe589ae643e..cef64ab6f746 100644 --- a/sys/dev/random/randomdev_soft.c +++ b/sys/dev/random/randomdev_soft.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2000-2004 Mark R V Murray + * Copyright (c) 2000-2009 Mark R V Murray * Copyright (c) 2004 Robert N. M. Watson * All rights reserved. * @@ -56,7 +56,7 @@ __FBSDID("$FreeBSD$"); #define RANDOM_FIFO_MAX 256 /* How many events to queue up */ static void random_kthread(void *); -static void +static void random_harvest_internal(u_int64_t, const void *, u_int, u_int, u_int, enum esource); static int random_yarrow_poll(int event,struct thread *td); @@ -235,7 +235,7 @@ random_kthread(void *arg __unused) { STAILQ_HEAD(, harvest) local_queue; struct harvest *event = NULL; - int active, local_count; + int local_count; enum esource source; STAILQ_INIT(&local_queue); @@ -244,8 +244,6 @@ random_kthread(void *arg __unused) /* Process until told to stop */ for (; random_kthread_control >= 0;) { - active = 0; - /* Cycle through all the entropy sources */ mtx_lock_spin(&harvest_mtx); for (source = RANDOM_START; source < ENTROPYSOURCE; source++) { @@ -284,9 +282,8 @@ random_kthread(void *arg __unused) if (random_kthread_control == 1) random_kthread_control = 0; - /* Found nothing, so don't belabour the issue */ - if (!active) - pause("-", hz / 10); + /* Work done, so don't belabour the issue */ + pause("-", hz / 10); } @@ -381,7 +378,7 @@ random_yarrow_poll(int events, struct thread *td) revents = events & (POLLIN | POLLRDNORM); else selrecord(td, &random_systat.rsel); - + mtx_unlock(&random_reseed_mtx); return revents; } @@ -407,7 +404,7 @@ random_yarrow_block(int flag) mtx_unlock(&random_reseed_mtx); return error; -} +} /* Helper routine to perform explicit reseeds */ static void From cc7d853dfcb83a764bb7bc55345bb813745ca28f Mon Sep 17 00:00:00 2001 From: Mark Murray Date: Mon, 25 May 2009 23:06:46 +0000 Subject: [PATCH 528/544] I have been here long The duration I know not I tell what I can --- share/misc/committers-src.dot | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/share/misc/committers-src.dot b/share/misc/committers-src.dot index a1bf5b24a7cd..1b9f22cdc1b1 100644 --- a/share/misc/committers-src.dot +++ b/share/misc/committers-src.dot @@ -127,6 +127,7 @@ linimon [label="Mark Linimon\nlinimon@FreeBSD.org\n2006/09/30"] lstewart [label="Lawrence Stewart\nlstewart@FreeBSD.org\n2008/10/06"] lulf [label="Ulf Lilleengen\nlulf@FreeBSD.org\n2007/10/24"] marcel [label="Marcel Moolenaar\nmarcel@FreeBSD.org\n1999/07/03"] +markm [label="Mark Murray\nmarkm@FreeBSD.org\n199?/??/??"] marks [label="Mark Santcroos\nmarks@FreeBSD.org\n2004/03/18"] markus [label="Markus Brueffer\nmarkus@FreeBSD.org\n2006/06/01"] matteo [label="Matteo Riondato\nmatteo@FreeBSD.org\n2006/01/18"] @@ -344,6 +345,8 @@ marcel -> arun marcel -> marius marcel -> nwhitehorn +markm -> sheldonh + mdodd -> jake mlaier -> benjsc @@ -378,6 +381,8 @@ philip -> matteo pjd -> lulf +rgrimes -> markm + rpaulo -> avg ru -> ceri From 7dcdb93f9181918bb3f7e91225f106a62dc0cd1c Mon Sep 17 00:00:00 2001 From: Doug Barton Date: Tue, 26 May 2009 00:07:02 +0000 Subject: [PATCH 529/544] Per the man page: The makekey utility has been deprecated and will be removed in a future release of FreeBSD. Actually removing it was approved back on 10/29/2007 by re (kensmith) but I dropped the ball on actually removing it. It's doubtful that it's become more relevant/useful in the intervening time. --- libexec/Makefile | 1 - libexec/makekey/Makefile | 10 ----- libexec/makekey/makekey.8 | 69 -------------------------------- libexec/makekey/makekey.c | 84 --------------------------------------- 4 files changed, 164 deletions(-) delete mode 100644 libexec/makekey/Makefile delete mode 100644 libexec/makekey/makekey.8 delete mode 100644 libexec/makekey/makekey.c diff --git a/libexec/Makefile b/libexec/Makefile index 04fc38b349f1..72ec91315afe 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -11,7 +11,6 @@ SUBDIR= ${_atrun} \ getty \ lukemftpd \ ${_mail.local} \ - makekey \ ${_mknetid} \ ${_pppoed} \ rbootd \ diff --git a/libexec/makekey/Makefile b/libexec/makekey/Makefile deleted file mode 100644 index d09f8127dc21..000000000000 --- a/libexec/makekey/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# @(#)Makefile 8.1 (Berkeley) 6/4/93 -# $FreeBSD$ - -PROG= makekey -MAN= makekey.8 - -DPADD= ${LIBCRYPT} -LDADD= -lcrypt - -.include diff --git a/libexec/makekey/makekey.8 b/libexec/makekey/makekey.8 deleted file mode 100644 index 7f7f054d012b..000000000000 --- a/libexec/makekey/makekey.8 +++ /dev/null @@ -1,69 +0,0 @@ -.\" Copyright (c) 1990, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. All advertising materials mentioning features or use of this software -.\" must display the following acknowledgement: -.\" This product includes software developed by the University of -.\" California, Berkeley and its contributors. -.\" 4. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)makekey.8 8.2 (Berkeley) 12/11/93 -.\" $FreeBSD$ -.\" -.Dd October 8, 2003 -.Dt MAKEKEY 8 -.Os -.Sh NAME -.Nm makekey -.Nd make encrypted keys or passwords -.Sh SYNOPSIS -.Nm -.Sh DESCRIPTION -.Bf Em -The -.Nm -utility has been deprecated and will be removed in a future release of -.Fx . -.Ef -.Pp -The -.Nm -utility encrypts a key and salt which it reads from the standard input -and writes the result to the standard output. -The key is expected to be -eight bytes; the salt is expected to be two bytes. -See -.Xr crypt 3 -for more information on what characters the key and salt can contain -and how the encrypted value is calculated. -.Sh SEE ALSO -.Xr login 1 , -.Xr openssl 1 , -.Xr crypt 3 -.Sh HISTORY -A -.Nm -utility appeared in -.At v7 . diff --git a/libexec/makekey/makekey.c b/libexec/makekey/makekey.c deleted file mode 100644 index 2b541bf87b63..000000000000 --- a/libexec/makekey/makekey.c +++ /dev/null @@ -1,84 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#ifndef lint -static const char copyright[] = -"@(#) Copyright (c) 1990, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; -#endif /* not lint */ - -#ifndef lint -#if 0 -static char sccsid[] = "@(#)makekey.c 8.1 (Berkeley) 6/4/93"; -#endif -static const char rcsid[] = - "$FreeBSD$"; -#endif /* not lint */ - -#include - -#include -#include -#include -#include -#include -#include - -static void get(char *, int); - -int -main(int argc __unused, char *argv[] __unused) -{ - int len; - char *r, key[9], salt[3]; - - get(key, sizeof(key) - 1); - get(salt, sizeof(salt) - 1); - len = strlen(r = crypt(key, salt)); - if (write(STDOUT_FILENO, r, len) != len) - err(1, "stdout"); - exit(0); -} - -static void -get(char *bp, int len) -{ - int nr; - - bp[len] = '\0'; - if ((nr = read(STDIN_FILENO, bp, len)) == len) - return; - if (nr >= 0) - errno = EFTYPE; - err(1, "stdin"); -} From 415670e4c2d53cf74bf05f738e30bca222d3ffd9 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 26 May 2009 01:09:33 +0000 Subject: [PATCH 530/544] Fix the experimental nfs server's interface to the new krpc so that it handles the case of a non-exported NFSv4 root correctly. Also, delete handling for the case where nd_repstat is already set in nfs_proc(), since that no longer happens. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdkrpc.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index f0b57655dc59..dde5f3bd556d 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -210,8 +210,15 @@ nfssvc_program(struct svc_req *rqst, SVCXPRT *xprt) #ifdef MAC mac_cred_associate_nfsd(nd.nd_cred); #endif - if ((nd.nd_flag & ND_NFSV4)) + if ((nd.nd_flag & ND_NFSV4) != 0) { nd.nd_repstat = nfsvno_v4rootexport(&nd); + if (nd.nd_repstat != 0) { + svcerr_weakauth(rqst); + svc_freereq(rqst); + m_freem(nd.nd_mrep); + return; + } + } cacherep = nfs_proc(&nd, rqst->rq_xid, xprt->xp_socket, xprt->xp_sockref, &rp); @@ -272,22 +279,17 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, struct socket *so, NFSGETTIME(&nd->nd_starttime); /* - * Several cases: + * Two cases: * 1 - For NFSv2 over UDP, if we are near our malloc/mget * limit, just drop the request. There is no * NFSERR_RESOURCE or NFSERR_DELAY for NFSv2 and the * client will timeout/retry over UDP in a little while. - * 2 - nd_repstat set to some error, so generate the reply now. - * 3 - nd_repstat == 0 && nd_mreq == NULL, which + * 2 - nd_repstat == 0 && nd_mreq == NULL, which * means a normal nfs rpc, so check the cache */ if ((nd->nd_flag & ND_NFSV2) && nd->nd_nam2 != NULL && nfsrv_mallocmget_limit()) { cacherep = RC_DROPIT; - } else if (nd->nd_repstat) { - cacherep = RC_REPLY; - if ((nd->nd_flag & ND_NFSV4) == 0) - panic("nfs_repstat for nfsv2,3"); } else { /* * For NFSv3, play it safe and assume that the client is @@ -315,9 +317,6 @@ nfs_proc(struct nfsrv_descript *nd, u_int32_t xid, struct socket *so, else cacherep = RC_REPLY; *rpp = nfsrvd_updatecache(nd, so); - } else if (cacherep == RC_REPLY) { - /* Generate the error reply message for NFSv4 */ - nfsrvd_dorpc(nd, isdgram, td); } return (cacherep); } From 9183a2a33e1a5974ecd0c35681b9f4a09d285386 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 26 May 2009 01:16:09 +0000 Subject: [PATCH 531/544] Fix the handling of NFSv4 Illegal Operation number to conform to RFC3530 (the operation number in the reply must be set to the value for OP_ILLEGAL). Also cleaned up some indentation. Approved by: kib (mentor) --- sys/fs/nfs/nfsport.h | 3 +++ sys/fs/nfsserver/nfs_nfsdsocket.c | 25 ++++++++++++++----------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/sys/fs/nfs/nfsport.h b/sys/fs/nfs/nfsport.h index c1aa06140fb9..71b6cb470bb0 100644 --- a/sys/fs/nfs/nfsport.h +++ b/sys/fs/nfs/nfsport.h @@ -235,6 +235,9 @@ */ #define NFSV4OP_NOPS 40 +/* Quirky case if the illegal op code */ +#define NFSV4OP_OPILLEGAL 10044 + /* * Fake NFSV4OP_xxx used for nfsstat. Start at NFSV4OP_NOPS. */ diff --git a/sys/fs/nfsserver/nfs_nfsdsocket.c b/sys/fs/nfsserver/nfs_nfsdsocket.c index 54307bc38e43..fc6e39e63cfd 100644 --- a/sys/fs/nfsserver/nfs_nfsdsocket.c +++ b/sys/fs/nfsserver/nfs_nfsdsocket.c @@ -639,13 +639,16 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, for (i = 0; i < numops; i++) { NFSM_DISSECT(tl, u_int32_t *, NFSX_UNSIGNED); NFSM_BUILD(repp, u_int32_t *, 2 * NFSX_UNSIGNED); - *repp++ = *tl; + *repp = *tl; op = fxdr_unsigned(int, *tl); if (op < NFSV4OP_ACCESS || op >= NFSV4OP_NOPS) { - nd->nd_repstat = NFSERR_OPILLEGAL; - *repp = nfsd_errmap(nd); - retops++; - break; + nd->nd_repstat = NFSERR_OPILLEGAL; + *repp++ = txdr_unsigned(NFSV4OP_OPILLEGAL); + *repp = nfsd_errmap(nd); + retops++; + break; + } else { + repp++; } /* @@ -682,12 +685,12 @@ nfsrvd_compound(struct nfsrv_descript *nd, int isdgram, nd->nd_repstat = NFSERR_RESOURCE; *repp = nfsd_errmap(nd); if (op == NFSV4OP_SETATTR) { - /* - * Setattr replies require a bitmap. - * even for errors like these. - */ - NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); - *tl = 0; + /* + * Setattr replies require a bitmap. + * even for errors like these. + */ + NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED); + *tl = 0; } retops++; break; From 10a5a16efa9cc51b4a68c30ee2eb14d96f14be0f Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 26 May 2009 01:47:37 +0000 Subject: [PATCH 532/544] Add two sysctl variables to the experimental nfs server, so that the range of versions of NFS handled by the server can be limited. The nfsd daemon must be restarted after these sysctl variables are changed, in order for the change to take effect. Approved by: kib (mentor) --- sys/fs/nfsserver/nfs_nfsdkrpc.c | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/sys/fs/nfsserver/nfs_nfsdkrpc.c b/sys/fs/nfsserver/nfs_nfsdkrpc.c index dde5f3bd556d..e1179554d7f9 100644 --- a/sys/fs/nfsserver/nfs_nfsdkrpc.c +++ b/sys/fs/nfsserver/nfs_nfsdkrpc.c @@ -82,6 +82,14 @@ SYSCTL_INT(_vfs_newnfs, OID_AUTO, nfs_privport, CTLFLAG_RW, &nfs_privport, 0, "Only allow clients using a privileged port for NFSv2 and 3"); +static int nfs_minvers = NFS_VER2; +SYSCTL_INT(_vfs_newnfs, OID_AUTO, server_min_nfsvers, CTLFLAG_RW, + &nfs_minvers, 0, "The lowest version of NFS handled by the server"); + +static int nfs_maxvers = NFS_VER4; +SYSCTL_INT(_vfs_newnfs, OID_AUTO, server_max_nfsvers, CTLFLAG_RW, + &nfs_maxvers, 0, "The highest version of NFS handled by the server"); + static int nfs_proc(struct nfsrv_descript *, u_int32_t, struct socket *, u_int64_t, struct nfsrvcache **); @@ -353,9 +361,15 @@ nfsrvd_addsock(struct file *fp) fp->f_ops = &badfileops; fp->f_data = NULL; xprt->xp_sockref = ++sockref; - svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, NULL); - svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, NULL); - svc_reg(xprt, NFS_PROG, NFS_VER4, nfssvc_program, NULL); + if (nfs_minvers == NFS_VER2) + svc_reg(xprt, NFS_PROG, NFS_VER2, nfssvc_program, + NULL); + if (nfs_minvers <= NFS_VER3 && nfs_maxvers >= NFS_VER3) + svc_reg(xprt, NFS_PROG, NFS_VER3, nfssvc_program, + NULL); + if (nfs_maxvers >= NFS_VER4) + svc_reg(xprt, NFS_PROG, NFS_VER4, nfssvc_program, + NULL); } return (0); From 92e839c63879eb220347f51b9a1abb2e56fa9e5f Mon Sep 17 00:00:00 2001 From: Benjamin Close Date: Tue, 26 May 2009 03:56:56 +0000 Subject: [PATCH 533/544] Free the memory correctly in the error case Submitted by: frtzkatz at yahoo.com Approved by: sam MFC after: 1 month --- sys/dev/bktr/bktr_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bktr/bktr_os.c b/sys/dev/bktr/bktr_os.c index 1e0010f37eb8..7b44a47540db 100644 --- a/sys/dev/bktr/bktr_os.c +++ b/sys/dev/bktr/bktr_os.c @@ -470,7 +470,7 @@ bktr_attach( device_t dev ) if (bktr->res_irq) bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq); if (bktr->res_mem) - bus_release_resource(dev, SYS_RES_IRQ, bktr->mem_rid, bktr->res_mem); + bus_release_resource(dev, SYS_RES_MEM, bktr->mem_rid, bktr->res_mem); return error; } From 816192653fc25bd6d2d9be1bca63605ff67d48a8 Mon Sep 17 00:00:00 2001 From: Rafal Jaworowski Date: Tue, 26 May 2009 06:24:50 +0000 Subject: [PATCH 534/544] Set PG_WRITEABLE in Book-E pmap_enter[_locked] if it creates a mapping that permits write access. This is similar to r192671. Pointed out and reviewed by: alc --- sys/powerpc/booke/pmap.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sys/powerpc/booke/pmap.c b/sys/powerpc/booke/pmap.c index ff8a6d4d8ca1..961836cdeaa7 100644 --- a/sys/powerpc/booke/pmap.c +++ b/sys/powerpc/booke/pmap.c @@ -1574,6 +1574,8 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, flags |= PTE_SW; if (!su) flags |= PTE_UW; + + vm_page_flag_set(m, PG_WRITEABLE); } else { /* Handle modified pages, sense modify status. */ @@ -1638,6 +1640,8 @@ mmu_booke_enter_locked(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, flags |= PTE_SW; if (!su) flags |= PTE_UW; + + vm_page_flag_set(m, PG_WRITEABLE); } if (prot & VM_PROT_EXECUTE) { From bf7d2c17971e008aeca69413f76dfb453241b7aa Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 26 May 2009 07:29:17 +0000 Subject: [PATCH 535/544] - Add 'show bio' DDB command. MFC after: 3 weeks --- sys/geom/geom_subr.c | 70 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index b67c0d576656..d9f6244c892d 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1258,6 +1258,76 @@ DB_SHOW_COMMAND(geom, db_show_geom) } } +static void +db_print_bio_cmd(struct bio *bp) +{ + printf(" cmd: "); + switch (bp->bio_cmd) { + case BIO_READ: printf("BIO_READ"); break; + case BIO_WRITE: printf("BIO_WRITE"); break; + case BIO_DELETE: printf("BIO_DELETE"); break; + case BIO_GETATTR: printf("BIO_GETATTR"); break; + case BIO_FLUSH: printf("BIO_FLUSH"); break; + case BIO_CMD0: printf("BIO_CMD0"); break; + case BIO_CMD1: printf("BIO_CMD1"); break; + case BIO_CMD2: printf("BIO_CMD2"); break; + default: printf("UNKNOWN"); break; + } + printf("\n"); +} + +static void +db_print_bio_flags(struct bio *bp) +{ + int comma; + + comma = 0; + printf(" flags: "); + if (bp->bio_flags & BIO_ERROR) { + printf("BIO_ERROR"); + comma = 1; + } + if (bp->bio_flags & BIO_DONE) { + printf("%sBIO_ERROR", (comma ? ", " : "")); + comma = 1; + } + if (bp->bio_flags & BIO_ONQUEUE) + printf("%sBIO_ONQUEUE", (comma ? ", " : "")); + printf("\n"); +} + +/* + * Print useful information in a BIO + */ +DB_SHOW_COMMAND(bio, db_show_bio) +{ + struct bio *bp; + + if (have_addr) { + bp = (struct bio *)addr; + printf("BIO %p\n", bp); + db_print_bio_cmd(bp); + db_print_bio_flags(bp); + printf(" cflags: 0x%hhx\n", bp->bio_cflags); + printf(" pflags: 0x%hhx\n", bp->bio_pflags); + printf(" offset: %lld\n", bp->bio_offset); + printf(" length: %lld\n", bp->bio_length); + printf(" bcount: %ld\n", bp->bio_bcount); + printf(" resid: %ld\n", bp->bio_resid); + printf(" completed: %lld\n", bp->bio_completed); + printf(" children: %u\n", bp->bio_children); + printf(" inbed: %u\n", bp->bio_inbed); + printf(" error: %d\n", bp->bio_error); + printf(" parent: %p\n", bp->bio_parent); + printf(" driver1: %p\n", bp->bio_driver1); + printf(" driver2: %p\n", bp->bio_driver2); + printf(" caller1: %p\n", bp->bio_caller1); + printf(" caller2: %p\n", bp->bio_caller2); + printf(" bio_from: %p\n", bp->bio_from); + printf(" bio_to: %p\n", bp->bio_to); + } +} + #undef gprintf #undef gprintln #undef ADDFLAG From 096d622d17a1b94c559a27ce84cc16c83aa98b12 Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Tue, 26 May 2009 07:32:08 +0000 Subject: [PATCH 536/544] Fix a race that can stall the timer when we remove a timer that has another timer with a <0.05 second delta next to it. This is done by avoiding the possibility of updating the first residual time delta in the timer list to zero. PR: 102747 Submitted by: Sergey Zaharchenko - doublef-ctm at yandex dot ru MFC after: 3 weeks --- usr.sbin/ppp/timer.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/usr.sbin/ppp/timer.c b/usr.sbin/ppp/timer.c index 77b2af7e4f44..c1b589b78ef3 100644 --- a/usr.sbin/ppp/timer.c +++ b/usr.sbin/ppp/timer.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 1996 - 2001 Brian Somers + * Copyright (c) 1996 - 2001, 2009 Brian Somers * based on work by Toshiharu OHNO * Internet Initiative Japan, Inc (IIJ) * All rights reserved. @@ -94,9 +94,12 @@ timer_Start(struct pppTimer *tp) return; } - /* Adjust our first delta so that it reflects what's really happening */ + /* + * We just need to insert tp in the correct relative place. We don't + * need to adjust TimerList->rest (yet). + */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = RESTVAL(itimer); + ticks = RESTVAL(itimer) - TimerList->rest; pt = NULL; for (t = TimerList; t; t = t->next) { @@ -132,6 +135,7 @@ timer_Start(struct pppTimer *tp) static void StopTimerNoBlock(struct pppTimer *tp) { + struct itimerval itimer; struct pppTimer *t, *pt; /* @@ -156,14 +160,11 @@ StopTimerNoBlock(struct pppTimer *tp) timer_TermService(); /* Terminate Timer Service */ } if (t->next) { - if (!pt) { /* t (tp) was the first in the list */ - struct itimerval itimer; - - if (getitimer(ITIMER_REAL, &itimer) == 0) - t->rest = RESTVAL(itimer); - } - t->next->rest += t->rest; - if (!pt) /* t->next is now the first in the list */ + if (!pt && getitimer(ITIMER_REAL, &itimer) == 0) + t->next->rest += RESTVAL(itimer); /* t (tp) was the first in the list */ + else + t->next->rest += t->rest; + if (!pt && t->next->rest > 0) /* t->next is now the first in the list */ timer_InitService(1); } } else { @@ -235,11 +236,19 @@ timer_Show(int LogLevel, struct prompt *prompt) { struct itimerval itimer; struct pppTimer *pt; - u_long rest = 0; + long rest; - /* Adjust our first delta so that it reflects what's really happening */ + /* + * Adjust the base time so that the deltas reflect what's really + * happening. Changing TimerList->rest might cause it to become zero + * (if getitimer() returns a value close to zero), and the + * timer_InitService() call will call setitimer() with zero it_value, + * stopping the itimer... so be careful! + */ if (TimerList && getitimer(ITIMER_REAL, &itimer) == 0) - TimerList->rest = RESTVAL(itimer); + rest = RESTVAL(itimer) - TimerList->rest; + else + rest = 0; #define SECS(val) ((val) / SECTICKS) #define HSECS(val) (((val) % SECTICKS) * 100 / SECTICKS) From a063878a50beb4e1af5cca0c91cfe62966e129dc Mon Sep 17 00:00:00 2001 From: Brian Somers Date: Tue, 26 May 2009 07:40:32 +0000 Subject: [PATCH 537/544] Mention the danger of running programs using ``!''. PR: 112481 MFC after: 1 week --- share/examples/ppp/ppp.linkup.sample | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/share/examples/ppp/ppp.linkup.sample b/share/examples/ppp/ppp.linkup.sample index 18073cf712e7..f061147231de 100644 --- a/share/examples/ppp/ppp.linkup.sample +++ b/share/examples/ppp/ppp.linkup.sample @@ -30,11 +30,16 @@ MYADDR: 192.244.176.32: add 192.244.176.0 0 HISADDR -#You may want to execute a script after connecting. This script can do +# You may want to execute a script after connecting. This script can do # nice things such as kick off "sendmail -q", "popclient my.isp" and # "slurp -d news". It can be passed MYADDR, HISADDR and INTERFACE # as arguments too - useful for informing a DNS of your assigned IP. # +# NOTE: It's vital that you use ``!bg'' rather than ``!'' if the program +# you're running will take some time or will require network +# connectivity. Using ``!'' will delay ppp 'till the completion +# of the program being run! +# # You may also want some sound effects.... # pmdemand: From 0970b4bae0839ecdc2fc1dbc9bb05ec75b58eadf Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 26 May 2009 08:21:59 +0000 Subject: [PATCH 538/544] MFp4 changes neccessary for NFSv4 ACLs support in ZFS. This is mostly about removing a few #ifdefs and providing compatibility wrappers and VOP implementations to get and set an ACL; ZFS does ACL enforcement all by itself. Note that the VOPs are ifdefed out for now, so this change should be a no-op. Reviewed by: pjd --- .../compat/opensolaris/kern/opensolaris_acl.c | 216 ++++++++++++++++++ sys/cddl/compat/opensolaris/sys/acl.h | 39 ++++ .../opensolaris/common/acl/acl_common.c | 4 +- .../opensolaris/common/acl/acl_common.h | 2 + .../uts/common/fs/zfs/sys/zfs_acl.h | 2 - .../opensolaris/uts/common/fs/zfs/zfs_acl.c | 4 - .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 100 +++++++- .../contrib/opensolaris/uts/common/sys/acl.h | 14 +- .../opensolaris/uts/common/sys/acl_impl.h | 4 +- sys/modules/zfs/Makefile | 1 + 10 files changed, 370 insertions(+), 16 deletions(-) create mode 100644 sys/cddl/compat/opensolaris/kern/opensolaris_acl.c create mode 100644 sys/cddl/compat/opensolaris/sys/acl.h diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c b/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c new file mode 100644 index 000000000000..d5cc3e64aea1 --- /dev/null +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c @@ -0,0 +1,216 @@ +/*- + * Copyright (c) 2008, 2009 Edward Tomasz NapieraÅ‚a + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE + * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +struct zfs2bsd { + uint32_t zb_zfs; + int zb_bsd; +}; + +struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA}, + {ACE_WRITE_DATA, ACL_WRITE_DATA}, + {ACE_EXECUTE, ACL_EXECUTE}, + {ACE_APPEND_DATA, ACL_APPEND_DATA}, + {ACE_DELETE_CHILD, ACL_DELETE_CHILD}, + {ACE_DELETE, ACL_DELETE}, + {ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES}, + {ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES}, + {ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS}, + {ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS}, + {ACE_READ_ACL, ACL_READ_ACL}, + {ACE_WRITE_ACL, ACL_WRITE_ACL}, + {ACE_WRITE_OWNER, ACL_WRITE_OWNER}, + {ACE_SYNCHRONIZE, ACL_SYNCHRONIZE}, + {0, 0}}; + +struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE, + ACL_ENTRY_FILE_INHERIT}, + {ACE_DIRECTORY_INHERIT_ACE, + ACL_ENTRY_DIRECTORY_INHERIT}, + {ACE_NO_PROPAGATE_INHERIT_ACE, + ACL_ENTRY_NO_PROPAGATE_INHERIT}, + {ACE_INHERIT_ONLY_ACE, + ACL_ENTRY_INHERIT_ONLY}, + {ACE_SUCCESSFUL_ACCESS_ACE_FLAG, + ACL_ENTRY_SUCCESSFUL_ACCESS}, + {ACE_FAILED_ACCESS_ACE_FLAG, + ACL_ENTRY_FAILED_ACCESS}, + {0, 0}}; + +static int +_bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table) +{ + const struct zfs2bsd *tmp; + int bsd = 0; + + for (tmp = table; tmp->zb_zfs != 0; tmp++) { + if (zfs & tmp->zb_zfs) + bsd |= tmp->zb_bsd; + } + + return (bsd); +} + +static uint32_t +_zfs_from_bsd(int bsd, const struct zfs2bsd *table) +{ + const struct zfs2bsd *tmp; + uint32_t zfs = 0; + + for (tmp = table; tmp->zb_bsd != 0; tmp++) { + if (bsd & tmp->zb_bsd) + zfs |= tmp->zb_zfs; + } + + return (zfs); +} + +int +acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries) +{ + int i; + struct acl_entry *entry; + const ace_t *ace; + + KASSERT(nentries >= 1, ("empty ZFS ACL")); + + if (nentries > ACL_MAX_ENTRIES) { + /* + * I believe it may happen only when moving a pool + * from SunOS to FreeBSD. + */ + printf("acl_from_aces: ZFS ACL too big to fit " + "into 'struct acl'; returning EINVAL.\n"); + return (EINVAL); + } + + bzero(aclp, sizeof(*aclp)); + aclp->acl_maxcnt = ACL_MAX_ENTRIES; + aclp->acl_cnt = nentries; + + for (i = 0; i < nentries; i++) { + entry = &(aclp->acl_entry[i]); + ace = &(aces[i]); + + if (ace->a_flags & ACE_OWNER) + entry->ae_tag = ACL_USER_OBJ; + else if (ace->a_flags & ACE_GROUP) + entry->ae_tag = ACL_GROUP_OBJ; + else if (ace->a_flags & ACE_EVERYONE) + entry->ae_tag = ACL_EVERYONE; + else if (ace->a_flags & ACE_IDENTIFIER_GROUP) + entry->ae_tag = ACL_GROUP; + else + entry->ae_tag = ACL_USER; + + if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP) + entry->ae_id = ace->a_who; + else + entry->ae_id = ACL_UNDEFINED_ID; + + entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms); + entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags); + + switch (ace->a_type) { + case ACE_ACCESS_ALLOWED_ACE_TYPE: + entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW; + break; + case ACE_ACCESS_DENIED_ACE_TYPE: + entry->ae_entry_type = ACL_ENTRY_TYPE_DENY; + break; + case ACE_SYSTEM_AUDIT_ACE_TYPE: + entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT; + break; + case ACE_SYSTEM_ALARM_ACE_TYPE: + entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM; + break; + default: + panic("acl_from_aces: a_type is 0x%x", ace->a_type); + } + } + + return (0); +} + +void +aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp) +{ + int i; + const struct acl_entry *entry; + ace_t *ace; + + bzero(aces, sizeof(*aces) * aclp->acl_cnt); + + *nentries = aclp->acl_cnt; + + for (i = 0; i < aclp->acl_cnt; i++) { + entry = &(aclp->acl_entry[i]); + ace = &(aces[i]); + + ace->a_who = entry->ae_id; + + if (entry->ae_tag == ACL_USER_OBJ) + ace->a_flags = ACE_OWNER; + else if (entry->ae_tag == ACL_GROUP_OBJ) + ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP); + else if (entry->ae_tag == ACL_GROUP) + ace->a_flags = ACE_IDENTIFIER_GROUP; + else if (entry->ae_tag == ACL_EVERYONE) + ace->a_flags = ACE_EVERYONE; + else /* ACL_USER */ + ace->a_flags = 0; + + ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms); + ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags); + + switch (entry->ae_entry_type) { + case ACL_ENTRY_TYPE_ALLOW: + ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_DENY: + ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_ALARM: + ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE; + break; + case ACL_ENTRY_TYPE_AUDIT: + ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE; + break; + default: + panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type); + } + } +} diff --git a/sys/cddl/compat/opensolaris/sys/acl.h b/sys/cddl/compat/opensolaris/sys/acl.h new file mode 100644 index 000000000000..2bb0c5e2ca4e --- /dev/null +++ b/sys/cddl/compat/opensolaris/sys/acl.h @@ -0,0 +1,39 @@ +/*- + * Copyright (c) 2008, 2009 Edward Tomasz NapieraÅ‚a + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE + * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef OPENSOLARIS_SYS_ACL_H +#define OPENSOLARIS_SYS_ACL_H + +#include_next + +struct acl; + +void aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp); +int acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries); + +#endif /* OPENSOLARIS_SYS_ACL_H */ diff --git a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c index 8d0cc85f341c..5e8de19bae7a 100644 --- a/sys/cddl/contrib/opensolaris/common/acl/acl_common.c +++ b/sys/cddl/contrib/opensolaris/common/acl/acl_common.c @@ -424,7 +424,7 @@ cacl_free(void *ptr, size_t size) #endif } -#ifndef __FreeBSD__ +#if !defined(_KERNEL) acl_t * acl_alloc(enum acl_type type) { @@ -470,7 +470,6 @@ acl_free(acl_t *aclp) cacl_free(aclp, sizeof (acl_t)); } -#endif static uint32_t access_mask_set(int haswriteperm, int hasreadperm, int isowner, int isallow) @@ -1727,3 +1726,4 @@ acl_translate(acl_t *aclp, int target_flavor, int isdir, uid_t owner, return (error); #endif } +#endif /* _KERNEL */ diff --git a/sys/cddl/contrib/opensolaris/common/acl/acl_common.h b/sys/cddl/contrib/opensolaris/common/acl/acl_common.h index 84bd04f52fd6..85ba0bdd5e9a 100644 --- a/sys/cddl/contrib/opensolaris/common/acl/acl_common.h +++ b/sys/cddl/contrib/opensolaris/common/acl/acl_common.h @@ -46,6 +46,7 @@ extern int ace_trivial(ace_t *acep, int aclcnt); extern int ace_trivial_common(void *, int, uint64_t (*walk)(void *, uint64_t, int aclcnt, uint16_t *, uint16_t *, uint32_t *mask)); +#if !defined(_KERNEL) extern acl_t *acl_alloc(acl_type_t); extern void acl_free(acl_t *aclp); extern int acl_translate(acl_t *aclp, int target_flavor, @@ -53,6 +54,7 @@ extern int acl_translate(acl_t *aclp, int target_flavor, void ksort(caddr_t v, int n, int s, int (*f)()); int cmp2acls(void *a, void *b); +#endif /* _KERNEL */ #ifdef __cplusplus } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h index fe953184db44..df148c624945 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_acl.h @@ -188,10 +188,8 @@ struct zfs_fuid_info; #ifdef _KERNEL void zfs_perm_init(struct znode *, struct znode *, int, vattr_t *, dmu_tx_t *, cred_t *, zfs_acl_t *, zfs_fuid_info_t **); -#ifdef TODO int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); int zfs_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); -#endif void zfs_acl_rele(void *); void zfs_oldace_byteswap(ace_t *, int); void zfs_ace_byteswap(void *, size_t, boolean_t); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c index ec7d29e64f70..dfbebc240362 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c @@ -1909,7 +1909,6 @@ zfs_perm_init(znode_t *zp, znode_t *parent, int flag, zfs_acl_free(aclp); } -#ifdef TODO /* * Retrieve a files ACL */ @@ -2005,7 +2004,6 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) return (0); } -#endif /* TODO */ int zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, @@ -2062,7 +2060,6 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, return (0); } -#ifdef TODO /* * Set a files ACL */ @@ -2170,7 +2167,6 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) return (error); } -#endif /* TODO */ /* * working_mode returns the permissions that were not granted diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index f9b83c29d087..a7f47b2cec4a 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include @@ -67,6 +66,7 @@ #include #include #include +#include /* * Programming rules. @@ -3846,7 +3846,6 @@ zfs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr, } } -#ifdef TODO /*ARGSUSED*/ static int zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, @@ -3864,9 +3863,7 @@ zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, return (error); } -#endif /* TODO */ -#ifdef TODO /*ARGSUSED*/ static int zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, @@ -3883,7 +3880,6 @@ zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag, cred_t *cr, ZFS_EXIT(zfsvfs); return (error); } -#endif /* TODO */ static int zfs_freebsd_open(ap) @@ -4777,6 +4773,90 @@ vop_listextattr { return (error); } +int +zfs_freebsd_getacl(ap) + struct vop_getacl_args /* { + struct vnode *vp; + acl_type_t type; + struct acl *aclp; + struct ucred *cred; + struct thread *td; + } */ *ap; +{ + int error; + vsecattr_t vsecattr; + + if (ap->a_type != ACL_TYPE_NFS4) + return (EOPNOTSUPP); + + vsecattr.vsa_mask = VSA_ACE | VSA_ACECNT; + if (error = zfs_getsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL)) + return (error); + + error = acl_from_aces(ap->a_aclp, vsecattr.vsa_aclentp, vsecattr.vsa_aclcnt); + if (vsecattr.vsa_aclentp != NULL) + kmem_free(vsecattr.vsa_aclentp, vsecattr.vsa_aclentsz); + + return (error); +} + +int +zfs_freebsd_setacl(ap) + struct vop_setacl_args /* { + struct vnode *vp; + acl_type_t type; + struct acl *aclp; + struct ucred *cred; + struct thread *td; + } */ *ap; +{ + int error; + vsecattr_t vsecattr; + int aclbsize; /* size of acl list in bytes */ + aclent_t *aaclp; + + if (ap->a_type != ACL_TYPE_NFS4) + return (EOPNOTSUPP); + + if (ap->a_aclp->acl_cnt < 1 || ap->a_aclp->acl_cnt > MAX_ACL_ENTRIES) + return (EINVAL); + + /* + * With NFS4 ACLs, chmod(2) may need to add additional entries, + * splitting every entry into two and appending "canonical six" + * entries at the end. Don't allow for setting an ACL that would + * cause chmod(2) to run out of ACL entries. + */ + if (ap->a_aclp->acl_cnt * 2 + 6 > ACL_MAX_ENTRIES) + return (ENOSPC); + + vsecattr.vsa_mask = VSA_ACE; + aclbsize = ap->a_aclp->acl_cnt * sizeof(ace_t); + vsecattr.vsa_aclentp = kmem_alloc(aclbsize, KM_SLEEP); + aaclp = vsecattr.vsa_aclentp; + vsecattr.vsa_aclentsz = aclbsize; + + aces_from_acl(vsecattr.vsa_aclentp, &vsecattr.vsa_aclcnt, ap->a_aclp); + error = zfs_setsecattr(ap->a_vp, &vsecattr, 0, ap->a_cred, NULL); + kmem_free(aaclp, aclbsize); + + return (error); +} + +int +zfs_freebsd_aclcheck(ap) + struct vop_aclcheck_args /* { + struct vnode *vp; + acl_type_t type; + struct acl *aclp; + struct ucred *cred; + struct thread *td; + } */ *ap; +{ + + return (EOPNOTSUPP); +} + struct vop_vector zfs_vnodeops; struct vop_vector zfs_fifoops; @@ -4816,6 +4896,11 @@ struct vop_vector zfs_vnodeops = { .vop_deleteextattr = zfs_deleteextattr, .vop_setextattr = zfs_setextattr, .vop_listextattr = zfs_listextattr, +#ifdef notyet + .vop_getacl = zfs_freebsd_getacl, + .vop_setacl = zfs_freebsd_setacl, + .vop_aclcheck = zfs_freebsd_aclcheck, +#endif }; struct vop_vector zfs_fifoops = { @@ -4829,4 +4914,9 @@ struct vop_vector zfs_fifoops = { .vop_setattr = zfs_freebsd_setattr, .vop_write = VOP_PANIC, .vop_fid = zfs_freebsd_fid, +#ifdef notyet + .vop_getacl = zfs_freebsd_getacl, + .vop_setacl = zfs_freebsd_setacl, + .vop_aclcheck = zfs_freebsd_aclcheck, +#endif }; diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h index 27fd577371a9..f10fec629008 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/acl.h @@ -31,12 +31,22 @@ #include #include +#if defined(_KERNEL) +/* + * When compiling OpenSolaris kernel code, this file is getting + * included instead of FreeBSD one. Pull the original sys/acl.h as well. + */ +#undef _SYS_ACL_H +#include_next +#define _SYS_ACL_H +#endif /* _KERNEL */ + #ifdef __cplusplus extern "C" { #endif #define MAX_ACL_ENTRIES (1024) /* max entries of each type */ -typedef struct acl { +typedef struct { int a_type; /* the type of ACL entry */ uid_t a_id; /* the entry in -uid or gid */ o_mode_t a_perm; /* the permission field */ @@ -49,7 +59,9 @@ typedef struct ace { uint16_t a_type; /* allow or deny */ } ace_t; +#if !defined(_KERNEL) typedef struct acl_info acl_t; +#endif /* * The following are Defined types for an aclent_t. diff --git a/sys/cddl/contrib/opensolaris/uts/common/sys/acl_impl.h b/sys/cddl/contrib/opensolaris/uts/common/sys/acl_impl.h index b82f259143ac..878ddcbeb09f 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/sys/acl_impl.h +++ b/sys/cddl/contrib/opensolaris/uts/common/sys/acl_impl.h @@ -44,10 +44,10 @@ extern "C" { typedef enum acl_type { ACLENT_T = 0, ACE_T = 1 -} acl_type_t; +} zfs_acl_type_t; struct acl_info { - acl_type_t acl_type; /* style of acl */ + zfs_acl_type_t acl_type; /* style of acl */ int acl_cnt; /* number of acl entries */ int acl_entry_size; /* sizeof acl entry */ int acl_flags; /* special flags about acl */ diff --git a/sys/modules/zfs/Makefile b/sys/modules/zfs/Makefile index ae7ce471d26c..e5b9ad064f7f 100644 --- a/sys/modules/zfs/Makefile +++ b/sys/modules/zfs/Makefile @@ -16,6 +16,7 @@ SRCS+= nvpair.c SRCS+= u8_textprep.c .PATH: ${.CURDIR}/../../cddl/compat/opensolaris/kern +SRCS+= opensolaris_acl.c SRCS+= opensolaris_kmem.c SRCS+= opensolaris_kobj.c SRCS+= opensolaris_kstat.c From ce332f1e6732c01db77bf627718722fcc00a7316 Mon Sep 17 00:00:00 2001 From: Pawel Jakub Dawidek Date: Tue, 26 May 2009 09:19:21 +0000 Subject: [PATCH 539/544] Add missing socket options. --- sys/kern/uipc_debug.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sys/kern/uipc_debug.c b/sys/kern/uipc_debug.c index 292f6e1fd981..57f4017b4f34 100644 --- a/sys/kern/uipc_debug.c +++ b/sys/kern/uipc_debug.c @@ -136,6 +136,14 @@ db_print_sooptions(short so_options) db_printf("%sSO_BINTIME", comma ? ", " : ""); comma = 1; } + if (so_options & SO_NO_OFFLOAD) { + db_printf("%sSO_NO_OFFLOAD", comma ? ", " : ""); + comma = 1; + } + if (so_options & SO_NO_DDP) { + db_printf("%sSO_NO_DDP", comma ? ", " : ""); + comma = 1; + } } static void From 6d66da20b7d7dbb7413707758857299eb19834a4 Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 26 May 2009 10:03:44 +0000 Subject: [PATCH 540/544] - Fix wrong print on BIO_DONE. - Use db_printf instead of printf. While here, apply this to other ddb commands as well. Pointed out by: pjd --- sys/geom/geom_subr.c | 92 ++++++++++++++++++++++---------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index d9f6244c892d..36c2829c92b9 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1048,12 +1048,12 @@ g_valid_obj(void const *ptr) #ifdef DDB #define gprintf(...) do { \ - printf("%*s", indent, ""); \ - printf(__VA_ARGS__); \ + db_printf("%*s", indent, ""); \ + db_printf(__VA_ARGS__); \ } while (0) #define gprintln(...) do { \ gprintf(__VA_ARGS__); \ - printf("\n"); \ + db_printf("\n"); \ } while (0) #define ADDFLAG(obj, flag, sflag) do { \ @@ -1118,8 +1118,8 @@ db_show_geom_consumer(int indent, struct g_consumer *cp) cp->provider != NULL ? cp->provider->name : "none", cp->acr, cp->acw, cp->ace); if (cp->spoiled) - printf(", spoiled=%d", cp->spoiled); - printf("\n"); + db_printf(", spoiled=%d", cp->spoiled); + db_printf("\n"); } } @@ -1152,11 +1152,11 @@ db_show_geom_provider(int indent, struct g_provider *pp) gprintf("provider: %s (%p), access=r%dw%de%d", pp->name, pp, pp->acr, pp->acw, pp->ace); if (pp->flags != 0) { - printf(", flags=%s (0x%04x)", + db_printf(", flags=%s (0x%04x)", provider_flags_to_string(pp, flags, sizeof(flags)), pp->flags); } - printf("\n"); + db_printf("\n"); } if (!LIST_EMPTY(&pp->consumers)) { LIST_FOREACH(cp, &pp->consumers, consumers) { @@ -1187,11 +1187,11 @@ db_show_geom_geom(int indent, struct g_geom *gp) } else { gprintf("geom: %s (%p), rank=%d", gp->name, gp, gp->rank); if (gp->flags != 0) { - printf(", flags=%s (0x%04x)", + db_printf(", flags=%s (0x%04x)", geom_flags_to_string(gp, flags, sizeof(flags)), gp->flags); } - printf("\n"); + db_printf("\n"); } if (!LIST_EMPTY(&gp->provider)) { LIST_FOREACH(pp, &gp->provider, provider) { @@ -1214,7 +1214,7 @@ db_show_geom_class(struct g_class *mp) { struct g_geom *gp; - printf("class: %s (%p)\n", mp->name, mp); + db_printf("class: %s (%p)\n", mp->name, mp); LIST_FOREACH(gp, &mp->geom, geom) { db_show_geom_geom(2, gp); if (db_pager_quit) @@ -1233,7 +1233,7 @@ DB_SHOW_COMMAND(geom, db_show_geom) /* No address given, print the entire topology. */ LIST_FOREACH(mp, &g_classes, class) { db_show_geom_class(mp); - printf("\n"); + db_printf("\n"); if (db_pager_quit) break; } @@ -1252,7 +1252,7 @@ DB_SHOW_COMMAND(geom, db_show_geom) db_show_geom_provider(0, (struct g_provider *)addr); break; default: - printf("Not a GEOM object.\n"); + db_printf("Not a GEOM object.\n"); break; } } @@ -1261,19 +1261,19 @@ DB_SHOW_COMMAND(geom, db_show_geom) static void db_print_bio_cmd(struct bio *bp) { - printf(" cmd: "); + db_printf(" cmd: "); switch (bp->bio_cmd) { - case BIO_READ: printf("BIO_READ"); break; - case BIO_WRITE: printf("BIO_WRITE"); break; - case BIO_DELETE: printf("BIO_DELETE"); break; - case BIO_GETATTR: printf("BIO_GETATTR"); break; - case BIO_FLUSH: printf("BIO_FLUSH"); break; - case BIO_CMD0: printf("BIO_CMD0"); break; - case BIO_CMD1: printf("BIO_CMD1"); break; - case BIO_CMD2: printf("BIO_CMD2"); break; - default: printf("UNKNOWN"); break; + case BIO_READ: db_printf("BIO_READ"); break; + case BIO_WRITE: db_printf("BIO_WRITE"); break; + case BIO_DELETE: db_printf("BIO_DELETE"); break; + case BIO_GETATTR: db_printf("BIO_GETATTR"); break; + case BIO_FLUSH: db_printf("BIO_FLUSH"); break; + case BIO_CMD0: db_printf("BIO_CMD0"); break; + case BIO_CMD1: db_printf("BIO_CMD1"); break; + case BIO_CMD2: db_printf("BIO_CMD2"); break; + default: db_printf("UNKNOWN"); break; } - printf("\n"); + db_printf("\n"); } static void @@ -1282,18 +1282,18 @@ db_print_bio_flags(struct bio *bp) int comma; comma = 0; - printf(" flags: "); + db_printf(" flags: "); if (bp->bio_flags & BIO_ERROR) { - printf("BIO_ERROR"); + db_printf("BIO_ERROR"); comma = 1; } if (bp->bio_flags & BIO_DONE) { - printf("%sBIO_ERROR", (comma ? ", " : "")); + db_printf("%sBIO_DONE", (comma ? ", " : "")); comma = 1; } if (bp->bio_flags & BIO_ONQUEUE) - printf("%sBIO_ONQUEUE", (comma ? ", " : "")); - printf("\n"); + db_printf("%sBIO_ONQUEUE", (comma ? ", " : "")); + db_printf("\n"); } /* @@ -1305,26 +1305,26 @@ DB_SHOW_COMMAND(bio, db_show_bio) if (have_addr) { bp = (struct bio *)addr; - printf("BIO %p\n", bp); + db_printf("BIO %p\n", bp); db_print_bio_cmd(bp); db_print_bio_flags(bp); - printf(" cflags: 0x%hhx\n", bp->bio_cflags); - printf(" pflags: 0x%hhx\n", bp->bio_pflags); - printf(" offset: %lld\n", bp->bio_offset); - printf(" length: %lld\n", bp->bio_length); - printf(" bcount: %ld\n", bp->bio_bcount); - printf(" resid: %ld\n", bp->bio_resid); - printf(" completed: %lld\n", bp->bio_completed); - printf(" children: %u\n", bp->bio_children); - printf(" inbed: %u\n", bp->bio_inbed); - printf(" error: %d\n", bp->bio_error); - printf(" parent: %p\n", bp->bio_parent); - printf(" driver1: %p\n", bp->bio_driver1); - printf(" driver2: %p\n", bp->bio_driver2); - printf(" caller1: %p\n", bp->bio_caller1); - printf(" caller2: %p\n", bp->bio_caller2); - printf(" bio_from: %p\n", bp->bio_from); - printf(" bio_to: %p\n", bp->bio_to); + db_printf(" cflags: 0x%hhx\n", bp->bio_cflags); + db_printf(" pflags: 0x%hhx\n", bp->bio_pflags); + db_printf(" offset: %lld\n", bp->bio_offset); + db_printf(" length: %lld\n", bp->bio_length); + db_printf(" bcount: %ld\n", bp->bio_bcount); + db_printf(" resid: %ld\n", bp->bio_resid); + db_printf(" completed: %lld\n", bp->bio_completed); + db_printf(" children: %u\n", bp->bio_children); + db_printf(" inbed: %u\n", bp->bio_inbed); + db_printf(" error: %d\n", bp->bio_error); + db_printf(" parent: %p\n", bp->bio_parent); + db_printf(" driver1: %p\n", bp->bio_driver1); + db_printf(" driver2: %p\n", bp->bio_driver2); + db_printf(" caller1: %p\n", bp->bio_caller1); + db_printf(" caller2: %p\n", bp->bio_caller2); + db_printf(" bio_from: %p\n", bp->bio_from); + db_printf(" bio_to: %p\n", bp->bio_to); } } From b7014134a7355adb60a1d5c4174703d7e92da7e2 Mon Sep 17 00:00:00 2001 From: Edward Tomasz Napierala Date: Tue, 26 May 2009 11:42:06 +0000 Subject: [PATCH 541/544] Change license to more bori^Wadul^Wcanonical. Submitted by: rwatson@ --- lib/libc/posix1e/acl_compat.c | 22 +++++++++---------- .../compat/opensolaris/kern/opensolaris_acl.c | 22 +++++++++---------- sys/cddl/compat/opensolaris/sys/acl.h | 22 +++++++++---------- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lib/libc/posix1e/acl_compat.c b/lib/libc/posix1e/acl_compat.c index 6172f5e48aff..c4339204f8cd 100644 --- a/lib/libc/posix1e/acl_compat.c +++ b/lib/libc/posix1e/acl_compat.c @@ -11,17 +11,17 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE - * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c b/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c index d5cc3e64aea1..a458f6d39e2a 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c @@ -11,17 +11,17 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE - * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include diff --git a/sys/cddl/compat/opensolaris/sys/acl.h b/sys/cddl/compat/opensolaris/sys/acl.h index 2bb0c5e2ca4e..57fad6faa001 100644 --- a/sys/cddl/compat/opensolaris/sys/acl.h +++ b/sys/cddl/compat/opensolaris/sys/acl.h @@ -11,17 +11,17 @@ * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE - * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL - * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, - * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. * * $FreeBSD$ */ From 927a7c4ffb14a23dfbcc22d401ad48dd335beb1a Mon Sep 17 00:00:00 2001 From: Ed Schouten Date: Tue, 26 May 2009 12:01:37 +0000 Subject: [PATCH 542/544] Unbreak bktr(4). --- sys/dev/bktr/bktr_os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/dev/bktr/bktr_os.c b/sys/dev/bktr/bktr_os.c index 7b44a47540db..327c4bbdb959 100644 --- a/sys/dev/bktr/bktr_os.c +++ b/sys/dev/bktr/bktr_os.c @@ -470,7 +470,7 @@ bktr_attach( device_t dev ) if (bktr->res_irq) bus_release_resource(dev, SYS_RES_IRQ, bktr->irq_rid, bktr->res_irq); if (bktr->res_mem) - bus_release_resource(dev, SYS_RES_MEM, bktr->mem_rid, bktr->res_mem); + bus_release_resource(dev, SYS_RES_MEMORY, bktr->mem_rid, bktr->res_mem); return error; } From 4147dd02cd85f148c9af0339de217e27791875ca Mon Sep 17 00:00:00 2001 From: Ulf Lilleengen Date: Tue, 26 May 2009 14:15:06 +0000 Subject: [PATCH 543/544] - Unbreak 64 bit platforms by casting off_t to intmax. --- sys/geom/geom_subr.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sys/geom/geom_subr.c b/sys/geom/geom_subr.c index 36c2829c92b9..c3ab15acb777 100644 --- a/sys/geom/geom_subr.c +++ b/sys/geom/geom_subr.c @@ -1310,11 +1310,11 @@ DB_SHOW_COMMAND(bio, db_show_bio) db_print_bio_flags(bp); db_printf(" cflags: 0x%hhx\n", bp->bio_cflags); db_printf(" pflags: 0x%hhx\n", bp->bio_pflags); - db_printf(" offset: %lld\n", bp->bio_offset); - db_printf(" length: %lld\n", bp->bio_length); + db_printf(" offset: %jd\n", (intmax_t)bp->bio_offset); + db_printf(" length: %jd\n", (intmax_t)bp->bio_length); db_printf(" bcount: %ld\n", bp->bio_bcount); db_printf(" resid: %ld\n", bp->bio_resid); - db_printf(" completed: %lld\n", bp->bio_completed); + db_printf(" completed: %jd\n", (intmax_t)bp->bio_completed); db_printf(" children: %u\n", bp->bio_children); db_printf(" inbed: %u\n", bp->bio_inbed); db_printf(" error: %d\n", bp->bio_error); From 03914b0bb26916a22b74d01c561dc74743e27d29 Mon Sep 17 00:00:00 2001 From: Rick Macklem Date: Tue, 26 May 2009 15:19:04 +0000 Subject: [PATCH 544/544] Add two new utilities and two new daemons to /usr/src/usr.sbin that are specifically used by the experimental nfsv4 subsystem. nfscbd - The NFSv4 client callback daemon. nfsuserd - The NFSv4 daemon that maps between user and group name and their corresponding uid/gid numbers. nfsdumpstate - A utility that dumps out the NFSv4 Open/Lock state. nfsrevoke - Administratively revokes an NFSv4 client, releasing all NFSv4 Open/Lock state it holds on the server. Approved by: kib (mentor) --- usr.sbin/Makefile | 4 + usr.sbin/nfscbd/Makefile | 6 + usr.sbin/nfscbd/nfscbd.8 | 87 ++++ usr.sbin/nfscbd/nfscbd.c | 380 +++++++++++++++ usr.sbin/nfsdumpstate/Makefile | 6 + usr.sbin/nfsdumpstate/nfsdumpstate.8 | 71 +++ usr.sbin/nfsdumpstate/nfsdumpstate.c | 280 +++++++++++ usr.sbin/nfsrevoke/Makefile | 6 + usr.sbin/nfsrevoke/nfsrevoke.8 | 64 +++ usr.sbin/nfsrevoke/nfsrevoke.c | 124 +++++ usr.sbin/nfsuserd/Makefile | 6 + usr.sbin/nfsuserd/nfsuserd.8 | 114 +++++ usr.sbin/nfsuserd/nfsuserd.c | 665 +++++++++++++++++++++++++++ 13 files changed, 1813 insertions(+) create mode 100644 usr.sbin/nfscbd/Makefile create mode 100644 usr.sbin/nfscbd/nfscbd.8 create mode 100644 usr.sbin/nfscbd/nfscbd.c create mode 100644 usr.sbin/nfsdumpstate/Makefile create mode 100644 usr.sbin/nfsdumpstate/nfsdumpstate.8 create mode 100644 usr.sbin/nfsdumpstate/nfsdumpstate.c create mode 100644 usr.sbin/nfsrevoke/Makefile create mode 100644 usr.sbin/nfsrevoke/nfsrevoke.8 create mode 100644 usr.sbin/nfsrevoke/nfsrevoke.c create mode 100644 usr.sbin/nfsuserd/Makefile create mode 100644 usr.sbin/nfsuserd/nfsuserd.8 create mode 100644 usr.sbin/nfsuserd/nfsuserd.c diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index eb13bf1ff3b3..1a3d9f6232f3 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -110,7 +110,11 @@ SUBDIR= ${_ac} \ ${_ndiscvt} \ ${_ndp} \ newsyslog \ + nfscbd \ nfsd \ + nfsdumpstate \ + nfsrevoke \ + nfsuserd \ ${_ngctl} \ ${_nghook} \ nologin \ diff --git a/usr.sbin/nfscbd/Makefile b/usr.sbin/nfscbd/Makefile new file mode 100644 index 000000000000..1e11e3a81711 --- /dev/null +++ b/usr.sbin/nfscbd/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= nfscbd +MAN= nfscbd.8 + +.include diff --git a/usr.sbin/nfscbd/nfscbd.8 b/usr.sbin/nfscbd/nfscbd.8 new file mode 100644 index 000000000000..802dff39465e --- /dev/null +++ b/usr.sbin/nfscbd/nfscbd.8 @@ -0,0 +1,87 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 25, 2009 +.Dt NFSCBD 8 +.Os +.Sh NAME +.Nm nfscbd +.Tn NFSv4 +client side callback daemon +.Sh SYNOPSIS +.Nm nfscbd +.Op Fl p Ar port_number +.Op Fl P Ar client_principal +.Sh DESCRIPTION +.Nm +runs on a client using +.Tn NFSv4 +to handle callback requests from the NFSv4 server. +If no +.Nm +is running, NFSv4 mounts will still work, but the server will never issue +Open Delegations to the client. +.Pp +One callback server and one master server +are always started. +.Pp +The following options are available: +.Bl -tag -width Ds +.It Fl p Ar port_number +Specifies what port# the callback server should use. +.It Fl P Ar client_principal +Specifies the host based principal name to be used as the target for +callbacks over RPCSEC_GSS. For KerberosV, it must be in the client's +default keytab file. +This client_principal should be the same one specified by the +.Cm gssname +argument being used by nfsv4 mounts. +If you do not specify this argument, callbacks will still work over AUTH_SYS, +which is what many extant servers use even for RPCSEC_GSS mounts, as of 2009. +.El +.Pp +For example, +.Dq Li "nfscbd -p 7654 -P root" +starts the daemon to handle callbacks on port# 7654 and is using the host based +principal root@. as the callback target. +.Pp +.Nm +listens for service requests at the port +defined by NFSV4_CBPORT in /usr/include/fs/nfs/nfs.h, unless +.Fl p +has been specified. +For more information on what callbacks and Open Delegations do, see +.%T "Network File System (NFS) Version 4 Protocol" , +RFC3530 . +.Pp +The +.Nm +utility exits 0 on success or >0 if an error occurred. +.Sh SEE ALSO +.Xr nfsv4 4 , +.Xr mount_nfs 8 +.Sh HISTORY +First introduced with the experimental nfs client for NFSv4 support in 2009. diff --git a/usr.sbin/nfscbd/nfscbd.c b/usr.sbin/nfscbd/nfscbd.c new file mode 100644 index 000000000000..3920360d2a1f --- /dev/null +++ b/usr.sbin/nfscbd/nfscbd.c @@ -0,0 +1,380 @@ +/*- + * Copyright (c) 2009 Rick Macklem, University of Guelph + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Global defs */ +#ifdef DEBUG +#define syslog(e, s) fprintf(stderr,(s)) +int debug = 1; +#else +int debug = 0; +#endif + +pid_t children; + +void nonfs(int); +void reapchild(int); +void usage(void); +void cleanup(int); +void child_cleanup(int); +void nfscbd_exit(int); +void killchildren(void); + +/* + * Nfs callback server daemon. + * + * 1 - do file descriptor and signal cleanup + * 2 - fork the nfscbd(s) + * 4 - create callback server socket(s) + * 5 - set up server socket for rpc + * + * For connectionless protocols, just pass the socket into the kernel via. + * nfssvc(). + * For connection based sockets, loop doing accepts. When you get a new + * socket from accept, pass the msgsock into the kernel via. nfssvc(). + */ +int +main(int argc, char *argv[], char **envp) +{ + struct group *grp; + struct nfscbd_args nfscbdargs; + struct nfsd_nfscbd_args nfscbdargs2; + struct passwd *pwd; + struct ucred *cr; + struct sockaddr_in inetaddr, inetpeer; + struct timeval ktv; + fd_set ready, sockbits; + int ch, connect_type_cnt, i, len, maxsock, msgsock, error; + int nfssvc_flag, on, sock, tcpsock, ret, mustfreeai = 0; + char *cp, **cpp, princname[128]; + char myname[MAXHOSTNAMELEN], *myfqdnname = NULL; + struct addrinfo *aip, hints; + pid_t pid; + sigset_t signew; + short myport = NFSV4_CBPORT; + + if (modfind("nfscl") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfscl") < 0 || + modfind("nfscl") < 0) + errx(1, "nfscl is not available"); + } + /* + * First, get our fully qualified host name, if possible. + */ + if (gethostname(myname, MAXHOSTNAMELEN) >= 0) { + cp = strchr(myname, '.'); + if (cp != NULL && *(cp + 1) != '\0') { + cp = myname; + } else { + /* + * No domain on myname, so try looking it up. + */ + cp = NULL; + memset((void *)&hints, 0, sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(myname, NULL, &hints, &aip); + if (error == 0) { + if (aip->ai_canonname != NULL && + (cp = strchr(aip->ai_canonname, '.')) != NULL + && *(cp + 1) != '\0') { + cp = aip->ai_canonname; + mustfreeai = 1; + } else { + freeaddrinfo(aip); + } + } + } + if (cp == NULL) + warnx("Can't get fully qualified host name"); + myfqdnname = cp; + } + + princname[0] = '\0'; +#define GETOPT "p:P:" +#define USAGE "[ -p port_num ] [ -P client_principal ]" + while ((ch = getopt(argc, argv, GETOPT)) != -1) + switch (ch) { + case 'p': + myport = atoi(optarg); + if (myport < 1) { + warnx("port# non-positive, reset to %d", + NFSV4_CBPORT); + myport = NFSV4_CBPORT; + } + break; + case 'P': + cp = optarg; + if (cp != NULL && strlen(cp) > 0 && + strlen(cp) < sizeof (princname)) { + if (strchr(cp, '@') == NULL && + myfqdnname != NULL) + snprintf(princname, sizeof (princname), + "%s@%s", cp, myfqdnname); + else + strlcpy(princname, cp, + sizeof (princname)); + } else { + warnx("client princ invalid. ignored\n"); + } + break; + default: + case '?': + usage(); + }; + argv += optind; + argc -= optind; + + if (argc > 0) + usage(); + + if (mustfreeai) + freeaddrinfo(aip); + nfscbdargs2.principal = (const char *)princname; + if (debug == 0) { + daemon(0, 0); + (void)signal(SIGTERM, SIG_IGN); + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + } + (void)signal(SIGSYS, nonfs); + (void)signal(SIGCHLD, reapchild); + + openlog("nfscbd:", LOG_PID, LOG_DAEMON); + + pid = fork(); + if (pid < 0) { + syslog(LOG_ERR, "fork: %m"); + nfscbd_exit(1); + } else if (pid > 0) { + children = pid; + } else { + (void)signal(SIGUSR1, child_cleanup); + setproctitle("server"); + nfssvc_flag = NFSSVC_NFSCBD; + if (nfssvc(nfssvc_flag, &nfscbdargs2) < 0) { + syslog(LOG_ERR, "nfssvc: %m"); + nfscbd_exit(1); + } + exit(0); + } + (void)signal(SIGUSR1, cleanup); + + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + syslog(LOG_ERR, "can't create udp socket"); + nfscbd_exit(1); + } + memset(&inetaddr, 0, sizeof inetaddr); + inetaddr.sin_family = AF_INET; + inetaddr.sin_addr.s_addr = INADDR_ANY; + inetaddr.sin_port = htons(myport); + inetaddr.sin_len = sizeof(inetaddr); + ret = bind(sock, (struct sockaddr *)&inetaddr, sizeof(inetaddr)); + /* If bind() fails, this is a restart, so just skip UDP. */ + if (ret == 0) { + len = sizeof(inetaddr); + if (getsockname(sock, (struct sockaddr *)&inetaddr, &len) < 0){ + syslog(LOG_ERR, "can't get bound addr"); + nfscbd_exit(1); + } + nfscbdargs.port = ntohs(inetaddr.sin_port); + if (nfscbdargs.port != myport) { + syslog(LOG_ERR, "BAD PORT#"); + nfscbd_exit(1); + } + nfscbdargs.sock = sock; + nfscbdargs.name = NULL; + nfscbdargs.namelen = 0; + if (nfssvc(NFSSVC_CBADDSOCK, &nfscbdargs) < 0) { + syslog(LOG_ERR, "can't Add UDP socket"); + nfscbd_exit(1); + } + } + (void)close(sock); + + /* Now set up the master server socket waiting for tcp connections. */ + on = 1; + FD_ZERO(&sockbits); + connect_type_cnt = 0; + if ((tcpsock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + syslog(LOG_ERR, "can't create tcp socket"); + nfscbd_exit(1); + } + if (setsockopt(tcpsock, + SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof(on)) < 0) + syslog(LOG_ERR, "setsockopt SO_REUSEADDR: %m"); + /* sin_port is already set */ + inetaddr.sin_family = AF_INET; + inetaddr.sin_addr.s_addr = INADDR_ANY; + inetaddr.sin_port = htons(myport); + inetaddr.sin_len = sizeof(inetaddr); + if (bind(tcpsock, + (struct sockaddr *)&inetaddr, sizeof (inetaddr)) < 0) { + syslog(LOG_ERR, "can't bind tcp addr"); + nfscbd_exit(1); + } + if (listen(tcpsock, 5) < 0) { + syslog(LOG_ERR, "listen failed"); + nfscbd_exit(1); + } + FD_SET(tcpsock, &sockbits); + maxsock = tcpsock; + connect_type_cnt++; + + setproctitle("master"); + + /* + * Loop forever accepting connections and passing the sockets + * into the kernel for the mounts. + */ + for (;;) { + ready = sockbits; + if (connect_type_cnt > 1) { + if (select(maxsock + 1, + &ready, NULL, NULL, NULL) < 1) { + syslog(LOG_ERR, "select failed: %m"); + nfscbd_exit(1); + } + } + if (FD_ISSET(tcpsock, &ready)) { + len = sizeof(inetpeer); + if ((msgsock = accept(tcpsock, + (struct sockaddr *)&inetpeer, &len)) < 0) { + syslog(LOG_ERR, "accept failed: %m"); + nfscbd_exit(1); + } + memset(inetpeer.sin_zero, 0, + sizeof (inetpeer.sin_zero)); + if (setsockopt(msgsock, SOL_SOCKET, + SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0) + syslog(LOG_ERR, + "setsockopt SO_KEEPALIVE: %m"); + nfscbdargs.sock = msgsock; + nfscbdargs.name = (caddr_t)&inetpeer; + nfscbdargs.namelen = sizeof(inetpeer); + nfssvc(NFSSVC_CBADDSOCK, &nfscbdargs); + (void)close(msgsock); + } + } +} + +void +usage(void) +{ + + errx(1, "usage: nfscbd %s", USAGE); +} + +void +nonfs(int signo) +{ + syslog(LOG_ERR, "missing system call: NFS not available"); +} + +void +reapchild(int signo) +{ + pid_t pid; + int i; + + while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) { + if (pid == children) + children = -1; + } +} + +void +killchildren(void) +{ + int i; + + if (children > 0) + kill(children, SIGKILL); +} + +/* + * Cleanup master after SIGUSR1. + */ +void +cleanup(int signo) +{ + nfscbd_exit(0); +} + +/* + * Cleanup child after SIGUSR1. + */ +void +child_cleanup(int signo) +{ + exit(0); +} + +void +nfscbd_exit(int status) +{ + killchildren(); + exit(status); +} diff --git a/usr.sbin/nfsdumpstate/Makefile b/usr.sbin/nfsdumpstate/Makefile new file mode 100644 index 000000000000..938fb072ed9e --- /dev/null +++ b/usr.sbin/nfsdumpstate/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= nfsdumpstate +MAN= nfsdumpstate.8 + +.include diff --git a/usr.sbin/nfsdumpstate/nfsdumpstate.8 b/usr.sbin/nfsdumpstate/nfsdumpstate.8 new file mode 100644 index 000000000000..ca48c020cd9a --- /dev/null +++ b/usr.sbin/nfsdumpstate/nfsdumpstate.8 @@ -0,0 +1,71 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 25, 2009 +.Dt NFSDUMPSTATE 8 +.Os +.Sh NAME +.Nm nfsdumpstate +.Nd display +.Tn NFSv4 +open/lock state +.Sh SYNOPSIS +.Nm nfsdumpstate +.Op Fl o +.Op Fl l Ar filename +.Sh DESCRIPTION +.Nm +displays open/lock state for the +.Tn NFSv4 +client and server in the experimental nfs subsystem. +.Pp +The options are as follows: +.Bl -tag -width Ds +.It Fl o +Displays a summary of Clients for NFSv4. Each line lists a Client with +the ClientID being the last field of the line. +.sp +.nf +The following are the client flag values displayed: +NC - Needs Confirmation +CB - Callbacks are enabled +GSS - Using RPCSEC_GSS +REV - Administratively Revoked, via nfsrevoke(8) +.fi +.sp +.It Fl l Ar filename +Displays a list of all NFSv4 Opens and Locks on the file specified by +the +.Ar filename . +The ClientID is the last field of each line. +.El +.Sh SEE ALSO +.Xr nfsv4 4 , +.Xr nfsrevoke 8 +.Sh HISTORY +The +.Nm +utility was introduced with the NFSv4 experimental subsystem in 2009. diff --git a/usr.sbin/nfsdumpstate/nfsdumpstate.c b/usr.sbin/nfsdumpstate/nfsdumpstate.c new file mode 100644 index 000000000000..54841dcba94e --- /dev/null +++ b/usr.sbin/nfsdumpstate/nfsdumpstate.c @@ -0,0 +1,280 @@ +/*- + * Copyright (c) 2009 Rick Macklem, University of Guelph + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define DUMPSIZE 10000 + +static void dump_lockstate(char *); +static void dump_openstate(void); +static void usage(void); +static char *open_flags(uint32_t); +static char *deleg_flags(uint32_t); +static char *lock_flags(uint32_t); +static char *client_flags(uint32_t); + +static struct nfsd_dumpclients dp[DUMPSIZE]; +static struct nfsd_dumplocks lp[DUMPSIZE]; +static char flag_string[20]; + +int +main(int argc, char **argv) +{ + int ch, openstate; + char *lockfile; + + if (modfind("nfsd") < 0) + errx(1, "nfsd not loaded - self terminating"); + openstate = 0; + lockfile = NULL; + while ((ch = getopt(argc, argv, "ol")) != -1) + switch (ch) { + case 'o': + openstate = 1; + break; + case 'l': + lockfile = optarg; + break; + default: + usage(); + } + argc -= optind; + argv += optind; + + if (openstate == 0 && lockfile == NULL) + openstate = 1; + else if (openstate != 0 && lockfile != NULL) + errx(1, "-o and -l cannot both be specified"); + + /* + * For -o, dump all open/lock state. + * For -l, dump lock state for that file. + */ + if (openstate != 0) + dump_openstate(); + else + dump_lockstate(lockfile); + exit(0); +} + +static void +usage(void) +{ + + errx(1, "usage: nfsdumpstate [-o] [-l]"); +} + +/* + * Dump all open/lock state. + */ +static void +dump_openstate(void) +{ + struct nfsd_dumplist dumplist; + int cnt, i; + + dumplist.ndl_size = DUMPSIZE; + dumplist.ndl_list = (void *)dp; + if (nfssvc(NFSSVC_DUMPCLIENTS, &dumplist) < 0) + errx(1, "Can't perform dump clients syscall"); + + printf("%-13s %9.9s %9.9s %9.9s %9.9s %9.9s %9.9s %-15s %s\n", + "Flags", "OpenOwner", "Open", "LockOwner", + "Lock", "Deleg", "OldDeleg", "Clientaddr", "ClientID"); + /* + * Loop through results, printing them out. + */ + cnt = 0; + while (dp[cnt].ndcl_clid.nclid_idlen > 0 && cnt < DUMPSIZE) { + printf("%-13s ", client_flags(dp[cnt].ndcl_flags)); + printf("%9d %9d %9d %9d %9d %9d ", + dp[cnt].ndcl_nopenowners, + dp[cnt].ndcl_nopens, + dp[cnt].ndcl_nlockowners, + dp[cnt].ndcl_nlocks, + dp[cnt].ndcl_ndelegs, + dp[cnt].ndcl_nolddelegs); + if (dp[cnt].ndcl_addrfam == AF_INET) + printf("%-15s ", + inet_ntoa(dp[cnt].ndcl_cbaddr.sin_addr)); + for (i = 0; i < dp[cnt].ndcl_clid.nclid_idlen; i++) + printf("%02x", dp[cnt].ndcl_clid.nclid_id[i]); + printf("\n"); + cnt++; + } +} + +/* + * Dump the lock state for a file. + */ +static void +dump_lockstate(char *fname) +{ + struct nfsd_dumplocklist dumplocklist; + int cnt, i; + + dumplocklist.ndllck_size = DUMPSIZE; + dumplocklist.ndllck_list = (void *)lp; + dumplocklist.ndllck_fname = fname; + if (nfssvc(NFSSVC_DUMPLOCKS, &dumplocklist) < 0) + errx(1, "Can't dump locks for %s\n", fname); + + printf("%-11s %-36s %-15s %s\n", + "Open/Lock", + " Stateid or Lock Range", + "Clientaddr", + "Owner and ClientID"); + /* + * Loop through results, printing them out. + */ + cnt = 0; + while (lp[cnt].ndlck_clid.nclid_idlen > 0 && cnt < DUMPSIZE) { + if (lp[cnt].ndlck_flags & NFSLCK_OPEN) + printf("%-11s %9d %08x %08x %08x ", + open_flags(lp[cnt].ndlck_flags), + lp[cnt].ndlck_stateid.seqid, + lp[cnt].ndlck_stateid.other[0], + lp[cnt].ndlck_stateid.other[1], + lp[cnt].ndlck_stateid.other[2]); + else if (lp[cnt].ndlck_flags & (NFSLCK_DELEGREAD | + NFSLCK_DELEGWRITE)) + printf("%-11s %9d %08x %08x %08x ", + deleg_flags(lp[cnt].ndlck_flags), + lp[cnt].ndlck_stateid.seqid, + lp[cnt].ndlck_stateid.other[0], + lp[cnt].ndlck_stateid.other[1], + lp[cnt].ndlck_stateid.other[2]); + else + printf("%-11s %17lld %17lld ", + lock_flags(lp[cnt].ndlck_flags), + lp[cnt].ndlck_first, + lp[cnt].ndlck_end); + if (lp[cnt].ndlck_addrfam == AF_INET) + printf("%-15s ", + inet_ntoa(lp[cnt].ndlck_cbaddr.sin_addr)); + else + printf("%-15s ", " "); + for (i = 0; i < lp[cnt].ndlck_owner.nclid_idlen; i++) + printf("%02x", lp[cnt].ndlck_owner.nclid_id[i]); + printf(" "); + for (i = 0; i < lp[cnt].ndlck_clid.nclid_idlen; i++) + printf("%02x", lp[cnt].ndlck_clid.nclid_id[i]); + printf("\n"); + cnt++; + } +} + +/* + * Parse the Open/Lock flag bits and create a string to be printed. + */ +static char * +open_flags(uint32_t flags) +{ + int i, j; + + strlcpy(flag_string, "Open ", sizeof (flag_string)); + i = 5; + if (flags & NFSLCK_READACCESS) + flag_string[i++] = 'R'; + if (flags & NFSLCK_WRITEACCESS) + flag_string[i++] = 'W'; + flag_string[i++] = ' '; + flag_string[i++] = 'D'; + flag_string[i] = 'N'; + j = i; + if (flags & NFSLCK_READDENY) + flag_string[i++] = 'R'; + if (flags & NFSLCK_WRITEDENY) + flag_string[i++] = 'W'; + if (i == j) + i++; + flag_string[i] = '\0'; + return (flag_string); +} + +static char * +deleg_flags(uint32_t flags) +{ + + if (flags & NFSLCK_DELEGREAD) + strlcpy(flag_string, "Deleg R", sizeof (flag_string)); + else + strlcpy(flag_string, "Deleg W", sizeof (flag_string)); + return (flag_string); +} + +static char * +lock_flags(uint32_t flags) +{ + + if (flags & NFSLCK_READ) + strlcpy(flag_string, "Lock R", sizeof (flag_string)); + else + strlcpy(flag_string, "Lock W", sizeof (flag_string)); + return (flag_string); +} + +static char * +client_flags(uint32_t flags) +{ + + flag_string[0] = '\0'; + if (flags & LCL_NEEDSCONFIRM) + strlcat(flag_string, "NC ", sizeof (flag_string)); + if (flags & LCL_CALLBACKSON) + strlcat(flag_string, "CB ", sizeof (flag_string)); + if (flags & LCL_GSS) + strlcat(flag_string, "GSS ", sizeof (flag_string)); + if (flags & LCL_ADMINREVOKED) + strlcat(flag_string, "REV", sizeof (flag_string)); + return (flag_string); +} diff --git a/usr.sbin/nfsrevoke/Makefile b/usr.sbin/nfsrevoke/Makefile new file mode 100644 index 000000000000..ab78aa3300c3 --- /dev/null +++ b/usr.sbin/nfsrevoke/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= nfsrevoke +MAN= nfsrevoke.8 + +.include diff --git a/usr.sbin/nfsrevoke/nfsrevoke.8 b/usr.sbin/nfsrevoke/nfsrevoke.8 new file mode 100644 index 000000000000..00a8915e361b --- /dev/null +++ b/usr.sbin/nfsrevoke/nfsrevoke.8 @@ -0,0 +1,64 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 25, 2009 +.Dt NFSREVOKE 8 +.Os +.Sh NAME +.Nm nfsrevoke +.Nd revoke +.Tn NFS +V4 client +.Sh SYNOPSIS +.Nm nfsrevoke +.Ar ClientId +.Sh DESCRIPTION +.Nm +This command is used by a system administrator to revoke a client's access +to the NFS Version 4 server. All Open/Lock state held by the client will +be released. +After revocation, the client will no longer be able to use state on the server +until it does a fresh SetClientID/SetClientIDConfirm operations sequence. +THIS SHOULD BE DONE AS A LAST RESORT ONLY, when clients are holding state +that must be released on the server. +.Pp +The +.Ar ClientId +argument is a hexadecimal string, which is the last field +of the +.Xr nfsdumpstate 8 +command's +.Fl o +and +.Fl l +options output. +.Sh SEE ALSO +.Xr nfsv4 4 , +.Xr nfsdumpstate 8 +.Sh HISTORY +The +.Nm +command was introduced as a part of the experimental nfs server subsystem. diff --git a/usr.sbin/nfsrevoke/nfsrevoke.c b/usr.sbin/nfsrevoke/nfsrevoke.c new file mode 100644 index 000000000000..f6ba813f0ea4 --- /dev/null +++ b/usr.sbin/nfsrevoke/nfsrevoke.c @@ -0,0 +1,124 @@ +/*- + * Copyright (c) 2009 Rick Macklem, University of Guelph + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void usage(void); +extern int errno; + +int +main(int argc, char **argv) +{ + char *cp; + u_char val; + int cnt, even; + struct nfsd_clid revoke; + + if (modfind("nfsd") < 0) + errx(1, "nfsd not loaded - self terminating"); + if (argc != 2) + usage(); + cnt = 0; + cp = argv[1]; + if (strlen(cp) % 2) + even = 0; + else + even = 1; + val = 0; + while (*cp) { + if (*cp >= '0' & *cp <= '9') + val += (u_char)(*cp - '0'); + else if (*cp >= 'A' && *cp <= 'F') + val += ((u_char)(*cp - 'A')) + 0xa; + else if (*cp >= 'a' && *cp <= 'f') + val += ((u_char)(*cp - 'a')) + 0xa; + else + errx(1, "Non hexadecimal digit in %s", argv[1]); + if (even) { + val <<= 4; + even = 0; + } else { + revoke.nclid_id[cnt++] = val; + if (cnt > NFSV4_OPAQUELIMIT) + errx(1, "Clientid %s, loo long", argv[1]); + val = 0; + even = 1; + } + cp++; + } + + /* + * Do the revocation system call. + */ + revoke.nclid_idlen = cnt; +#ifdef DEBUG + printf("Idlen=%d\n", revoke.nclid_idlen); + for (cnt = 0; cnt < revoke.nclid_idlen; cnt++) + printf("%02x", revoke.nclid_id[cnt]); + printf("\n"); +#else + if (nfssvc(NFSSVC_ADMINREVOKE, &revoke) < 0) + err(1, "Admin revoke failed"); +#endif +} + +void +usage(void) +{ + + errx(1, "Usage: nfsrevoke "); +} diff --git a/usr.sbin/nfsuserd/Makefile b/usr.sbin/nfsuserd/Makefile new file mode 100644 index 000000000000..377b5af7fd59 --- /dev/null +++ b/usr.sbin/nfsuserd/Makefile @@ -0,0 +1,6 @@ +# $FreeBSD$ + +PROG= nfsuserd +MAN= nfsuserd.8 + +.include diff --git a/usr.sbin/nfsuserd/nfsuserd.8 b/usr.sbin/nfsuserd/nfsuserd.8 new file mode 100644 index 000000000000..b98c34afd0db --- /dev/null +++ b/usr.sbin/nfsuserd/nfsuserd.8 @@ -0,0 +1,114 @@ +.\" Copyright (c) 2009 Rick Macklem, University of Guelph +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 25, 2009 +.Dt NFSUSERD 8 +.Os +.Sh NAME +.Nm nfsuserd +.Nd load user and group information into the kernel for +.Tn NFSv4 +services +.Sh SYNOPSIS +.Nm nfsuserd +.Op Fl domain Ar domain_name +.Op Fl usertimeout Ar minutes +.Op Fl usermax Ar max_cache_size +.Op Fl verbose +.Op Fl force +.Op Ar num_servers +.Sh DESCRIPTION +.Nm +loads user and group information into the kernel for NFSv4. +It must be running for NFSv4 to function correctly, either client or server. +.Pp +Upon startup, it loads the machines DNS domain name, plus timeout and +cache size limit into the kernel. It then preloads the cache with group +and user information, up to the cache size limit and forks off N children +(default 4), that service requests from the kernel for cache misses. The +master server is there for the sole purpose of killing off the slaves. +To stop the nfsuserd, send a SIGUSR1 to the master server. +.Pp +The following options are available: +.Bl -tag -width Ds +.It Fl domain Ar domain_name +This option allows you to override the default DNS domain name, which +is acquired by taking either the suffix on the machine's hostname or, +if that name is not a fully qualified host name, the cannonical name as +reported by +.Xr getaddrinfo 3 . +.It Fl usertimeout Ar minutes +Overrides the default timeout for cache entries, in minutes. If the +timeout is specified as 0, cache entries never time out. The longer the +time out, the better the performance, but the longer it takes for replaced +entries to be seen. If your user/group database management system almost +never re-uses the same names or id numbers, a large timeout is recommended. +The default is 1 minute. +.It Fl usermax Ar max_cache_size +Overrides the default upper bound on the cache size. The larger the cache, +the more kernel memory is used, but the better the performance. If your +system can afford the memory use, make this the sum of the number of +entries in your group and password databases. +The default is 200 entries. +.It Fl verbose +When set, the server logs a bunch of information to syslog. +.It Fl force +This flag option must be set to restart the daemon after it has gone away +abnormally and refuses to start, because it thinks nfsuserd is already +running. +.It Ar num_servers +Specifies how many servers to create (max 20). +The default of 4 may be sufficient. You should run enough servers, so that +.Xr ps 1 +shows almost no running time for one or two of the slaves after the system +has been running for a long period. Running too few will have a major +performance impact, whereas running too many will only tie up some resources, +such as a process table entry and swap space. +.El +.Sh SEE ALSO +.Xr getpwent 3 , +.Xr getgrent 3 , +.Xr nfsv4 4 , +.Xr group 5 , +.Xr passwd 5 , +.Xr nfsd 8 . +.Sh HISTORY +The +.Nm +utility was introduced with the NFSv4 experimental subsystem in 2009. +.Sh BUGS +The +.Nm +use +.Xr getgrent 3 +and +.Xr getpwent 3 +library calls to resolve requests and will hang if the servers handling +those requests fail and the library functions don't return. See +.Xr group 5 +and +.Xr passwd 5 +for more information on how the databases are accessed. diff --git a/usr.sbin/nfsuserd/nfsuserd.c b/usr.sbin/nfsuserd/nfsuserd.c new file mode 100644 index 000000000000..7928a75261f1 --- /dev/null +++ b/usr.sbin/nfsuserd/nfsuserd.c @@ -0,0 +1,665 @@ +/*- + * Copyright (c) 2009 Rick Macklem, University of Guelph + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * This program loads the password and group databases into the kernel + * for NFS V4. + */ + +void cleanup_term(int); +void usage(void); +void nfsuserdsrv(struct svc_req *, SVCXPRT *); +bool_t xdr_getid(XDR *, caddr_t); +bool_t xdr_getname(XDR *, caddr_t); +bool_t xdr_retval(XDR *, caddr_t); + +#define MAXNAME 1024 +#define MAXNFSUSERD 20 +#define DEFNFSUSERD 4 +#define DEFUSERMAX 200 +#define DEFUSERTIMEOUT (1 * 60) +struct info { + long id; + long retval; + char name[MAXNAME + 1]; +}; + +u_char *dnsname = "default.domain"; +u_char *defaultuser = "nobody"; +uid_t defaultuid = (uid_t)32767; +u_char *defaultgroup = "nogroup"; +gid_t defaultgid = (gid_t)32767; +int verbose = 0, im_a_slave = 0, nfsuserdcnt = -1, forcestart = 0; +int defusertimeout = DEFUSERTIMEOUT; +pid_t slaves[MAXNFSUSERD]; + +int +main(int argc, char *argv[], char *envp[]) +{ + int i; + int error, len, mustfreeai = 0; + struct nfsd_idargs nid; + struct passwd *pwd; + struct group *grp; + int sock, one = 1; + SVCXPRT *udptransp, *tcptransp; + struct passwd *pw; + u_short portnum; + sigset_t signew; + char hostname[MAXHOSTNAMELEN + 1], *cp, **aliases; + struct addrinfo *aip, hints; + + if (modfind("nfscommon") < 0) { + /* Not present in kernel, try loading it */ + if (kldload("nfscommon") < 0 || + modfind("nfscommon") < 0) + errx(1, "Experimental nfs subsystem is not available"); + } + + /* + * First, figure out what our domain name and Kerberos Realm + * seem to be. Command line args may override these later. + */ + if (gethostname(hostname, MAXHOSTNAMELEN) == 0) { + if ((cp = strchr(hostname, '.')) != NULL && + *(cp + 1) != '\0') { + dnsname = cp + 1; + } else { + memset((void *)&hints, 0, sizeof (hints)); + hints.ai_flags = AI_CANONNAME; + error = getaddrinfo(hostname, NULL, &hints, &aip); + if (error == 0) { + if (aip->ai_canonname != NULL && + (cp = strchr(aip->ai_canonname, '.')) != NULL + && *(cp + 1) != '\0') { + dnsname = cp + 1; + mustfreeai = 1; + } else { + freeaddrinfo(aip); + } + } + } + } + nid.nid_usermax = DEFUSERMAX; + nid.nid_usertimeout = defusertimeout; + + argc--; + argv++; + while (argc >= 1) { + if (!strcmp(*argv, "-domain")) { + if (argc == 1) + usage(); + argc--; + argv++; + strncpy(hostname, *argv, MAXHOSTNAMELEN); + hostname[MAXHOSTNAMELEN] = '\0'; + dnsname = hostname; + } else if (!strcmp(*argv, "-verbose")) { + verbose = 1; + } else if (!strcmp(*argv, "-force")) { + forcestart = 1; + } else if (!strcmp(*argv, "-usermax")) { + if (argc == 1) + usage(); + argc--; + argv++; + i = atoi(*argv); + if (i < 10 || i > 100000) { + fprintf(stderr, + "usermax out of range 10<->100000\n", i); + usage(); + } + nid.nid_usermax = i; + } else if (!strcmp(*argv, "-usertimeout")) { + if (argc == 1) + usage(); + argc--; + argv++; + i = atoi(*argv); + if (i < 0 || i > 100000) { + fprintf(stderr, + "usertimeout out of range 0<->100000\n", + i); + usage(); + } + nid.nid_usertimeout = defusertimeout = i * 60; + } else if (nfsuserdcnt == -1) { + nfsuserdcnt = atoi(*argv); + if (nfsuserdcnt < 1) + usage(); + if (nfsuserdcnt > MAXNFSUSERD) { + warnx("nfsuserd count %d; reset to %d", + nfsuserdcnt, DEFNFSUSERD); + nfsuserdcnt = DEFNFSUSERD; + } + } else { + usage(); + } + argc--; + argv++; + } + if (nfsuserdcnt < 1) + nfsuserdcnt = DEFNFSUSERD; + + /* + * Strip off leading and trailing '.'s in domain name and map + * alphabetics to lower case. + */ + while (*dnsname == '.') + dnsname++; + if (*dnsname == '\0') + errx(1, "Domain name all '.'"); + len = strlen(dnsname); + cp = dnsname + len - 1; + while (*cp == '.') { + *cp = '\0'; + len--; + cp--; + } + for (i = 0; i < len; i++) { + if (!isascii(dnsname[i])) + errx(1, "Domain name has non-ascii char"); + if (isupper(dnsname[i])) + dnsname[i] = tolower(dnsname[i]); + } + + /* + * If the nfsuserd died off ungracefully, this is necessary to + * get them to start again. + */ + if (forcestart && nfssvc(NFSSVC_NFSUSERDDELPORT, NULL) < 0) + errx(1, "Can't do nfssvc() to delete the port"); + + if (verbose) + fprintf(stderr, + "nfsuserd: domain=%s usermax=%d usertimeout=%d\n", + dnsname, nid.nid_usermax, nid.nid_usertimeout); + + for (i = 0; i < nfsuserdcnt; i++) + slaves[i] = (pid_t)-1; + + /* + * Set up the service port to accept requests via UDP from + * localhost (127.0.0.1). + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) + err(1, "cannot create udp socket"); + + /* + * Not sure what this does, so I'll leave it here for now. + */ + setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); + + if ((udptransp = svcudp_create(sock)) == NULL) + err(1, "Can't set up socket"); + + /* + * By not specifying a protocol, it is linked into the + * dispatch queue, but not registered with portmapper, + * which is just what I want. + */ + if (!svc_register(udptransp, RPCPROG_NFSUSERD, RPCNFSUSERD_VERS, + nfsuserdsrv, 0)) + err(1, "Can't register nfsuserd"); + + /* + * Tell the kernel what my port# is. + */ + portnum = htons(udptransp->xp_port); +#ifdef DEBUG + printf("portnum=0x%x\n", portnum); +#else + if (nfssvc(NFSSVC_NFSUSERDPORT, (caddr_t)&portnum) < 0) { + if (errno == EPERM) { + fprintf(stderr, + "Can't start nfsuserd when already running"); + fprintf(stderr, + " If not running, use the -force option.\n"); + } else { + fprintf(stderr, "Can't do nfssvc() to add port\n"); + } + exit(1); + } +#endif + + pwd = getpwnam(defaultuser); + if (pwd) + nid.nid_uid = pwd->pw_uid; + else + nid.nid_uid = defaultuid; + grp = getgrnam(defaultgroup); + if (grp) + nid.nid_gid = grp->gr_gid; + else + nid.nid_gid = defaultgid; + nid.nid_name = dnsname; + nid.nid_namelen = strlen(nid.nid_name); + nid.nid_flag = NFSID_INITIALIZE; +#ifdef DEBUG + printf("Initialize uid=%d gid=%d dns=%s\n", nid.nid_uid, nid.nid_gid, + nid.nid_name); +#else + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) + errx(1, "Can't initialize nfs user/groups"); +#endif + + i = 0; + /* + * Loop around adding all groups. + */ + setgrent(); + while (i < nid.nid_usermax && (grp = getgrent())) { + nid.nid_gid = grp->gr_gid; + nid.nid_name = grp->gr_name; + nid.nid_namelen = strlen(grp->gr_name); + nid.nid_flag = NFSID_ADDGID; +#ifdef DEBUG + printf("add gid=%d name=%s\n", nid.nid_gid, nid.nid_name); +#else + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) + errx(1, "Can't add group %s", grp->gr_name); +#endif + i++; + } + + /* + * Loop around adding all users. + */ + setpwent(); + while (i < nid.nid_usermax && (pwd = getpwent())) { + nid.nid_uid = pwd->pw_uid; + nid.nid_name = pwd->pw_name; + nid.nid_namelen = strlen(pwd->pw_name); + nid.nid_flag = NFSID_ADDUID; +#ifdef DEBUG + printf("add uid=%d name=%s\n", nid.nid_uid, nid.nid_name); +#else + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) + errx(1, "Can't add user %s", pwd->pw_name); +#endif + i++; + } + + /* + * I should feel guilty for not calling this for all the above exit() + * upon error cases, but I don't. + */ + if (mustfreeai) + freeaddrinfo(aip); + +#ifdef DEBUG + exit(0); +#endif + /* + * Temporarily block SIGUSR1 and SIGCHLD, so slaves[] can't + * end up bogus. + */ + sigemptyset(&signew); + sigaddset(&signew, SIGUSR1); + sigaddset(&signew, SIGCHLD); + sigprocmask(SIG_BLOCK, &signew, NULL); + + daemon(0, 0); + (void)signal(SIGHUP, SIG_IGN); + (void)signal(SIGINT, SIG_IGN); + (void)signal(SIGQUIT, SIG_IGN); + (void)signal(SIGTERM, SIG_IGN); + (void)signal(SIGUSR1, cleanup_term); + (void)signal(SIGCHLD, cleanup_term); + + openlog("nfsuserd:", LOG_PID, LOG_DAEMON); + + /* + * Fork off the slave daemons that do the work. All the master + * does is kill them off and cleanup. + */ + for (i = 0; i < nfsuserdcnt; i++) { + slaves[i] = fork(); + if (slaves[i] == 0) { + im_a_slave = 1; + setproctitle("slave"); + sigemptyset(&signew); + sigaddset(&signew, SIGUSR1); + sigprocmask(SIG_UNBLOCK, &signew, NULL); + + /* + * and away we go. + */ + svc_run(); + syslog(LOG_ERR, "nfsuserd died: %m"); + exit(1); + } else if (slaves[i] < 0) { + syslog(LOG_ERR, "fork: %m"); + } + } + + /* + * Just wait for SIGUSR1 or a child to die and then... + * As the Governor of California would say, "Terminate them". + */ + setproctitle("master"); + sigemptyset(&signew); + while (1) + sigsuspend(&signew); +} + +/* + * The nfsuserd rpc service + */ +void +nfsuserdsrv(struct svc_req *rqstp, SVCXPRT *transp) +{ + int i; + char *cp; + struct passwd *pwd; + struct group *grp; + int error; + u_short sport; + struct info info; + struct nfsd_idargs nid; + u_int32_t saddr; + + /* + * Only handle requests from 127.0.0.1 on a reserved port number. + * (Since a reserved port # at localhost implies a client with + * local root, there won't be a security breach. This is about + * the only case I can think of where a reserved port # means + * something.) + */ + sport = ntohs(transp->xp_raddr.sin_port); + saddr = ntohl(transp->xp_raddr.sin_addr.s_addr); + if ((rqstp->rq_proc != NULLPROC && sport >= IPPORT_RESERVED) || + saddr != 0x7f000001) { + syslog(LOG_ERR, "req from ip=0x%x port=%d\n", saddr, sport); + svcerr_weakauth(transp); + return; + } + switch (rqstp->rq_proc) { + case NULLPROC: + if (!svc_sendreply(transp, (xdrproc_t)xdr_void, NULL)) + syslog(LOG_ERR, "Can't send reply"); + return; + case RPCNFSUSERD_GETUID: + if (!svc_getargs(transp, (xdrproc_t)xdr_getid, + (caddr_t)&info)) { + svcerr_decode(transp); + return; + } + pwd = getpwuid((uid_t)info.id); + info.retval = 0; + if (pwd != NULL) { + nid.nid_usertimeout = defusertimeout; + nid.nid_uid = pwd->pw_uid; + nid.nid_name = pwd->pw_name; + } else { + nid.nid_usertimeout = 5; + nid.nid_uid = (uid_t)info.id; + nid.nid_name = defaultuser; + } + nid.nid_namelen = strlen(nid.nid_name); + nid.nid_flag = NFSID_ADDUID; + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) { + info.retval = error; + syslog(LOG_ERR, "Can't add user %s\n", pwd->pw_name); + } else if (verbose) { + syslog(LOG_ERR,"Added uid=%d name=%s\n", + nid.nid_uid, nid.nid_name); + } + if (!svc_sendreply(transp, (xdrproc_t)xdr_retval, + (caddr_t)&info)) + syslog(LOG_ERR, "Can't send reply"); + return; + case RPCNFSUSERD_GETGID: + if (!svc_getargs(transp, (xdrproc_t)xdr_getid, + (caddr_t)&info)) { + svcerr_decode(transp); + return; + } + grp = getgrgid((gid_t)info.id); + info.retval = 0; + if (grp != NULL) { + nid.nid_usertimeout = defusertimeout; + nid.nid_gid = grp->gr_gid; + nid.nid_name = grp->gr_name; + } else { + nid.nid_usertimeout = 5; + nid.nid_gid = (gid_t)info.id; + nid.nid_name = defaultgroup; + } + nid.nid_namelen = strlen(nid.nid_name); + nid.nid_flag = NFSID_ADDGID; + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) { + info.retval = error; + syslog(LOG_ERR, "Can't add group %s\n", + grp->gr_name); + } else if (verbose) { + syslog(LOG_ERR,"Added gid=%d name=%s\n", + nid.nid_gid, nid.nid_name); + } + if (!svc_sendreply(transp, (xdrproc_t)xdr_retval, + (caddr_t)&info)) + syslog(LOG_ERR, "Can't send reply"); + return; + case RPCNFSUSERD_GETUSER: + if (!svc_getargs(transp, (xdrproc_t)xdr_getname, + (caddr_t)&info)) { + svcerr_decode(transp); + return; + } + pwd = getpwnam(info.name); + info.retval = 0; + if (pwd != NULL) { + nid.nid_usertimeout = defusertimeout; + nid.nid_uid = pwd->pw_uid; + nid.nid_name = pwd->pw_name; + } else { + nid.nid_usertimeout = 5; + nid.nid_uid = defaultuid; + nid.nid_name = info.name; + } + nid.nid_namelen = strlen(nid.nid_name); + nid.nid_flag = NFSID_ADDUSERNAME; + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) { + info.retval = error; + syslog(LOG_ERR, "Can't add user %s\n", pwd->pw_name); + } else if (verbose) { + syslog(LOG_ERR,"Added uid=%d name=%s\n", + nid.nid_uid, nid.nid_name); + } + if (!svc_sendreply(transp, (xdrproc_t)xdr_retval, + (caddr_t)&info)) + syslog(LOG_ERR, "Can't send reply"); + return; + case RPCNFSUSERD_GETGROUP: + if (!svc_getargs(transp, (xdrproc_t)xdr_getname, + (caddr_t)&info)) { + svcerr_decode(transp); + return; + } + grp = getgrnam(info.name); + info.retval = 0; + if (grp != NULL) { + nid.nid_usertimeout = defusertimeout; + nid.nid_gid = grp->gr_gid; + nid.nid_name = grp->gr_name; + } else { + nid.nid_usertimeout = 5; + nid.nid_gid = defaultgid; + nid.nid_name = info.name; + } + nid.nid_namelen = strlen(nid.nid_name); + nid.nid_flag = NFSID_ADDGROUPNAME; + error = nfssvc(NFSSVC_IDNAME, &nid); + if (error) { + info.retval = error; + syslog(LOG_ERR, "Can't add group %s\n", + grp->gr_name); + } else if (verbose) { + syslog(LOG_ERR,"Added gid=%d name=%s\n", + nid.nid_gid, nid.nid_name); + } + if (!svc_sendreply(transp, (xdrproc_t)xdr_retval, + (caddr_t)&info)) + syslog(LOG_ERR, "Can't send reply"); + return; + default: + svcerr_noproc(transp); + return; + }; +} + +/* + * Xdr routine to get an id number + */ +bool_t +xdr_getid(XDR *xdrsp, caddr_t cp) +{ + struct info *ifp = (struct info *)cp; + + return (xdr_long(xdrsp, &ifp->id)); +} + +/* + * Xdr routine to get a user name + */ +bool_t +xdr_getname(XDR *xdrsp, caddr_t cp) +{ + struct info *ifp = (struct info *)cp; + long len; + + if (!xdr_long(xdrsp, &len)) + return (0); + if (len > MAXNAME) + return (0); + if (!xdr_opaque(xdrsp, ifp->name, len)) + return (0); + ifp->name[len] = '\0'; + return (1); +} + +/* + * Xdr routine to return the value. + */ +bool_t +xdr_retval(XDR *xdrsp, caddr_t cp) +{ + struct info *ifp = (struct info *)cp; + long val; + + val = ifp->retval; + return (xdr_long(xdrsp, &val)); +} + +/* + * cleanup_term() called via SIGUSR1. + */ +void +cleanup_term(int signo) +{ + int i, cnt; + + if (im_a_slave) + exit(0); + + /* + * Ok, so I'm the master. + * As the Governor of California might say, "Terminate them". + */ + cnt = 0; + for (i = 0; i < nfsuserdcnt; i++) { + if (slaves[i] != (pid_t)-1) { + cnt++; + kill(slaves[i], SIGUSR1); + } + } + + /* + * and wait for them to die + */ + for (i = 0; i < cnt; i++) + wait3(NULL, 0, NULL); + + /* + * Finally, get rid of the socket + */ + if (nfssvc(NFSSVC_NFSUSERDDELPORT, NULL) < 0) { + syslog(LOG_ERR, "Can't do nfssvc() to delete the port\n"); + exit(1); + } + exit(0); +} + +void +usage(void) +{ + + errx(1, + "usage: nfsuserd [-usermax cache_size] [-usertimeout minutes] [-verbose] [-domain domain_name] [n]"); +}
-Data on recordings of "Save That Time," Russ Long, Serrob Publishing, BMI:
---------------------------------------------------------------------------
-Artist:		Karrin Allyson
-CD:		I Didn't Know About You
-Copyright Date:	1993
-Label:		Concord Jazz, Inc.
-ID:		CCD-4543
-Track Time:	3:44
-Personnel:	Karrin Allyson, vocal
-		Russ Long, piano
-		Gerald Spaits, bass
-		Todd Strait, drums
-Notes:		CD notes "additional lyric by Karrin Allyson;
-		arranged by Russ Long and Karrin Allyson"
-ADO Rating:	1 star
-AMG Rating:	3.5 stars
-Penguin Rating:	3.5 stars
---------------------------------------------------------------------------
-Artist:		Kevin Mahogany
-CD:		Double Rainbow
-Copyright Date:	1993
-Label:		Enja Records
-ID:		ENJ-7097 2
-Track Time:	6:27
-Personnel:	Kevin Mahogany, vocal
-		Kenny Barron, piano
-		Ray Drummond, bss
-		Ralph Moore, tenor saxophone
-		Lewis Nash, drums
-ADO Rating:	1.5 stars
-AMG Rating:	unrated
-Penguin Rating:	3 stars
---------------------------------------------------------------------------
-Artist:		Joe Williams
-CD:		Here's to Life
-Copyright Date:	1994
-Label:		Telarc International Corporation
-ID:		CD-83357
-Track Time:	3:58
-Personnel:	Joe Williams, vocal
-		The Robert Farnon [39 piece] Orchestra
-Notes:		On-line information and samples available at
-		http://telarc.dmn.com/telarc/releases/release.req?ID=83357
-ADO Rating:	black dot
-AMG Rating:	2 stars
-Penguin Rating:	3 stars
---------------------------------------------------------------------------
-Artist:		Charles Fambrough
-CD:		Keeper of the Spirit
-Copyright Date:	1995
-Label:		AudioQuest Music
-ID:		AQ-CD1033
-Track Time:	7:07
-Personnel:	Charles Fambrough, bass
-		Joel Levine, tenor recorder
-		Edward Simon, piano
-		Lenny White, drums
-		Marion Simon, percussion
-Notes:		On-line information and samples available at
-		http://wwmusic.com/~music/audioq/rel/1033.html
-ADO Rating:	2 stars
-AMG Rating:	unrated
-Penguin Rating:	3 stars
-==========================================================================
-Also of note:
---------------------------------------------------------------------------
-Artist:		Holly Cole Trio
-CD:		Blame It On My Youth
-Copyright Date:	1992
-Label:		Manhattan
-ID:		CDP 7 97349 2
-Total Time:	37:45
-Personnel:	Holly Cole, voice
-		Aaron Davis, piano
-		David Piltch, string bass
-Notes:		Lyrical reference to "Eastern Standard Time" in
-			Tom Waits' "Purple Avenue"
-ADO Rating:	2.5 stars
-AMG Rating:	2 stars
-Penguin Rating:	unrated
---------------------------------------------------------------------------
-Artist:		Milt Hinton
-CD:		Old Man Time
-Copyright Date:	1990
-Label:		Chiaroscuro
-ID:		CR(D) 310
-Total Time:	149:38 (two CDs)
-Personnel:	Milt Hinton, bass
-		Doc Cheatham, Dizzy Gillespie, Clark Terry, trumpet
-		Al Grey, trombone
-		Eddie Barefield, Joe Camel (Flip Phillips), Buddy Tate,
-			clarinet and saxophone
-		John Bunch, Red Richards, Norman Simmons, Derek Smith,
-			Ralph Sutton, piano
-		Danny Barker, Al Casey, guitar
-		Gus Johnson, Gerryck King, Bob Rosengarden, Jackie Williams,
-			drums
-		Lionel Hampton, vibraphone
-		Cab Calloway, Joe Williams, vocal
-		Buck Clayton, arrangements
-Notes:		tunes include Old Man Time, Time After Time,
-			Sometimes I'm Happy,
-			A Hot Time in the Old Town Tonight,
-			Four or Five Times, Now's the Time,
-			Time on My Hands, This Time It's Us,
-			and Good Time Charlie
-		On-line samples available at
-		http://www.globalmusic.com/labels/chiaroscuro/chiaro_cd_gallery.html
-ADO Rating:	3 stars
-AMG Rating:	4.5 stars
-Penguin Rating:	3 stars
---------------------------------------------------------------------------
-Artist:		Paul Broadbent
-CD:		Pacific Standard Time
-Copyright Date:	1995
-Label:		Concord Jazz, Inc.
-ID:		CCD-4664
-Total Time:	62:42
-Personnel:	Paul Broadbent, piano
-		Putter Smith, Bass
-		Frank Gibson, Jr., drums
-Notes:		The CD cover features an analemma for equation of time fans
-ADO Rating:	1 star
-AMG Rating:	3 stars
-Penguin Rating:	3.5 stars
---------------------------------------------------------------------------
-Artist:		Anthony Braxton/Richard Teitelbaum
-CD:		Silence/Time Zones
-Copyright Date:	1996
-Label:		Black Lion
-ID:		BLCD 760221
-Total Time:	72:58
-Personnel:	Anthony Braxton, sopranino and alto saxophones,
-			contrebasse clarinet, miscellaneous instruments
-		Leo Smith, trumpet and miscellaneous instruments
-		Leroy Jenkins, violin and miscellaneous instruments
-		Richard Teitelbaum, modular moog and micromoog synthesizer
-ADO Rating:	black dot
-AMG Rating:	unrated
---------------------------------------------------------------------------
-Artist:		Jules Verne
-Book:		Le Tour du Monde en Quatre-Vingts Jours
-		(Around the World in Eighty Days)
-Notes:		Wall-clock time plays a central role in the plot.
-		European readers of the 1870s clearly held the U.S. press in
-		deep contempt; the protagonists cross the U.S. without once
-		reading a paper.
-		An on-line French-language version of the book
-		"with illustrations from the original 1873 French-language edition"
-		is available at
-		http://fourmilab.ch/etexts/www/tdm80j
-		An on-line English-language translation of the book is available at
-		http://www.literature.org/Works/Jules-Verne/eighty
---------------------------------------------------------------------------
-Film:		Bell Science - About Time
-Notes:		The Frank Baxter/Richard Deacon extravaganza
-		Information on ordering is available at
-		http://www.videoflicks.com/VF/38/038332.htm
---------------------------------------------------------------------------
-The syndicated comic strip "Dilbert" featured an all-too-rare example of
-time zone humor on 1998-03-14.
-