diff --git a/LICENSE b/LICENSE index 484535a..885e986 100644 --- a/LICENSE +++ b/LICENSE @@ -1,988 +1,49 @@ - The TwinSock, TKERN and IRC II for Windows License - Version 1, 16-January-1995 +Troy Rollo's "Sponsorware" License +Synopsis +How we can continue to provide software to you free of charge while still covering rising costs. +Preamble +Ten years ago, it was easy to find free software for all environments. Today, finding free software for Windows is a difficult task. Most of the offerings on public archive sites are "shareware", requiring payment for continued use. -Preamble: +Much of the move to shareware has been attributed to the rising costs of the production of this software. Development tools are more expensive, and expensive CD-ROM subscriptions are required to stay abreast of changes. - The person who made this software possible was billed for - Citizens Utilities toll calls to a number he believed to be - a local (no charge) call, and attempted to the best of his - abilities to verify were local calls. +In addition to these problems, new problems have arisen with the recent explosion of interest in the Internet. Every man and his dog is now able to publish, and at times the material published can be slanderous or wildly inaccurate. Producing software for free means that the author is exposed to this sort of treatment without receiving any funds with which to fight it. - Citizens Utilities have refused to withdraw or refund the - charges for those toll calls. +A further area of concern is that of trademarks. While the trademark of a free software product does have the protection of law, the cost of pursuing a trademark abuse case in the courts is upwards of $US20,000, not including the travel costs required to proceed with a case on the other side of the world, and in order to claim compensation (for instance, the cost of the proceedings), you must have the trademark registered in a jurisdiction recognised by the court (this means having registration in at least your own country, the USA, and at least one European country) - more money. - As the bulk of those toll calls were made while developing, - improving and testing the software products TwinSock and - IRCII for Windows, which are provided free, the Citizens - Utilities Company of California has effectively asked the - author of this software to pay for the privilege of producing - the software and giving it away free of charge. +The sponsorware concept is aimed at providing an alternative to fund the costs of development without having to sacrifice the free nature of the software. Sponsorware may be either Free Software as defined by Richard Stallman, or public domain, the only difference being that sponsorware is distributed with paid advertising material contained in it, and that any redistribution of the software in verbatim or modified form must contain that advertising until a stated date. There may also be an exclusion on including advertising from vendors competing with existing advertisers. - Consequently, this license is designed to ensure that - Citizens Utilities and any affiliated companies cannot - derive any benefit from this software without paying license - fees. +If you contact a company as a result of advertising in sponsorware, you should let the advertiser know the name of the program which contained the advertisement. By doing this you will encourage further advertising, which will mean more free software for you. - If you have no dealings whatsoever with any company named - Citizens Utilities, this license is effectively identical - to the appropriate GNU license for the package you are - using, or to the standard ircII license if the package is - ircII. If you do have dealings with a company named Citizens - Utilities, there may be additional conditions imposed on - your use of the software. +This license may be reproduced and applied to your own programs, either in verbatim or modified form, provided that this preamble remains intact. If you modify the license, you should add a line at the top stating your name, that you have modified the license, and the date of the modification. - This license applies retrospectively to the degree that as of - 16-January-1995, the products TKERN and TwinSock, which had - previously been made available under another license, are - withdrawn, and both current and previous versions of TKERN - and TwinSock are re-released under this license. +Troy Rollo +October 1995 - If any licensing fees are payable, they should be fowarded - in the form of American Express Travellers Cheques or - international money orders payable to Troy Rollo to: +Conditions of the License - Troy Rollo - Sycomp Pty Ltd - Level 4 - 1 James Place - North Sydney 2060 - AUSTRALIA +1. The documentation for this software and/or the software itself contains advertising material. This advertising material and any links to that advertising material must be included unmodified in any redistribution of this software at least until the date stated at the start of the advertisement. - All money amounts are in United States Dollars. +2. Some advertisements may contain the text "Non competition clause applies" at the start. If this is the case, you may not include advertising for a product which competes with the product advertised until the advertisement expires as detailed in part 1 of this license. If you are unsure if a product competes with a product in such an advertisement, you should contact the advertiser for their opinion. -This product is licensed under the following terms: +3. You are free to redistribute verbatim copies of this software including all existing files and no additional files. - 1. Subject to the remaining conditions of this license, all the - terms of the following licenses shall apply to various parts - of the software: +4. You are free to redistribute modified copies of this software provided that: - i) for ircII, the license for ircII 2.6 for UNIX +i) you include the full source code to the modified version of the software. +ii) you include, at the start of the documentation, a notice stating that you have modified the software, stating your name and the release date of the modified version. +iii) you release the entire modified package under the terms of this license without any modification to its terms. - ii) for TwinSock, and for parts of TKERN which are included - in TKFMANGR.EXE, the GNU GENERAL PUBLIC LICENSE, Version 2 - (Included herein as Schedule 1) shall apply to this software. + +If you make significant enhancements you may also include additional advertising to help meet your costs, or remove any advertising which has expired. - iii) For the remainder of TKERN, the GNU LIBRARY GENERAL PUBLIC - LICENSE, Version 2 (Included herein as Schedule 2) +5. You may not remove or modify any credits contained in this software or in its documentation. - 2. A license fee of $231.02 (Two hundred and thirty one dollars - and two cents) per machine installed shall be payable by anybody - who is: +6. As you have not signed this license, you are not obliged to accept it, however as nothing else gives you the right to redistribute and modify this software, doing so would be illegal. Consequently, your redistribution or modification of this software will be construed as acceptance of this license. - (a) a company named Citizens Utilities incorporated in any - state or territory of the United States of America +7. Any person who violates this license loses the right to use, modify and redistribute this software and any software based on it, and may also be required to pay financial compensation to the authors of the software. - OR +8. If you are unable to operate within the terms of this license, you are free to contact the authors to ask for their approval of modifications to it, provided the modifications do not go against the spirit of this license. - (b) a parent company of any company covered by (a) +9. Because this program is supplied free of charge, it comes without any warranty, including the implied warranties of merchantability and fitness for a purpose. All risks related to the use of the software are assumed by you, the user. - i) For the purposes of this license, a parent company - is any company holding more than 20% of the shares - of the company by cash value. - - ii) A parent company of any company covered by (b) is - itself considered to be a parent company, and thus - is also covered by (b) - - OR - - (c) an agent of a company covered by (a) or (b) - - OR - - (d) a person holding shares in a company covered by (a) - - OR - - (e) an employee of a company covered by (a) or (b) - - OR - - (f) a person living in the same residence as a person - covered by (e) - - OR - - (g) a govornment or govornment department holding more - than 10% of the shares in a company covered by (a) - - 3. The software may not be transmitted over any communications - service provided by a company named Citizens Utilities - incorporated in any state or territory of the United States - of America. Any copies inadvertantly received by such - transmission must be destroyed. - - 4. If the software is communications software, it may not be - used to transmit or receive data over any communications - service provided by a company named Citizens Utilities - incorporated in any state or territory of the United States - of America. - - 5. If there is no alternative service provider available - in the area, the software may be tansmitted or used over - a communications service provided by a company covered by - (3) and (4) if - - (a) The user of the software witholds payment of all - bills received until the last day payable - - AND - - (b) The user submits, with each bill payment, a complaint - about Citizens Utilities toll charges on account - 916/683-2400 between 15-December-1994 and 15-January-1995, - requesting that the full amount of those charges be - refunded - - AND - - (c) The user request to pay each bill by credit card if they - posess any of the following cards: Visa, Mastercard, - American Express. - - 6. A person whose telephone service is provided by a company - covered by (4), who switches to another provider within - 14 days of receiving the software, or before 22-February-1995, - whichever is later, may continue to use the software over - the existing service until the new service is in place or - for before the 8th day after the request is made to cancel - the original service (whichever is earlier) provided that - they inform the provider covered by (4) that they are - participating in the Citizens Utilities boycott relating - to account 916/683-2400. - - 7. Should any part of this license be held by a court to be - illegal or unenforcable, all licenses to use the software - shall be terminated. - - 8. Within the scope of this license, excluding the scheduled - items, modifying the software shall be considered to be using - the software. - - -SCHEDULE 1 -========== - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - 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 -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. - - 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. - - 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. - - 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. - - 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. - - 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. - - 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". - -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. - - 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. - -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. - - 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: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - 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. - - 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. - -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. - -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. - - 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: - - 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, - - 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, - - 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 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. - -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. - - 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. - - 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 -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 -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. - -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. - -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. - -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. - - 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 -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. - - 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. - - NO WARRANTY - - 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. - - 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. - - END OF TERMS AND CONDITIONS - - Appendix: 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 -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 -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - 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 - (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., 675 Mass Ave, Cambridge, MA 02139, USA. - -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: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision 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. - -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: - - 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. - - -SCHEDULE 2 -========== - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, 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. - - 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 library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, 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 library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete 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 distribute a copy of this License along with the -Library. - - 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. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -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 Library, 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. - -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 Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you 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. - - If distribution of 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 satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. 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. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library 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. - - 9. 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 Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -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 -this License. - - 11. 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 -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 Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library 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 Library. - -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. - -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. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library 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. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library 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 Library -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 Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -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. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "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 -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. 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 LIBRARY 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 -LIBRARY (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 LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. 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 the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! +10. Under no circumstances will anybody who contributes or redistributes this software be liable for any damages relating to your use, misuse or inability to use this software. diff --git a/build.sh b/build.sh index 85ff7f3..0cc0428 100644 --- a/build.sh +++ b/build.sh @@ -151,7 +151,7 @@ esac rm -f a.out test.c -OBJECTS="tshost.o packet.o getentry.o commands.o ${TERM_OBJECT} $NEED_MEM" +OBJECTS="tshost.o packet.o getentry.o commands.o getsock.o sockinfo.o ${TERM_OBJECT} $NEED_MEM" echo "Building makefile" echo ".c.o:" > Makefile @@ -164,4 +164,4 @@ echo echo 'Running "make -f Makefile"' echo exec make -f Makefile - + \ No newline at end of file diff --git a/commands.c b/commands.c index c1534c2..36b10dc 100644 --- a/commands.c +++ b/commands.c @@ -18,9 +18,11 @@ #include #include #include +#include #include "twinsock.h" #include "tx.h" #include "wserror.h" +#include "sockinfo.h" #ifdef NEED_H_ERRNO extern int h_errno; @@ -356,6 +358,18 @@ ConvertSA(struct func_arg *pfa, struct sockaddr_in *sin) return (struct sockaddr *) sin; } +struct sockaddr * +ConvertSABack(struct func_arg *pfa, struct sockaddr_in *sin) +{ + u_short tmp; + + tmp = sin->sin_family; + tmp = RevFamily(tmp); + *(u_short *) sin = htons(tmp); + memcpy(pfa->pvData, sin, sizeof(*sin)); + return (struct sockaddr *) sin; +} + int MapError(int iError) { @@ -632,11 +646,44 @@ SendRemapMessage( short iFrom, free(ptxr); } +void +Get_Arguments( struct tx_request *ptxr, + struct func_arg **ppfaArgs, + struct func_arg *pfaResult, + int *pnArgs) +{ + int i, nArgs; + char *pchData; + struct func_arg *pfaArgs, faResult; + + nArgs = ntohs(ptxr->nArgs); + + pfaArgs = (struct func_arg *) malloc(sizeof(struct func_arg) * nArgs); + pchData = ptxr->pchData; + for (i = 0; i < nArgs; i++) + { + pfaArgs[i].at = (enum arg_type) ntohs(ToShort(pchData)); + pchData += sizeof(short); + pfaArgs[i].iLen = ntohs(ToShort(pchData)); + pchData += sizeof(short); + pfaArgs[i].pvData = pchData; + pchData += pfaArgs[i].iLen; + } + faResult.at = (enum arg_type) ntohs(ToShort(pchData)); + pchData += sizeof(short); + faResult.iLen = ntohs(ToShort(pchData)); + pchData += sizeof(short); + faResult.pvData = pchData; + *ppfaArgs = pfaArgs; + *pfaResult = faResult; + *pnArgs = nArgs; +} + void ResponseReceived(struct tx_request *ptxr_) { enum Functions ft; - short nArgs; + int nArgs; short nLen; short id; short iInPort; @@ -666,29 +713,25 @@ ResponseReceived(struct tx_request *ptxr_) ptxr = (struct tx_request *) malloc(nLen); memcpy(ptxr, ptxr_, nLen); ft = (enum Functions) ntohs(ptxr->iType); - nArgs = ntohs(ptxr->nArgs); - - pfaArgs = (struct func_arg *) malloc(sizeof(struct func_arg) * nArgs); - pchData = ptxr->pchData; - for (i = 0; i < nArgs; i++) - { - pfaArgs[i].at = (enum arg_type) ntohs(ToShort(pchData)); - pchData += sizeof(short); - pfaArgs[i].iLen = ntohs(ToShort(pchData)); - pchData += sizeof(short); - pfaArgs[i].pvData = pchData; - pchData += pfaArgs[i].iLen; - } - faResult.at = (enum arg_type) ntohs(ToShort(pchData)); - pchData += sizeof(short); - faResult.iLen = ntohs(ToShort(pchData)); - pchData += sizeof(short); - faResult.pvData = pchData; + Get_Arguments(ptxr, &pfaArgs, &faResult, &nArgs); iErrorSent = 0; errno = 0; h_errno = 0; + if (ft != FN_Socket && HasSocketArg(ft)) + { + iSocket = GetServerFromClient(GetIntVal(&pfaArgs[0])); + if (iSocket == -1) + { + ptxr->nError = htons(WSAENOTSOCK); + ptxr->nLen = htons(sizeof(short) * 5); + PacketTransmitData(ptxr, sizeof(short) * 5, -2); + iErrorSent = 1; + ft = (enum Functions) -1; + } + } + switch(ft) { case FN_IOCtl: @@ -702,23 +745,25 @@ ResponseReceived(struct tx_request *ptxr_) break; case FN_Send: - SetIntVal(&faResult, - send(GetIntVal(&pfaArgs[0]), - pfaArgs[1].pvData, - GetIntVal(&pfaArgs[2]), - GetIntVal(&pfaArgs[3]))); + SetIntVal(&faResult, GetIntVal(&pfaArgs[2])); + QueueSendRequest(iSocket, + pfaArgs[1].pvData, + GetIntVal(&pfaArgs[2]), + GetIntVal(&pfaArgs[3]), + 0); nLen = CompressArg(ptxr, pfaArgs, nArgs, &faResult, 1); + errno = 0; break; case FN_SendTo: - SetIntVal(&faResult, - sendto(GetIntVal(&pfaArgs[0]), - pfaArgs[1].pvData, - GetIntVal(&pfaArgs[2]), - GetIntVal(&pfaArgs[3]), - ConvertSA(&pfaArgs[4], &sin), - GetIntVal(&pfaArgs[5]))); + SetIntVal(&faResult, GetIntVal(&pfaArgs[2])); + QueueSendRequest(iSocket, + pfaArgs[1].pvData, + GetIntVal(&pfaArgs[2]), + GetIntVal(&pfaArgs[3]), + ConvertSA(&pfaArgs[4], &sin)); nLen = CompressArg(ptxr, pfaArgs, nArgs, &faResult, 1); + errno = 0; break; case FN_Bind: @@ -729,11 +774,16 @@ ResponseReceived(struct tx_request *ptxr_) { errno = 0; sin.sin_port = htons(iPort); - iValue = bind(GetIntVal(&pfaArgs[0]), + iValue = bind(iSocket, (struct sockaddr *) &sin, GetIntVal(&pfaArgs[2])); if (!iValue) { + iLen = sizeof(sin); + getsockname(iSocket, + (struct sockaddr *) &sin, + &iLen); + ConvertSABack(&pfaArgs[1], &sin); if (iPort != iInPort) SendRemapMessage(iInPort, iPort); break; @@ -743,32 +793,47 @@ ResponseReceived(struct tx_request *ptxr_) break; case FN_Connect: - iSocket = GetIntVal(&pfaArgs[0]); iValue = connect(iSocket, ConvertSA(&pfaArgs[1], &sin), GetIntVal(&pfaArgs[2])); SetIntVal(&faResult, iValue); if (iValue != -1) + { BumpLargestFD(iSocket); + iLen = sizeof(sin); + getsockname(iSocket, + (struct sockaddr *) &sin, + &iLen); + ConvertSABack(&pfaArgs[1], &sin); + errno = 0; + } + else if (errno == EINPROGRESS) + { + SetWriter(iSocket); + QueueConnectWait(iSocket, ptxr); + iErrorSent = 1; + } break; case FN_Close: SetIntVal(&faResult, - close(GetIntVal(&pfaArgs[0]))); - FlushStream(GetIntVal(&pfaArgs[0])); - SetClosed(GetIntVal(&pfaArgs[0])); + close(iSocket)); + iValue = GetIntVal(&pfaArgs[0]); + FlushStream(iValue); + SetClosed(iSocket); + ReleaseSocketEntry(iValue); + ReleaseServerSocket(iValue); break; case FN_Shutdown: SetIntVal(&faResult, - shutdown(GetIntVal(&pfaArgs[0]), + shutdown(iSocket, GetIntVal(&pfaArgs[1]))); if (GetIntVal(&pfaArgs[1]) != 1) - SetClosed(GetIntVal(&pfaArgs[0])); + SetClosed(iSocket); break; case FN_Listen: - iSocket = GetIntVal(&pfaArgs[0]); iValue = listen(iSocket, GetIntVal(&pfaArgs[1])); SetIntVal(&faResult, iValue); @@ -780,12 +845,13 @@ ResponseReceived(struct tx_request *ptxr_) break; case FN_Socket: - iSocket = socket(GetFamily(GetIntVal(&pfaArgs[0])), - GetType(GetIntVal(&pfaArgs[1])), - GetProtocol(GetIntVal(&pfaArgs[2]))); + iSocket = socket(GetFamily(GetIntVal(&pfaArgs[1])), + GetType(GetIntVal(&pfaArgs[2])), + GetProtocol(GetIntVal(&pfaArgs[3]))); SetIntVal(&faResult,iSocket); if (iSocket != -1) { + AddSocketEntry(GetIntVal(&pfaArgs[0]), iSocket); BumpLargestFD(iSocket); nOptVal = 1; iLen = sizeof(nOptVal); @@ -794,13 +860,16 @@ ResponseReceived(struct tx_request *ptxr_) SO_OOBINLINE, (char *) &nOptVal, iLen); + iValue = fcntl(iSocket, F_GETFL, 0); + iValue |= FNDELAY; + fcntl(iSocket, F_SETFL, iValue); errno = 0; } break; case FN_GetPeerName: iLen = GetIntVal(&pfaArgs[2]); - iValue = getpeername(GetIntVal(&pfaArgs[0]), + iValue = getpeername(iSocket, (struct sockaddr *) pfaArgs[1].pvData, &iLen); if (iValue != -1) @@ -818,7 +887,7 @@ ResponseReceived(struct tx_request *ptxr_) case FN_GetSockName: iLen = GetIntVal(&pfaArgs[2]); - iValue = getsockname(GetIntVal(&pfaArgs[0]), + iValue = getsockname(iSocket, (struct sockaddr *) pfaArgs[1].pvData, &iLen); if (iValue != -1) @@ -837,7 +906,7 @@ ResponseReceived(struct tx_request *ptxr_) case FN_GetSockOpt: iLen = GetIntVal(&pfaArgs[4]); nOptName = GetOption(GetIntVal(&pfaArgs[2])); - iValue = getsockopt( GetIntVal(&pfaArgs[0]), + iValue = getsockopt( iSocket, GetIntVal(&pfaArgs[1]), nOptName, (char *) pfaArgs[3].pvData, @@ -856,7 +925,7 @@ ResponseReceived(struct tx_request *ptxr_) nOptName = GetOption(GetIntVal(&pfaArgs[2])); SwapSockOptIn(&pfaArgs[3], nOptName); - iValue = setsockopt( GetIntVal(&pfaArgs[0]), + iValue = setsockopt( iSocket, SOL_SOCKET, nOptName, (char *) pfaArgs[3].pvData, @@ -966,6 +1035,39 @@ ResponseReceived(struct tx_request *ptxr_) free(pfaArgs); } +void +FinishConnect(tws_sockinfo *psi) +{ + int iResult; + struct sockaddr_in sin; + int iLen; + struct tx_request *ptxr = psi->ptxrConnect; + struct func_arg *pfaArgs, faResult; + char c; + int nArgs; + + Get_Arguments(ptxr, &pfaArgs, &faResult, &nArgs); + psi->ptxrConnect = 0; + iLen = sizeof(sin); + getsockname(psi->iServerSocket, + (struct sockaddr *) &sin, &iLen); + iResult = write(psi->iServerSocket, &c, 0); + if (iResult == -1) + { + ptxr->nError = htons(MapError(errno)); + } + else + { + BumpLargestFD(psi->iServerSocket); + ptxr->nError = 0; + } + ConvertSABack(&pfaArgs[1], &sin); + SetIntVal(&faResult, iResult); + PacketTransmitData(ptxr, ntohs(ptxr->nLen), -2); + free(ptxr); + free(pfaArgs); +} + void SendSocketData(int iSocket, void *pvData, diff --git a/comms.c b/comms.c index feaf24d..d2c01dd 100644 --- a/comms.c +++ b/comms.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "twinsock.h" extern HINSTANCE hinst; @@ -32,45 +33,79 @@ enum LineSpeed { B110, B300, B600, B1200, B2400, B4800, B9600, unsigned GetSpeedIndex(enum LineSpeed lsSpeed); void +#ifdef __FLAT__ +InitComm(HANDLE idComm) +#else InitComm(int idComm) +#endif { DCB dcb; unsigned speed; - + int iFlowType; +#ifdef __FLAT__ + COMMTIMEOUTS cto; +#endif + + memset(&dcb, 0, sizeof(dcb)); +#ifdef __FLAT__ + dcb.DCBlength = sizeof(dcb); + dcb.fDtrControl = GetConfigInt("fDtrControl", + iFlowType ? DTR_CONTROL_HANDSHAKE : + DTR_CONTROL_ENABLE); + dcb.fDsrSensitivity = GetConfigInt("fDsrSensitivity", 0); + dcb.fTXContinueOnXoff = GetConfigInt("fTXContinueOnXoff", TRUE); + dcb.fErrorChar = 0; + dcb.fRtsControl = GetConfigInt("fRtsControl", + iFlowType ? RTS_CONTROL_ENABLE : + RTS_CONTROL_HANDSHAKE); + dcb.fAbortOnError = GetConfigInt("fAbortOnError", FALSE); + dcb.wReserved = 0; + dcb.ErrorChar = 0; + dcb.wReserved1 = 0; +#else dcb.Id = idComm; + dcb.RlsTimeout = GetConfigInt("RlsTimeout", 0); + dcb.CtsTimeout = GetConfigInt("CtsTimeout", 0); + dcb.DsrTimeout = GetConfigInt("DsrTimeout", 1000); + dcb.PeChar = 0; + dcb.fChEvt = 0; + dcb.fDtrflow = GetConfigInt("fDtrFlow", (iFlowType == 1)); + dcb.fRtsflow = GetConfigInt("fRtsFlow", (iFlowType == 0)); + dcb.TxDelay = 0; + dcb.fDtrDisable = GetConfigInt("fDtrDisable", FALSE); + dcb.fRtsDisable = GetConfigInt("fRtsDisable", FALSE); + dcb.fPeChar = 0; + dcb.fDummy = 0; +#endif + iFlowType = GetConfigInt("FlowType", 0); speed = GetConfigInt("Speed", B19200); dcb.BaudRate = GetSpeedIndex((enum LineSpeed) speed); dcb.ByteSize = GetConfigInt("Databits", 8); dcb.Parity = GetConfigInt("Parity", NOPARITY); dcb.StopBits = GetConfigInt("StopBits", ONESTOPBIT); - dcb.RlsTimeout = GetConfigInt("RlsTimeout", 0); - dcb.CtsTimeout = GetConfigInt("CtsTimeout", 0); - dcb.DsrTimeout = GetConfigInt("DsrTimeout", 0); dcb.fBinary = TRUE; - dcb.fRtsDisable = GetConfigInt("fRtsDisable", FALSE); dcb.fParity = GetConfigInt("fParity", FALSE); - dcb.fOutxCtsFlow = GetConfigInt("OutxCtsFlow", TRUE); - dcb.fOutxDsrFlow = GetConfigInt("OutxDsrFlow", FALSE); - dcb.fDummy = 0; - dcb.fDtrDisable = GetConfigInt("fDtrDisable", FALSE); - dcb.fOutX = GetConfigInt("fOutX", TRUE); + dcb.fOutxCtsFlow = GetConfigInt("OutxCtsFlow", (iFlowType == 0)); + dcb.fOutxDsrFlow = GetConfigInt("OutxDsrFlow", (iFlowType == 1)); + dcb.fOutX = GetConfigInt("fOutX", FALSE); dcb.fInX = GetConfigInt("fInX", FALSE); - dcb.fPeChar = 0; dcb.fNull = 0; - dcb.fChEvt = 0; - dcb.fDtrflow = GetConfigInt("fDtrFlow", FALSE); - dcb.fRtsflow = GetConfigInt("fRtsFlow", FALSE); dcb.fDummy2 = 0; dcb.XonChar = '\021'; dcb.XoffChar = '\023'; dcb.XonLim = 100; dcb.XoffLim = 900; - dcb.PeChar = 0; dcb.EofChar = 0; dcb.EvtChar = 0; - dcb.TxDelay = 0; +#ifdef __FLAT__ + memset(&cto, 0, sizeof(cto)); + cto.ReadIntervalTimeout = 5; + SetCommState(idComm, &dcb); + SetCommTimeouts(idComm, &cto); +#else SetCommState(&dcb); +#endif } static struct @@ -144,6 +179,10 @@ char *apchStopBits[] = #define CE_DATABITS 105 #define CE_PARITY 107 #define CE_STOPBITS 109 +#define CE_CTSRTS 121 +#define CE_DTRDSR 122 +#define CE_NOFLOW 123 +#define CE_BUFFER 130 static void FillCommsDialog(HWND hDlg) @@ -171,18 +210,25 @@ FillCommsDialog(HWND hDlg) sprintf(achTmp, "%d", i); SendDlgItemMessage(hDlg, CE_DATABITS, CB_ADDSTRING, 0, (LPARAM) achTmp); } - i = GetPrivateProfileInt("Config", "DataBits", 8, "TWINSOCK.INI"); + i = GetConfigInt("DataBits", 8); SendDlgItemMessage(hDlg, CE_DATABITS, CB_SETCURSEL, i - 5, 0); for (i = 0; apchParities[i]; i++) SendDlgItemMessage(hDlg, CE_PARITY, CB_ADDSTRING, 0, (LPARAM) apchParities[i]); - i = GetPrivateProfileInt("Config", "Parity", 0, "TWINSOCK.INI"); + i = GetConfigInt("Parity", 0); SendDlgItemMessage(hDlg, CE_PARITY, CB_SETCURSEL, i, 0); for (i = 0; apchStopBits[i]; i++) SendDlgItemMessage(hDlg, CE_STOPBITS, CB_ADDSTRING, 0, (LPARAM) apchStopBits[i]); - i = GetPrivateProfileInt("Config", "StopBits", 0, "TWINSOCK.INI"); + i = GetConfigInt("StopBits", 0); SendDlgItemMessage(hDlg, CE_STOPBITS, CB_SETCURSEL, i, 0); + + i = GetConfigInt("FlowType", 0); + SendDlgItemMessage(hDlg, CE_CTSRTS + i, BM_SETCHECK, 1, 0); + + i = GetConfigInt("BufferSize", 16384); + sprintf(achTmp, "%d", i); + SetDlgItemText(hDlg, CE_BUFFER, achTmp); } void @@ -213,6 +259,17 @@ ReadCommsDialog(HWND hDlg) i = SendDlgItemMessage(hDlg, CE_STOPBITS, CB_GETCURSEL, 0, 0); sprintf(achTemp, "%d", i); WritePrivateProfileString("Config", "StopBits", achTemp, "TWINSOCK.INI"); + + for (i = 0; i < 3; i++) + if (SendDlgItemMessage(hDlg, CE_CTSRTS + i, BM_GETCHECK, 0, 0)) + break; + sprintf(achTemp, "%d", i); + WritePrivateProfileString("Config", "FlowType", achTemp, "TWINSOCK.INI"); + + GetDlgItemText(hDlg, CE_BUFFER, achTemp, sizeof(achTemp)); + if (atoi(achTemp) <= 0) + strcpy(achTemp, "16384"); + WritePrivateProfileString("Config", "BufferSize", achTemp, "TWINSOCK.INI"); } #pragma argsused @@ -239,6 +296,11 @@ CommsDlgProc( HWND hDlg, case IDCANCEL: EndDialog(hDlg, FALSE); break; + + case 3: + WinHelp(hDlg, "TWINSOCK.HLP", HELP_CONTENTS, 0); + break; + } break; } @@ -302,6 +364,7 @@ DialDlgProc( HWND hDlg, EndDialog(hDlg, FALSE); break; + case DL_NUMBER: EnableWindow(GetDlgItem(hDlg, IDOK), (GetDlgItemText(hDlg, DL_NUMBER, achNumber, 80) != 0)); diff --git a/corvu.rtf b/corvu.rtf new file mode 100644 index 0000000..9d93eed --- /dev/null +++ b/corvu.rtf @@ -0,0 +1,1149 @@ +{\rtf1\ansi \deff0\deflang1024{\fonttbl{\f0\froman Times New Roman;}{\f1\froman Symbol;}{\f2\fswiss Arial;}{\f3\froman Tms Rmn;}{\f4\fswiss Helv;}{\f5\fmodern Courier New;}{\f6\fnil Crillee;}}{\colortbl;\red0\green0\blue0; +\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue127;\red0\green127\blue127;\red0\green127\blue0;\red127\green0\blue127; +\red127\green0\blue0;\red127\green127\blue0;\red127\green127\blue127;\red192\green192\blue192;}{\stylesheet{\s243\tqc\tx4320\tqr\tx8640 \f3\lang2057 \sbasedon0\snext243 header;}{\s244 \f3\fs16\up6\lang2057 \sbasedon0\snext0 footnote reference;}{\s245 +\f3\fs20\lang2057 \sbasedon0\snext245 footnote text;}{\s252\li360 \b\f3\lang2057 \sbasedon0\snext255 heading 3;}{\s253\sb120 \b\f4\lang2057 \sbasedon0\snext0 heading 2;}{\s254\sb240 \b\f4\ul\lang2057 \sbasedon0\snext0 heading 1;}{\s255\li720 \f3\lang2057 +\sbasedon0\snext255 Normal Indent;}{\f3\lang2057 \snext0 Normal;}{\s2\li567 \b\f3\lang2057 \sbasedon0\snext2 CRT;}{\s3\li567 \f3\lang2057 \sbasedon0\snext3 Example;}{\s4\fi-288\li576 \f3\lang2057 \sbasedon0\snext4 Level2;}{\s5\fi-144\li144 \f3\lang2057 +\sbasedon0\snext5 Level1;}{\s6\fi-288\li1152 \f3\lang2057 \sbasedon0\snext6 Level3;}{\s7\li144 \f3\lang2057 \sbasedon5\snext7 Follow1;}{\s8\li576 \f3\lang2057 \sbasedon4\snext8 Follow2;}{\s9\li1152 \f3\lang2057 \sbasedon6\snext9 Follow3;}}{\info +{\author Sycomp}{\operator Sycomp}{\creatim\yr1995\mo3\dy30\hr22\min5}{\revtim\yr1995\mo3\dy30\hr22\min5}{\printim\yr1995\mo11\dy4\hr15\min3}{\version2}{\edmins375}{\nofpages0}{\nofwords65536}{\nofchars65536}{\vern16417}} +\paperw11906\paperh16838\margl1800\margr1800\margt1440\margb1440\gutter0 \widowctrl\ftnbj \sectd \linex0\headery709\footery709\colsx709\endnhere \pard\plain \qc \f3\lang2057 {\fs16\up6 #{\footnote \pard\plain \s245\tx900 \f3\fs20\lang2057 {\fs16\up6 #} + CorVu}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} CorVu Pty Ltd}} {\fs20 Expires 1st January 2005}{\fs20 +\par }{\fs20 Non competition clause applies} +\par {\pard\plain \qc \f3\lang2057 {\object\objemb\rsltmerge\objsetsize\objw7683\objh2858{\*\objclass PaintShopPro}{\*\objdata 01050000020000000d0000005061696e7453686f7050726f00000000000000000080b70000 +28000000f4010000ba000000010004000000000018b7000000000000000000001000000010000000000000000000bf0000bf000000bfbf00bf000000bf00bf00bfbf0000c0c0c000808080000000ff0000ff000000ffff00ff000000ff00ff00ffff0000ffffff0000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000eeeeeee000000000eeee0000000eee00eeee00eeeee000000000000000000e00000000e0000000eeeee00eeeee0eeeee0000eeee0ee0000000eeee000000000e00000e000000000000eeeeeee00eeeee0eeeee0000eee000000eeee00000000000000eeeeeee00000e +eeee0eeeee0000eeee00000000000eeeeeee0000000000eee00eeee0000eee00000eee00eeee00eeeee00000000eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee000000000eee00eee0000eeeee0eee0000eee000000000000000000ee0000000eee0000000eee0000eee000eee0000eee00eeeee000eee00eee000000eee000eee0000000000000eee00000eee000eee0000eeeee000eee00eee00000000000000eee00000000 +eee000eee0000eeeeeee00000000000eee00000000000eeeee0eee0000eeeee000eeeee0eee0000eee00000000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee000000000ee0000ee0000eee00eeee0000eee000000000000000000eee000000eee0000000eee0000eee000eee0000ee0000eee0000ee0000ee000000eee000eee0000000000000eee00000eee000eee0000eee00e00ee0000ee00000000000000eee00000000 +eee000eee0000eee000e00000000000eee00000000000eee00eeee0000eee00e00eee00eeee0000eee00000000eee000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee000000000000000000eee000000eee0000000eee0000eee000eee000eee0000eee000eee0000eee00000eee000eee0000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000 +eee000eee000eeee0000e0000000000eee00000000000eee000eee0000eee00000eee000eee0000eee0000000eeee0000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eeee0000000eee0000eee000eee000eee0000eee000eee0000eee0000eeee00eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000 +eee000eee000eee0000000000000000eee000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000 +eee000eee000eee0000000000000000eee000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee0000000000000000eeee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000 +eee000eee000eeeeeeeee0000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0000000eeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000eeeee0000000eee0000eee000eee000eee0000eee0000000000000000eee000e00eee00e000000eee0000eee000eee000eee0000eee000eee0000eee000eee00eeee000e00000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000 +eee000eee000eee000eee0000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0000000eee000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000eeee0e00000000ee0000ee0000eee000eee0000eeee0eee00000000000eee000e00eee000e00000eee0000eeee00eee0000ee0000eee0000ee0000ee0000eee000eee000e00000000000eee00000eeee00eee0000eee00000ee0000ee00000000000000eee00000000 +eeee00eee0000ee000ee00000000000eeeeeee0000000eee000eee0000eee00000eee000eee0000eeee0eee000ee000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000eee000e0000000eee00eee0000eee000eee0000eee0eeee0000000000eeee000e00eee000e00000eee0000eee0eeeee0000eee00eeee0000eee00eee000eee0000eee0000e0000000000eee00000eee0eeeee0000eee00000eee00eee00000000000000eee00000000 +eee0eeeee0000eee00ee00000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0eeee000eee00ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000eeee000e000000000eeee00000eeee00eeee000eeee00eee0000000000eee00000eeee0000e0000eeee000eeee00eee0000000eee0eee000000eeee0000eeeee0eeeeee0eeee000000000eee0000eeee00eee0000eeeeee00000eeee0000000000000000eee00000000 +eee00eee0000000eeee000000000000eee00ee000000eeee00eeee000eeeeee00eeee00eeee000eeee00eee00000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000eee00000e0000000000000000000000000000000000000000000000000eee00000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee000000000000000000eee000000000000000000000000000eee00000000 +eee0000000000000000000000000000eee000e000e0000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000eee000000e000000000000000000000000000000000000000000000000eee000000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee0000000000000000000ee000000000000000000000000000eee00000000 +eee0000000000000000000000000000eee000e000e00000000000000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000eeee0000000e00000000000000000000000000000000000000000000000eee000000eee000000e0000eee00000000000000000000000eee0000000000000000000000000000000000000000eee00000000000000000000e0000000000000000000000e0000eee0000e000 +eee0000000000000000000000000000eee000000ee000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000eee00000000ee000000000000000000000000000000000000000000000eeee00000eeee000000ee000eee00000000000000000000000eee0000000000000000000000000000000000000000eee00000000000000000000e0000000000000000000000ee000eee000ee000 +eee0000000000000000000000000000eee00000eee000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000eeeeeee0000eeeee0000000000000000000000000000000000000000000eeeeee000eeeeeee000eeee00eee0000000000000000000000eeee00000000000000000000000000000000000000eeeeeee00000000000000000000000000000000000000000eeeeeeeeeeeee00e +eee00000000000000000000000000eeeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000878000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000088008f8008700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000008708f7087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000778f78f8000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000008f7f7f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000777777777777777777777777777777777777777 +777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777 +7777777777777777777777777777777777777777777777777777777777777777777777788888777ff777888800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88777777777f7777777777880000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000888888888888888888888888888888888888888 +888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 +888888888888888888888888888888888888888888888888888888888888888888888888888887ff778888d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000008f8f777ec4cdd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000008788f7877eee4ddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000078e8f86088aaecccdd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000007ee68f86668bb2eeccddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000008eece078424669b2eee4ccdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000eecece786662469b2eee4ccddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000e0cecec7860646669b2aae4ccdcdd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000ee0cecece7e066262469bbbaeee4ccddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000eeecececec8cec64666269bbbaeae4ccdcddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000eeececeeece8ecee06064246bbbaeeeeecdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eeecececececececec06666264bbb2aae4ecccdcddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000e0ececececececececec06064666bbb2aaeee4ecdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000ee0ecececececececececec0662624699b2aaeae4ecccdcddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000eeceeeceeec0eece0eceeeceee646662699bbb2eeeee4ccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000eececececec00ecec00ecececece060642469bbb2aaeee4ccccdcddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000eececececec0cececece0ecececece066662649bbb2aaeeeeecccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000e0cecececec0cecececece0ecececece060646669bbb2aaeae4e4ccccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000ee0ceeeceeec0eeceeeceeece0eceeeceee066262469bbb2baeaeee4ecccdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000eeecececece00cecececececece00cecececec64666269b9b2b2aaeae4e4ccccdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000eeeceeecece00eecececeeececece00cececeeec06064246b9bbb2aaeeeee4ecccdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000eeecececece0ecececececececececec0cecececec0666626499bbb2aaeaeee4ccccccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000e0eceeeceee0eeeceeec0eece0eceeecee0ceeeceeec0606466699bbb2baeaeeeeececccdcddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000ee0ecececece0ecececec0cecece0ecececec0cecececec0662624699bbb2aaaaeae4e4ccccccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000eececeeecec00eeececec0eececece0ecececee00ececeeece646662699bbb2baeaeeeee4ecccdcdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000eececececec00ececece00cecececece00cececec00ecececece060642469b9b2b2aaeaeee4e4ccccccdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000eeeeceeecee0ceeeceee00eeceeeceeece00ceeeceee0eeeceeece066662649bbbbb2aaeaeeeee4ecccdcdcdddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececececececec0cececece0ecececece06064666999bbb2aaaaeaeee4ecccccccdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000ee0eeceeecee0ceeeceee0eeeceeeceeeceeecee0ceeeceee0eeeceeece066262469b9bbb2baeaeeeeeeececccdcdcdddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000eeecececece00cececece0ececece0ecec0cececec0cececece00cecececec6466626999bbb2baaaeaeee4e4ccccccdcdcddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000eeeeeceeeee00ceeeeee00eeeeeee00eeee00ceeeeee00eeeeeee00eeeeeecee06064246b9bbbbbaaaeaeeeee4ececccdcdcdddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ecececec0cececec00ecececec0cecececec0666626499b9b2b2aaaaeaeee4ecccccccdcdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000e0eeeceeece0eceeecee0ceeeceee0eeeceeecee0ceeeceee0eeeceeec0eeceeecee0606466699bbbbb2baeaeeeeeeecececccdcdcdddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000ee0ecececece0ecececec0cececece0ecececececec0cececece0ecececec0cecececec0662606699b9bbb2aaaaeaeae4e4ecccccccdcdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000eeeeeeceeee00eceeeeee0ceeeeee00eeeeeeeceeeeee00eeeeeee0eeeeeeec00eeeeeceee646642699b9bbb2baaaeaeeeeeeececccccdcdcddddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000eececececec00ececece00cececec00ecececececececec00ececece00cececec00ecececece06266266999bbb2baaaaaeaeee4e4ecccccccdcdcdddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000eeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000eeceeeceeec0eeceeece00ceeecee0ceeecee0ceee0eeeceee0eeeceee00eeceeece0eceeeceee064642669b9bbbbbabaeaeaeeeeeeececccdcdcdcddddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000ee000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000e0cecececec0cececece0ecececec0cececec0cecece0ececece0ecececec0cececece0ecececece06266466999bbb2b2aaaaeaeaeee4ecccccccccdcdcdddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000ee0000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000ee0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee064262469b9bbbbb2baaaeaeeeeeeecececccdcdcdcddddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000eeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000ee0cececece00cececece0ececece00cecece00cecececece00cecece00cececec0cececece00cececece06646606999b9bbb2baaaaaeaeee4e4ecccccccccdcdcdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000eeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000eeeceeeceee00eeceeec00eceeece00ceeece00ceeeceeeceee00eeceee00eeceeec00eceeece00ceeeceeec0626626699bbbbb2babaeaeaeeeeeeecececccdcdcdcddddddd0000000000000000000000000000000000000000000000000eeeeee0000eeeeeee0eeeee00eeeee00 +000000eeeeeee0000eeeeeeeeeee00eeeeeeeeee00eeeee0eeeee0000eeee00e0eeee000000000eeeeeee0000eeeeee000eee00000e0eeee000000eee00000eeeee0000000000e000000000eee0000000eeee0ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000eeecececece0ecececec00ececece0ececece0ecececececececec0cececec0cececec00ecececec0cecececec0646460699b9bbb2baaaaaeaeaeee4e4ecccccccccdcdcdcdddd0000000000000000000000000000000000000000000000000e000000000eeee000eee0000eee000 +00000000eee00000eeee0000eee000ee00000000000eee000eee0000eeeee00ee000ee0000000000eee00000eeee0000eeeeeee000ee000ee000eeeeeee0000eee0000000000ee0000000eeeeeee0000eee00eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee0626666099b9bbbbbabaaaeaeeeeeeeeecececccdcdcdddddddddd00000000000000000000000000000000000000000000000e00000000eee0000eee0000eee000 +00000000eee00000eee00000eee0000e00000000000eee000eee0000eee00e0e0000ee0000000000eee00000eee00000eee000e000e0000ee000eee000e0000eee0000000000eee000000eee000e0000ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000e0ecececece0ecececec0cececece0ececece0ececec0cecece0ececec0cececec0cececece0ecececec0cecececec064246669999bbb2b2aaaaaaeaeaeee4ececccccccccdcdcdcddddd000000000000000000000000000000000000000000000e0000000eee00000eee0000eee000 +00000000eee0000eee000000eee00000eeeee000000eee000eee0000eee00000000eee0000000000eee0000eee00000eee00000e000000eee00eee00000e000eee000000000eeee00000eee00000e00eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeeeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee0662624699b9bbbbb2baaaeaeaeeeeeeecececccccdcdcdddddddddd00000000000000000000000000000000000000000000eeeeeeeeee00000eee0000eee000 +00000000eee000eeee000000eee0000eee00eee0000eee000eee0000eee0000000eeee0000000000eee000eeee00000eee00000000000eeee00eee000000000eee000000000eee0e0000eee00000000eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000eececececec00ececece00cececec00ececec00ecece00cecececece00cecec00ececec00ececece00cececec00ecececece06466264999b9bbb2baaaaaaaeaeee4e4ecccccccccccdcdcdcddddd000000000000000000000000000000000000000000e00000eeee00000eee0000eee000 +00000000eee00eeee0000000eee000eee0000eee000eee000eee0000eee00000eeeee00000000000eee00eeee000000eee000000000eeeee000eee000000000eee000000000eee0e0000eee00000000eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeeeeeeeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee062642649b9bbbbbbbabaaaeaeeeeeeeeecececccccdcdcdddddddddd0000000000000000000000000000000000000000e00000eee000000eee0000eee000 +00000000eee00eee00000000eee000eee0000eee000eee000eee0000eee0000eeeee000000000000eee00eee0000000eeeeeeeee00eeeee0000eeeeeeeee000eee00000000eeee00e000eeeeeeeee00eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000e0cecececec0cececece0ecececec0cececec0cecece0ecececececececec0cecece0ececece0ecececec0cececece0ecececece06466266999b9bbb2baaaaaaaeaeaeee4e4ecccccccccccdcdcdcddddd000000000000000000000000000000000000000e0000eee000000eee0000eee000 +00000000eeeeeeeee0000000eee000eee0000eee000eee000eee0000eee0000eee00000000000000eeeeeeeee000000eee000eee00eee000000eee000eee000eee00000000eee000e000eee000eee00eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeeee6264646999bbbbbbbabaaaeaeaeeeeeeeeecececccccdcdcdddddddddd0000000000000000000000000000000000000e000eee0000000eee0000eee000 +00000000eee0000eee000000eee000eee0000eee000eeee00eee0000eee0000ee000e00000000000eee0000eee000000ee000eee00ee000e0000ee000eee000eeee0eee000eee0000e000ee000eee000ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000eeececeeece00ceeecece0eeecece00eecece00eecece0eeece00ceeece00ceeec0ceceee00ceceee00ceceeec0ceceeece00ceeececec4626266999b9bbb2b2baaaaaaaeaeeeee4ececccccccccccdcdcdcddddd000000000000000000000000000000000000e00eee0000000eee0000eee000 +00000000eee000000ee00000eee0000eee00eee0000eee0eeeee0000eee0000ee00ee00000000000eee000000ee00000eee00ee000ee00ee0000eee00ee0000eee0eeee00eee00000e000eee00ee0000eee00eeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeeeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee6466606699b9bbbbb2babaaaeaeaeeeeeeececececccdcdcdcdddddddddd0000000000000000000000000000000000e0eeee0000000eee0000eee000 +00000000eee000000eee000eeee00000eeeeeeeee00eee00eee0000eeeeee000eee0e00000000000eee000000eee000000eeee00000eee0e000000eeee0000eeee0eeee0eeeee000eee0000eeee000000eeee0eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000eeecececece0ecececec00ececece0ececece0ececec00ecece0ecececececec0cecec00ececec0cececec0cececec00ecececec0cecececec060662469999b9bbb2baaaaaaaeaeaeee4e4ececccccccccccdcdcdcdddddd0000000000000000000000000000000e0eee00000000eee0000eee000 +00000000eee000000eee00000000000000000000000eee0000000000eee000000000000000000000eee000000eee00000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeeeeeeeeeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee0664626699b9bbbbbbbabaaaeaeaeeeeeeeeececececccdcdcdcddddddddddd000000000000000000000000000000eeee00000000eee0000eee000 +00000000eee000000eee00000000000000000000000eee00000000000ee000000000000000000000eee000000eee00000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000e0ececeeece0eceeecec0ceeecece0eeecece0eeecec0ceeece0eceee0ecec0eecec0ceeece0eceeec0ceceeec0ceceeece0eceeecec0ceeececec062664649999b9bbb2baaaaaaaaaeaeaeee4e4ecccccccccccdcdcdcdcdddddd0000000000000000000000000000eee000000000eee0000eee000 +00000000eee00000eee00000eee0000000000000000eee000000000000e000000000000000000000eee00000eee000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee462626699b9bbbbbbbababaaaeaeaeeeeeeeeecececccccdcdcdcddddddddd00000000000000000000000000000ee000000000eee0000eee000 +00000000eee0000eeee00000eee0000000000000000eee000000000000e000000000000000000000eee0000eeee000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000eececececec00ececece00cececec00ececec00ecece00cecec00ecece0ecececec0cecec00ecece00cecec00ececec00ececece00cececec00ecececece64666066999b9bbb2b2baaaaaaaeaeaeeeee4ececccccccccccdcdcdcdcdd00000000000000000000000000000ee00000000eeee000eeee000 +000000eeeeeeeeeee0000000eee000000000000000eeee00000000000000000000000000000000eeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000eeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeeeeeeeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee060662469b9b9bbbbb2babaaaeaeaeeeeeeeeececececccccdcdcdcddddd00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000e0ceeeceeec0eeceeece00ceeecee0ceeecee0ceeece0eceeec0eecee00eeeceeeceeec00eceee0eeecee0ceeece0eceeece0eceeece00ceeeceee0eeeceeece06646266999b9b9bbb2baaaaaaaaaeaeaeee4e4ececccccccccccdcdcdc00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266466999b9bbbbbbbabaaaaaeaeaeeeeeeeeececececccccdcdcdcd00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeecececece00cececece0ececece00cecece00cecece0ecece00cecec0cecec0cecece0ecece0ecece00cecec0cecece00cecece00cececec0cececece00cecececec462624609999b9bbb2babaaaaaaaeaeaeeeee4ececccccccccccccdc00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeeeeeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee6466626499b9bbbbbbbababaaaeaeaeeeeeeeeeeececececccccdcd00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000eeeceeeceee0eeeceeec00eceeece0eceeece0eceeec00eceee0eeece00ceee00eeceeeceee00eece00ceeec0eecee00eeecee0ceeecee0ceeecee00eeeceeec0eeceeecee060642649999b9bbb2b2baaaaaaaaaeaeaeee4e4ececcccccccccc00000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee0eeeeee0eeeee00eeee00eeeeeeeeeeee00eeee00eeeee0eeeeee0eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666626699b9bbbbbbbbbabaaaaaeaeaeeeeeeeeecececececccc00000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eee0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000e0eceeecece0eeececec0eececece0ececece0ececec0eecece0eeece0eceee0ecece0ecec0ceeec0cecee0cecec0eecece0eeecec0ceeecec0ceeecece0eeececec0eecececee060646469999b9b9bbb2baaaaaaaaaeaeaeaeee4e4ececcccccc00000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eee0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeeeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee0662626609b9b9bbbbbbbababaaaeaeaeeeeeeeeeeececececc00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00eeeeceeecee00eeeceee00eeceeec00eceeec00eceee00eecee00eeece0eceee0eeec00eceeecee00eeec0eecee0ceeec00eceee00eecee00eeecee00eeeceee00eeceeec00eceeeceee64666066999b9b9bbb2babaaaaaaaaaeaeaeeeee4ecececcc00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeeeeeeeeeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06066246999b9bbbbbbbababaaaeaeaeaeeeeeeeeeeecece000000000000000000000000000eeeeee000000000eeee00000ee +eee0000000000000e00000000000eee00eeee00000000eeeeeee0000000000eeee000000ee000000000000eeeeeeeeeeeee00000eeee0000eeee0ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +e0ceceeecec0ceeecece00eececec0eececec0eecece00eecec0ceeec00ecee00ecec0eece0ecee0cece0eeec00ecee00ecece0ecece00eecece0eeecece0eeecece00eececece0ecececeee0664626699999b9bbb2b2baaaaaaaaaeaeaeaeee4e4ecec0000000000000000000000000eee00000ee00000eee00eee0000e +ee0000000000000ee0000000000eeeee0eee00000000000eee00000000000eeeee000000ee00000000000000eee00000eee0000eeeee000eee00eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e +0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeeeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06264646999b9bbbbbbbbbababaaaeaeaeaeeeeeeeeece000000000000000000000000eee00000000e0000ee0000ee0000e +ee0000000000000eee000000000eee00eeee00000000000eee00000000000eee00e0000eeee0000000000000eee0000000e0000eee00e00ee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee +eeceeece00ceeeceee0eeeceee00eeceee00eeceee0eeece00ceeec0eecee0ceee00eece0eceeecee0ceee00eece0eceee0eeece00ceeec0eeceee00eeceee00eeceeec0eeceeece00ceeeceeec462626609999b9bbbbb2babaaaaaaaaaeaeaeeeee4e400000000000000000000000eee0000000000000eee0000eee000e +ee000000000000eeee000000000eee000eee00000000000eee00000000000eee0000000eeee0000000000000eee0000000ee000eee0000eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee +eeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeee00eee00eeeeeeeeee00eee00eeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee664642c699b9b9bbbbbbbababaaaeaeaeaeeeeeeeee00000000000000000000000eee0000000000000eee0000eee000e +ee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eeeee0000000000000eee00000000e000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee +ceeece0eceeecee00eeeceee0eeeceee0eeecee00eeece0eceee00eece00ceee0eeec00ece0ecee0cee00eeec0eece00ceee00eecee0ceeec00eceeec0eeceeec0eeceeec00eceeecee0ceeeceeec062662649999b9b9bbb2babaaaaaaaaaeaeaeaeeee0000000000000000000000eeee0000000000000eee0000eee000e +ee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eee00e000000000000eee00000000e000eee0000eee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeee +eeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee0eeee00eeee00eeee0eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0646426699b9b9bbbbbbbabababaaaeaeaeaeeeee0000000000000000000000eee00000000000000eee0000eee000e +ee00000000000eeee00e0000000eee000eee00000000000eee00000000000eee00000eeee00e000000000000eee000000000000eee0000eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeece +eeee0eceeeeee0ceeeeeee0eeeeeee0eeeeee0ceeeee0eceee0eeece0eeeee0eeee0eece0eeeeecee0eeee0eeee0eecee0eeeec0eeeee0ceeeee0eceeee0eeceeee0eeceeeee0eceeeeee0ceeeeeeec062664669999b9b9bbb2b2baaaaaaaaaaaeaeaea0000000000000000000000eee00000000000000eee0000eee000e +ee00000000000eee000e0000000eee000eee00000000000eeeeeeee000000eee00000eee0000e00000000000eee000000000000eee0000eee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeee +ee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eeeeeeeeee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee642624609b9b9bbbbbbbbbababaaaeaeaeaeee0000000000000000000000eee000000000000000ee0000ee0000e +eee0eee000000eee000e0000000eee000eee00000000000eee0000eee0000eee0000eeee0000e00000000000eee000000000000eee00000ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeceeeceee +c00eceeecee0ceeecee00eeecee00eeece00ceeec00eceee0eeece0ecee00eee00eece0ece0ecee0cee0ceee00eec00ecee0ceeec0eecee00eeece00ceeec00eceeec00eceeece0eceeecee00eeeceeece6646606699999b9bbbbb2babaaaaaaaaaeaea0000000000000000000000eee000000000000000eee00eee0000e +ee0eeee00000eee00000e000000eee000eee00000000000eee00000eee000eee0000eee00000ee0000000000eee000000000000eee00000eee00eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee +0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eeeeee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06266266999b9bbbbbbbbbababaaaaaeaeae0000000000000000000000eeee000000000e000000eeee00000ee +ee0eeee00000eee00000e00000eeee00eeee00000000000eee00000eee00eeeeee0eeeee000eeee000000000eee00000000000eeeeee0000eeee0eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeceeee0 +eeceeeee00ceeeeee0ceeeeee0ceeeee00ceeee0eecee00eeec00eeee0ceee0eeec00eee0eceeeeee0cee00eeec0eeee0ecee00eeec00eeeee0eeeee00ceeeee0eceeeee0eceeeee00ceeeeeee0eeeeeeece0646424699999b9b9bbb2babaaaaaaaaaaa00000000000000000000000eee000000000e00000000000000000 +00000000000eeee000000e0000000000000000000000000eee00000eee000eee000000000000000000000000eee000000000000eee00000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0e +eeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eee00eeeeeeeeee00eee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266664999b9b9bbbbbbbbbababaaaeae00000000000000000000000eee00000000ee00000000000000000 +00000000000eee0000000e0000000000000000000000000eee00000eee0000ee000000000000000000000000eee0000000000000ee00000000000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ceeeceee00ee +ceeece0eceeece00ceeece00ceeece0eceee00eecee0ceeec0eece00ceee0eeec0eec00ece0ecee0cee00eee0eeec0eece00ceee0eeece0eceee00eecee0ceeece00ceeece00ceeecee0ceeeceee00eeceeece0642426609999b9b9bbb2b2babaaaaaaa000000000000000000000000eee000000eee00000000000000000 +00000000000eee00000000e000000000000000000000000eee00000eee00000e000000000000000000000000eee00000000000000e00000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eee +eeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eee00eeee0eee0eee00eeeeee00eee0eee0eeee00eee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6666606699b9b9bbbbbbbbbababaaaa0000000000000000000000000eee0000eeee00000000000000000 +0000000000eeee00000000ee00000000000000000000000eee0000eee000000e000000000000000000000000eee00000000000000e00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeee +eee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00eeeeeeee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee060660669999b9b9bbbbb2babaaaaa000000000000000000000000000eeeeee00e00000000000000000 +00000000eeeeeee00000eeeee00000000000000000000eeeeeeeeee0000000000000000000000000000000eeeeeee00000000000000000000000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeee +ee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee0eee0eeee0eee0eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666660699b9b9bbbbbbbbbababab00000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eceeeceee0eeeceee +c0eeceeece0eceeece0eceeec0eeceee0eeece0eceee0eeece0ecee0ceee0eeec0eec0eec0eeceee0eee0eee0eeec0eece0ecee0ceeec0eecee0ceeec0eeceee0eeecee0ceeecee0ceeeceee0eeeceeec0eeceeecee06066660999999b9b9bbb2babaaa00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee +0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00eee0eee0eeeeeeee0eee0eee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee066066660999b9b9bbbbbbbbbab00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee00eeeeeeee0 +eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00ee00ee00ee0eeee0ee00ee00ee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6606060099999b9b9bbb2b2ba00000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee0eeeeeeee00e +eeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06660000999b9b9bbbbbbbbb00000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeee0eeeeeeee00ee +eeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0600000099999b9b9bbbbb2000000000000000000000000000000000000000000000000000ee +eee00000000eee0000000000000000000000000000eeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeee0eeeeeeee0eeee +eeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eeee0eee0eee0eee0ee0e00e0ee0eee0eee0eee0eeee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeeee0000000999b9b9bbbbbbb0000000000000000000000000000000000000000000000000000e +ee00000000eee0e00000000000000000000000000ee000000ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9b9b9bb0000000000000000000000000000000000000000000000000000e +ee00000000eee0e00000000000000000000000000ee0000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099b9b9bbbbb0000000000000000000000000000000000000000000000000000e +ee0000000000000e00000000000000000000000000eeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999999b9b90000000000000000000000000000000000000000000000000000e +ee0000000000000e0000000000000000000000000eeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9b9b000000000000000000000000000eeeeee000000000eeee000000e +ee0eeee00000000ee000000eeeee000000eeeee00eeeeeeeeee00eeeee0eeeee0000eeee00000000eeeeeeee0000eee000000000eee000000000eeeeeeee000000000000eeeeeeee0000eee000000000eee0000000000eeeeee0000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999999b90000000000000000000000000eee00000ee00000eee00eee0000e +eee00eee0000000ee0000000eee00000000eee000ee00000000000eee000eee0000eeeee00000000000eee00000000eee000000000eee0000000000eee00000000000000000eee00000000eee000000000eee0000000eeee000e000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999b9b000000000000000000000000eee00000000e0000ee0000ee0000e +ee0000ee000000eeee000000eee00000000eee0000e00000000000eee000eee0000eee00e0000000000eee0000000000eee000000000eee00000000eee00000000000000000eee0000000000eee000000000eee00000eee00000e00000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000eeeeeee00000000000000000000000000eeeeeee0000000000000000000eeeee00000000000000000000000000eeeee000000000000000000000000eeeeee000eeee0000000000000000000000000000000000000000000009999900000000000000000000000eee0000000000000eee0000eee000e +ee0000eee00000eeee000000eee00000000eee00000eeeee000000eee000eee0000eee0000000000000eee00000000000eee000000000eee0000000eee00000000000000000eee00000000000eee000000000eee000000000000ee0000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000eeeeeeeeeeee000000000000000000000eeeeeeeeeee00000000000000000eeeee0000000000000000000000000eeeeeee0000000000000000000000eeeeeeeee0eeee0000000000000000000000000000000000000000000000999b00000000000000000000000eee0000000000000eee0000eee000e +ee0000eee0000eeeee000000eee00000000eee0000eee00eee0000eee000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee0000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000eeeeeeeeeeeeeee0000000000000000000eeeeeeeeeeeee0000000000000000eeeee0000000000000000000000000eeeeeee000000000000000000000eeeeeeeeeeeeeee000000000000000000000000000000000000000000000009990000000000000000000000eeee0000000000000eee0000eee000e +ee0000eee0000eee00e00000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee0000000000000000000000000000000000000000000000000000000000000000000000 +000000000000eeeeeeeeeeeeeeeee00000000000000000eeeeeeeeeeeeeee000000000000000eeeee000000000000000000000000eeeeeeeee00000000000000000000eeeeeeeeeeeeeee000000000000000000000000000000000000000000000000990000000000000000000000eee00000000000000eee0000eee000e +ee0000eee000eeee00e00000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee00000000eeeeeee00000eeeeeee000000eee00000000000000000eee00000000eeeeeee00000eeeeeee0000000000eee0000000000000000000000000000000000000000000000000000000000000000000000 +00000000000eeeeeee00000eeeeeee000000000000000eeeeeee0000eeeeee00000000000000eeeee000000000000000000000000eeeeeeeee0000000000000000000eeeeee000eeeeeee000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000eee0000eee000e +ee0000eee000eee0000e0000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee0000000eee000eee000eee000eee00000eee00000000000000000eee0000000eee000eee000eee000eee00000000eeee0000000000000000000000000000000000000000000000000000000000000000000000 +00000000000eeeee00000000eeeeee000000000000000eeeee0000000eeeee00000000000000eeeee000000000000000000000000eeee0eeee0000000000000000000eeeee00000eeeeee000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000ee0000ee0000e +ee0000ee000eeee0000e0000eeee0eee000eee000eee0000eee000eeee00eee0000eee0000000000000eee000000eeee000eee00eeee000eee00000eee00000000000000000eee000000eeee000eee00eeee000eee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000 +0000000000eeeee0000000000eeeeee0000000000000eeeeee0000000eeeeee0000000000000eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000eee00eee0000e +eee00eee000eee00000ee000eee0eeee000eee0000eee00eee0000eee0eeeee0000eee0000000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee00eeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000 +0000000000eeeee0000000000eeeee00000000000000eeeee000000000eeeee0000000000000eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000eeee000000000e000000eeee00000ee +ee0eeee000eeeee000eeee0eeee0eeee00eeee00000eeeeeeeee00eee00eee0000eeeeee00000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeeeee0000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000e00000000000000000eeeee000000000eeeee0000000000000eeeee00000000000000000000000eeee000eeee000000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000eee000000000e00000000000000000 +000000000000000000000000000000000000000000000000000000eee0000000000eee0000000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeee000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000eee00000000ee00000000000000000 +000000000000000000000000000000000000000000000000000000eee00000000000ee0000000000eeeeee000000eee0000eee00eee0000eee00eeeeee00000000000000eeeeee000000eee0000eee00eee0000eee000e000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000eee000000eee00000000000000000 +00000000000000000000000000000000000eee0000000000000000eee000000000000e00000000000eeeee0000000ee000eee0000ee000eee0000eeeee000000000000000eeeee0000000ee000eee0000ee000eee00000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeee00000eeee00000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000eee0000eeee00000000000000000 +00000000000000000000000000000000000eee0000000000000000eee000000000000e0000000000000eee0000000eee00ee00000eee00ee0000000eee00000000000000000eee0000000eee00ee00000eee00ee000000eeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000000000000000000000eeeeee0000000eeeeee0000000000000eeeeee00000000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000eeeeee00e00000000000000000 +00000000000000000000000000000000000eee000000000000000eeee0000000000000000000000000000e000000000eeee00000000eeee0000000000e0000000000000000000e000000000eeee00000000eeee00000000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee0000000000000000000000000000000eeeee0000000eeeee00000000000000eeeeeee0000000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee0000000000000000000000000000000eeeeee00000eeeeee00000000000000eeeeeeeeeee000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee00000000000000000000000000000000eeeeeeeeeeeeeee000000000000000eeeeeeeeeee00000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeeee000000000000000000000000000000000eeeeeeeeeeeee0000000000000000eeeeeeeeeee00000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000eeeee00000000000eee0000000000000000000eeeeeeeeeee00000000000000000eeee0eeeeeee0000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000eeeee0000000000eeeeee0000000000000000000eeeeeee0000000000000000000eeee00eeeee0000000000000eeeee000000000eeeee00000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000eeeee000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000eeeeeee00000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000eeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000eeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000eeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001050000050000000d000000 +4d45544146494c455049435400ef3400004fecffff48b800000800ef34b1135612 +010009000003105c00000100ce5b00000000050000000b0200000000050000000c02b113ef3425000000f7000003100000000000bf00000000bf0000bfbf00000000bf00bf00bf0000bfbf00c0c0c00080808000ff00000000ff0000ffff00000000ff00ff00ff0000ffff00ffffff000400000034020000030000003500 +ce5b0000430f2000cc000000ba00f40100000000b113ef340000000028000000f4010000ba000000010004000000000018b7000000000000000000001000000010000000000000000000bf0000bf000000bfbf00bf000000bf00bf00bfbf0000c0c0c000808080000000ff0000ff000000ffff00ff000000ff00ff00ffff +0000ffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee000000000eeee0000000eee00eeee00eeeee000000000000000000e00000000e0000000eeeee00eeeee0eeeee0000eeee0ee0000000eeee000000000e00000e000000000000eeeeeee0 +0eeeee0eeeee0000eee000000eeee00000000000000eeeeeee00000eeeee0eeeee0000eeee00000000000eeeeeee0000000000eee00eeee0000eee00000eee00eeee00eeeee00000000eeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000000000eee00eee0000eeeee0eee0000eee000000000000000000ee0000000eee0000000eee0000eee000eee0000eee00eeeee000eee00eee000000eee000eee0000000000000eee000 +00eee000eee0000eeeee000eee00eee00000000000000eee00000000eee000eee0000eeeeeee00000000000eee00000000000eeeee0eee0000eeeee000eeeee0eee0000eee00000000eeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000000000ee0000ee0000eee00eeee0000eee000000000000000000eee000000eee0000000eee0000eee000eee0000ee0000eee0000ee0000ee000000eee000eee0000000000000eee000 +00eee000eee0000eee00e00ee0000ee00000000000000eee00000000eee000eee0000eee000e00000000000eee00000000000eee00eeee0000eee00e00eee00eeee0000eee00000000eee000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee000000000000000000eee000000eee0000000eee0000eee000eee000eee0000eee000eee0000eee00000eee000eee0000000000000eee000 +00eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eeee0000e0000000000eee00000000000eee000eee0000eee00000eee000eee0000eee0000000eeee0000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eeee0000000eee0000eee000eee000eee0000eee000eee0000eee0000eeee00eee0e000000000000eee000 +00eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee0000000000000000eee000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee000 +00eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee0000000000000000eee000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000eee0000eee000eee000eee0000eee0000000000000000eeee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee000 +00eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eeeeeeeee0000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0000000eeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000eee0000eee000eee000eee0000eee0000000000000000eee000e00eee00e000000eee0000eee000eee000eee0000eee000eee0000eee000eee00eeee000e00000000000eee000 +00eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee000eee0000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0000000eee000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee0e00000000ee0000ee0000eee000eee0000eeee0eee00000000000eee000e00eee000e00000eee0000eeee00eee0000ee0000eee0000ee0000ee0000eee000eee000e00000000000eee000 +00eeee00eee0000eee00000ee0000ee00000000000000eee00000000eeee00eee0000ee000ee00000000000eeeeeee0000000eee000eee0000eee00000eee000eee0000eeee0eee000ee000ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000e0000000eee00eee0000eee000eee0000eee0eeee0000000000eeee000e00eee000e00000eee0000eee0eeeee0000eee00eeee0000eee00eee000eee0000eee0000e0000000000eee000 +00eee0eeeee0000eee00000eee00eee00000000000000eee00000000eee0eeeee0000eee00ee00000000000eee00ee0000000eee000eee0000eee00000eee000eee0000eee0eeee000eee00ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee000e000000000eeee00000eeee00eeee000eeee00eee0000000000eee00000eeee0000e0000eeee000eeee00eee0000000eee0eee000000eeee0000eeeee0eeeeee0eeee000000000eee000 +0eeee00eee0000eeeeee00000eeee0000000000000000eee00000000eee00eee0000000eeee000000000000eee00ee000000eeee00eeee000eeeeee00eeee00eeee000eeee00eee00000eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000e0000000000000000000000000000000000000000000000000eee00000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee000 +000000000000000eee000000000000000000000000000eee00000000eee0000000000000000000000000000eee000e000e0000000000000000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000000e000000000000000000000000000000000000000000000000eee000000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee000 +0000000000000000ee000000000000000000000000000eee00000000eee0000000000000000000000000000eee000e000e00000000000000000ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee0000000e00000000000000000000000000000000000000000000000eee000000eee000000e0000eee00000000000000000000000eee0000000000000000000000000000000000000000eee000 +00000000000000000e0000000000000000000000e0000eee0000e000eee0000000000000000000000000000eee000000ee000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000ee000000000000000000000000000000000000000000000eeee00000eeee000000ee000eee00000000000000000000000eee0000000000000000000000000000000000000000eee000 +00000000000000000e0000000000000000000000ee000eee000ee000eee0000000000000000000000000000eee00000eee000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee0000eeeee0000000000000000000000000000000000000000000eeeeee000eeeeeee000eeee00eee0000000000000000000000eeee00000000000000000000000000000000000000eeeeeee0 +0000000000000000000000000000000000000000eeeeeeeeeeeee00eeee00000000000000000000000000eeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008780000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088008f80087000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008708f70870000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000778f78f80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f7f7f800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000007777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777 +777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777788888777ff7778888000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88777777777f77777777778800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000008888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 +88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888887ff778888d0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f8f777ec4cdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008788f7877eee4ddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078e8f86088aaecccdd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ee68f86668bb2eeccddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008eece078424669b2eee4ccdd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eecece786662469b2eee4ccddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecec7860646669b2aae4ccdcdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0cecece7e066262469bbbaeee4ccddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececec8cec64666269bbbaeae4ccdcddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeececeeece8ecee06064246bbbaeeeeecdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececececececec06666264bbb2aae4ecccdcddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ececececececececec06064666bbb2aaeee4ecdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ecececececececececec0662624699b2aaeae4ecccdcddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeceeeceeec0eece0eceeeceee646662699bbb2eeeee4ccdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ecec00ecececece060642469bbb2aaeee4ccccdcddd000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec0cececece0ecececece066662649bbb2aaeeeeecccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cecececece0ecececece060646669bbb2aaeae4e4ccccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ceeeceeec0eeceeeceeece0eceeeceee066262469bbb2baeaeee4ecccdcddddd00000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece00cecececececece00cecececec64666269b9b2b2aaeae4e4ccccdcdddd000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeceeecece00eecececeeececece00cececeeec06064246b9bbb2aaeeeee4ecccdcddddd0000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececececececececec0cecececec0666626499bbb2aaeaeee4ccccccdcdddd00000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eceeeceee0eeeceeec0eece0eceeecee0ceeeceeec0606466699bbb2baeaeeeeececccdcddddd000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ecececece0ecececec0cecece0ecececec0cecececec0662624699bbb2aaaaeae4e4ccccccdcdddd0000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececeeecec00eeececec0eececece0ecececee00ececeeece646662699bbb2baeaeeeee4ecccdcdcddddd00000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cecececece00cececec00ecececece060642469b9b2b2aaeaeee4e4ccccccdcdddd000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeceeecee0ceeeceee00eeceeeceeece00ceeeceee0eeeceeece066662649bbbbb2aaeaeeeee4ecccdcdcdddddd000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececececececec0cececece0ecececece06064666999bbb2aaaaeaeee4ecccccccdcddddd0000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeceeecee0ceeeceee0eeeceeeceeeceeecee0ceeeceee0eeeceeece066262469b9bbb2baeaeeeeeeececccdcdcdddddd00000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece00cececece0ececece0ecec0cececec0cececece00cecececec6466626999bbb2baaaeaeee4e4ccccccdcdcddddd000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeceeeee00ceeeeee00eeeeeee00eeee00ceeeeee00eeeeeee00eeeeeecee06064246b9bbbbbaaaeaeeeee4ececccdcdcdddddd0000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ecececec0cececec00ecececec0cecececec0666626499b9b2b2aaaaeaeee4ecccccccdcdcddddd00000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeceeece0eceeecee0ceeeceee0eeeceeecee0ceeeceee0eeeceeec0eeceeecee0606466699bbbbb2baeaeeeeeeecececccdcdcdddddd000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ecececece0ecececec0cececece0ecececececec0cececece0ecececec0cecececec0662606699b9bbb2aaaaeaeae4e4ecccccccdcdcddddd0000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeceeee00eceeeeee0ceeeeee00eeeeeeeceeeeee00eeeeeee0eeeeeeec00eeeeeceee646642699b9bbb2baaaeaeeeeeeececccccdcdcddddddd0000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cececec00ecececececececec00ececece00cececec00ecececece06266266999bbb2baaaaaeaeee4e4ecccccccdcdcdddddd00000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeceeeceeec0eeceeece00ceeecee0ceeecee0ceee0eeeceee0eeeceee00eeceeece0eceeeceee064642669b9bbbbbabaeaeaeeeeeeececccdcdcdcddddddd000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee000000ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececec0cececec0cecece0ececece0ecececec0cececece0ecececece06266466999bbb2b2aaaaeaeaeee4ecccccccccdcdcdddddd0000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee064262469b9bbbbb2baaaeaeeeeeeecececccdcdcdcddddddd00000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0cececece00cececece0ececece00cecece00cecececece00cecece00cececec0cececece00cececece06646606999b9bbb2baaaaaeaeee4e4ecccccccccdcdcdcdddd000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeceeeceee00eeceeec00eceeece00ceeece00ceeeceeeceee00eeceee00eeceeec00eceeece00ceeeceeec0626626699bbbbb2babaeaeaeeeeeeecececccdcdcdcddddddd0000000000000000000000000 +000000000000000000000000eeeeee0000eeeeeee0eeeee00eeeee00000000eeeeeee0000eeeeeeeeeee00eeeeeeeeee00eeeee0eeeee0000eeee00e0eeee000000000eeeeeee0000eeeeee000eee00000e0eeee000000eee00000eeeee0000000000e000000000eee0000000eeee0ee0000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ececece0ecececececececec0cececec0cececec00ecececec0cecececec0646460699b9bbb2baaaaaeaeaeee4e4ecccccccccdcdcdcdddd00000000000000000000000 +00000000000000000000000000e000000000eeee000eee0000eee00000000000eee00000eeee0000eee000ee00000000000eee000eee0000eeeee00ee000ee0000000000eee00000eeee0000eeeeeee000ee000ee000eeeeeee0000eee0000000000ee0000000eeeeeee0000eee00eeeee00000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee0626666099b9bbbbbabaaaeaeeeeeeeeecececccdcdcdddddddddd00000000000000000000 +000000000000000000000000000e00000000eee0000eee0000eee00000000000eee00000eee00000eee0000e00000000000eee000eee0000eee00e0e0000ee0000000000eee00000eee00000eee000e000e0000ee000eee000e0000eee0000000000eee000000eee000e0000ee0000eee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ecececece0ecececec0cececece0ececece0ececec0cecece0ececec0cececec0cececece0ecececec0cecececec064246669999bbb2b2aaaaaaeaeaeee4ececccccccccdcdcdcddddd000000000000000000 +000000000000000000000000000e0000000eee00000eee0000eee00000000000eee0000eee000000eee00000eeeee000000eee000eee0000eee00000000eee0000000000eee0000eee00000eee00000e000000eee00eee00000e000eee000000000eeee00000eee00000e00eee0000eee000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeeeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee0662624699b9bbbbb2baaaeaeaeeeeeeecececccccdcdcdddddddddd0000000000000000 +0000000000000000000000000000eeeeeeeeee00000eee0000eee00000000000eee000eeee000000eee0000eee00eee0000eee000eee0000eee0000000eeee0000000000eee000eeee00000eee00000000000eeee00eee000000000eee000000000eee0e0000eee00000000eee0000eee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cececec00ececec00ecece00cecececece00cecec00ececec00ececece00cececec00ecececece06466264999b9bbb2baaaaaaaeaeee4e4ecccccccccccdcdcdcddddd00000000000000 +0000000000000000000000000000e00000eeee00000eee0000eee00000000000eee00eeee0000000eee000eee0000eee000eee000eee0000eee00000eeeee00000000000eee00eeee000000eee000000000eeeee000eee000000000eee000000000eee0e0000eee00000000eee0000eee000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeeeeeeeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee062642649b9bbbbbbbabaaaeaeeeeeeeeecececccccdcdcdddddddddd000000000000 +0000000000000000000000000000e00000eee000000eee0000eee00000000000eee00eee00000000eee000eee0000eee000eee000eee0000eee0000eeeee000000000000eee00eee0000000eeeeeeeee00eeeee0000eeeeeeeee000eee00000000eeee00e000eeeeeeeee00eee0000eee000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececec0cececec0cecece0ecececececececec0cecece0ececece0ecececec0cececece0ecececece06466266999b9bbb2baaaaaaaeaeaeee4e4ecccccccccccdcdcdcddddd0000000000 +00000000000000000000000000000e0000eee000000eee0000eee00000000000eeeeeeeee0000000eee000eee0000eee000eee000eee0000eee0000eee00000000000000eeeeeeeee000000eee000eee00eee000000eee000eee000eee00000000eee000e000eee000eee00eee0000eee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeeee6264646999bbbbbbbabaaaeaeaeeeeeeeeecececccccdcdcdddddddddd00000000 +00000000000000000000000000000e000eee0000000eee0000eee00000000000eee0000eee000000eee000eee0000eee000eeee00eee0000eee0000ee000e00000000000eee0000eee000000ee000eee00ee000e0000ee000eee000eeee0eee000eee0000e000ee000eee000ee0000eee000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000eeececeeece00ceeecece0eeecece00eecece00eecece0eeece00ceeece00ceeec0ceceee00ceceee00ceceeec0ceceeece00ceeececec4626266999b9bbb2b2baaaaaaaeaeeeee4ececccccccccccdcdcdcddddd000000 +000000000000000000000000000000e00eee0000000eee0000eee00000000000eee000000ee00000eee0000eee00eee0000eee0eeeee0000eee0000ee00ee00000000000eee000000ee00000eee00ee000ee00ee0000eee00ee0000eee0eeee00eee00000e000eee00ee0000eee00eeee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeeeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee6466606699b9bbbbb2babaaaeaeaeeeeeeececececccdcdcdcdddddddddd0000 +000000000000000000000000000000e0eeee0000000eee0000eee00000000000eee000000eee000eeee00000eeeeeeeee00eee00eee0000eeeeee000eee0e00000000000eee000000eee000000eeee00000eee0e000000eeee0000eeee0eeee0eeeee000eee0000eeee000000eeee0eee000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ececece0ececec00ecece0ecececececec0cecec00ececec0cececec0cececec00ecececec0cecececec060662469999b9bbb2baaaaaaaeaeaeee4e4ececccccccccccdcdcdcdddddd0 +000000000000000000000000000000e0eee00000000eee0000eee00000000000eee000000eee00000000000000000000000eee0000000000eee000000000000000000000eee000000eee00000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeeeeeeeeeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee0664626699b9bbbbbbbabaaaeaeaeeeeeeeeececececccdcdcdcdddddddddd +d000000000000000000000000000000eeee00000000eee0000eee00000000000eee000000eee00000000000000000000000eee00000000000ee000000000000000000000eee000000eee00000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000e0ececeeece0eceeecec0ceeecece0eeecece0eeecec0ceeece0eceee0ecec0eecec0ceeece0eceeec0ceceeec0ceceeece0eceeecec0ceeececec062664649999b9bbb2baaaaaaaaaeaeaeee4e4ecccccccccccdcdcdcdcddd +ddd0000000000000000000000000000eee000000000eee0000eee00000000000eee00000eee00000eee0000000000000000eee000000000000e000000000000000000000eee00000eee000000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee462626699b9bbbbbbbababaaaeaeaeeeeeeeeecececccccdcdcdcdddddd +ddd00000000000000000000000000000ee000000000eee0000eee00000000000eee0000eeee00000eee0000000000000000eee000000000000e000000000000000000000eee0000eeee000000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cececec00ececec00ecece00cecec00ecece0ecececec0cecec00ecece00cecec00ececec00ececece00cececec00ecececece64666066999b9bbb2b2baaaaaaaeaeaeeeee4ececccccccccccdcdcdcd +cdd00000000000000000000000000000ee00000000eeee000eeee000000000eeeeeeeeeee0000000eee000000000000000eeee00000000000000000000000000000000eeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000eeee000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeeeeeeeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee060662469b9b9bbbbb2babaaaeaeaeeeeeeeeececececccccdcdcdcdd +ddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000e0ceeeceeec0eeceeece00ceeecee0ceeecee0ceeece0eceeec0eecee00eeeceeeceeec00eceee0eeecee0ceeece0eceeece0eceeece00ceeeceee0eeeceeece06646266999b9b9bbb2baaaaaaaaaeaeaeee4e4ececccccccccccdcd +cdc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266466999b9bbbbbbbabaaaaaeaeaeeeeeeeeececececccccdcdc +dcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeecececece00cececece0ececece00cecece00cecece0ecece00cecec0cecec0cecece0ecece0ecece00cecec0cecece00cecece00cececec0cececece00cecececec462624609999b9bbb2babaaaaaaaeaeaeeeee4ececccccccccccc +cdc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeeeeeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee6466626499b9bbbbbbbababaaaeaeaeeeeeeeeeeececececcccc +dcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000eeeceeeceee0eeeceeec00eceeece0eceeece0eceeec00eceee0eeece00ceee00eeceeeceee00eece00ceeec0eecee00eeecee0ceeecee0ceeecee00eeeceeec0eeceeecee060642649999b9bbb2b2baaaaaaaaaeaeaeee4e4ececccccccc +ccc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee0eeeeee0eeeee00eeee00eeeeeeeeeeee00eeee00eeeee0eeeeee0eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666626699b9bbbbbbbbbabaaaaaeaeaeeeeeeeeececececec +ccc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000e0eceeecece0eeececec0eececece0ececece0ececec0eecece0eeece0eceee0ecece0ecec0ceeec0cecee0cecec0eecece0eeecec0ceeecec0ceeecece0eeececec0eecececee060646469999b9b9bbb2baaaaaaaaaeaeaeaeee4e4ececccc +ccc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee0e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeeeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee0662626609b9b9bbbbbbbababaaaeaeaeeeeeeeeeeececec +ecc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000eeeeceeecee00eeeceee00eeceeec00eceeec00eceee00eecee00eeece0eceee0eeec00eceeecee00eeec0eecee0ceeec00eceee00eecee00eeecee00eeeceee00eeceeec00eceeeceee64666066999b9b9bbb2babaaaaaaaaaeaeaeeeee4ecece +ccc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeeeeeeeeeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06066246999b9bbbbbbbababaaaeaeaeaeeeeeeeeeeec +ece000000000000000000000000000eeeeee000000000eeee00000eeeee0000000000000e00000000000eee00eeee00000000eeeeeee0000000000eeee000000ee000000000000eeeeeeeeeeeee00000eeee0000eeee0ee00000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000e0ceceeecec0ceeecece00eececec0eececec0eecece00eecec0ceeec00ecee00ecec0eece0ecee0cece0eeec00ecee00ecece0ecece00eecece0eeecece0eeecece00eececece0ecececeee0664626699999b9bbb2b2baaaaaaaaaeaeaeaeee4e4e +cec0000000000000000000000000eee00000ee00000eee00eee0000eee0000000000000ee0000000000eeeee0eee00000000000eee00000000000eeeee000000ee00000000000000eee00000eee0000eeeee000eee00eeeee000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeeeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06264646999b9bbbbbbbbbababaaaeaeaeaeeeeeeee +ece000000000000000000000000eee00000000e0000ee0000ee0000eee0000000000000eee000000000eee00eeee00000000000eee00000000000eee00e0000eeee0000000000000eee0000000e0000eee00e00ee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000eeeeeceeece00ceeeceee0eeeceee00eeceee00eeceee0eeece00ceeec0eecee0ceee00eece0eceeecee0ceee00eece0eceee0eeece00ceeec0eeceee00eeceee00eeceeec0eeceeece00ceeeceeec462626609999b9bbbbb2babaaaaaaaaaeaeaeeeee +4e400000000000000000000000eee0000000000000eee0000eee000eee000000000000eeee000000000eee000eee00000000000eee00000000000eee0000000eeee0000000000000eee0000000ee000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeee00eee00eeeeeeeeee00eee00eeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee664642c699b9b9bbbbbbbababaaaeaeaeaeeeeee +eee00000000000000000000000eee0000000000000eee0000eee000eee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eeeee0000000000000eee00000000e000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000eeeeeceeece0eceeecee00eeeceee0eeeceee0eeecee00eeece0eceee00eece00ceee0eeec00ece0ecee0cee00eeec0eece00ceee00eecee0ceeec00eceeec0eeceeec0eeceeec00eceeecee0ceeeceeec062662649999b9b9bbb2babaaaaaaaaaeaeaeae +eee0000000000000000000000eeee0000000000000eee0000eee000eee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eee00e000000000000eee00000000e000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee0eeee00eeee00eeee0eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0646426699b9b9bbbbbbbabababaaaeaeaeaee +eee0000000000000000000000eee00000000000000eee0000eee000eee00000000000eeee00e0000000eee000eee00000000000eee00000000000eee00000eeee00e000000000000eee000000000000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000e0eeeceeeee0eceeeeee0ceeeeeee0eeeeeee0eeeeee0ceeeee0eceee0eeece0eeeee0eeee0eece0eeeeecee0eeee0eeee0eecee0eeeec0eeeee0ceeeee0eceeee0eeceeee0eeceeeee0eceeeeee0ceeeeeeec062664669999b9b9bbb2b2baaaaaaaaaaaeae +aea0000000000000000000000eee00000000000000eee0000eee000eee00000000000eee000e0000000eee000eee00000000000eeeeeeee000000eee00000eee0000e00000000000eee000000000000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eeeeeeeeee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee642624609b9b9bbbbbbbbbababaaaeaeaea +eee0000000000000000000000eee000000000000000ee0000ee0000eeee0eee000000eee000e0000000eee000eee00000000000eee0000eee0000eee0000eeee0000e00000000000eee000000000000eee00000ee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000eeceeeceeec00eceeecee0ceeecee00eeecee00eeece00ceeec00eceee0eeece0ecee00eee00eece0ece0ecee0cee0ceee00eec00ecee0ceeec0eecee00eeece00ceeec00eceeec00eceeece0eceeecee00eeeceeece6646606699999b9bbbbb2babaaaaaaaaae +aea0000000000000000000000eee000000000000000eee00eee0000eee0eeee00000eee00000e000000eee000eee00000000000eee00000eee000eee0000eee00000ee0000000000eee000000000000eee00000eee00eeee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eeeeee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06266266999b9bbbbbbbbbababaaaaaea +eae0000000000000000000000eeee000000000e000000eeee00000eeee0eeee00000eee00000e00000eeee00eeee00000000000eee00000eee00eeeeee0eeeee000eeee000000000eee00000000000eeeeee0000eeee0eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000e0eeeeceeee0eeceeeee00ceeeeee0ceeeeee0ceeeee00ceeee0eecee00eeec00eeee0ceee0eeec00eee0eceeeeee0cee00eeec0eeee0ecee00eeec00eeeee0eeeee00ceeeee0eceeeee0eceeeee00ceeeeeee0eeeeeeece0646424699999b9b9bbb2babaaaaaaaa +aaa00000000000000000000000eee000000000e0000000000000000000000000000eeee000000e0000000000000000000000000eee00000eee000eee000000000000000000000000eee000000000000eee00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eee00eeeeeeeeee00eee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266664999b9b9bbbbbbbbbababaaa +eae00000000000000000000000eee00000000ee0000000000000000000000000000eee0000000e0000000000000000000000000eee00000eee0000ee000000000000000000000000eee0000000000000ee00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000ee0ceeeceee00eeceeece0eceeece00ceeece00ceeece0eceee00eecee0ceeec0eece00ceee0eeec0eec00ece0ecee0cee00eee0eeec0eece00ceee0eeece0eceee00eecee0ceeece00ceeece00ceeecee0ceeeceee00eeceeece0642426609999b9b9bbb2b2babaaaa +aaa000000000000000000000000eee000000eee0000000000000000000000000000eee00000000e000000000000000000000000eee00000eee00000e000000000000000000000000eee00000000000000e00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eee00eeee0eee0eee00eeeeee00eee0eee0eeee00eee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6666606699b9b9bbbbbbbbbababa +aaa0000000000000000000000000eee0000eeee000000000000000000000000000eeee00000000ee00000000000000000000000eee0000eee000000e000000000000000000000000eee00000000000000e00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00eeeeeeee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee060660669999b9b9bbbbb2babaa +aaa000000000000000000000000000eeeeee00e0000000000000000000000000eeeeeee00000eeeee00000000000000000000eeeeeeeeee0000000000000000000000000000000eeeeeee00000000000000000000000eeee0000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee0eee0eeee0eee0eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666660699b9b9bbbbbbbbbaba +bab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000e0eceeeceee0eeeceeec0eeceeece0eceeece0eceeec0eeceee0eeece0eceee0eeece0ecee0ceee0eeec0eec0eec0eeceee0eee0eee0eeec0eece0ecee0ceeec0eecee0ceeec0eeceee0eeecee0ceeecee0ceeeceee0eeeceeec0eeceeecee06066660999999b9b9bbb2bab +aaa000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00eee0eee0eeeeeeee0eee0eee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee066066660999b9b9bbbbbbbb +bab000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000eeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00ee00ee00ee0eeee0ee00ee00ee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6606060099999b9b9bbb2b +2ba000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000eeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06660000999b9b9bbbbbb +bbb000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0600000099999b9b9bbb +bb2000000000000000000000000000000000000000000000000000eeeee00000000eee0000000000000000000000000000eeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eeee0eee0eee0eee0ee0e00e0ee0eee0eee0eee0eeee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeeee0000000999b9b9bbbb +bbb0000000000000000000000000000000000000000000000000000eee00000000eee0e00000000000000000000000000ee000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9b9b +9bb0000000000000000000000000000000000000000000000000000eee00000000eee0e00000000000000000000000000ee0000000ee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099b9b9bb +bbb0000000000000000000000000000000000000000000000000000eee0000000000000e00000000000000000000000000eeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999999b +9b90000000000000000000000000000000000000000000000000000eee0000000000000e0000000000000000000000000eeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9 +b9b000000000000000000000000000eeeeee000000000eeee000000eee0eeee00000000ee000000eeeee000000eeeee00eeeeeeeeee00eeeee0eeeee0000eeee00000000eeeeeeee0000eee000000000eee000000000eeeeeeee000000000000eeeeeeee0000eee000000000eee0000000000eeeeee00000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099999 +9b90000000000000000000000000eee00000ee00000eee00eee0000eeee00eee0000000ee0000000eee00000000eee000ee00000000000eee000eee0000eeeee00000000000eee00000000eee000000000eee0000000000eee00000000000000000eee00000000eee000000000eee0000000eeee000e0000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999 +b9b000000000000000000000000eee00000000e0000ee0000ee0000eee0000ee000000eeee000000eee00000000eee0000e00000000000eee000eee0000eee00e0000000000eee0000000000eee000000000eee00000000eee00000000000000000eee0000000000eee000000000eee00000eee00000e000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000000000000000000000000eeeeeee0000000000000000000eeeee00000000000000000000000000eeeee000000000000000000000000eeeeee000eeee00000000000000000000000000000000000000000000099 +99900000000000000000000000eee0000000000000eee0000eee000eee0000eee00000eeee000000eee00000000eee00000eeeee000000eee000eee0000eee0000000000000eee00000000000eee000000000eee0000000eee00000000000000000eee00000000000eee000000000eee000000000000ee00000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeee000000000000000000000eeeeeeeeeee00000000000000000eeeee0000000000000000000000000eeeeeee0000000000000000000000eeeeeeeee0eeee00000000000000000000000000000000000000000000009 +99b00000000000000000000000eee0000000000000eee0000eee000eee0000eee0000eeeee000000eee00000000eee0000eee00eee0000eee000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee00000000000000 +000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeee0000000000000000000eeeeeeeeeeeee0000000000000000eeeee0000000000000000000000000eeeeeee000000000000000000000eeeeeeeeeeeeeee00000000000000000000000000000000000000000000000 +9990000000000000000000000eeee0000000000000eee0000eee000eee0000eee0000eee00e00000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee00000000000000 +00000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeee00000000000000000eeeeeeeeeeeeeee000000000000000eeeee000000000000000000000000eeeeeeeee00000000000000000000eeeeeeeeeeeeeee00000000000000000000000000000000000000000000000 +0990000000000000000000000eee00000000000000eee0000eee000eee0000eee000eeee00e00000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee00000000eeeeeee00000eeeeeee000000eee00000000000000000eee00000000eeeeeee00000eeeeeee0000000000eee00000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000eeeeeee000000000000000eeeeeee0000eeeeee00000000000000eeeee000000000000000000000000eeeeeeeee0000000000000000000eeeeee000eeeeeee00000000000000000000000000000000000000000000000 +0000000000000000000000000eee00000000000000eee0000eee000eee0000eee000eee0000e0000eee00000000eee000eee0000eee000eee000eee0000eee0000000000000eee0000000eee000eee000eee000eee00000eee00000000000000000eee0000000eee000eee000eee000eee00000000eeee00000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eeeee00000000eeeeee000000000000000eeeee0000000eeeee00000000000000eeeee000000000000000000000000eeee0eeee0000000000000000000eeeee00000eeeeee00000000000000000000000000000000000000000000000 +0000000000000000000000000eee000000000000000ee0000ee0000eee0000ee000eeee0000e0000eeee0eee000eee000eee0000eee000eeee00eee0000eee0000000000000eee000000eeee000eee00eeee000eee00000eee00000000000000000eee000000eeee000eee00eeee000eee000000eeeee000000000000000 +000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeeee0000000000000eeeeee0000000eeeeee0000000000000eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +0000000000000000000000000eee000000000000000eee00eee0000eeee00eee000eee00000ee000eee0eeee000eee0000eee00eee0000eee0eeeee0000eee0000000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee00eeeeeeeee000000000000000 +000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeee00000000000000eeeee000000000eeeee0000000000000eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +0000000000000000000000000eeee000000000e000000eeee00000eeee0eeee000eeeee000eeee0eeee0eeee00eeee00000eeeeeeeee00eee00eee0000eeeeee00000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeeeee00000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000e00000000000000000eeeee000000000eeeee0000000000000eeeee00000000000000000000000eeee000eeee000000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +00000000000000000000000000eee000000000e00000000000000000000000000000000000000000000000000000000000000000000000eee0000000000eee0000000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeee0000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +00000000000000000000000000eee00000000ee00000000000000000000000000000000000000000000000000000000000000000000000eee00000000000ee0000000000eeeeee000000eee0000eee00eee0000eee00eeeeee00000000000000eeeeee000000eee0000eee00eee0000eee000e0000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000eee000000eee0000000000000000000000000000000000000000000000000000eee0000000000000000eee000000000000e00000000000eeeee0000000ee000eee0000ee000eee0000eeeee000000000000000eeeee0000000ee000eee0000ee000eee00000eeeeeee000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0000000000000000000000eeee00000eeee00000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +0000000000000000000000000000eee0000eeee0000000000000000000000000000000000000000000000000000eee0000000000000000eee000000000000e0000000000000eee0000000eee00ee00000eee00ee0000000eee00000000000000000eee0000000eee00ee00000eee00ee000000eeeeeeee00000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeeee0000000eeeeee0000000000000eeeeee00000000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000eeeeee00e0000000000000000000000000000000000000000000000000000eee000000000000000eeee0000000000000000000000000000e000000000eeee00000000eeee0000000000e0000000000000000000e000000000eeee00000000eeee00000000eeeeeee00000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000000000000000000000eeeee0000000eeeee00000000000000eeeeeee0000000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000000000000000000000eeeeee00000eeeeee00000000000000eeeeeeeeeee000000000000000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee00000000000000000000000000000000eeeeeeeeeeeeeee000000000000000eeeeeeeeeee00000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000000eeeeeeeeeeeee0000000000000000eeeeeeeeeee00000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eee0000000000000000000eeeeeeeeeee00000000000000000eeee0eeeeeee0000000000000eeeee0000000eeeee000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeeee0000000000000000000eeeeeee0000000000000000000eeee00eeeee0000000000000eeeee000000000eeeee00000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000300000000000000000000000000000000000000000000000000000000000000000000000000}{\result {{\pict\wmetafile8\picw13551\pich5041\picwgoal7683\pichgoal2858 +010009000003105c00000100ce5b00000000050000000b0200000000050000000c02b113ef3425000000f7000003100000000000bf00000000bf0000bfbf00000000bf00bf00bf0000bfbf00c0c0c00080808000ff00000000ff0000ffff00000000ff00ff00ff0000ffff00ffffff000400000034020000030000003500ce +5b0000430f2000cc000000ba00f40100000000b113ef340000000028000000f4010000ba000000010004000000000018b7000000000000000000001000000010000000000000000000bf0000bf000000bfbf00bf000000bf00bf00bfbf0000c0c0c000808080000000ff0000ff000000ffff00ff000000ff00ff00ffff0000 +ffffff00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000eeeeeee000000000eeee0000000eee00eeee00eeeee000000000000000000e00000000e0000000eeeee00eeeee0eeeee0000eeee0ee0000000eeee000000000e00000e000000000000eeeeeee00eeeee0eeeee0000eee000000eeee00000000000000eeeeeee00000eeeee0eeeee0000 +eeee00000000000eeeeeee0000000000eee00eeee0000eee00000eee00eeee00eeeee00000000eeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000eee000000000eee00eee0000eeeee0eee0000eee000000000000000000ee0000000eee0000000eee0000eee000eee0000eee00eeeee000eee00eee000000eee000eee0000000000000eee00000eee000eee0000eeeee000eee00eee00000000000000eee00000000eee000eee0000eeeee +ee00000000000eee00000000000eeeee0eee0000eeeee000eeeee0eee0000eee00000000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000eee000000000ee0000ee0000eee00eeee0000eee000000000000000000eee000000eee0000000eee0000eee000eee0000ee0000eee0000ee0000ee000000eee000eee0000000000000eee00000eee000eee0000eee00e00ee0000ee00000000000000eee00000000eee000eee0000eee000e00 +000000000eee00000000000eee00eeee0000eee00e00eee00eeee0000eee00000000eee000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000eee00000000eee0000eee000eee000eee0000eee000000000000000000eee000000eee0000000eee0000eee000eee000eee0000eee000eee0000eee00000eee000eee0000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eeee0000e00000 +00000eee00000000000eee000eee0000eee00000eee000eee0000eee0000000eeee0000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eeee0000000eee0000eee000eee000eee0000eee000eee0000eee0000eeee00eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee000000000000000 +0eee000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000eee00000000eee0000eee000eee000eee0000eee00000000000000000eee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee0000000000000000eee +000e0000000eee000eee0000eee00000eee000eee0000eee0000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000eee00000000eee0000eee000eee000eee0000eee0000000000000000eeee0e0000eee0e000000eee0000eee000eee000eee0000eee000eee0000eee0000eee0e0eee0e000000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eeeeeeeee0000000000eee00ee +0000000eee000eee0000eee00000eee000eee0000eee0000000eeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000eeeee0000000eee0000eee000eee000eee0000eee0000000000000000eee000e00eee00e000000eee0000eee000eee000eee0000eee000eee0000eee000eee00eeee000e00000000000eee00000eee000eee0000eee0000eee0000eee0000000000000eee00000000eee000eee000eee000eee0000000000eee00ee0000 +000eee000eee0000eee00000eee000eee0000eee0000000eee000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee +ee0e00000000ee0000ee0000eee000eee0000eeee0eee00000000000eee000e00eee000e00000eee0000eeee00eee0000ee0000eee0000ee0000ee0000eee000eee000e00000000000eee00000eeee00eee0000eee00000ee0000ee00000000000000eee00000000eeee00eee0000ee000ee00000000000eeeeeee0000000e +ee000eee0000eee00000eee000eee0000eeee0eee000ee000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000 +e0000000eee00eee0000eee000eee0000eee0eeee0000000000eeee000e00eee000e00000eee0000eee0eeeee0000eee00eeee0000eee00eee000eee0000eee0000e0000000000eee00000eee0eeeee0000eee00000eee00eee00000000000000eee00000000eee0eeeee0000eee00ee00000000000eee00ee0000000eee00 +0eee0000eee00000eee000eee0000eee0eeee000eee00ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee000e000 +000000eeee00000eeee00eeee000eeee00eee0000000000eee00000eeee0000e0000eeee000eeee00eee0000000eee0eee000000eeee0000eeeee0eeeeee0eeee000000000eee0000eeee00eee0000eeeeee00000eeee0000000000000000eee00000000eee00eee0000000eeee000000000000eee00ee000000eeee00eeee +000eeeeee00eeee00eeee000eeee00eee00000eeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000e000000 +0000000000000000000000000000000000000000000eee00000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee000000000000000000eee000000000000000000000000000eee00000000eee0000000000000000000000000000eee000e000e0000000000000000 +eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee000000e0000000000 +00000000000000000000000000000000000000eee000000eeee00000e000000000000000000000000000000eee0000000000000000000000000000000000000000eee0000000000000000000ee000000000000000000000000000eee00000000eee0000000000000000000000000000eee000e000e00000000000000000ee0 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeee0000000e0000000000000 +0000000000000000000000000000000000eee000000eee000000e0000eee00000000000000000000000eee0000000000000000000000000000000000000000eee00000000000000000000e0000000000000000000000e0000eee0000e000eee0000000000000000000000000000eee000000ee000000000000000000e00000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000ee0000000000000000 +00000000000000000000000000000eeee00000eeee000000ee000eee00000000000000000000000eee0000000000000000000000000000000000000000eee00000000000000000000e0000000000000000000000ee000eee000ee000eee0000000000000000000000000000eee00000eee000000000000000000e000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee0000eeeee0000000000000000000 +000000000000000000000000eeeeee000eeeeeee000eeee00eee0000000000000000000000eeee00000000000000000000000000000000000000eeeeeee00000000000000000000000000000000000000000eeeeeeeeeeeee00eeee00000000000000000000000000eeeeeeeeeeeee00000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000780000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000087800008000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088008f8008700000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008708f70870000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000778f78f800000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f7f7f80000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000077777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777 +77777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777777788888777ff7778888000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff88777777777f777777777788000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000008888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888 +88888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888888887ff778888d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008f8f777ec4cdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008788f7877eee4ddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000078e8f86088aaecccdd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007ee68f86668bb2eeccddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008eece078424669b2eee4ccdd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eecece786662469b2eee4ccddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecec7860646669b2aae4ccdcdd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0cecece7e066262469bbbaeee4ccddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececec8cec64666269bbbaeae4ccdcddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeececeeece8ecee06064246bbbaeeeeecdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececececececec06666264bbb2aae4ecccdcddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ececececececececec06064666bbb2aaeee4ecdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ecececececececececec0662624699b2aaeae4ecccdcddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeceeeceeec0eece0eceeeceee646662699bbb2eeeee4ccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ecec00ecececece060642469bbb2aaeee4ccccdcddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000eececececec0cececece0ecececece066662649bbb2aaeeeeecccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cecececece0ecececece060646669bbb2aaeae4e4ccccdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000ee0ceeeceeec0eeceeeceeece0eceeeceee066262469bbb2baeaeee4ecccdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000eeecececece00cecececececece00cecececec64666269b9b2b2aaeae4e4ccccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000eeeceeecece00eecececeeececece00cececeeec06064246b9bbb2aaeeeee4ecccdcddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000eeecececece0ecececececececececec0cecececec0666626499bbb2aaeaeee4ccccccdcdddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000e0eceeeceee0eeeceeec0eece0eceeecee0ceeeceeec0606466699bbb2baeaeeeeececccdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000ee0ecececece0ecececec0cecece0ecececec0cecececec0662624699bbb2aaaaeae4e4ccccccdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000eececeeecec00eeececec0eececece0ecececee00ececeeece646662699bbb2baeaeeeee4ecccdcdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000eececececec00ececece00cecececece00cececec00ecececece060642469b9b2b2aaeaeee4e4ccccccdcdddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000eeeeceeecee0ceeeceee00eeceeeceeece00ceeeceee0eeeceeece066662649bbbbb2aaeaeeeee4ecccdcdcdddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000e0cecececec0cececece0ecececececececec0cececece0ecececece06064666999bbb2aaaaeaeee4ecccccccdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000ee0eeceeecee0ceeeceee0eeeceeeceeeceeecee0ceeeceee0eeeceeece066262469b9bbb2baeaeeeeeeececccdcdcdddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000eeecececece00cececece0ececece0ecec0cececec0cececece00cecececec6466626999bbb2baaaeaeee4e4ccccccdcdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000eeeeeceeeee00ceeeeee00eeeeeee00eeee00ceeeeee00eeeeeee00eeeeeecee06064246b9bbbbbaaaeaeeeee4ececccdcdcdddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e +eecececece0ecececec00ececece0ecececec0cececec00ecececec0cecececec0666626499b9b2b2aaaaeaeee4ecccccccdcdcddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeec +eeece0eceeecee0ceeeceee0eeeceeecee0ceeeceee0eeeceeec0eeceeecee0606466699bbbbb2baeaeeeeeeecececccdcdcdddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0ecececece +0ecececec0cececece0ecececececec0cececece0ecececec0cecececec0662606699b9bbb2aaaaeaeae4e4ecccccccdcdcddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeceeee00ecee +eeee0ceeeeee00eeeeeeeceeeeee00eeeeeee0eeeeeeec00eeeeeceee646642699b9bbb2baaaeaeeeeeeececccccdcdcddddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00 +cececec00ecececececececec00ececece00cececec00ecececece06266266999bbb2baaaaaeaeee4e4ecccccccdcdcdddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeee00000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeceeeceeec0eeceeece00ceeec +ee0ceeecee0ceee0eeeceee0eeeceee00eeceeece0eceeeceee064642669b9bbbbbabaeaeaeeeeeeececccdcdcdcddddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee000000ee00000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececec0ce +cecec0cecece0ececece0ecececec0cececece0ecececece06266466999bbb2b2aaaaeaeaeee4ecccccccccdcdcdddddd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0000000ee00000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee +0eeeeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee064262469b9bbbbb2baaaeaeeeeeeecececccdcdcdcddddddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0cececece00cececece0ececece00cecece00cece +cecece00cecece00cececec0cececece00cececece06646606999b9bbb2baaaaaeaeee4e4ecccccccccdcdcdcdddd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeceeeceee00eeceeec00eceeece00ceeece00ceeeceeec +eee00eeceee00eeceeec00eceeece00ceeeceeec0626626699bbbbb2babaeaeaeeeeeeecececccdcdcdcddddddd0000000000000000000000000000000000000000000000000eeeeee0000eeeeeee0eeeee00eeeee00000000eeeeeee0000eeeeeeeeeee00eeeeeeeeee00eeeee0eeeee0000eeee00e0eeee000000000eeee +eee0000eeeeee000eee00000e0eeee000000eee00000eeeee0000000000e000000000eee0000000eeee0ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ececece0ececececececece +c0cececec0cececec00ecececec0cecececec0646460699b9bbb2baaaaaeaeaeee4e4ecccccccccdcdcdcdddd0000000000000000000000000000000000000000000000000e000000000eeee000eee0000eee00000000000eee00000eeee0000eee000ee00000000000eee000eee0000eeeee00ee000ee0000000000eee000 +00eeee0000eeeeeee000ee000ee000eeeeeee0000eee0000000000ee0000000eeeeeee0000eee00eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeee0eeeeee0e +eeeeee0eeeeeeee0eeeeeeee0eeeeeeeee0626666099b9bbbbbabaaaeaeeeeeeeeecececccdcdcdddddddddd00000000000000000000000000000000000000000000000e00000000eee0000eee0000eee00000000000eee00000eee00000eee0000e00000000000eee000eee0000eee00e0e0000ee0000000000eee00000ee +e00000eee000e000e0000ee000eee000e0000eee0000000000eee000000eee000e0000ee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ecececece0ecececec0cececece0ececece0ececec0cecece0ececec0cece +cec0cececece0ecececec0cecececec064246669999bbb2b2aaaaaaeaeaeee4ececccccccccdcdcdcddddd000000000000000000000000000000000000000000000e0000000eee00000eee0000eee00000000000eee0000eee000000eee00000eeeee000000eee000eee0000eee00000000eee0000000000eee0000eee0000 +0eee00000e000000eee00eee00000e000eee000000000eeee00000eee00000e00eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeeeeee0eeeeee00eeeeee +00eeeeeee0eeeeeeee00eeeeeeee0662624699b9bbbbb2baaaeaeaeeeeeeecececccccdcdcdddddddddd00000000000000000000000000000000000000000000eeeeeeeeee00000eee0000eee00000000000eee000eeee000000eee0000eee00eee0000eee000eee0000eee0000000eeee0000000000eee000eeee00000eee +00000000000eeee00eee000000000eee000000000eee0e0000eee00000000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cececec00ececec00ecece00cecececece00cecec00ececec00e +cecece00cececec00ecececece06466264999b9bbb2baaaaaaaeaeee4e4ecccccccccccdcdcdcddddd000000000000000000000000000000000000000000e00000eeee00000eee0000eee00000000000eee00eeee0000000eee000eee0000eee000eee000eee0000eee00000eeeee00000000000eee00eeee000000eee0000 +00000eeeee000eee000000000eee000000000eee0e0000eee00000000eee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeeeeeeeeee00eeeeee0eeeeeee0eeee +eee00eeeeeeee0eeeeeeeee062642649b9bbbbbbbabaaaeaeeeeeeeeecececccccdcdcdddddddddd0000000000000000000000000000000000000000e00000eee000000eee0000eee00000000000eee00eee00000000eee000eee0000eee000eee000eee0000eee0000eeeee000000000000eee00eee0000000eeeeeeeee00 +eeeee0000eeeeeeeee000eee00000000eeee00e000eeeeeeeee00eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0cecececec0cececece0ecececec0cececec0cecece0ecececececececec0cecece0ececece0ececece +c0cececece0ecececece06466266999b9bbb2baaaaaaaeaeaeee4e4ecccccccccccdcdcdcddddd000000000000000000000000000000000000000e0000eee000000eee0000eee00000000000eeeeeeeee0000000eee000eee0000eee000eee000eee0000eee0000eee00000000000000eeeeeeeee000000eee000eee00eee0 +00000eee000eee000eee00000000eee000e000eee000eee00eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0e +eeeeeee0eeeeeeeeee6264646999bbbbbbbabaaaeaeaeeeeeeeeecececccccdcdcdddddddddd0000000000000000000000000000000000000e000eee0000000eee0000eee00000000000eee0000eee000000eee000eee0000eee000eeee00eee0000eee0000ee000e00000000000eee0000eee000000ee000eee00ee000e00 +00ee000eee000eeee0eee000eee0000e000ee000eee000ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeececeeece00ceeecece0eeecece00eecece00eecece0eeece00ceeece00ceeec0ceceee00ceceee00ceceeec0cece +eece00ceeececec4626266999b9bbb2b2baaaaaaaeaeeeee4ececccccccccccdcdcdcddddd000000000000000000000000000000000000e00eee0000000eee0000eee00000000000eee000000ee00000eee0000eee00eee0000eee0eeeee0000eee0000ee00ee00000000000eee000000ee00000eee00ee000ee00ee0000ee +e00ee0000eee0eeee00eee00000e000eee00ee0000eee00eeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeeeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeee +e00eeeeeeeee6466606699b9bbbbb2babaaaeaeaeeeeeeececececccdcdcdcdddddddddd0000000000000000000000000000000000e0eeee0000000eee0000eee00000000000eee000000eee000eeee00000eeeeeeeee00eee00eee0000eeeeee000eee0e00000000000eee000000eee000000eeee00000eee0e000000eeee +0000eeee0eeee0eeeee000eee0000eeee000000eeee0eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece0ecececec00ececece0ececece0ececec00ecece0ecececececec0cecec00ececec0cececec0cececec00ecececec0 +cecececec060662469999b9bbb2baaaaaaaeaeaeee4e4ececccccccccccdcdcdcdddddd0000000000000000000000000000000e0eee00000000eee0000eee00000000000eee000000eee00000000000000000000000eee0000000000eee000000000000000000000eee000000eee0000000000000000000000000000000000 +0000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeeeeeeeeeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eee +eeeeee0664626699b9bbbbbbbabaaaeaeaeeeeeeeeececececccdcdcdcddddddddddd000000000000000000000000000000eeee00000000eee0000eee00000000000eee000000eee00000000000000000000000eee00000000000ee000000000000000000000eee000000eee00000000000000000000000000000000000000 +000000000000000000000000000000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ececeeece0eceeecec0ceeecece0eeecece0eeecec0ceeece0eceee0ecec0eecec0ceeece0eceeec0ceceeec0ceceeece0eceeecec0ceeece +cec062664649999b9bbb2baaaaaaaaaeaeaeee4e4ecccccccccccdcdcdcdcdddddd0000000000000000000000000000eee000000000eee0000eee00000000000eee00000eee00000eee0000000000000000eee000000000000e000000000000000000000eee00000eee0000000000000000000000000000000000000000000 +00000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee +e462626699b9bbbbbbbababaaaeaeaeeeeeeeeecececccccdcdcdcddddddddd00000000000000000000000000000ee000000000eee0000eee00000000000eee0000eeee00000eee0000000000000000eee000000000000e000000000000000000000eee0000eeee00000000000000000000000000000000000000000000000 +0000000000000000000000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eececececec00ececece00cececec00ececec00ecece00cecec00ecece0ecececec0cecec00ecece00cecec00ececec00ececece00cececec00ecececece64 +666066999b9bbb2b2baaaaaaaeaeaeeeee4ececccccccccccdcdcdcdcdd00000000000000000000000000000ee00000000eeee000eeee000000000eeeeeeeeeee0000000eee000000000000000eeee00000000000000000000000000000000eeeeeeeeeee00000000000000000000000000000000000000000000000000000 +00000000000000000000000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeeeeeeeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06066 +2469b9b9bbbbb2babaaaeaeaeeeeeeeeececececccccdcdcdcddddd0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0ceeeceeec0eeceeece00ceeecee0ceeecee0ceeece0eceeec0eecee00eeeceeeceeec00eceee0eeecee0ceeece0eceeece0eceeece00ceeeceee0eeeceeece06646266 +999b9b9bbb2baaaaaaaaaeaeaeee4e4ececccccccccccdcdcdc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266466999 +b9bbbbbbbabaaaaaeaeaeeeeeeeeececececccccdcdcdcd000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeecececece00cececece0ececece00cecece00cecece0ecece00cecec0cecec0cecece0ecece0ecece00cecec0cecece00cecece00cececec0cececece00cecececec462624609999b +9bbb2babaaaaaaaeaeaeeeee4ececccccccccccccdc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeeeeeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee6466626499b9bbbb +bbbababaaaeaeaeeeeeeeeeeececececccccdcd00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeceeeceee0eeeceeec00eceeece0eceeece0eceeec00eceee0eeece00ceee00eeceeeceee00eece00ceeec0eecee00eeecee0ceeecee0ceeecee00eeeceeec0eeceeecee060642649999b9bbb2b +2baaaaaaaaaeaeaeee4e4ececcccccccccc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee0eeeeee0eeeee00eeee00eeeeeeeeeeee00eeee00eeeee0eeeeee0eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666626699b9bbbbbbbbba +baaaaaeaeaeeeeeeeeecececececccc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee0e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eceeecece0eeececec0eececece0ececece0ececec0eecece0eeece0eceee0ecece0ecec0ceeec0cecee0cecec0eecece0eeecec0ceeecec0ceeecece0eeececec0eecececee060646469999b9b9bbb2baaaa +aaaaaeaeaeaeee4e4ececcccccc000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eee0e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeeeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee0662626609b9b9bbbbbbbababaaa +eaeaeeeeeeeeeeececececc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000eeeeceeecee00eeeceee00eeceeec00eceeec00eceee00eecee00eeece0eceee0eeec00eceeecee00eeec0eecee0ceeec00eceee00eecee00eeecee00eeeceee00eeceeec00eceeeceee64666066999b9b9bbb2babaaaaaaaa +aeaeaeeeee4ecececcc00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeeeeeeeeeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06066246999b9bbbbbbbababaaaeaeaea +eeeeeeeeeeecece000000000000000000000000000eeeeee000000000eeee00000eeeee0000000000000e00000000000eee00eeee00000000eeeeeee0000000000eeee000000ee000000000000eeeeeeeeeeeee00000eeee0000eeee0ee0000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000e0ceceeecec0ceeecece00eececec0eececec0eecece00eecec0ceeec00ecee00ecec0eece0ecee0cece0eeec00ecee00ecece0ecece00eecece0eeecece0eeecece00eececece0ecececeee0664626699999b9bbb2b2baaaaaaaaaeaeae +aeee4e4ecec0000000000000000000000000eee00000ee00000eee00eee0000eee0000000000000ee0000000000eeeee0eee00000000000eee00000000000eeeee000000ee00000000000000eee00000eee0000eeeee000eee00eeeee000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeeeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06264646999b9bbbbbbbbbababaaaeaeaeaeeee +eeeeece000000000000000000000000eee00000000e0000ee0000ee0000eee0000000000000eee000000000eee00eeee00000000000eee00000000000eee00e0000eeee0000000000000eee0000000e0000eee00e00ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000eeeeeceeece00ceeeceee0eeeceee00eeceee00eeceee0eeece00ceeec0eecee0ceee00eece0eceeecee0ceee00eece0eceee0eeece00ceeec0eeceee00eeceee00eeceeec0eeceeece00ceeeceeec462626609999b9bbbbb2babaaaaaaaaaeaeaeeeee +4e400000000000000000000000eee0000000000000eee0000eee000eee000000000000eeee000000000eee000eee00000000000eee00000000000eee0000000eeee0000000000000eee0000000ee000eee0000eee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000eeeeeeeeeee00eeeeeee00eeeeeee00eeeeee00eeeee00eeeee00eeeee0eeeee0eeee00eee00eeeeeeeeee00eee00eeee0eeeee0eeeee00eeeee00eeeee00eeeeee00eeeeeee00eeeeeee00eeeeeeeee664642c699b9b9bbbbbbbababaaaeaeaeaeeeeeeeee0 +0000000000000000000000eee0000000000000eee0000eee000eee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eeeee0000000000000eee00000000e000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000eeeeeceeece0eceeecee00eeeceee0eeeceee0eeecee00eeece0eceee00eece00ceee0eeec00ece0ecee0cee00eeec0eece00ceee00eecee0ceeec00eceeec0eeceeec0eeceeec00eceeecee0ceeeceeec062662649999b9b9bbb2babaaaaaaaaaeaeaeaeeee00000 +00000000000000000eeee0000000000000eee0000eee000eee000000000000eee0e00000000eee000eee00000000000eee00000000000eee000000eee00e000000000000eee00000000e000eee0000eee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000e0eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee0eeee00eeee00eeee0eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0646426699b9b9bbbbbbbabababaaaeaeaeaeeeee000000000 +0000000000000eee00000000000000eee0000eee000eee00000000000eeee00e0000000eee000eee00000000000eee00000000000eee00000eeee00e000000000000eee000000000000eee0000eee0000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000e0eeeceeeee0eceeeeee0ceeeeeee0eeeeeee0eeeeee0ceeeee0eceee0eeece0eeeee0eeee0eece0eeeeecee0eeee0eeee0eecee0eeeec0eeeee0ceeeee0eceeee0eeceeee0eeceeeee0eceeeeee0ceeeeeeec062664669999b9b9bbb2b2baaaaaaaaaaaeaeaea0000000000000 +000000000eee00000000000000eee0000eee000eee00000000000eee000e0000000eee000eee00000000000eeeeeeee000000eee00000eee0000e00000000000eee000000000000eee0000eee0000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000eeeeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eeeeeeeeee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee642624609b9b9bbbbbbbbbababaaaeaeaeaeee00000000000000000 +00000eee000000000000000ee0000ee0000eeee0eee000000eee000e0000000eee000eee00000000000eee0000eee0000eee0000eeee0000e00000000000eee000000000000eee00000ee0000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000eeceeeceeec00eceeecee0ceeecee00eeecee00eeece00ceeec00eceee0eeece0ecee00eee00eece0ece0ecee0cee0ceee00eec00ecee0ceeec0eecee00eeece00ceeec00eceeec00eceeece0eceeecee00eeeceeece6646606699999b9bbbbb2babaaaaaaaaaeaea000000000000000000000 +0eee000000000000000eee00eee0000eee0eeee00000eee00000e000000eee000eee00000000000eee00000eee000eee0000eee00000ee0000000000eee000000000000eee00000eee00eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000eeeeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eeeeee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06266266999b9bbbbbbbbbababaaaaaeaeae0000000000000000000000eee +e000000000e000000eeee00000eeee0eeee00000eee00000e00000eeee00eeee00000000000eee00000eee00eeeeee0eeeee000eeee000000000eee00000000000eeeeee0000eeee0eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000e0eeeeceeee0eeceeeee00ceeeeee0ceeeeee0ceeeee00ceeee0eecee00eeec00eeee0ceee0eeec00eee0eceeeeee0cee00eeec0eeee0ecee00eeec00eeeee0eeeee00ceeeee0eceeeee0eceeeee00ceeeeeee0eeeeeeece0646424699999b9b9bbb2babaaaaaaaaaaa00000000000000000000000eee000 +000000e0000000000000000000000000000eeee000000e0000000000000000000000000eee00000eee000eee000000000000000000000000eee000000000000eee00000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000e0eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeeee0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eee00eeeeeeeeee00eee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeee06266664999b9b9bbbbbbbbbababaaaeae00000000000000000000000eee0000000 +0ee0000000000000000000000000000eee0000000e0000000000000000000000000eee00000eee0000ee000000000000000000000000eee0000000000000ee00000000000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000ee0ceeeceee00eeceeece0eceeece00ceeece00ceeece0eceee00eecee0ceeec0eece00ceee0eeec0eec00ece0ecee0cee00eee0eeec0eece00ceee0eeece0eceee00eecee0ceeece00ceeece00ceeecee0ceeeceee00eeceeece0642426609999b9b9bbb2b2babaaaaaaa000000000000000000000000eee000000eee0 +000000000000000000000000000eee00000000e000000000000000000000000eee00000eee00000e000000000000000000000000eee00000000000000e00000000000eee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee +eeeeeeeee00eeeeeeee0eeeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eee00eeee0eee0eee00eeeeee00eee0eee0eeee00eee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6666606699b9b9bbbbbbbbbababaaaa0000000000000000000000000eee0000eeee00000 +0000000000000000000000eeee00000000ee00000000000000000000000eee0000eee000000e000000000000000000000000eee00000000000000e00000000000eee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee +eeee0eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00eeeeeeee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee060660669999b9b9bbbbb2babaaaaa000000000000000000000000000eeeeee00e000000000 +0000000000000000eeeeeee00000eeeee00000000000000000000eeeeeeeeee0000000000000000000000000000000eeeeeee00000000000000000000000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eeeeeeeee0 +eeeeeeee00eeeeeee0eeeeeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee0eee0eeee0eee0eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0666660699b9b9bbbbbbbbbababab0000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e0eceeeceee0eeece +eec0eeceeece0eceeece0eceeec0eeceee0eeece0eceee0eeece0ecee0ceee0eeec0eec0eec0eeceee0eee0eee0eeec0eece0ecee0ceeec0eecee0ceeec0eeceee0eeecee0ceeecee0ceeeceee0eeeceeec0eeceeecee06066660999999b9b9bbb2babaaa00000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ee0eeeeeeee00eeeeeeee0e +eeeeee00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00eee0eee0eeeeeeee0eee0eee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeee066066660999b9b9bbbbbbbbbab000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee00eeeeeeee0eeeeee +e00eeeeee00eeeeee0eeeee00eeeee0eeeee0eeee00eeee0eeee0eee00ee00ee00ee0eeee0ee00ee00ee00eee0eeee0eeee00eeee0eeeee0eeeee00eeeee0eeeeee00eeeeee00eeeeeee0eeeeeeee00eeeeeeeee6606060099999b9b9bbb2b2ba0000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeee0eeeeeeee00eeeeeee0eee +eeee0eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee06660000999b9b9bbbbbbbbb00000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeee0eeeeeeee00eeeeeee0eeeeeee0 +eeeeee00eeeee0eeeee00eeee00eeee0eeee00eee00eee0eee00ee00ee0eeeeeeee0ee00ee00eee0eee00eee00eeee0eeee00eeee00eeeee0eeeee00eeeeee0eeeeeee0eeeeeee00eeeeeeee0eeeeeeeee0600000099999b9b9bbbbb2000000000000000000000000000000000000000000000000000eeeee00000000eee00 +00000000000000000000000000eeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeee0eeeeeeee0eeeeeeee0eeeeeee0eeeee +e0eeeeee0eeeee0eeeee0eeeee0eeee0eeee0eeee0eee0eee0eee0ee0e00e0ee0eee0eee0eee0eeee0eeee0eeee0eeeee0eeeee0eeeee0eeeeee0eeeeee0eeeeeee0eeeeeeee0eeeeeeee0eeeeeeeeee0000000999b9b9bbbbbbb0000000000000000000000000000000000000000000000000000eee00000000eee0e00000 +000000000000000000000ee000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9b9b9bb0000000000000000000000000000000000000000000000000000eee00000000eee0e000000000 +00000000000000000ee0000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000099b9b9bbbbb0000000000000000000000000000000000000000000000000000eee0000000000000e000000000000 +00000000000000eeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999999b9b90000000000000000000000000000000000000000000000000000eee0000000000000e0000000000000000 +000000000eeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009999b9b9b000000000000000000000000000eeeeee000000000eeee000000eee0eeee00000000ee000000eeeee000000ee +eee00eeeeeeeeee00eeeee0eeeee0000eeee00000000eeeeeeee0000eee000000000eee000000000eeeeeeee000000000000eeeeeeee0000eee000000000eee0000000000eeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999999b90000000000000000000000000eee00000ee00000eee00eee0000eeee00eee0000000ee0000000eee00000000eee00 +0ee00000000000eee000eee0000eeeee00000000000eee00000000eee000000000eee0000000000eee00000000000000000eee00000000eee000000000eee0000000eeee000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000999b9b000000000000000000000000eee00000000e0000ee0000ee0000eee0000ee000000eeee000000eee00000000eee0000e0 +0000000000eee000eee0000eee00e0000000000eee0000000000eee000000000eee00000000eee00000000000000000eee0000000000eee000000000eee00000eee00000e0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee0000000000000000000000 +0000eeeeeee0000000000000000000eeeee00000000000000000000000000eeeee000000000000000000000000eeeeee000eeee0000000000000000000000000000000000000000000009999900000000000000000000000eee0000000000000eee0000eee000eee0000eee00000eeee000000eee00000000eee00000eeeee +000000eee000eee0000eee0000000000000eee00000000000eee000000000eee0000000eee00000000000000000eee00000000000eee000000000eee000000000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeee000000000000000000000ee +eeeeeeeee00000000000000000eeeee0000000000000000000000000eeeeeee0000000000000000000000eeeeeeeee0eeee0000000000000000000000000000000000000000000000999b00000000000000000000000eee0000000000000eee0000eee000eee0000eee0000eeeee000000eee00000000eee0000eee00eee00 +00eee000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee00000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeee0000000000000000000eeeeeee +eeeeee0000000000000000eeeee0000000000000000000000000eeeeeee000000000000000000000eeeeeeeeeeeeeee000000000000000000000000000000000000000000000009990000000000000000000000eeee0000000000000eee0000eee000eee0000eee0000eee00e00000eee00000000eee000eee0000eee000ee +e000eee0000eee0000000000000eee000000000000eee000000000eee000000eee00000eeeeeee00000eee000000000000eee000000000eee00000000000ee0000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeee00000000000000000eeeeeeeeeeee +eee000000000000000eeeee000000000000000000000000eeeeeeeee00000000000000000000eeeeeeeeeeeeeee000000000000000000000000000000000000000000000000990000000000000000000000eee00000000000000eee0000eee000eee0000eee000eeee00e00000eee00000000eee000eee0000eee000eee000 +eee0000eee0000000000000eee00000000eeeeeee00000eeeeeee000000eee00000000000000000eee00000000eeeeeee00000eeeeeee0000000000eee000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000eeeeeee000000000000000eeeeeee0000eeeeee +00000000000000eeeee000000000000000000000000eeeeeeeee0000000000000000000eeeeee000eeeeeee000000000000000000000000000000000000000000000000000000000000000000000000eee00000000000000eee0000eee000eee0000eee000eee0000e0000eee00000000eee000eee0000eee000eee000eee0 +000eee0000000000000eee0000000eee000eee000eee000eee00000eee00000000000000000eee0000000eee000eee000eee000eee00000000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000eeeeee000000000000000eeeee0000000eeeee0000 +0000000000eeeee000000000000000000000000eeee0eeee0000000000000000000eeeee00000eeeeee000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000ee0000ee0000eee0000ee000eeee0000e0000eeee0eee000eee000eee0000eee000eeee00eee0000e +ee0000000000000eee000000eeee000eee00eeee000eee00000eee00000000000000000eee000000eeee000eee00eeee000eee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeeee0000000000000eeeeee0000000eeeeee0000000 +000000eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000eee000000000000000eee00eee0000eeee00eee000eee00000ee000eee0eeee000eee0000eee00eee0000eee0eeeee0000eee00 +00000000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee00eeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeee00000000000000eeeee000000000eeeee00000000000 +00eeeee00000000000000000000000eeeee0eeeee000000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000eeee000000000e000000eeee00000eeee0eeee000eeeee000eeee0eeee0eeee00eeee00000eeeeeeeee00eee00eee0000eeeeee0000 +0000000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000e00000000000000000eeeee000000000eeeee0000000000000ee +eee00000000000000000000000eeee000eeee000000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000eee000000000e00000000000000000000000000000000000000000000000000000000000000000000000eee0000000000eee0000000000 +000eee000000eee0000eee00eee0000eee00000eee00000000000000000eee000000eee0000eee00eee0000eee000eeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee0 +000000000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000eee00000000ee00000000000000000000000000000000000000000000000000000000000000000000000eee00000000000ee0000000000eeee +ee000000eee0000eee00eee0000eee00eeeeee00000000000000eeeeee000000eee0000eee00eee0000eee000e000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee00000 +00000000000000000eeeee000eeeee00000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000eee000000eee0000000000000000000000000000000000000000000000000000eee0000000000000000eee000000000000e00000000000eeeee00 +00000ee000eee0000ee000eee0000eeeee000000000000000eeeee0000000ee000eee0000ee000eee00000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeee000000000eeeee0000000000000eeeee000000000 +0000000000000eeee00000eeee00000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000eee0000eeee0000000000000000000000000000000000000000000000000000eee0000000000000000eee000000000000e0000000000000eee000000 +0eee00ee00000eee00ee0000000eee00000000000000000eee0000000eee00ee00000eee00ee000000eeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000eeeeee0000000eeeeee0000000000000eeeeee000000000000 +00000000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000eeeeee00e0000000000000000000000000000000000000000000000000000eee000000000000000eeee0000000000000000000000000000e000000000e +eee00000000eeee0000000000e0000000000000000000e000000000eeee00000000eeee00000000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000000000000000000000eeeee0000000eeeee00000000000000eeeeeee000000000000000 +0000eeeee00000eeeee0000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000000000000000000000eeeeee00000eeeeee00000000000000eeeeeeeeeee000000000000000 +eeeee00000eeeee0000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000000000000000000000000eeeeeeeeeeeeeee000000000000000eeeeeeeeeee00000000000000eeeee +0000000eeeee000000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000000000000000000000000000eeeeeeeeeeeee0000000000000000eeeeeeeeeee00000000000000eeeee0000 +000eeeee000000000000000eeeee000000eeeee00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eee0000000000000000000eeeeeeeeeee00000000000000000eeee0eeeeeee0000000000000eeeee0000000e +eeee000000000000000eeeee000000eeeee000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000eeeeee0000000000000000000eeeeeee0000000000000000000eeee00eeeee0000000000000eeeee000000000eeee +e00000000000000eeeee000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000eeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee000000000eeeee0000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee0000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeeeeee00000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee00000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeeeeeeee000000000000000000000000000000000000000000000000000000000000000000000000eeeee00000000000eeeee000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000eeeeeee00000000000000000000000000000000000000000000000000000000000000000000000000eeeee0000000000000eeeee000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 +000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000000000000000}}}}} +\par \pard +\par \pard \qj +For your end user report writing, ad hoc querying, forecasting and EIS needs, consider our CorVu Enterprise Information and Reporting System. Visit our home page at http://www.corvu.com.au/ or contact CorVu Pty Ltd for details of a reseller near you. + +\par +\par \pard\plain \s255\li720 \f3\lang2057 CorVu Pty Ltd +\par Level 4 +\par 1 James Place +\par North Sydney 2060 +\par AUSTRALIA +\par +\par Ph: +61 2 9959 3522 +\par Fax: +61 2 9959 3583 +\par Email: enquiries@corvu.com.au +\par Web: http://www.corvu.com.au/ (192.108.227.4) +\par \pard\plain \qj \f3\lang2057 +\par } \ No newline at end of file diff --git a/dde.c b/dde.c new file mode 100644 index 0000000..2313d1f --- /dev/null +++ b/dde.c @@ -0,0 +1,296 @@ +/* + * TwinSock - "Troy's Windows Sockets" + * + * Copyright (C) 1994-1995 Troy Rollo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the license in the file LICENSE.TXT included + * with the TwinSock distribution. + * + * 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. + */ + +#include +#include +#include +#include +#include +#include "tx.h" + +#ifndef __DLL__ +static DWORD iid; +static FARPROC lpDdeProc; +static HSZ hszService; +static HSZ hszTopic; +static HSZ hszHostInfo; +#endif + +tws_hostinfo hostinfo = { 0 }; + +struct DataPacket +{ + int iBytes; + char *pchData; + struct DataPacket *pktNext; +}; + +struct ClientStruct +{ + HCONV hconv; + HSZ hszItem; + struct DataPacket *pktResponse; + struct ClientStruct *pcsNext; +}; + +struct ClientStruct *pcsList = 0; + +struct ClientStruct * +GetClientStruct(HCONV hconv) +{ + struct ClientStruct *pcs; + + for (pcs = pcsList; pcs && pcs->hconv != hconv; pcs = pcs->pcsNext); + return pcs; +} + +void +CreateClientStruct(HCONV hconv) +{ + struct ClientStruct *pcs; + + pcs = (struct ClientStruct *) malloc(sizeof(struct ClientStruct)); + pcs->hconv = hconv; + pcs->pcsNext = pcsList; + pcs->hszItem = 0; + pcs->pktResponse = 0; + pcsList = pcs; +} + +#pragma argsused +HDDEDATA CALLBACK _export +DdeProc( UINT type, + UINT fmt, + HCONV hconv, + HSZ hsz1, + HSZ hsz2, + HDDEDATA hData, + DWORD dwData1, + DWORD dwData2) +{ + struct ClientStruct *pcs; + struct DataPacket *pkt; + int iSize; + char *pchData; + + switch(type) + { +#ifndef __DLL__ + case XTYP_ADVSTART: + if (hsz1 != hszTopic) + return FALSE; + pcs = GetClientStruct(hconv); + if (!pcs) + return FALSE; + pcs->hszItem = hsz2; + DdeKeepStringHandle(iid, hsz2); + return (HDDEDATA) TRUE; + + case XTYP_CONNECT: + if (hsz1 != hszTopic || + hsz2 != hszService) + return FALSE; + return (HDDEDATA) TRUE; + + case XTYP_CONNECT_CONFIRM: + CreateClientStruct(hconv); + return 0; + + case XTYP_ADVREQ: + pcs = GetClientStruct(hconv); + pkt = pcs->pktResponse; + if (!pkt) + return 0; + pcs->pktResponse = pkt->pktNext; + pchData = (char *) malloc(pkt->iBytes + sizeof(long)); + *(long *) pchData = pkt->iBytes; + memcpy(pchData + sizeof(long), pkt->pchData, pkt->iBytes); + hData = DdeCreateDataHandle(iid, + pchData, + pkt->iBytes + sizeof(long), + 0, + pcs->hszItem, + CF_PRIVATEFIRST, + 0); + free(pchData); + free(pkt->pchData); + free(pkt); + if (pcs->pktResponse) + DdePostAdvise(iid, hszTopic, pcs->hszItem); + return hData; + + case XTYP_REQUEST: + hData = DdeCreateDataHandle(iid, + (char *) &hostinfo, + sizeof(hostinfo), + 0, + hszHostInfo, + CF_PRIVATEFIRST, + 0); + return hData; + + case XTYP_POKE: +#endif + case XTYP_ADVDATA: + iSize = (int) DdeGetData(hData, 0, 0, 0); + pchData = (char *) malloc(iSize); + DdeGetData(hData, pchData, iSize, 0); + iSize = (int) *(long *) pchData; + ResponseReceived(pchData + sizeof(long), iSize, (long) hconv); + free(pchData); + return DDE_FACK; + + default: + switch(type & XCLASS_MASK) + { + case XCLASS_BOOL: + return FALSE; + + case XCLASS_DATA: + return 0; + + case XCLASS_FLAGS: + return DDE_FNOTPROCESSED; + + case XCLASS_NOTIFICATION: + return 0; + } + break; + } + return 0; +} + +#pragma argsused +BOOL +StartDDE(DC_ARGS + HINSTANCE hInst) +{ + char achItem[9]; +#ifdef __DLL__ + HSZ hszHostInfo; +#endif + +#ifndef __DLL__ + lpDdeProc = MakeProcInstance((FARPROC) DdeProc, hInst); +#endif + DC_CI(iid) = 0; + if ( +#ifdef __DLL__ + DdeInitialize(&pClient->iid, + (PFNCALLBACK) DdeProc, + APPCMD_CLIENTONLY, + 0) +#else + DdeInitialize(&iid, + (PFNCALLBACK) lpDdeProc, + 0, 0) +#endif + ) + { +#ifndef __DLL__ + FreeProcInstance(lpDdeProc); +#endif + return FALSE; + } + DC_CI(hszService) = DdeCreateStringHandle(DC_CI(iid), "TwinSock", 0); + DC_CI(hszTopic) = DdeCreateStringHandle(DC_CI(iid), "Connection", 0); + +#ifdef __DLL__ + pClient->hconv = DdeConnect(pClient->iid, + pClient->hszService, + pClient->hszTopic, 0); + if (!pClient->hconv) + { + DdeUninitialize(pClient->iid); + return FALSE; + } + sprintf(achItem, "%08lx", (long) pClient->hconv); + pClient->hszItem = DdeCreateStringHandle(pClient->iid, achItem, 0); + DdeClientTransaction(0, 0, pClient->hconv, pClient->hszItem, + CF_PRIVATEFIRST, + XTYP_ADVSTART, 1000, 0); +#else + DdeNameService(iid, hszService, 0, DNS_REGISTER); +#endif +#ifdef __DLL__ + if (!hostinfo.nHosts) + { + HDDEDATA hData; + + hszHostInfo = DdeCreateStringHandle(pClient->iid, "HostInfo", 0); + hData = DdeClientTransaction(0, 0, pClient->hconv, hszHostInfo, + CF_PRIVATEFIRST, + XTYP_REQUEST, 1000, 0); + if (hData) + { + DdeGetData(hData, (char *) &hostinfo, sizeof(hostinfo), 0); + DdeFreeDataHandle(hData); + } + } +#else + hszHostInfo = DdeCreateStringHandle(iid, "HostInfo", 0); +#endif + + return TRUE; +} + +void +StopDDE(DC_ARGS_) +{ +#ifdef __DLL__ + DdeDisconnect(pClient->hconv); + DdeClientTransaction(0, 0, pClient->hconv, pClient->hszItem, + 0, XTYP_ADVSTOP, 1000, 0); +#else + DdeNameService(iid, hszService, 0, DNS_UNREGISTER); +#endif + DdeFreeStringHandle(DC_CI(iid), DC_CI(hszService)); + DdeFreeStringHandle(DC_CI(iid), DC_CI(hszTopic)); + DdeUninitialize(DC_CI(iid)); +#ifndef __DLL__ + FreeProcInstance(lpDdeProc); +#endif +} + +void +SendDataTo( DC_ARGS + char *pchData, + int iBytes, + long iTo) +{ +#ifdef __DLL__ + char *pchDataNew; + + pchDataNew = (char *) malloc(iBytes + sizeof(long)); + *(long *) pchDataNew = iBytes; + memcpy(pchDataNew + sizeof(long), pchData, iBytes); + DdeClientTransaction(pchDataNew, iBytes + sizeof(long), + pClient->hconv, pClient->hszItem, CF_PRIVATEFIRST, + XTYP_POKE, TIMEOUT_ASYNC, 0); + free(pchDataNew); +#else + struct ClientStruct *pcs; + struct DataPacket **ppkt, *pkt; + + pcs = GetClientStruct((HCONV) iTo); + pkt = (struct DataPacket *) malloc(sizeof(struct DataPacket)); + pkt->iBytes = iBytes; + pkt->pchData = (char *) malloc(iBytes); + memcpy(pkt->pchData, pchData, iBytes); + pkt->pktNext = 0; + for (ppkt = &pcs->pktResponse; *ppkt; ppkt = &(*ppkt)->pktNext); + *ppkt = pkt; + DdePostAdvise(iid, hszTopic, pcs->hszItem); +#endif +} diff --git a/dns.h b/dns.h new file mode 100644 index 0000000..066a3a1 --- /dev/null +++ b/dns.h @@ -0,0 +1,276 @@ +/* + * Copyright (c) 1983, 1987, 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +typedef unsigned char u_char; +typedef unsigned short u_short; +typedef unsigned long u_long; + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ + /* Number of bytes of fixed size data in query structure */ +#define QFIXEDSZ 4 + /* number of bytes of fixed size data in resource record */ +#define RRFIXEDSZ 10 + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ + +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* connonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_ANY 255 +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW -1 +#define CONV_BADFMT -2 +#define CONV_BADCKSUM -3 +#define CONV_BADBUFLEN -4 + +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* BYTE_ORDER */ + +/* + * Structure for query header, the order of the fields is machine and + * compiler dependent, in our case, the bits within a byte are assignd + * least significant first, while the order of transmition is most + * significant first. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + u_short id; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + u_char qr:1; /* response flag */ + u_char opcode:4; /* purpose of message */ + u_char aa:1; /* authoritive answer */ + u_char tc:1; /* truncated message */ + u_char rd:1; /* recursion desired */ + /* fields in fourth byte */ + u_char ra:1; /* recursion available */ + u_char pr:1; /* primary server required (non standard) */ + u_char unused:2; /* unused bits */ + u_char rcode:4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + u_char rd:1; /* recursion desired */ + u_char tc:1; /* truncated message */ + u_char aa:1; /* authoritive answer */ + u_char opcode:4; /* purpose of message */ + u_char qr:1; /* response flag */ + /* fields in fourth byte */ + u_char rcode:4; /* response code */ + u_char unused:2; /* unused bits */ + u_char pr:1; /* primary server required (non standard) */ + u_char ra:1; /* recursion available */ +#endif + /* remaining bytes */ + u_short qdcount; /* number of question entries */ + u_short ancount; /* number of answer entries */ + u_short nscount; /* number of authority entries */ + u_short arcount; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + short r_zone; /* zone number */ + short r_class; /* class number */ + short r_type; /* type number */ + u_long r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +extern u_short _getshort(u_char *); +extern u_long _getlong(u_char *); + +/* + * Inline versions of get/put short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETSHORT(s, cp) { \ + (s) = *(cp)++ << 8; \ + (s) |= *(cp)++; \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp)++ << 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; \ +} + + +#define PUTSHORT(s, cp) { \ + *(cp)++ = (s) >> 8; \ + *(cp)++ = (s); \ +} + +/* + * Warning: PUTLONG destroys its first argument. + */ +#define PUTLONG(l, cp) { \ + (cp)[3] = l; \ + (cp)[2] = (l >>= 8); \ + (cp)[1] = (l >>= 8); \ + (cp)[0] = l >> 8; \ + (cp) += sizeof(u_long); \ +} +/* + * Global defines and variables for resolver stub. + */ + +#define MAXNS 3 /* max # name servers we'll track */ +#define MAXDFLSRCH 3 /* # default domain levels to try */ +#define MAXDNSRCH 6 /* max # default domain levels to try */ +#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ + +#define RES_TIMEOUT 5 /* seconds between retries */ + +struct state +{ + int retrans; /* retransmition time interval */ + int retry; /* number of times to retransmit */ + long options; /* option flags - see below. */ + int nscount; /* number of name servers */ + char nsaddr_list[MAXNS][4]; /* address of name server */ +#define nsaddr nsaddr_list[0] /* for backward compatibility */ + u_short id; /* current packet id */ + char defdname[MAXDNAME]; /* default domain */ +}; + +#define RES_INIT 0x0001 /* address initialized */ +#define RES_USEVC 0x0008 /* use virtual circuit */ +#define RES_IGNTC 0x0020 /* ignore trucation errors */ +#define RES_RECURSE 0x0040 /* recursion desired */ +#define RES_DEFNAMES 0x0080 /* use default domain name */ +#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES) + +extern struct state _res; + +#define MAXPACKET 1024 + +typedef union +{ + HEADER hdr; + u_char buf[MAXPACKET]; +} querybuf; + + +void putshort(u_short s, + u_char *msgp); +void putlong(u_long l, + u_char *msgp); +int dn_comp(u_char *exp_dn, + u_char *comp_dn, + int length, + u_char **dnptrs, + u_char **lastdnptr); +int dn_expand(u_char *msg, + u_char *eomorig, + u_char *comp_dn, + u_char *exp_dn, + int length); +int res_mkquery( int op, + char *dname, + int class, + int type, + char *data, + int datalen, + struct rrec *newrr, + char *buf, + int buflen); +void res_init(void); +struct hostent * +getanswer( querybuf *answer, + int anslen, + int iquery, + struct hostent *phost, /* The hostent */ + char *hostbuf, /* The buffer for host names */ + int buflen, /* The size of the host names buffer */ + char **h_addr_ptrs, /* The address list */ + char **host_aliases, /* The alias list */ + int *ph_errno + ); +int dn_skipname(u_char *comp_dn, + u_char *eom); + diff --git a/getsock.c b/getsock.c new file mode 100644 index 0000000..7dae083 --- /dev/null +++ b/getsock.c @@ -0,0 +1,139 @@ +/* + * TwinSock - "Troy's Windows Sockets" + * + * Copyright (C) 1994-1995 Troy Rollo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the license in the file LICENSE.TXT included + * with the TwinSock distribution. + * + * 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. + */ + +#include "twinsock.h" +#include + +/* The following defines the maximum for each type of socket */ +#define MAX_SOCKETS 256 +#define INT_BITS 32 +#define MAX_SOCKINTS (MAX_SOCKETS / INT_BITS) + +static unsigned long aiClientSockets[MAX_SOCKINTS]; +static unsigned long aiServerSockets[MAX_SOCKINTS]; + +static int iInitialised = 0; + +static void +InitSocks(void) +{ + if (!iInitialised) + { + iInitialised = 1; + memset(aiClientSockets, 0, sizeof(aiClientSockets)); + memset(aiServerSockets, 0, sizeof(aiServerSockets)); + } +} + +static int +GetNewSocket(unsigned long *piSockets) +{ + unsigned long iNow; + int i, j; + + for (i = 0; i < MAX_SOCKINTS; i++) + { + for (j = 0, iNow = 1; j < INT_BITS; j++, iNow <<= 1) + { + if (!(piSockets[i] & iNow)) + { + piSockets[i] |= iNow; + return i * INT_BITS + j; + } + } + } + return -1; +} + +int +GetClientSocket(void) +{ + int iSocket; + + InitSocks(); + iSocket = GetNewSocket(aiClientSockets); + if (iSocket == -1) + return iSocket; + else + return iSocket * 2; +} + +int +GetServerSocket(void) +{ + int iSocket; + + InitSocks(); + iSocket = GetNewSocket(aiServerSockets); + if (iSocket == -1) + return iSocket; + else + return iSocket * 2 + 1; +} + +static void +ReleaseSocket( unsigned long *piSockets, + int iSocket) +{ + int i; + int j; + + i = iSocket / INT_BITS; + j = iSocket % INT_BITS; + piSockets[i] &= ~(1L << j); +} + +void +ReleaseClientSocket(int iSocket) +{ + ReleaseSocket(aiClientSockets, iSocket / 2); +} + +void +ReleaseServerSocket(int iSocket) +{ + ReleaseSocket(aiServerSockets, (iSocket - 1) / 2); +} + +/* Fortunately all the calls which include sockets in their + * arguments have them as argument 1. HasSocketArg returns + * true if the function specified has this argument. If it + * does, we will need to replace the argument. + */ + +int +HasSocketArg(enum Functions fn) +{ + switch(fn) + { + case FN_Bind: + case FN_Close: + case FN_Connect: + case FN_IOCtl: + case FN_GetPeerName: /* Obsolete */ + case FN_GetSockName: /* Obsolete */ + case FN_Listen: + case FN_Select: /* Obsolete */ + case FN_Send: + case FN_SendTo: + case FN_SetSockOpt: + case FN_Shutdown: + case FN_Socket: /* Has the client's idea in it */ + return 1; + + default: + return 0; + } +} + diff --git a/makefile b/makefile index 5438196..a4071b0 100644 --- a/makefile +++ b/makefile @@ -1,11 +1,56 @@ -all: twinsock.exe +all: twinsock.exe twnsck32.exe winsock.dll wsock32.dll -winsock.dll: winsock.c - bcc -WD -ml -v -lc -lm -ls winsock.c + +winsock.dll: winsock.obj ddedll.obj gsdll16.obj \ + res_comp.obj res_init.obj res_mkq.obj + bcc -WD -ml -v -lc -lm -ls $** winsock.lib : winsock.dll implib winsock.lib winsock.dll +res_comp.obj: res_comp.c + bcc -WD -ml -v -c res_comp.c + +res_init.obj: res_init.c + bcc -WD -ml -v -c res_init.c + +res_mkq.obj: res_mkq.c + bcc -WD -ml -v -c res_mkq.c + +winsock.obj: winsock.c + bcc -WD -ml -v -c winsock.c + +ddedll.obj: dde.c + bcc -WD -ml -v -oddedll -c dde.c + +gsdll16.obj: getsock.c + bcc -WD -ml -v -ogsdll16 -c getsock.c + +ddedll32.obj: dde.c + bcc32 -WD -v -oddedll32 -c dde.c + +gsdll32.obj: getsock.c + bcc32 -WD -v -ogsdll32 -c getsock.c + +wsock32.dll: wsock32.obj ddedll32.obj gsdll32.obj \ + r32_comp.obj r32_init.obj r32_mkq.obj + bcc32 -WD -v -lc -lm -ls -ewsock32 $** + +wsock32.obj: winsock.c + bcc32 -WD -v -owsock32 -c winsock.c + +r32_comp.obj: res_comp.c + bcc32 -WD -v -or32_comp -c res_comp.c + +r32_init.obj: res_init.c + bcc32 -WD -v -or32_init -c res_init.c + +r32_mkq.obj: res_mkq.c + bcc32 -WD -v -or32_mkq -c res_mkq.c + +dde.obj: dde.c + bcc -WE -ml -v -c dde.c + packet.obj: packet.c bcc -WE -ml -v -c packet.c @@ -18,13 +63,69 @@ showprot.obj: showprot.c twinsock.obj: twinsock.c bcc -WE -ml -v -c twinsock.c +script.obj: script.c + bcc -WE -ml -v -c script.c + about.obj: about.c bcc -WE -ml -v -c about.c comms.obj: comms.c bcc -WE -ml -v -c comms.c -twinsock.exe: twinsock.obj packet.obj about.obj comms.obj showprot.obj getentry.obj winsock.lib - bcc -WE -lc -lm -ls -ml -v twinsock.obj packet.obj about.obj comms.obj showprot.obj getentry.obj winsock.lib +getsock.obj: getsock.c + bcc -WE -ml -v -c getsock.c + +ns.obj: ns.c + bcc -WE -ml -v -c ns.c + +twinsock.exe: twinsock.obj packet.obj about.obj comms.obj \ + showprot.obj getentry.obj script.obj \ + dde.obj getsock.obj ns.obj + bcc -WE -lc -lm -ls -ml -v @&&! + twinsock.obj packet.obj \ + about.obj comms.obj showprot.obj getentry.obj \ + script.obj dde.obj getsock.obj ns.obj +! rc twinsock - \ No newline at end of file + +dde32.obj: dde.c + bcc32 -WE -v -odde32 -c dde.c + +pkt32.obj: packet.c + bcc32 -WE -v -opkt32 -c packet.c + +getent32.obj: getentry.c + bcc32 -WE -v -ogetent32 -c getentry.c + +shwprt32.obj: showprot.c + bcc32 -WE -v -oshwprt32 -c showprot.c + +twnsck32.obj: twinsock.c + bcc32 -WE -v -otwnsck32 -c twinsock.c + +script32.obj: script.c + bcc32 -WE -v -oscript32 -c script.c + +about32.obj: about.c + bcc32 -WE -v -oabout32 -c about.c + +comms32.obj: comms.c + bcc32 -WE -v -ocomms32 -c comms.c + +getsck32.obj: getsock.c + bcc32 -WE -v -ogetsck32 -c getsock.c + +ns32.obj: ns.c + bcc32 -WE -v -ons32 -c ns.c + +twnsck32.exe: twnsck32.obj pkt32.obj about32.obj comms32.obj \ + shwprt32.obj getent32.obj script32.obj \ + dde32.obj getsck32.obj ns32.obj + brc32 -r -fotwnsck32 twinsock.rc + bcc32 -WE -lc -lm -ls -v @&&! + twnsck32.obj pkt32.obj \ + about32.obj comms32.obj shwprt32.obj getent32.obj \ + script32.obj dde32.obj getsck32.obj ns32.obj +! + brc32 twnsck32.res + diff --git a/nameser.h b/nameser.h new file mode 100644 index 0000000..975a197 --- /dev/null +++ b/nameser.h @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1983, 1989 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)nameser.h 5.24 (Berkeley) 6/1/90 + */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ + /* Number of bytes of fixed size data in query structure */ +#define QFIXEDSZ 4 + /* number of bytes of fixed size data in resource record */ +#define RRFIXEDSZ 10 + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ + +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* connonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW -1 +#define CONV_BADFMT -2 +#define CONV_BADCKSUM -3 +#define CONV_BADBUFLEN -4 + +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* BYTE_ORDER */ + +/* + * Structure for query header, the order of the fields is machine and + * compiler dependent, in our case, the bits within a byte are assignd + * least significant first, while the order of transmition is most + * significant first. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + u_short id; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + u_char qr:1; /* response flag */ + u_char opcode:4; /* purpose of message */ + u_char aa:1; /* authoritive answer */ + u_char tc:1; /* truncated message */ + u_char rd:1; /* recursion desired */ + /* fields in fourth byte */ + u_char ra:1; /* recursion available */ + u_char pr:1; /* primary server required (non standard) */ + u_char unused:2; /* unused bits */ + u_char rcode:4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + u_char rd:1; /* recursion desired */ + u_char tc:1; /* truncated message */ + u_char aa:1; /* authoritive answer */ + u_char opcode:4; /* purpose of message */ + u_char qr:1; /* response flag */ + /* fields in fourth byte */ + u_char rcode:4; /* response code */ + u_char unused:2; /* unused bits */ + u_char pr:1; /* primary server required (non standard) */ + u_char ra:1; /* recursion available */ +#endif + /* remaining bytes */ + u_short qdcount; /* number of question entries */ + u_short ancount; /* number of answer entries */ + u_short nscount; /* number of authority entries */ + u_short arcount; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + short r_zone; /* zone number */ + short r_class; /* class number */ + short r_type; /* type number */ + u_long r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +extern u_short _getshort(); +extern u_long _getlong(); + +/* + * Inline versions of get/put short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETSHORT(s, cp) { \ + (s) = *(cp)++ << 8; \ + (s) |= *(cp)++; \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp)++ << 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; \ +} + + +#define PUTSHORT(s, cp) { \ + *(cp)++ = (s) >> 8; \ + *(cp)++ = (s); \ +} + +/* + * Warning: PUTLONG destroys its first argument. + */ +#define PUTLONG(l, cp) { \ + (cp)[3] = l; \ + (cp)[2] = (l >>= 8); \ + (cp)[1] = (l >>= 8); \ + (cp)[0] = l >> 8; \ + (cp) += sizeof(u_long); \ +} diff --git a/ns.c b/ns.c new file mode 100644 index 0000000..040ffe6 --- /dev/null +++ b/ns.c @@ -0,0 +1,203 @@ +/* + * TwinSock - "Troy's Windows Sockets" + * + * Copyright (C) 1994 Troy Rollo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the license in the file LICENSE.TXT included + * with the TwinSock distribution. + * + * 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. + */ +#include +#include +#include +#include +#include +#include "twinsock.h" + +extern HINSTANCE hinst; + +#define RESOLV_DOMAIN 101 +#define RESOLV_NS1 111 +#define RESOLV_NS2 121 +#define RESOLV_NS3 131 +#define RESOLV_OVERRIDE 141 + +static void +SetNSItem( char *pchBuffer, + HWND hDlg, + int iItem) +{ + char *pchDot; + int i; + + for (i = 0; pchBuffer && i < 4; i++) + { + if (pchBuffer) + { + pchDot = strchr(pchBuffer, '.'); + if (pchDot) + *pchDot++ = 0; + SetDlgItemText(hDlg, iItem + i, pchBuffer); + pchBuffer = pchDot; + } + } +} + +static void +FillResolvDialog(HWND hDlg) +{ + static char achBuffer[256]; + + GetTwinSockSetting("Resolver", "Domain", "", achBuffer, sizeof(achBuffer)); + SetDlgItemText(hDlg, RESOLV_DOMAIN, achBuffer); + GetTwinSockSetting("Resolver", "Server1", "", achBuffer, sizeof(achBuffer)); + SetNSItem(achBuffer, hDlg, RESOLV_NS1); + GetTwinSockSetting("Resolver", "Server2", "", achBuffer, sizeof(achBuffer)); + SetNSItem(achBuffer, hDlg, RESOLV_NS2); + GetTwinSockSetting("Resolver", "Server3", "", achBuffer, sizeof(achBuffer)); + SetNSItem(achBuffer, hDlg, RESOLV_NS3); + GetTwinSockSetting("Resolver", "Override", "0", achBuffer, sizeof(achBuffer)); + SendDlgItemMessage(hDlg, RESOLV_OVERRIDE, BM_SETCHECK, (*achBuffer == '1'), 0); +} + +static void +VerifyResolvOK(HWND hDlg) +{ + int i, j; + int idCtl; + BOOL bOneEmpty = FALSE; + BOOL bOK = TRUE; + BOOL bOverride; + char *c; + int nValue; + static char achBuffer[256]; + + bOverride = SendDlgItemMessage(hDlg, RESOLV_OVERRIDE, BM_GETCHECK, 0, 0); + for (i = 0; i < 3; i++) + { + for (j = 0; j < 4; j++) + { + idCtl = RESOLV_NS1 + 10 * i + j; + GetDlgItemText(hDlg, idCtl, achBuffer, sizeof(achBuffer)); + if (strlen(achBuffer) > 3) + bOK = FALSE; + for (c = achBuffer; *c; c++) + if (!isdigit(*c)) + bOK = FALSE; + if (*achBuffer == 0) + { + if (j == 0) + bOneEmpty = TRUE; + else if (!bOneEmpty) + bOK = FALSE; + } + else if (bOneEmpty) + { + bOK = FALSE; + } + else + { + nValue = atoi(achBuffer); + if (nValue > 255) + bOK = FALSE; + } + } + if (!i && bOverride && bOneEmpty) + bOK = FALSE; + } + GetDlgItemText(hDlg, RESOLV_DOMAIN, achBuffer, sizeof(achBuffer)); + if (bOverride && !*achBuffer) + bOK = FALSE; + EnableWindow(GetDlgItem(hDlg, IDOK), bOK); +} + +static char *achResNames[3] = +{ + "Server1", "Server2", "Server3" +}; + +static void +ReadResolvDialog(HWND hDlg) +{ + int i, j; + int idCtl; + BOOL bOneEmpty = FALSE; + BOOL bOK = TRUE; + BOOL bOverride; + char *c; + int nValue; + static char achBuffer[256]; + char achSmallBuf[20]; + + bOverride = SendDlgItemMessage(hDlg, RESOLV_OVERRIDE, BM_GETCHECK, 0, 0); + WritePrivateProfileString("Resolver", "Override", bOverride ? "1" : "0", "TWINSOCK.INI"); + for (i = 0; i < 3; i++) + { + achBuffer[0] = 0; + for (j = 0; j < 4; j++) + { + idCtl = RESOLV_NS1 + 10 * i + j; + GetDlgItemText(hDlg, idCtl, achSmallBuf, sizeof(achSmallBuf)); + if (*achSmallBuf) + { + if (j > 0) + strcat(achBuffer, "."); + strcat(achBuffer, achSmallBuf); + } + } + WritePrivateProfileString("Resolver", achResNames[i], achBuffer, "TWINSOCK.INI"); + } + GetDlgItemText(hDlg, RESOLV_DOMAIN, achBuffer, sizeof(achBuffer)); + WritePrivateProfileString("Resolver", "Domain", achBuffer, "TWINSOCK.INI"); +} + + +#pragma argsused +BOOL CALLBACK +ResolvDlgProc( HWND hDlg, + UINT wMsg, + WPARAM wParam, + LPARAM lParam) +{ + switch(wMsg) + { + case WM_INITDIALOG: + FillResolvDialog(hDlg); + return TRUE; + + case WM_COMMAND: + switch(wParam) + { + case IDOK: + ReadResolvDialog(hDlg); + EndDialog(hDlg, TRUE); + break; + + case IDCANCEL: + EndDialog(hDlg, FALSE); + break; + + default: + VerifyResolvOK(hDlg); + break; + } + break; + } + return FALSE; +} + +BOOL +ResolvEdit(HWND hwndParent) +{ + FARPROC fpDlgProc; + BOOL bStatus; + + fpDlgProc = MakeProcInstance((FARPROC) ResolvDlgProc, hinst); + bStatus = DialogBox(hinst, "NS_DLG", hwndParent, fpDlgProc); + FreeProcInstance(fpDlgProc); + return bStatus; +} diff --git a/packet.c b/packet.c index 13d2dd9..a7ec43e 100644 --- a/packet.c +++ b/packet.c @@ -13,7 +13,8 @@ */ #include -#ifdef __MSDOS__ +#include +#ifdef _Windows #include #include #include @@ -25,7 +26,7 @@ #include "twinsock.h" #define MAX_STREAMS 256 -#define WINDOW_SIZE 4 +#define WINDOW_SIZE 8 short nInSeq = 0; short nOutSeq = 0; @@ -276,12 +277,12 @@ int TransmitData(void *pvData, int iDataLen) strcpy(pchDataOut + iOut, "@X"); iOut += 2; } - else if (eLine == E_8NoX && c == '\023') + else if ((eLine == E_8NoX || eLine == E_8NoHiX) && c == '\023') { strcpy(pchDataOut + iOut, "@S"); iOut += 2; } - else if (eLine == E_8NoX && c == '\021') + else if ((eLine == E_8NoX || eLine == E_8NoHiX) && c == '\021') { strcpy(pchDataOut + iOut, "@Q"); iOut += 2; diff --git a/res_comp.c b/res_comp.c new file mode 100644 index 0000000..54aa89f --- /dev/null +++ b/res_comp.c @@ -0,0 +1,326 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted provided + * that: (1) source distributions retain this entire copyright notice and + * comment, and (2) distributions including binaries display the following + * acknowledgement: ``This product includes software developed by the + * University of California, Berkeley and its contributors'' in the + * documentation or other materials provided with the distribution and in + * all advertising materials mentioning features or use of this software. + * 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_comp.c 6.18 (Berkeley) 6/27/90"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include "dns.h" + +static dn_find(u_char *exp_dn, + u_char *msg, + u_char **dnptrs, + u_char **lastdnptr); + +/* + * Expand compressed domain name 'comp_dn' to full domain name. + * 'msg' is a pointer to the begining of the message, + * 'eomorig' points to the first location after the message, + * 'exp_dn' is a pointer to a buffer of size 'length' for the result. + * Return size of compressed name or -1 if there was an error. + */ +dn_expand(u_char *msg, + u_char *eomorig, + u_char *comp_dn, + u_char *exp_dn, + int length) +{ + register u_char *cp, *dn; + register int n, c; + u_char *eom; + int len = -1, checked = 0; + + dn = exp_dn; + cp = comp_dn; + eom = exp_dn + length; + /* + * fetch next label in domain name + */ + while ((n = *cp++) != 0) { + /* + * Check for indirection + */ + switch (n & INDIR_MASK) { + case 0: + if (dn != exp_dn) { + if (dn >= eom) + return (-1); + *dn++ = '.'; + } + if (dn+n >= eom) + return (-1); + checked += n + 1; + while (--n >= 0) { + if ((c = *cp++) == '.') { + if (dn + n + 2 >= eom) + return (-1); + *dn++ = '\\'; + } + *dn++ = c; + if (cp >= eomorig) /* out of range */ + return(-1); + } + break; + + case INDIR_MASK: + if (len < 0) + len = cp - comp_dn + 1; + cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); + if (cp < msg || cp >= eomorig) /* out of range */ + return(-1); + checked += 2; + /* + * Check for loops in the compressed name; + * if we've looked at the whole message, + * there must be a loop. + */ + if (checked >= eomorig - msg) + return (-1); + break; + + default: + return (-1); /* flag error */ + } + } + *dn = '\0'; + if (len < 0) + len = cp - comp_dn; + return (len); +} + +/* + * Compress domain name 'exp_dn' into 'comp_dn'. + * Return the size of the compressed name or -1. + * 'length' is the size of the array pointed to by 'comp_dn'. + * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] + * is a pointer to the beginning of the message. The list ends with NULL. + * 'lastdnptr' is a pointer to the end of the arrary pointed to + * by 'dnptrs'. Side effect is to update the list of pointers for + * labels inserted into the message as we compress the name. + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' + * is NULL, we don't update the list. + */ +dn_comp(u_char *exp_dn, + u_char *comp_dn, + int length, + u_char **dnptrs, + u_char **lastdnptr) +{ + register u_char *cp, *dn; + register int c, l; + u_char **cpp, **lpp, *sp, *eob; + u_char *msg; + + dn = exp_dn; + cp = comp_dn; + eob = cp + length; + if (dnptrs != NULL) { + if ((msg = *dnptrs++) != NULL) { + for (cpp = dnptrs; *cpp != NULL; cpp++) + ; + lpp = cpp; /* end of list to search */ + } + } else + msg = NULL; + for (c = *dn++; c != '\0'; ) { + /* look to see if we can use pointers */ + if (msg != NULL) { + if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { + if (cp+1 >= eob) + return (-1); + *cp++ = (l >> 8) | INDIR_MASK; + *cp++ = l % 256; + return (cp - comp_dn); + } + /* not found, save it */ + if (lastdnptr != NULL && cpp < lastdnptr-1) { + *cpp++ = cp; + *cpp = NULL; + } + } + sp = cp++; /* save ptr to length byte */ + do { + if (c == '.') { + c = *dn++; + break; + } + if (c == '\\') { + if ((c = *dn++) == '\0') + break; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = c; + } while ((c = *dn++) != '\0'); + /* catch trailing '.'s but not '..' */ + if ((l = cp - sp - 1) == 0 && c == '\0') { + cp--; + break; + } + if (l <= 0 || l > MAXLABEL) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *sp = l; + } + if (cp >= eob) { + if (msg != NULL) + *lpp = NULL; + return (-1); + } + *cp++ = '\0'; + return (cp - comp_dn); +} + +/* + * Skip over a compressed domain name. Return the size or -1. + */ +dn_skipname(u_char *comp_dn, + u_char *eom) +{ + register u_char *cp; + register int n; + + cp = comp_dn; + while (cp < eom && (n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + cp += n; + continue; + default: /* illegal type */ + return (-1); + case INDIR_MASK: /* indirection */ + cp++; + } + break; + } + return (cp - comp_dn); +} + +/* + * Search for expanded name from a list of previously compressed names. + * Return the offset from msg if found or -1. + * dnptrs is the pointer to the first name on the list, + * not the pointer to the start of the message. + */ +static dn_find(u_char *exp_dn, + u_char *msg, + u_char **dnptrs, + u_char **lastdnptr) +{ + register u_char *dn, *cp, **cpp; + register int n; + u_char *sp; + + for (cpp = dnptrs; cpp < lastdnptr; cpp++) { + dn = exp_dn; + sp = cp = *cpp; + while ((n = *cp++) != 0) { + /* + * check for indirection + */ + switch (n & INDIR_MASK) { + case 0: /* normal case, n == len */ + while (--n >= 0) { + if (*dn == '.') + goto next; + if (*dn == '\\') + dn++; + if (*dn++ != *cp++) + goto next; + } + if ((n = *dn++) == '\0' && *cp == '\0') + return (sp - msg); + if (n == '.') + continue; + goto next; + + default: /* illegal type */ + return (-1); + + case INDIR_MASK: /* indirection */ + cp = msg + (((n & 0x3f) << 8) | *cp); + } + } + if (*dn == '\0') + return (sp - msg); + next: ; + } + return (-1); +} + +/* + * Routines to insert/extract short/long's. Must account for byte + * order and non-alignment problems. This code at least has the + * advantage of being portable. + * + * used by sendmail. + */ + +u_short +_getshort(u_char *msgp) +{ + register u_char *p = (u_char *) msgp; + register u_short u; + + u = *p++ << 8; + return ((u_short)(u | *p)); +} + +u_long +_getlong(u_char *msgp) +{ + register u_char *p = (u_char *) msgp; + register u_long u; + + u = *p++; u <<= 8; + u |= *p++; u <<= 8; + u |= *p++; u <<= 8; + return (u | *p); +} + +void +putshort(u_short s, + u_char *msgp) +{ + + msgp[1] = s; + msgp[0] = s >> 8; +} + +void +putlong(u_long l, + u_char *msgp) +{ + + msgp[3] = l; + msgp[2] = (l >>= 8); + msgp[1] = (l >>= 8); + msgp[0] = l >> 8; +} diff --git a/res_init.c b/res_init.c new file mode 100644 index 0000000..f1e51aa --- /dev/null +++ b/res_init.c @@ -0,0 +1,50 @@ +#include +#include +#include +#include +#include "dns.h" +#include "tx.h" + +struct state _res = +{ + RES_TIMEOUT, /* retransmition time interval */ + 4, /* number of times to retransmit */ + RES_DEFAULT, /* options flags */ + 1, /* number of name servers */ +}; + +void +res_init() +{ + int i; + char *pch; + int nSearches; + char achAddresses[4]; + int aiAddresses[4]; + + memset(_res.nsaddr, 0, 4); + _res.nscount = 1; + + strncpy(_res.defdname, hostinfo.achDomainName, sizeof(_res.defdname)); + for (i = 0; i < MAXNS && i < hostinfo.nHosts; i++) + { + sscanf(hostinfo.aachHosts[i], "%d.%d.%d.%d", + &aiAddresses[0], + &aiAddresses[1], + &aiAddresses[2], + &aiAddresses[3]); + achAddresses[0] = aiAddresses[0]; + achAddresses[1] = aiAddresses[1]; + achAddresses[2] = aiAddresses[2]; + achAddresses[3] = aiAddresses[3]; + memcpy(&_res.nsaddr_list[i], + achAddresses, 4); + } + _res.nscount = i ? i : 1; + if (!_res.defdname[0]) + { + if ((pch = strchr(hostinfo.achHostName, '.')) != 0) + strcpy(_res.defdname, pch + 1); + } + _res.options |= RES_INIT; +} diff --git a/res_mkq.c b/res_mkq.c new file mode 100644 index 0000000..a6b9aaa --- /dev/null +++ b/res_mkq.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 1985 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)res_mkquery.c 6.12 (Berkeley) 6/1/90"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include "dns.h" +#include "twinsock.h" + +/* + * Form all types of queries. + * Returns the size of the result or -1. + */ +#pragma argsused +int +res_mkquery( int op, + char *dname, + int class, + int type, + char *data, + int datalen, + struct rrec *newrr, + char *buf, + int buflen) +{ + register HEADER *hp; + register char *cp; + register int n; + char *dnptrs[10], **dpp, **lastdnptr; + extern char *index(); + + /* + * Initialize header fields. + */ + if ((buf == NULL) || (buflen < sizeof(HEADER))) + return(-1); + memset(buf, 0, sizeof(HEADER)); + hp = (HEADER *) buf; + hp->id = htons(++_res.id); + hp->opcode = op; + hp->pr = 0; + hp->rd = 1; + hp->rcode = NOERROR; + cp = buf + sizeof(HEADER); + buflen -= sizeof(HEADER); + dpp = dnptrs; + *dpp++ = buf; + *dpp++ = NULL; + lastdnptr = dnptrs + sizeof(dnptrs)/sizeof(dnptrs[0]); + /* + * perform opcode specific processing + */ + switch (op) + { + case QUERY: + if ((buflen -= QFIXEDSZ) < 0) + return(-1); + if ((n = dn_comp((u_char *)dname, + (u_char *) cp, + buflen, + (u_char **) dnptrs, + (u_char **) lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + putshort(type, cp); + cp += sizeof(u_short); + putshort(class, cp); + cp += sizeof(u_short); + hp->qdcount = htons(1); + if (op == QUERY || data == NULL) + break; + /* + * Make an additional record for completion domain. + */ + buflen -= RRFIXEDSZ; + if ((n = dn_comp((u_char *) data, + (u_char *) cp, + buflen, + (u_char **) dnptrs, + (u_char **) lastdnptr)) < 0) + return (-1); + cp += n; + buflen -= n; + putshort(T_NULL, cp); + cp += sizeof(u_short); + putshort(class, cp); + cp += sizeof(u_short); + putlong(0, cp); + cp += sizeof(u_long); + putshort(0, cp); + cp += sizeof(u_short); + hp->arcount = htons(1); + break; + + case IQUERY: + /* + * Initialize answer section + */ + if (buflen < 1 + RRFIXEDSZ + datalen) + return (-1); + *cp++ = '\0'; /* no domain name */ + putshort(type, cp); + cp += sizeof(u_short); + putshort(class, cp); + cp += sizeof(u_short); + putlong(0, cp); + cp += sizeof(u_long); + putshort(datalen, cp); + cp += sizeof(u_short); + if (datalen) { + memcpy(cp, data, datalen); + cp += datalen; + } + hp->ancount = htons(1); + break; + } + return (cp - buf); +} + +#define host (*phost) +#define MAXADDRS (MAX_ALTERNATES - 1) +#define MAXALIASES (MAX_ALTERNATES - 1) + +typedef union +{ + long al; + char ac; +} align; + +struct hostent * +getanswer( querybuf *answer, + int anslen, + int iquery, + struct hostent *phost, /* The hostent */ + char *hostbuf, /* The buffer for host names */ + int buflen, /* The size of the host names buffer */ + char **h_addr_ptrs, /* The address list */ + char **host_aliases, /* The alias list */ + int *ph_errno /* Where do we store the error? */ + ) +{ + HEADER *hp; + u_char *cp; + int n; + u_char *eom; + char *bp, **ap; + int type, class, ancount, qdcount; + int haveanswer, getclass = C_ANY; + char **hap; + int hbufsize = buflen; + + eom = answer->buf + anslen; + /* + * find first satisfactory answer + */ + hp = &answer->hdr; + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + bp = hostbuf; + cp = answer->buf + sizeof(HEADER); + if (qdcount) + { + if (iquery) + { + if ((n = dn_expand((char *)answer->buf, eom, + cp, bp, buflen)) < 0) + { + *ph_errno = WSANO_RECOVERY; + return ((struct hostent *) NULL); + } + cp += n + QFIXEDSZ; + host.h_name = bp; + n = strlen(bp) + 1; + bp += n; + buflen -= n; + } + else + { + cp += dn_skipname(cp, eom) + QFIXEDSZ; + } + while (--qdcount > 0) + cp += dn_skipname(cp, eom) + QFIXEDSZ; + } + else if (iquery) + { + if (hp->aa) + *ph_errno = WSAHOST_NOT_FOUND; + else + *ph_errno = WSATRY_AGAIN; + return ((struct hostent *) NULL); + } + ap = host_aliases; + *ap = NULL; + host.h_aliases = host_aliases; + hap = h_addr_ptrs; + *hap = NULL; + host.h_addr_list = h_addr_ptrs; + haveanswer = 0; + while (--ancount >= 0 && cp < eom) + { + if ((n = dn_expand((char *)answer->buf, eom, cp, bp, buflen)) < 0) + break; + cp += n; + type = _getshort(cp); + cp += sizeof(u_short); + class = _getshort(cp); + cp += sizeof(u_short) + sizeof(u_long); + n = _getshort(cp); + cp += sizeof(u_short); + if (type == T_CNAME) + { + cp += n; + if (ap >= &host_aliases[MAXALIASES-1]) + continue; + *ap++ = bp; + n = strlen(bp) + 1; + bp += n; + buflen -= n; + continue; + } + if (iquery && type == T_PTR) + { + if ((n = dn_expand((char *)answer->buf, eom, + cp, bp, buflen)) < 0) + { + cp += n; + continue; + } + cp += n; + host.h_name = bp; + return(&host); + } + if (iquery || type != T_A) + { + cp += n; + continue; + } + if (haveanswer) + { + if (n != host.h_length) + { + cp += n; + continue; + } + if (class != getclass) + { + cp += n; + continue; + } + } + else + { + host.h_length = n; + getclass = class; + host.h_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; + if (!iquery) + { + host.h_name = bp; + bp += strlen(bp) + 1; + } + } + + bp += sizeof(align) - ((u_long)bp % sizeof(align)); + + if (bp + n >= &hostbuf[hbufsize]) + break; + memcpy(*hap++ = bp, (char *)cp, n); + bp +=n; + cp += n; + haveanswer++; + } + if (haveanswer) + { + *ap = NULL; + *hap = NULL; + return (&host); + } + else + { + *ph_errno = WSATRY_AGAIN; + return ((struct hostent *) NULL); + } +} + diff --git a/resolv.h b/resolv.h new file mode 100644 index 0000000..aae7475 --- /dev/null +++ b/resolv.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 1983, 1987, 1989 The Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that: (1) source distributions retain this entire copyright + * notice and comment, and (2) distributions including binaries display + * the following acknowledgement: ``This product includes software + * developed by the University of California, Berkeley and its contributors'' + * in the documentation or other materials provided with the distribution + * and in all advertising materials mentioning features or use of this + * software. 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 256 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ + /* Number of bytes of fixed size data in query structure */ +#define QFIXEDSZ 4 + /* number of bytes of fixed size data in resource record */ +#define RRFIXEDSZ 10 + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ + +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* connonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW -1 +#define CONV_BADFMT -2 +#define CONV_BADCKSUM -3 +#define CONV_BADBUFLEN -4 + +#ifndef BYTE_ORDER +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */ + +#define BYTE_ORDER LITTLE_ENDIAN + +#endif /* BYTE_ORDER */ + +/* + * Structure for query header, the order of the fields is machine and + * compiler dependent, in our case, the bits within a byte are assignd + * least significant first, while the order of transmition is most + * significant first. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + u_short id; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + u_char qr:1; /* response flag */ + u_char opcode:4; /* purpose of message */ + u_char aa:1; /* authoritive answer */ + u_char tc:1; /* truncated message */ + u_char rd:1; /* recursion desired */ + /* fields in fourth byte */ + u_char ra:1; /* recursion available */ + u_char pr:1; /* primary server required (non standard) */ + u_char unused:2; /* unused bits */ + u_char rcode:4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + u_char rd:1; /* recursion desired */ + u_char tc:1; /* truncated message */ + u_char aa:1; /* authoritive answer */ + u_char opcode:4; /* purpose of message */ + u_char qr:1; /* response flag */ + /* fields in fourth byte */ + u_char rcode:4; /* response code */ + u_char unused:2; /* unused bits */ + u_char pr:1; /* primary server required (non standard) */ + u_char ra:1; /* recursion available */ +#endif + /* remaining bytes */ + u_short qdcount; /* number of question entries */ + u_short ancount; /* number of answer entries */ + u_short nscount; /* number of authority entries */ + u_short arcount; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +/* + * Structure for passing resource records around. + */ +struct rrec { + short r_zone; /* zone number */ + short r_class; /* class number */ + short r_type; /* type number */ + u_long r_ttl; /* time to live */ + int r_size; /* size of data area */ + char *r_data; /* pointer to data */ +}; + +extern u_short _getshort(); +extern u_long _getlong(); + +/* + * Inline versions of get/put short/long. + * Pointer is advanced; we assume that both arguments + * are lvalues and will already be in registers. + * cp MUST be u_char *. + */ +#define GETSHORT(s, cp) { \ + (s) = *(cp)++ << 8; \ + (s) |= *(cp)++; \ +} + +#define GETLONG(l, cp) { \ + (l) = *(cp)++ << 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; (l) <<= 8; \ + (l) |= *(cp)++; \ +} + + +#define PUTSHORT(s, cp) { \ + *(cp)++ = (s) >> 8; \ + *(cp)++ = (s); \ +} + +/* + * Warning: PUTLONG destroys its first argument. + */ +#define PUTLONG(l, cp) { \ + (cp)[3] = l; \ + (cp)[2] = (l >>= 8); \ + (cp)[1] = (l >>= 8); \ + (cp)[0] = l >> 8; \ + (cp) += sizeof(u_long); \ +} +/* + * Global defines and variables for resolver stub. + */ + +#define MAXNS 3 /* max # name servers we'll track */ +#define MAXDFLSRCH 3 /* # default domain levels to try */ +#define MAXDNSRCH 6 /* max # default domain levels to try */ +#define LOCALDOMAINPARTS 2 /* min levels in name that is "local" */ + +#define RES_TIMEOUT 5 /* seconds between retries */ + +struct state +{ + int retrans; /* retransmition time interval */ + int retry; /* number of times to retransmit */ + long options; /* option flags - see below. */ + int nscount; /* number of name servers */ + struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */ +#define nsaddr nsaddr_list[0] /* for backward compatibility */ + u_short id; /* current packet id */ + char defdname[MAXDNAME]; /* default domain */ + char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ +}; + +#define RES_INIT 0x0001 /* address initialized */ +#define RES_DEBUG 0x0002 /* print debug messages */ +#define RES_AAONLY 0x0004 /* authoritative answers only */ +#define RES_USEVC 0x0008 /* use virtual circuit */ +#define RES_PRIMARY 0x0010 /* query primary server only */ +#define RES_IGNTC 0x0020 /* ignore trucation errors */ +#define RES_RECURSE 0x0040 /* recursion desired */ +#define RES_DEFNAMES 0x0080 /* use default domain name */ +#define RES_STAYOPEN 0x0100 /* Keep TCP socket open */ +#define RES_DNSRCH 0x0200 /* search up local domain tree */ + +#define RES_DEFAULT (RES_RECURSE | RES_DEFNAMES | RES_DNSRCH) + +extern struct state _res; + + + diff --git a/script.c b/script.c new file mode 100644 index 0000000..ed31089 --- /dev/null +++ b/script.c @@ -0,0 +1,431 @@ + +#include +#include +#include +#include +#include +#include +#include "script.h" + + +// static data & structures + +#define MAXTOKENLEN 80 +#define MAXLINELEN 120 +#define MAXSCRIPTLINES 40 + + +static HACCEL hAccel; + +static BOOL bRunningScript = FALSE, bEof = FALSE; +static int iScriptLine = 0, iScriptIndex = 0, iLineNum = 0; +static int iNextMenuId = 2000; +static FILE *fScriptFile; + +static char token[MAXTOKENLEN]; +static char input_line[MAXLINELEN], *input_line_p = 0; + +struct ScriptLine { char *out, *in; int time; }; + +struct Script +{ + char *name; + int accel, vkeys; // vkey is CONTROL|SHIFT|ALT + BOOL onsysmenu, disconnect, quitatend; + int menuid; + struct Script *next; + + struct ScriptLine *text; +}; + +static struct Script *RunningScript; +static struct Script *FirstScript = 0; + + +// procedures + +static void KillScriptTimeout(HWND hWnd) +{ + KillTimer(hWnd, TIMER_ID_SCRIPT); +} + +static void SetScriptTimeout(HWND hWnd, unsigned int seconds) +{ + KillScriptTimeout(hWnd); + if (seconds > 0) SetTimer(hWnd, TIMER_ID_SCRIPT, 1000U * seconds, 0); +} + +static void SendScriptLine(HWND hWnd) +{ + char *s = RunningScript->text[iScriptLine].out; + SendData(s, strlen(s)); + SetScriptTimeout(hWnd, RunningScript->text[iScriptLine].time); +} + +static void InterpolateMessage(char *msg) +{ + extern void SendToScreen(char c); + int i; + for (i=0; msg[i] != 0; i++) SendToScreen(msg[i]); +} + +static void StartScript(HWND hWnd, struct Script *script) +{ + RunningScript = script; + iScriptLine = iScriptIndex = 0; + bRunningScript = TRUE; + SendScriptLine(hWnd); +} + + +void CheckScripts(HWND hWnd, char c) +{ + char *s; + if (! bRunningScript) return; + s = RunningScript->text[iScriptLine].in; + if (c == s[iScriptIndex]) + { + iScriptIndex += 1; + if (iScriptIndex >= strlen(s)) + { + iScriptLine += 1; + iScriptIndex = 0; + SendScriptLine(hWnd); + if (RunningScript->text[iScriptLine].in == NULL) + { + bRunningScript = FALSE; + if (RunningScript->quitatend) PostQuitMessage(0); + } + } + } + else iScriptIndex = 0; +} + +void PerhapsKillScript(HWND hWnd) +{ + if (bRunningScript) + { + bRunningScript = FALSE; + KillScriptTimeout(hWnd); + InterpolateMessage("\r\n** Script Cancelled **\r\n"); + } +} + +void ScriptTimeOut(HWND hWnd) +{ + KillScriptTimeout(hWnd); + bRunningScript = FALSE; + MessageBeep(MB_ICONEXCLAMATION); + InterpolateMessage("\r\n** Script Timed Out **\r\n"); +} + +void CheckScriptSysCommands(HWND hWnd, WPARAM wParam, LPARAM lParam) +{ + struct Script *s; + for (s = FirstScript; s; s = s->next) { + if (s->onsysmenu && s->menuid == wParam) { + if (IsIconic(hWnd)) ShowWindow(hWnd, SW_RESTORE); + SendMessage(hWnd, WM_COMMAND, wParam, lParam); + break; + } + } +} + +BOOL CheckScriptCommands(HWND hWnd, WPARAM wParam, BOOL *bpTerminal) +{ + struct Script *s; + for (s = FirstScript; s; s = s->next) { + if (s->menuid == wParam) { + if (s->disconnect && ! *bpTerminal) { + Shutdown(); // changes bTerminal + SendData("\030\030\030\030\030", 5); + } + if (*bpTerminal) { + StartScript(hWnd, s); + } + return TRUE; + } + } + return FALSE; +} + +static BOOL compare_names(char *name, char *param) +{ + while (*name) { + while (*name == '&' || *name == ' ') name++; + if (tolower(*name) != tolower(*param)) return FALSE; + name++; + param++; + } + if (*param != 0) return FALSE; + return TRUE; +} + +static char *menu_name(char *buff, struct Script *s) +{ + char kn[10]; + strcpy(buff, s->name); + if (s->accel) { + strcat(buff, "\t"); + if (s->vkeys & 4) strcat(buff, "Ctrl+"); + if (s->vkeys & 2) strcat(buff, "Shift+"); + if (s->vkeys & 1) strcat(buff, "Alt+"); + strcat(buff, "F"); + sprintf(kn, "%d", s->accel); + strcat(buff, kn); + } + return buff; +} + +static BOOL ScriptError(char *s) +{ + char buff[80]; + sprintf(buff, "%s on line %d", s, iLineNum); + MessageBox(0, buff, "TwinSock Error", MB_ICONSTOP | MB_OK); + return FALSE; +} + +static BOOL Ignorable(char c) +{ + if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == ',') return TRUE; + return FALSE; +} + +static BOOL NextLine(void) +{ + while (1) { + if (! fgets(input_line, MAXLINELEN, fScriptFile)) { + bEof = TRUE; + return FALSE; + } + iLineNum++; + input_line_p = input_line; + if (! *input_line_p || *input_line_p == ';') continue; + return TRUE; + } +} + +static char ReadChar(void) +{ + if (*input_line_p != '\\') return *input_line_p; + input_line_p++; + if (! *input_line_p) { input_line_p--; return 0; } + switch (*input_line_p) { + default: return *input_line_p; + case 'r': return '\r'; + case 'n': return '\n'; + case 'b': return '\b'; + case 't': return '\t'; + case 'f': return '\f'; + case 'a': return '\a'; + case 'e': return '\033'; + } +} + +static BOOL ReadToken(BOOL quoted) +{ + int i = 0; + while (1) { + if (! *input_line_p) { + if (quoted) return ScriptError("Unterminated string in script file"); + break; + } + if (quoted ? *input_line_p == '"' : Ignorable(*input_line_p)) break; + if (i >= MAXTOKENLEN) return ScriptError("String too long in script file"); + token[i] = ReadChar(); + input_line_p++; + i++; + } + token[i] = 0; + if (*input_line_p) input_line_p++; + return TRUE; +} + +static BOOL NextToken(void) +{ + while (1) { + while (*input_line_p && Ignorable(*input_line_p)) input_line_p++; + if (*input_line_p) break; + if (! NextLine()) return FALSE; + } + if (*input_line_p == '"') { + input_line_p++; + return ReadToken(TRUE); + } + else return ReadToken(FALSE); +} + +static BOOL OpenScriptFile(void) +{ + char filename[MAXPATH]; + GetPrivateProfileString("Config", "Scripts", "", filename, MAXPATH, "TWINSOCK.INI"); + if (filename[0] == 0) return FALSE; + fScriptFile = fopen(filename, "rt"); + if (fScriptFile == NULL) return ScriptError("Could not open script file"); + if (! NextLine()) return ScriptError("Script file is empty"); + if (! NextToken()) return ScriptError("No scripts in script file"); + return TRUE; +} + +static BOOL ReadIntError(char *s, char *fieldname) +{ + char buff[80]; + sprintf(buff, "%s field is %s", fieldname, s); + return ScriptError(buff); +} + +static BOOL read_int(int *v, int min, int max, char *fieldname) +{ + int i; + if (token[0] == 0) return ReadIntError("empty", fieldname); + for (i=0; token[i]; i++) if (token[i] < '0' || token[i] > '9') return ReadIntError("non-numeric", fieldname); + *v = atoi(token); + if (*v < min || *v > max) return ReadIntError("out of range", fieldname); + return TRUE; +} + +static void BuildScript(struct Script *scripthdr, struct ScriptLine *scriptlines, int nlines) +{ + struct Script *newscript; + int i; + + newscript = (struct Script*)malloc(sizeof(struct Script)); + *newscript = *scripthdr; + newscript->menuid = iNextMenuId++; + newscript->text = (struct ScriptLine*)malloc((nlines+1)*sizeof(struct ScriptLine)); + for (i=0; itext[i] = scriptlines[i]; + newscript->text[nlines].out = strdup(""); + newscript->text[nlines].in = 0; + newscript->text[nlines].time = 0; + newscript->next = 0; + if (FirstScript == 0) FirstScript = newscript; + else RunningScript->next = newscript; + RunningScript = newscript; + +} + +static BOOL ReadOneScript(void) +{ + struct Script temp_script; + struct ScriptLine temp_lines[MAXSCRIPTLINES]; + int nlines = 0; + + if (stricmp(token, "script") != 0) return ScriptError("Scripts must start with 'script' keyword"); + if (! NextToken()) goto PREMATURE_END; + temp_script.name = strdup(token); + if (! NextToken()) goto PREMATURE_END; + if (! read_int(&temp_script.accel, 0, 12, "Accelerator key")) return FALSE; + if (! NextToken()) goto PREMATURE_END; + if (! read_int(&temp_script.vkeys, 0, 7, "Accelerator shifts")) return FALSE; + if (! NextToken()) goto PREMATURE_END; + if (! read_int(&temp_script.onsysmenu, 0, 1, "System-menu-flag")) return FALSE; + if (! NextToken()) goto PREMATURE_END; + if (! read_int(&temp_script.disconnect, 0, 1, "Disconnect-flag")) return FALSE; + if (! NextToken()) goto PREMATURE_END; + if (! read_int(&temp_script.quitatend, 0, 1, "Quit-flag")) return FALSE; + if (! NextToken()) goto PREMATURE_END; + if (stricmp(token, "script") == 0) goto PREMATURE_END; + while (1) { + if (strcmp(token, "-") == 0) token[0] = 0; + temp_lines[nlines].out = strdup(token); + temp_lines[nlines].in = 0; + temp_lines[nlines].time = 0; + if (! NextToken() || stricmp(token, "script") == 0) break; + + if (strcmp(token, "-") == 0) token[0] = 0; + temp_lines[nlines].in = strdup(token); + if (! NextToken() || stricmp(token, "script") == 0) break; + + if (! read_int(&temp_lines[nlines].time, 0, 64, "Time-out")) return FALSE; + if (! NextToken() || stricmp(token, "script") == 0) break; + nlines++; + if (nlines >= MAXSCRIPTLINES) return ScriptError("Too many lines in script"); + } + BuildScript(&temp_script, temp_lines, ++nlines); + return ! bEof; +PREMATURE_END: + return ScriptError("Premature EOF in script file"); +} + +static void ReadScriptFile(void) +{ + if (! OpenScriptFile()) return; + while (1) { + if (! ReadOneScript()) break; // error or eof + } + fclose(fScriptFile); +} + +void ConfigureScripts(HINSTANCE hInstance, HWND hWnd, LPSTR lpCmdLine) +{ + HMENU hScriptMenu, hSysMenu = 0; + char buff[80]; + struct Script *s; + + hAccel = LoadAccelerators(hInstance, "TS_ACCELS"); + ReadScriptFile(); + hScriptMenu = CreateMenu(); + for (s = FirstScript; s; s = s->next) { + AppendMenu(hScriptMenu, MF_STRING, s->menuid, menu_name(buff, s)); + if (s->onsysmenu) { + if (hSysMenu == 0) { + hSysMenu = GetSystemMenu(hWnd, FALSE); + AppendMenu(hSysMenu, MF_SEPARATOR, 0, 0); + } + AppendMenu(hSysMenu, MF_STRING, s->menuid, menu_name(buff, s)); + } + } + AppendMenu(GetMenu(hWnd), MF_POPUP, (UINT) hScriptMenu, "S&cripts"); + DrawMenuBar(hWnd); + if (lpCmdLine && *lpCmdLine) { + char buff[80]; + for (s = FirstScript; s; s = s->next) { + if (compare_names(s->name, lpCmdLine)) { + StartScript(hWnd, s); + return; + } + } + sprintf(buff, "Can't find script '%s'", lpCmdLine); + MessageBox(hWnd, buff, "TwinSock Error", MB_ICONSTOP | MB_OK); + } +} + +void TerminateScripts() +{ + struct Script *s; + for (s = FirstScript; s; s = s->next) { +// free(s->name); + } +} + +static void ActivateMenuItem(HWND hWnd, WORD wID) +{ + HiliteMenuItem(hWnd, GetMenu(hWnd), wID, MF_BYCOMMAND | MF_HILITE); + SendMessage(hWnd, WM_COMMAND, wID, 0L); + HiliteMenuItem(hWnd, GetMenu(hWnd), wID, MF_BYCOMMAND | MF_UNHILITE); +} + +BOOL CustomTranslateAccelerator(HWND hWnd, MSG *msg) +{ + if (msg->message == WM_KEYDOWN || msg->message == WM_SYSKEYDOWN) { + char ks = -1; + struct Script *s; + for (s = FirstScript; s; s = s->next) { + if (s->accel && msg->wParam == VK_F1-1 + s->accel) { + if (ks == -1) { + ks = 0; + if ((UINT)GetKeyState(VK_CONTROL) & 0x1000) ks |= 4; + if ((UINT)GetKeyState(VK_SHIFT) & 0x1000) ks |= 2; + if ((UINT)GetKeyState(VK_MENU) & 0x1000) ks |= 1; + } + if (s->vkeys == ks) { + ActivateMenuItem(hWnd, s->menuid); + return TRUE; + } + } + } + } + if (hAccel) return TranslateAccelerator(hWnd, hAccel, msg); + return FALSE; +} + diff --git a/script.h b/script.h new file mode 100644 index 0000000..b5472dc --- /dev/null +++ b/script.h @@ -0,0 +1,15 @@ + +#define TIMER_ID_SCRIPT 6 + +void CheckScripts(HWND hWnd, char c); +void ScriptTimeOut(HWND hWnd); +void PerhapsKillScript(HWND hWnd); +void CheckScriptSysCommands(HWND hWnd, WPARAM wParam, LPARAM lParam); +BOOL CheckScriptCommands(HWND hWnd, WPARAM wParam, BOOL *bpTerminal); +void ConfigureScripts(HINSTANCE hInstance, HWND hWnd, LPSTR lpCmdLine); +void TerminateScripts(); +BOOL CustomTranslateAccelerator(HWND hwnd, MSG *msg); + +int SendData(void *pvData, int iDataLen); // from twinsock.c +void Shutdown(void); + diff --git a/sockinfo.c b/sockinfo.c new file mode 100644 index 0000000..5ce4ee1 --- /dev/null +++ b/sockinfo.c @@ -0,0 +1,156 @@ +/* + * TwinSock - "Troy's Windows Sockets" + * + * Copyright (C) 1994 Troy Rollo + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the license in the file LICENSE.TXT included + * with the TwinSock distribution. + * + * 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. + */ + +#include +#include +#include +#include +#include "sockinfo.h" +#include "tx.h" + +tws_sockinfo *psiList = 0; + +void +AddSocketEntry(int iClient, int iServer) +{ + tws_sockinfo *psi; + + psi = (tws_sockinfo *) malloc(sizeof(tws_sockinfo)); + psi->iClientSocket = iClient; + psi->iServerSocket = iServer; + psi->pdata = 0; + psi->psiNext = psiList; + psi->ptxrConnect = 0; + psiList = psi; + return; +} + +int +GetClientFromServer(int iServer) +{ + tws_sockinfo *psi; + + for (psi = psiList; psi; psi = psi->psiNext) + if (psi->iServerSocket == iServer) + return psi->iClientSocket; + return -1; +} + +int +GetServerFromClient(int iClient) +{ + tws_sockinfo *psi; + + for (psi = psiList; psi; psi = psi->psiNext) + if (psi->iClientSocket == iClient) + return psi->iServerSocket; + return -1; +} + + +tws_sockinfo * +FindSocketEntry(int iServer) +{ + tws_sockinfo *psi; + + for (psi = psiList; psi; psi = psi->psiNext) + if (psi->iServerSocket == iServer) + return psi; + return 0; +} + +void +ReleaseSocketEntry(int iClient) +{ + tws_sockinfo **ppsi, *psi; + + for (ppsi = &psiList; *ppsi; ppsi = &(*ppsi)->psiNext) + { + if ((*ppsi)->iClientSocket == iClient) + { + tws_data *pdata; + + psi = (*ppsi)->psiNext; + if ((*ppsi)->ptxrConnect) + free((*ppsi)->ptxrConnect); + while ((*ppsi)->pdata) + { + pdata = (*ppsi)->pdata; + (*ppsi)->pdata = pdata->pdataNext; + free(pdata->pchData); + free(pdata); + } + free(*ppsi); + *ppsi = psi; + return; + } + } +} + + +void +QueueConnectWait(int iSocket, + struct tx_request *ptxr_) +{ + tws_sockinfo *psi = FindSocketEntry(iSocket); + + if (psi) + { + int iBytes = ntohs(ptxr_->nLen); + struct tx_request *ptxr = (struct tx_request *) malloc(iBytes); + + memcpy(ptxr, ptxr_, iBytes); + psi->ptxrConnect = ptxr; + } + else + { + } +} + + +void +QueueSendRequest( int iServerSocket, + char *pchData, + int iBytes, + int iFlags, + struct sockaddr_in *psin) +{ + tws_data *pdata, **ppdata; + tws_sockinfo *psi = FindSocketEntry(iServerSocket); + + if (!psi) + return; + pdata = (tws_data *) malloc(sizeof(tws_data)); + pdata->pchData = (char *) malloc(iBytes); + memcpy(pdata->pchData, pchData, iBytes); + pdata->nBytes = iBytes; + pdata->iLoc = 0; + pdata->pdataNext = 0; + pdata->iFlags = iFlags; + if (psin) + { + pdata->sinDest = *psin; + pdata->bTo = 1; + } + else + { + pdata->bTo = 0; + } + for (ppdata = &psi->pdata; + *ppdata; + ppdata = &(*ppdata)->pdataNext); + *ppdata = pdata; + if (psi->pdata == pdata) + WriteSocketData(psi); +} diff --git a/sockinfo.h b/sockinfo.h new file mode 100644 index 0000000..dc858ba --- /dev/null +++ b/sockinfo.h @@ -0,0 +1,65 @@ +#ifndef __SOCKINFO_H +#define __SOCKINFO_H + +/* This file defines the structures mapping sockets numbers. + * In order to allow the socket() call to succeed immediately, + * the WINSOCK.DLL assigns its idea of the socket number, sends + * the request off in the background, and returns immediately. + * + * TWINSOCK.EXE then receives it, and stores WINSOCK.DLL's idea + * of the socket number in iClientSocket, and its own idea in + * iServerSocket. It then uses iServerSocket in its communications + * with the tshost. + * + * tshost receives the socket number, and stores it in iClientSocket. + * It then makes the socket() call and places the results in + * iServerSocket. The socket() call no longer passes its results + * back. If it fails, subsequent attempts to use the socket will + * be failed with different values depending on the nature of the + * call. + * + * The host component also maintains a list of data waiting to + * be sent to the socket, so it can send without blocking. + * The select() loop then has to let us know when the socket + * is ready. + * + * for accept() calls, the server assigns the client side, so + * the whole thing works backwards. This has the potential to + * result in collisions. This is fixed by assigning all sockets + * with bit 0 set to the server side, and all with bit 0 clear + * to the client side. + */ + +typedef struct __tws_data +{ + char *pchData; + int nBytes; + int iLoc; + struct sockaddr_in sinDest; + int iFlags; + int bTo; /* sendto or send? */ + struct __tws_data *pdataNext; +} tws_data; + +typedef struct __tws_sockinfo +{ + int iClientSocket; + int iServerSocket; + tws_data *pdata; + struct tx_request *ptxrConnect; + struct __tws_sockinfo *psiNext; +} tws_sockinfo; + +extern int GetClientSocket(void); +extern int GetServerSocket(void); +extern void ReleaseClientSocket(int iSocket); +extern void ReleaseServerSocket(int iSocket); +#ifndef __Windows +extern tws_sockinfo *FindClientSocket(int iClient); +extern tws_sockinfo *FindServerSocket(int iServer); +extern tws_sockinfo *FindSocketEntry(int iServer); +#endif + +extern int HasSocketArg(enum Functions fn); + +#endif diff --git a/tshost.c b/tshost.c index aedd476..2d3bb99 100644 --- a/tshost.c +++ b/tshost.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #ifdef NEED_SELECT_H @@ -22,6 +23,7 @@ #endif #include "twinsock.h" #include "tx.h" +#include "sockinfo.h" extern enum Encoding eLine; @@ -31,6 +33,7 @@ extern void PacketTransmitData(void *pvData, int iDataLen, int iStream); static fd_set fdsActive; static fd_set fdsListener; +static fd_set fdsWriting; static int nLargestFD; static char achBuffer[BUFFER_SIZE]; static int bFlushing = 0; @@ -38,8 +41,13 @@ void FlushInput(void); int GetNextExpiry(struct timeval *ptvValue); void CheckTimers(void); +void WriteSocketData(tws_sockinfo *psi); extern char *sys_errlist[]; +static int nHosts = 0; +static char achDomain[256] = ""; +static char aachHosts[4][30]; + #define TIMER_ID_SEND 0 #define TIMER_ID_RECEIVE 1 #define TIMER_ID_FLUSH 2 @@ -56,12 +64,68 @@ int SetListener(int iValue) FD_SET(iValue, &fdsListener); } +int SetWriter(int iValue) +{ + if (iValue > nLargestFD) + nLargestFD = iValue; + FD_SET(iValue, &fdsWriting); +} + int SetClosed(int iValue) { FD_CLR(iValue, &fdsListener); FD_CLR(iValue, &fdsActive); + FD_CLR(iValue, &fdsWriting); } +void +read_resolver(void) +{ + FILE *fp; + char achInput[80]; + char *pchIn, *pchOut; + + fp = fopen("/etc/resolv.conf", "r"); + if (!fp) + { + fp = fopen("/usr/etc/resolv.conf", "r"); + if (!fp) + return; + } + while (fgets(achInput, 80, fp)) + { + if (achInput[strlen(achInput) - 1] == '\n') + achInput[strlen(achInput) - 1] = 0; + pchIn = achInput; + while (isspace(*pchIn)) + pchIn++; + if (!strncmp(pchIn, "domain", 6)) + { + pchIn += 6; + while (isspace(*pchIn)) + pchIn++; + pchOut = achDomain; + while (*pchIn && !isspace(*pchIn)) + *pchOut++ = *pchIn++; + *pchOut = 0; + } + else if (!strncmp(pchIn, "nameserver", 10) && nHosts < 4) + { + pchIn += 10; + while (isspace(*pchIn)) + pchIn++; + pchOut = aachHosts[nHosts]; + while (*pchIn && !isspace(*pchIn)) + *pchOut++ = *pchIn++; + *pchOut = 0; + nHosts++; + } + } + fclose(fp); +} + +static char achHostName[256]; + main(int argc, char **argv) { fd_set fdsRead, fdsWrite, fdsExcept, fdsDummy; @@ -111,7 +175,8 @@ main(int argc, char **argv) } } - fprintf(stderr, "TwinSock Host 1.4\n"); + read_resolver(); + fprintf(stderr, "TwinSock Host 2.0\n"); fprintf(stderr, "Copyright 1994-1995 Troy Rollo\n"); fprintf(stderr, "This program is free software\n"); fprintf(stderr, "See the file COPYING for details\n"); @@ -121,19 +186,26 @@ main(int argc, char **argv) InitTerm(); InitProtocol(); - fprintf(stdout, "!@$TSStart%d$@", (int) eLine); + *achHostName = 0; + gethostname(achHostName, 256); + fprintf(stdout, "!@$TSStart%d:%s", (int) eLine, achHostName); + fprintf(stdout, "#%s", achDomain); + for ( i = 0; i < nHosts; i++) + fprintf(stdout, "*%s", aachHosts[i]); + fprintf(stdout, "$@"); fflush(stdout); nLargestFD = 0; FD_ZERO(&fdsActive); - FD_ZERO(&fdsWrite); FD_ZERO(&fdsExcept); + FD_ZERO(&fdsWriting); FD_SET(0, &fdsActive); while(1) { fdsRead = fdsActive; + fdsWrite = fdsWriting; iResult = select(nLargestFD + 1, &fdsRead, &fdsWrite, @@ -159,6 +231,18 @@ main(int argc, char **argv) } for (i = 3; i <= nLargestFD; i++) { + if (FD_ISSET(i, &fdsWrite)) + { + tws_sockinfo *psi; + + FD_CLR(i, &fdsWriting); + psi = FindSocketEntry(i); + if (!psi) + continue; + if (psi->ptxrConnect) + FinishConnect(psi); + WriteSocketData(psi); + } if (FD_ISSET(i, &fdsRead)) { FD_ZERO(&fdsDummy); @@ -174,14 +258,18 @@ main(int argc, char **argv) nSourceLen = sizeof(saSource); if (FD_ISSET(i, &fdsListener)) { + int iClient; + s = accept(i, &saSource, &nSourceLen); if (s == -1) continue; - s = htonl(s); + iClient = GetServerSocket(); + AddSocketEntry(iClient, s); BumpLargestFD(s); - SendSocketData(i, + s = htonl(iClient); + SendSocketData(GetClientFromServer(i), &s, sizeof(s), &saSource, @@ -200,11 +288,11 @@ main(int argc, char **argv) errno == ENOTCONN) { /* Was a datagram socket */ - SetClosed(i); + FD_CLR(i, &fdsActive); continue; } if (nRead >= 0) - SendSocketData(i, + SendSocketData(GetClientFromServer(i), achBuffer, nRead, &saSource, @@ -463,4 +551,49 @@ DataReceived(void *pvData, int iLen) } } } - \ No newline at end of file + +void +WriteSocketData(tws_sockinfo *psi) +{ + int iResult; + + if (!psi->pdata) + return; + if (psi->pdata->bTo) + { + iResult = sendto(psi->iServerSocket, + psi->pdata->pchData + psi->pdata->iLoc, + psi->pdata->nBytes - psi->pdata->iLoc, + psi->pdata->iFlags, + (struct sockaddr *) &psi->pdata->sinDest, + sizeof(struct sockaddr_in)); + } + else + { + iResult = sendto(psi->iServerSocket, + psi->pdata->pchData + psi->pdata->iLoc, + psi->pdata->nBytes - psi->pdata->iLoc, + psi->pdata->iFlags); + } + if (iResult >= 0) + { + tws_data *pdata = psi->pdata; + + pdata->iLoc += iResult; + if (pdata->iLoc == pdata->nBytes) + { + psi->pdata = pdata->pdataNext; + free(pdata->pchData); + free(pdata); + } + } + else + { + if (errno != EWOULDBLOCK && + errno != EINTR && + errno != EAGAIN) + return; /* The socket is dead */ + } + if (psi->pdata) + FD_SET(psi->iServerSocket, &fdsWriting); +} diff --git a/twinsock.c b/twinsock.c index e0d8680..9c2577f 100644 --- a/twinsock.c +++ b/twinsock.c @@ -13,20 +13,46 @@ */ #include +#include #include #include +#include #include "twinsock.h" #include "tx.h" +#include "script.h" +#include "sockinfo.h" + +typedef struct __tws_request +{ + short idRequest; + long iSender; + short idSenderRequest; + struct __tws_request *prqNext; +} tws_request; + +typedef struct __tws_socket +{ + tws_sockinfo si; + long iOwner; + struct __tws_socket *psckNext; +} tws_socket; + +short iRequestOut = 0; + +tws_request *prqList = 0; +tws_request **pprqTail = &prqList; +tws_socket *psckList = 0; +tws_socket **ppsckTail = &psckList; HINSTANCE hinst; +static BOOL bUseNotify = TRUE; -extern far pascal RegisterManager(HWND hwnd); -extern far pascal ResponseReceived(struct tx_request *ptxr); -extern far pascal SetInitialised(void); static void SendInitRequest(void); void Shutdown(void); void OpenPort(void); +BOOL ResolvEdit(HWND hwndParent); extern int iPortChanged; +static int iBufferSize; #define READ_MAX 1024 #define TIMER_ID_SEND 1 @@ -34,8 +60,16 @@ extern int iPortChanged; #define TIMER_ID_FLUSH 3 #define TIMER_ID_BREAK 4 #define TIMER_ID_COMMCHECK 5 +#define TIMER_ID_SCRIPT 6 + +#define READ_COMPLETED (WM_USER + 1000) +#define WRITE_COMPLETED (WM_USER + 1001) +#ifdef __FLAT__ +static HANDLE idComm; +#else static int idComm; +#endif static HWND hwnd; static BOOL bFlushing = FALSE; static BOOL bTerminal = TRUE; @@ -52,9 +86,80 @@ static char const achProtoInit[] = "@$TSStart$@"; extern enum Encoding eLine; static int iInitChar = 0; +static char *pchCollect = 0; +static char *pchCollEnd = 0; long nDiscarded = 0; long nBytesRecvd = 0; + +#ifdef __FLAT__ +char * +GetLastErrorText(void) +{ + char *pchError; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + 0, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &pchError, + 0, 0); + return pchError; +} +#endif + +u_short CALLBACK htons (u_short hostshort) +{ + char *pchValue = (char *) &hostshort; + char c; + + c = pchValue[0]; + pchValue[0] = pchValue[1]; + pchValue[1] = c; + return hostshort; +} + +u_long CALLBACK htonl (u_long hostlong) +{ + char *pchValue = (char *) &hostlong; + char c; + + c = pchValue[0]; + pchValue[0] = pchValue[3]; + pchValue[3] = c; + c = pchValue[1]; + pchValue[1] = pchValue[2]; + pchValue[2] = c; + return hostlong; +} + +u_short CALLBACK ntohs (u_short netshort) +{ + char *pchValue = (char *) &netshort; + char c; + + c = pchValue[0]; + pchValue[0] = pchValue[1]; + pchValue[1] = c; + return netshort; +} + +u_long CALLBACK ntohl (u_long netlong) +{ + char *pchValue = (char *) &netlong; + char c; + + c = pchValue[0]; + pchValue[0] = pchValue[3]; + pchValue[3] = c; + c = pchValue[1]; + pchValue[1] = pchValue[2]; + pchValue[2] = c; + return netlong; +} + extern void PacketReceiveData(void *pvData, int iLen); void SetTransmitTimeout(void) @@ -86,7 +191,7 @@ void FlushInput(void) SetTimer(hwnd, TIMER_ID_FLUSH, 1500, 0); } -static void +void SendToScreen(char c) { @@ -132,18 +237,102 @@ SendToScreen(char c) } } +static void +WriteToScreen(char *pch, int iBytes) +{ + while (iBytes--) + SendToScreen(*pch++); +} + +static void +FillResolverInfo(void) +{ + static char achBuffer[256]; + + GetTwinSockSetting("Resolver", "Override", "0", achBuffer, sizeof(achBuffer)); + if (*hostinfo.achDomainName && + hostinfo.nHosts && + achBuffer[0] == '0') + return; + + GetTwinSockSetting("Resolver", "Domain", "", achBuffer, sizeof(achBuffer)); + if (*achBuffer) + strcpy(hostinfo.achDomainName, achBuffer); + else if (!hostinfo.achDomainName) + strcpy(hostinfo.achDomainName, "no-domain-specified"); + + GetTwinSockSetting("Resolver", "Server1", "", achBuffer, sizeof(achBuffer)); + if (*achBuffer) + { + strcpy(hostinfo.aachHosts[0], achBuffer); + hostinfo.nHosts = 1; + } + else + { + if (!hostinfo.nHosts) + { + strcpy(hostinfo.aachHosts[0], "127.0.0.1"); + hostinfo.nHosts++; + } + return; + } + + GetTwinSockSetting("Resolver", "Server2", "", achBuffer, sizeof(achBuffer)); + if (*achBuffer) + { + strcpy(hostinfo.aachHosts[1], achBuffer); + hostinfo.nHosts = 2; + } + else + { + return; + } + + GetTwinSockSetting("Resolver", "Server3", "", achBuffer, sizeof(achBuffer)); + if (*achBuffer) + { + strcpy(hostinfo.aachHosts[2], achBuffer); + hostinfo.nHosts = 3; + } + else + { + return; + } +} + static void AddChar(char c) { + static BOOL bStillCollect = FALSE; + SendToScreen(c); - if (c == achProtoInit[iInitChar]) + if (pchCollect && + pchCollect != pchCollEnd && + c != ':' && c != '#' && c != '*' && c != '$' && c != '@') + { + *pchCollect++ = c; + *pchCollect = 0; + bStillCollect = TRUE; + return; + } + else if (c == achProtoInit[iInitChar]) { iInitChar++; if (iInitChar == strlen(achProtoInit)) { + FillResolverInfo(); + if (*hostinfo.achHostName && + !strchr(hostinfo.achHostName, '.')) + { + strcat(hostinfo.achHostName, "."); + strcat(hostinfo.achHostName, + hostinfo.achDomainName); + } + WriteToScreen("\r\nStarting Protocol, host=", 27); + WriteToScreen(hostinfo.achHostName, strlen(hostinfo.achHostName)); + WriteToScreen("\r\n", 2); iInitChar = 0; bTerminal = 0; - RegisterManager(hwnd); InitProtocol(); SendInitRequest(); } @@ -152,13 +341,98 @@ AddChar(char c) { eLine = (enum Encoding) (c - '0'); } + else if (iInitChar == 9 && c == '#') + { + pchCollect = hostinfo.achDomainName; + pchCollEnd = pchCollect + sizeof(hostinfo.achDomainName) - 1; + bStillCollect = TRUE; + } + else if (iInitChar == 9 && c == ':') + { + pchCollect = hostinfo.achHostName; + pchCollEnd = pchCollect + sizeof(hostinfo.achHostName) - 1; + bStillCollect = TRUE; + } + else if (iInitChar == 9 && c == '*' && hostinfo.nHosts < 4) + { + pchCollect = hostinfo.aachHosts[hostinfo.nHosts++]; + pchCollEnd = pchCollect + sizeof(hostinfo.aachHosts[0]) - 1; + bStillCollect = TRUE; + } else if (iInitChar) { iInitChar = 0; eLine = E_6Bit; } + if (!bStillCollect) + pchCollect = 0; + CheckScripts(hwnd, c); +} + +static void +ProcessReceivedData(char *pchBuffer, + int nRead) +{ + int i; + + if (bTerminal) + { + HideCaret(hwnd); + for (i = 0; i < nRead; i++) + AddChar(pchBuffer[i]); + SetCaretPos(iColumn * cxColumn, iRow * cyRow); + ShowCaret(hwnd); + } + else if (bFlushing) + { + nDiscarded += nRead; + FlushInput(); + } + else + { + nBytesRecvd += nRead; + PacketReceiveData(pchBuffer, nRead); + } +} + +#ifdef __FLAT__ +static char achReadBuffer[2048]; +static DWORD dwRead; +static DWORD dwWrite; +static OVERLAPPED olRead; +static OVERLAPPED olWrite; +static HANDLE heventRead = 0; +static HANDLE heventWrite = 0; +static void PrepareToRead(void); + +#pragma argsused +static void +ReceiveCompleted(void) +{ + ProcessReceivedData(achReadBuffer, (int) dwRead); + PrepareToRead(); +} + +static void +PrepareToRead(void) +{ + olRead.Internal = olRead.InternalHigh = olRead.Offset = olRead.OffsetHigh = 0; + olRead.hEvent = heventRead; + while (ReadFile(idComm, + achReadBuffer, sizeof(achReadBuffer), + &dwRead, &olRead)); + + if (GetLastError() != ERROR_IO_PENDING) + { + char *pchError = GetLastErrorText(); + + MessageBox(hwnd, pchError, "Fatal error reading communications port", MB_OK); + if (pchError) + LocalFree(pchError); + } } +#else static void DoReading(void) { static char achBuffer[READ_MAX]; @@ -180,29 +454,102 @@ static void DoReading(void) } if (nRead) { - if (bTerminal) - { - HideCaret(hwnd); - for (i = 0; i < nRead; i++) - AddChar(achBuffer[i]); - SetCaretPos(iColumn * cxColumn, iRow * cyRow); - ShowCaret(hwnd); - } - else if (bFlushing) - { - nDiscarded += nRead; - FlushInput(); - } - else - { - nBytesRecvd += nRead; - PacketReceiveData(achBuffer, nRead); - } + ProcessReceivedData(achBuffer, nRead); } } while (nRead || cs.cbInQue); bAlreadyHere = FALSE; } +#endif + +#ifdef __FLAT__ + +typedef struct __tws_outdata +{ + char *pchWrite; + int nWrite; + struct __tws_outdata *podNext; +} tws_outdata; + +static tws_outdata *podList = 0, **ppodTail = &podList; +static BOOL bWaiting = FALSE; + +void +AddToDataQueue(void *pvData, int iDataLen) +{ + tws_outdata *podNow = (tws_outdata *) malloc(sizeof(tws_outdata)); + + *ppodTail = podNow; + ppodTail = &podNow->podNext; + podNow->pchWrite = (char *) malloc(iDataLen); + memcpy(podNow->pchWrite, pvData, iDataLen); + podNow->nWrite = iDataLen; + podNow->podNext = 0; +} + +#pragma argsused +void WINAPI +SendCompleted( void) +{ + tws_outdata *pod; + + while (podList) + { + pod = podList; + podList = podList->podNext; + if (!podList) + ppodTail = &podList; + olWrite.Internal = olWrite.InternalHigh = olWrite.Offset = olWrite.OffsetHigh = 0; + olWrite.hEvent = heventWrite; + if (!WriteFile(idComm, pod->pchWrite, pod->nWrite, &dwWrite, &olWrite)) + { + if (GetLastError() != ERROR_IO_PENDING) + { + char *pchError = GetLastErrorText(); + MessageBox(hwnd, pchError, "Fatal error writing communications port", MB_OK); + if (pchError) + LocalFree(pchError); + } + free(pod->pchWrite); + free(pod); + return; + } + free(pod->pchWrite); + free(pod); + } + bWaiting = FALSE; +} + +int SendData(void *pvData, int iDataLen) +{ + if (bFlushing) + return iDataLen; /* Lie */ + if (bWaiting) + { + AddToDataQueue(pvData, iDataLen); + return iDataLen; + } + olWrite.Internal = olWrite.InternalHigh = olWrite.Offset = olWrite.OffsetHigh = 0; + olWrite.hEvent = heventWrite; + if (!WriteFile(idComm, pvData, iDataLen, &dwWrite, &olWrite)) + { + if (GetLastError() != ERROR_IO_PENDING) + { + char *pchError = GetLastErrorText(); + + MessageBox(hwnd, pchError, "Fatal error writing communications port", MB_OK); + if (pchError) + LocalFree(pchError); + } + else + { + bWaiting = TRUE; + } + } + return iDataLen; +} + +#else int SendData(void *pvData, int iDataLen) { int nWritten; @@ -214,6 +561,12 @@ int SendData(void *pvData, int iDataLen) iLen = iDataLen; do { + /* If the write would overflow the buffer, pretend we wrote it OK + * and return immediately + */ + GetCommError(idComm, &cs); + if (cs.cbOutQue + iLen >= iBufferSize) + return iDataLen; nWritten = WriteComm(idComm, pvData, iLen); if (nWritten < 0) { @@ -225,6 +578,67 @@ int SendData(void *pvData, int iDataLen) } while (iLen); return iDataLen; } +#endif + +#ifdef __FLAT__ + +static HANDLE hThread = 0; +static DWORD dwThreadID; + +#pragma argsused +DWORD +CommsReader(LPDWORD lpdwParam) +{ + DWORD dwEvents; + HANDLE ahEvents[2]; + + ahEvents[0] = heventRead; + ahEvents[1] = heventWrite; + while (1) + { + switch(WaitForMultipleObjects(2, ahEvents, FALSE, INFINITE)) + { + case WAIT_OBJECT_0: + GetOverlappedResult(idComm, &olRead, &dwRead, TRUE); + ResetEvent(heventRead); + PostMessage(hwnd, READ_COMPLETED, 0, 0); + break; + + case WAIT_OBJECT_0 + 1: + GetOverlappedResult(idComm, &olWrite, &dwWrite, TRUE); + ResetEvent(heventWrite); + PostMessage(hwnd, WRITE_COMPLETED, 0, 0); + break; + } + } +} + +void +StopCommThread(void) +{ + if (hThread) + { + CloseHandle(hThread); + hThread = 0; + } +} + +void +StartCommThread(void) +{ + StopCommThread(); + if (!heventRead) + heventRead = CreateEvent(0, TRUE, 0, 0); + if (!heventWrite) + heventWrite = CreateEvent(0, TRUE, 0, 0); + hThread = CreateThread( 0, + 8192, + (LPTHREAD_START_ROUTINE) CommsReader, + 0, + 0, + &dwThreadID); +} +#endif void PaintScreen( HWND hWnd) @@ -235,14 +649,12 @@ PaintScreen( HWND hWnd) HFONT hfontOld; HFONT hfontFixed; PAINTSTRUCT ps; - int cyHeight; int yPos; BeginPaint(hWnd, &ps); hfontFixed = (HFONT) GetStockObject(SYSTEM_FIXED_FONT); hfontOld = (HFONT) SelectObject(ps.hdc, (HGDIOBJ) hfontFixed); GetTextMetrics(ps.hdc, &tm); - cyHeight = tm.tmHeight + tm.tmExternalLeading; for (i = 0; i < SCREEN_ROWS; i++) { iRow = ROW_INDEX(i); @@ -262,7 +674,13 @@ WindowProc( HWND hWnd, switch(wMsg) { + case WM_SYSCOMMAND: + CheckScriptSysCommands(hWnd, wParam, lParam); + break; + case WM_COMMAND: + if (CheckScriptCommands(hWnd, wParam, &bTerminal)) + break; switch(wParam) { case 100: @@ -270,7 +688,12 @@ WindowProc( HWND hWnd, { if (iPortChanged) { +#ifdef __FLAT__ + StopCommThread(); + CloseHandle(idComm); +#else CloseComm(idComm); +#endif OpenPort(); } else @@ -280,15 +703,6 @@ WindowProc( HWND hWnd, } break; - case 101: - if (bTerminal) - { - bTerminal = 0; - RegisterManager(hwnd); - SendInitRequest(); - } - break; - case 102: if (!bTerminal) { @@ -319,12 +733,30 @@ WindowProc( HWND hWnd, ShowProtoInfo(hWnd); break; + case 107: + if (bTerminal) + ResolvEdit(hWnd); + break; + case 201: About(hWnd); break; + + case 301: + WinHelp(hWnd, "TWINSOCK.HLP", HELP_CONTENTS, 0); + break; } break; +#ifdef __FLAT__ + case READ_COMPLETED: + ReceiveCompleted(); + break; + + case WRITE_COMPLETED: + SendCompleted(); + break; +#else case WM_COMMNOTIFY: switch(LOWORD(lParam)) { @@ -333,8 +765,10 @@ WindowProc( HWND hWnd, break; } break; +#endif case WM_CHAR: + PerhapsKillScript(hWnd); if (bTerminal) { c = wParam; @@ -364,16 +798,21 @@ WindowProc( HWND hWnd, KillTimer(hWnd, TIMER_ID_BREAK); break; +#ifndef __FLAT__ case TIMER_ID_COMMCHECK: DoReading(); - break; + break; +#endif + + case TIMER_ID_SCRIPT: + ScriptTimeOut(hWnd); + break; } break; case WM_PAINT: PaintScreen(hWnd); return 0; - break; case WM_SETFOCUS: CreateCaret(hWnd, 0, cxColumn, cyRow); @@ -385,11 +824,6 @@ WindowProc( HWND hWnd, DestroyCaret(); break; - case WM_USER: - PacketTransmitData((void *) lParam, wParam, 0); - DoReading(); - break; - case WM_CLOSE: PostQuitMessage(0); break; @@ -397,6 +831,196 @@ WindowProc( HWND hWnd, return DefWindowProc(hWnd, wMsg, wParam, lParam); } +/* Process data received from a client */ +#pragma argsused +void +ResponseReceived( char *pchData, + int iSize, + long iFrom) +{ + struct tx_request *ptxr = (struct tx_request *) pchData; + tws_request *prq; + tws_socket *psck, **ppsck; + enum Functions ft; + int i; + char *c; + + prq = (tws_request *) malloc(sizeof(tws_request)); + prq->prqNext = 0; + prq->idRequest = iRequestOut++;; + prq->iSender = iFrom; + prq->idSenderRequest = ntohs(ptxr->id); + *pprqTail = prq; + pprqTail = &prq->prqNext; + ptxr->id = htons(prq->idRequest); + ft = (enum Functions) ntohs(ptxr->iType); + if (HasSocketArg(ft)) + { + /* If this is a socket call, we need to create an entry + * for the new socket + */ + if (ft == FN_Socket) + { + c = ptxr->pchData; + if (ntohs(*(short *) (c + 2)) == 2) + i = ntohs(*(short *) (c + 4)); + else + i = (short) ntohl(*(long *) (c + 4)); + if (i != -1) + { + psck = (tws_socket *) malloc(sizeof(tws_socket)); + psck->iOwner = iFrom; + psck->si.iClientSocket = i; + psck->si.iServerSocket = GetClientSocket(); + psck->psckNext = 0; + *ppsckTail = psck; + ppsckTail = &psck->psckNext; + } + } + + /* Now change the client's idea of the socket number into + * our idea of the socket number. + */ + c = ptxr->pchData; + if (ntohs(*(short *) (c + 2)) == 2) + i = ntohs(*(short *) (c + 4)); + else + i = (short) ntohl(*(long *) (c + 4)); + for (psck = psckList; + psck->si.iClientSocket != i || psck->iOwner != iFrom; + psck = psck->psckNext); + i = psck->si.iServerSocket; + if (ntohs(*(short *) (c + 2)) == 2) + *(short *) (c + 4) = htons(i); + else + *(long *) (c + 4) = htonl(i); + + } + PacketTransmitData(pchData, iSize, 0); +#ifndef __FLAT__ + DoReading(); +#endif +} + +long +AdjustDataIn( struct tx_request *ptxr, + enum Functions ft) +{ + tws_socket *psck; + short idRequest; + long iOwner; + int i; + BOOL bLong; + char *c; + + idRequest = ntohs(ptxr->id); + for (psck = psckList; + psck && psck->si.iServerSocket != idRequest; + psck = psck->psckNext); + if (!psck) + return 0; + iOwner = psck->iOwner; + ptxr->id = htons(psck->si.iClientSocket); + + if (ft == FN_Accept) + { + if (ntohs(ptxr->nLen) == + sizeof(struct sockaddr_in) + + sizeof(short) * 6) + i = ntohs(*(short *) (ptxr->pchData + + sizeof(struct sockaddr_in))); + else + i = (int) ntohl(*(long *) (ptxr->pchData + + sizeof(struct sockaddr_in))); + + psck = (tws_socket *) malloc(sizeof(tws_socket)); + psck->iOwner = iOwner; + /* Because this one is allocated by tshost, and is unique over the + * range of all applications using TwinSock, we can use it both ways + * as is + */ + psck->si.iServerSocket = i; + psck->si.iClientSocket = i; + psck->psckNext = 0; + *ppsckTail = psck; + ppsckTail = &psck->psckNext; + } + return iOwner; +} + +long +AdjustRequestIn(struct tx_request *ptxr, + enum Functions ft) +{ + short idRequest; + long iSender; + tws_request **pprq, *prqTemp; + tws_socket **ppsck, *psck; + int i; + char *c; + + idRequest = ntohs(ptxr->id); + for (pprq = &prqList; + *pprq && (*pprq)->idRequest != idRequest; + pprq = &(*pprq)->prqNext); + if (!*pprq) + return 0; + iSender = (*pprq)->iSender; + ptxr->id = htons((*pprq)->idSenderRequest); + prqTemp = (*pprq)->prqNext; + free(*pprq); + *pprq = prqTemp; + if (!prqTemp) + pprqTail = pprq; + if (HasSocketArg(ft)) + { + c = ptxr->pchData; + if (ntohs(*(short *) (c + 2)) == 2) + i = ntohs(*(short *) (c + 4)); + else + i = (short) ntohl(*(long *) (c + 4)); + for (psck = psckList; + psck && psck->si.iServerSocket != i; + psck = psck->psckNext); + if (psck) + { + i = psck->si.iClientSocket; + if (ntohs(*(short *) (c + 2)) == 2) + *(short *) (c + 4) = htons(i); + else + *(long *) (c + 4) = htonl(i); + } + + /* If this is a close call, remove our entry describing the + * socket. + */ + if (ft == FN_Close) + { + c = ptxr->pchData; + if (ntohs(*(short *) (c + 2)) == 2) + i = ntohs(*(short *) (c + 4)); + else + i = (short) ntohl(*(long *) (c + 4)); + for (ppsck = &psckList; + *ppsck && + ((*ppsck)->si.iClientSocket != i || (*ppsck)->iOwner != iSender); + ppsck = &(*ppsck)->psckNext); + if (*ppsck) + { + if (!((*ppsck)->si.iServerSocket & 1)) + ReleaseClientSocket((*ppsck)->si.iServerSocket); + psck = (*ppsck)->psckNext; + free(*ppsck); + *ppsck = psck; + if (!psck) + ppsckTail = ppsck; + } + } + } + + return iSender; +} + void DataReceived(void *pvData, int iLen) { @@ -407,6 +1031,7 @@ DataReceived(void *pvData, int iLen) enum Functions ft; int nCopy; int i; + long iSender; while (iLen) { @@ -446,21 +1071,36 @@ DataReceived(void *pvData, int iLen) { if (ptxr->id == -1) { - SetWindowText(hwnd, "TwinSock - Connected"); + if (hostinfo.achHostName) + { + char achBuffer[160]; + + strcpy(achBuffer, "TwinSock - "); + strcat(achBuffer, hostinfo.achHostName); + SetWindowText(hwnd, achBuffer); + } + else + { + SetWindowText(hwnd, "TwinSock - Connected"); + } CloseWindow(hwnd); - SetInitialised(); + StartDDE(hinst); } } else if (ft == FN_Message) { - SendToScreen('\r'); - SendToScreen('\n'); - for (i = 0; i < nPktLen - 10; i++) - SendToScreen(ptxr->pchData[i]); + WriteToScreen("\r\n", 2); + WriteToScreen(ptxr->pchData, nPktLen - 10); } else { - ResponseReceived(ptxr); + if (ft == FN_Data || + ft == FN_Accept) + iSender = AdjustDataIn(ptxr, ft); + else + iSender = AdjustRequestIn(ptxr, ft); + if (iSender) + SendDataTo((char *) ptxr, nBytes, iSender); } free(ptxr); ptxr = 0; @@ -491,6 +1131,7 @@ Shutdown(void) KillTimer(hwnd, TIMER_ID_SEND); KillTimer(hwnd, TIMER_ID_RECEIVE); KillTimer(hwnd, TIMER_ID_FLUSH); + KillTimer(hwnd, TIMER_ID_SCRIPT); ReInitPackets(); } @@ -499,17 +1140,31 @@ OpenPort(void) { char achProfileEntry[256]; char achMsgBuf[512]; - char *pchError; + char *pchError = 0; do { iPortChanged = 0; GetPrivateProfileString("Config", "Port", "COM1", achProfileEntry, 256, "TWINSOCK.INI"); - idComm = OpenComm(achProfileEntry, 16384, 16384); - if (idComm < 0) + iBufferSize = GetPrivateProfileInt("Config", "BufferSize", 16384, "TWINSOCK.INI"); +#ifdef __FLAT__ + idComm = CreateFile(achProfileEntry, + GENERIC_READ | GENERIC_WRITE, + 0, 0, OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, 0); + if (idComm != INVALID_HANDLE_VALUE) + { + SetupComm(idComm, iBufferSize, iBufferSize); + } + else { - switch(idComm) + pchError = GetLastErrorText(); +#else + idComm = OpenComm(achProfileEntry, iBufferSize, iBufferSize); + if (idComm < 0) { + switch(idComm) + { case IE_BADID: pchError = "No such device"; break; @@ -546,6 +1201,7 @@ OpenPort(void) pchError = "Error Unknown"; break; } +#endif sprintf(achMsgBuf, "Unable to open port \"%s\": %s", achProfileEntry, @@ -555,15 +1211,44 @@ OpenPort(void) if (!CommsEdit(hwnd)) exit(1); } +#ifdef __FLAT__ + if (pchError) + { + LocalFree(pchError); + pchError = 0; + } + } while (idComm == INVALID_HANDLE_VALUE); +#else } while (idComm < 0); +#endif InitComm(idComm); - EnableCommNotification(idComm, hwnd, 1, 0); - SetTimer(hwnd, TIMER_ID_COMMCHECK, 1000, 0); +#ifdef __FLAT__ + StartCommThread(); + PrepareToRead(); +#else + bUseNotify = GetPrivateProfileInt("Config", "UseNotify", 1, "TWINSOCK.INI"); + if (bUseNotify) + { + EnableCommNotification(idComm, hwnd, 10, 0); + SetTimer(hwnd, TIMER_ID_COMMCHECK, 1000, 0); + } +#endif +} + +static BOOL +MyPeekMessage( MSG *pmsg, + BOOL *pbHadMessage) +{ + *pbHadMessage = PeekMessage(pmsg, 0, 0, 0, PM_REMOVE); +#ifndef __FLAT__ + DoReading(); +#endif + return !*pbHadMessage || pmsg->message != WM_QUIT; } #pragma argsused -int far pascal +int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrec, LPSTR lpCmdLine, @@ -577,6 +1262,8 @@ WinMain(HINSTANCE hInstance, HWND hwndDesktop; HFONT hfontOld; HFONT hfontFixed; + BOOL bHadMessage; + BOOL bTempNotify; hinst = hInstance; hwndDesktop = GetDesktopWindow(); @@ -620,13 +1307,19 @@ WinMain(HINSTANCE hInstance, 0); OpenPort(); + ConfigureScripts(hInstance, hwnd, lpCmdLine); - while (GetMessage(&msg, 0, 0, 0)) + while ((bTempNotify = bUseNotify) ? GetMessage(&msg, 0, 0, 0) : MyPeekMessage(&msg, &bHadMessage)) { + if ((bTempNotify || bHadMessage) && + !CustomTranslateAccelerator(hwnd, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } + TerminateScripts(); + StopDDE(); + return 0; } - \ No newline at end of file + diff --git a/twinsock.h b/twinsock.h index 5ffbced..775c859 100644 --- a/twinsock.h +++ b/twinsock.h @@ -26,7 +26,11 @@ void FlushInput(void); void DataReceived(void *pvData, int iLen); void Shutdown(void); BOOL CommsEdit(HWND hwndParent); +#ifdef __FLAT__ +void InitComm(HANDLE idComm); +#else void InitComm(int idComm); +#endif BOOL DialNumber(HWND hwndParent); void ShowProtoInfo(HWND hwndParent); void About(HWND hwndParent); @@ -34,6 +38,10 @@ void TimeoutReceived(void); void PacketTransmitData(void *pvData, int iDataLen, int iStream); void ReInitPackets(void); +#if defined(__FLAT__) && !defined(HTASK) +#define HTASK int +#endif + #endif enum arg_type @@ -70,6 +78,9 @@ enum Encoding E_Explicit, }; +/* Functions marked as obsolete are now handled as side effects of + * other functions. + */ enum Functions { FN_Init = 0, @@ -78,11 +89,11 @@ enum Functions FN_Close, FN_Connect, FN_IOCtl, - FN_GetPeerName, - FN_GetSockName, + FN_GetPeerName, /* Obsolete - handled by connect() */ + FN_GetSockName, /* Obsolete - handled by bind() */ FN_GetSockOpt, FN_Listen, - FN_Select, + FN_Select, /* Obsolete - handled internally */ FN_Send, FN_SendTo, FN_SetSockOpt, @@ -130,6 +141,7 @@ struct data struct data *pdNext; }; +#ifdef __DLL__ struct per_task { HTASK htask; @@ -142,6 +154,7 @@ struct per_task struct hostent he; struct servent se; struct protoent pe; + char achRevAddress[4]; char achHostEnt[MAX_HOST_ENT]; char *apchHostAlii[MAX_ALTERNATES]; char *apchHostAddresses[MAX_ALTERNATES]; @@ -149,8 +162,32 @@ struct per_task char *apchServAlii[MAX_ALTERNATES]; char achProtoEnt[MAX_HOST_ENT]; char *apchProtoAlii[MAX_ALTERNATES]; + struct __tws_client *pClient; + HWND hwndDNS; }; +#define MAX_DNS_SERVERS 4 + +typedef struct __dns_info +{ + BOOL bVirtualCircuit; + BOOL bComplete; + int iError; + BOOL bNameToAddress; + int nTryNow; + int iTryNow; + int iRetry; + char aachTryNow[MAX_DNS_SERVERS][4]; + char achInput[4]; + char *pchQuery; + int iQueryLen; + HWND hwndNotify; + char *pchLocation; + u_int wMsg; + short idRequest; + short idSent; +} dns_info; + struct per_socket { SOCKET s; @@ -162,16 +199,22 @@ struct per_socket long iEvents; HWND hWnd; unsigned wMsg; + struct sockaddr_in sinLocal, sinRemote; long nOutstanding; + int iConnectResult; + dns_info *pdnsi; }; -#define PSF_ACCEPT 0x0001 -#define PSF_CONNECT 0x0002 -#define PSF_SHUTDOWN 0x0004 -#define PSF_NONBLOCK 0x0008 -#define PSF_CLOSED 0x0010 -#define PSF_MUSTCONN 0x0020 -#define PSF_CONNECTING 0x0040 +#define PSF_ACCEPT 0x0001 /* Socket is listening */ +#define PSF_CONNECT 0x0002 /* Socket is connected */ +#define PSF_SHUTDOWN 0x0004 /* Shutdown on send has been called */ +#define PSF_NONBLOCK 0x0008 /* Socket is non blocking */ +#define PSF_CLOSED 0x0010 /* Socket has been closed by the remote host */ +#define PSF_MUSTCONN 0x0020 /* Socket must connect before using send or recv */ +#define PSF_CONNECTING 0x0040 /* Socket is in the process of connecting */ +#define PSF_BOUND 0x0080 /* Socket is bound to a local address */ +#define PSF_CRUSED 0x0100 /* The result of the connect has been retrieved */ +#endif #define MAX_OUTSTANDING 2048 @@ -193,5 +236,6 @@ struct per_socket tf.pfaList = args, \ tf.pfaResult = &retval ) + #endif - \ No newline at end of file + diff --git a/twinsock.hpj b/twinsock.hpj new file mode 100644 index 0000000..182fba0 --- /dev/null +++ b/twinsock.hpj @@ -0,0 +1,11 @@ +[Options] +Contents=Contents +Title=TwinSock 2.0 Help + +[Config] +BrowseButtons() + +[Files] +TWINSOCK.RTF +CORVU.RTF + \ No newline at end of file diff --git a/twinsock.rc b/twinsock.rc index 6d4bd89..3cdae28 100644 --- a/twinsock.rc +++ b/twinsock.rc @@ -1,27 +1,37 @@ -#include "c:\bc4\include\windows.h" -#define IDHELP 3 +#include "d:\bc45\include\windows.h" TSICON ICON "twinsock.ico" TS_MENU MENU { - POPUP "Setup" + POPUP "&Setup" { - MENUITEM "Communications...", 100 - MENUITEM "Send break signal", 104 - MENUITEM "Dial...", 105 + MENUITEM "&Communications...", 100 + MENUITEM "&Name servers...", 107 + MENUITEM "&Send break signal", 104 + MENUITEM "&Dial...", 105 MENUITEM SEPARATOR - MENUITEM "Connect", 101 - MENUITEM "Disconnect", 102 - MENUITEM "Show protocol summary...", 106 + MENUITEM "D&isconnect\tF8", 102 + MENUITEM "Show &protocol summary...", 106 MENUITEM SEPARATOR - MENUITEM "About TwinSock...", 201 + MENUITEM "&Help", 301 + MENUITEM "&About TwinSock...", 201 MENUITEM SEPARATOR - MENUITEM "Exit", 103 + MENUITEM "E&xit\tAlt-X", 103 } + +} + +TS_ACCELS ACCELERATORS +{ + VK_F1, 301, VIRTKEY + VK_F7, 101, VIRTKEY + "X", 103, ASCII, ALT + "x", 103, ASCII, ALT } -COMMS_DLG DIALOG 5, 19, 217, 108 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU + +COMMS_DLG DIALOG 5, 19, 293, 134 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | 4 CAPTION "Communications Parameters" FONT 8, "MS Sans Serif" { @@ -35,28 +45,34 @@ FONT 8, "MS Sans Serif" COMBOBOX 107, 61, 68, 89, 70, CBS_DROPDOWNLIST | WS_TABSTOP RTEXT "Stop &Bits", 108, 6, 91, 53, 8 COMBOBOX 109, 61, 89, 89, 57, CBS_DROPDOWNLIST | WS_TABSTOP - DEFPUSHBUTTON "OK", IDOK, 161, 6, 50, 14, BS_DEFPUSHBUTTON | WS_TABSTOP - PUSHBUTTON "Cancel", IDCANCEL, 161, 24, 50, 14, WS_TABSTOP - PUSHBUTTON "Help", IDHELP, 161, 42, 50, 14, WS_TABSTOP + GROUPBOX "Flow Control", 120, 163, 5, 120, 68, BS_GROUPBOX + CONTROL "&RTS/CTS (Modem)", 121, "BUTTON", BS_AUTORADIOBUTTON, 169, 20, 107, 12 + CONTROL "DSR/DTR (Some direct)", 122, "BUTTON", BS_AUTORADIOBUTTON, 169, 37, 107, 12 + CONTROL "&None (If all else fails)", 123, "BUTTON", BS_AUTORADIOBUTTON, 169, 54, 107, 12 + LTEXT "Bu&ffers", -1, 165, 79, 116, 8 + EDITTEXT 130, 166, 90, 72, 12, ES_RIGHT | WS_BORDER | WS_TABSTOP + LTEXT "Bytes", -1, 243, 91, 42, 8 + DEFPUSHBUTTON "OK", 1, 43, 111, 50, 14, BS_DEFPUSHBUTTON | WS_TABSTOP + PUSHBUTTON "Cancel", 2, 111, 111, 50, 14, WS_TABSTOP + PUSHBUTTON "Help", 3, 179, 111, 50, 14, WS_TABSTOP } -ABOUT_DLG DIALOG 26, 40, 194, 132 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +ABOUT_DLG DIALOG 26, 40, 194, 108 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | 4 CAPTION "About TwinSock" FONT 8, "MS Sans Serif" { - DEFPUSHBUTTON "OK", IDOK, 72, 109, 50, 14 + DEFPUSHBUTTON "OK", IDOK, 73, 88, 50, 14 ICON "TSICON", -1, 9, 12, 18, 20 - CTEXT "TwinSock 1.4", -1, 33, 7, 127, 8 + CTEXT "TwinSock 2.0", -1, 33, 7, 127, 8 CTEXT "Copyright 1994-1995 Troy Rollo", -1, 33, 20, 127, 8 - CTEXT "This Program Is Free Software", -1, 33, 33, 127, 8 - LTEXT "You may redistribute it under the terms of the file LICENSE.TXT, included with the TwinSock software.", -1, 33, 44, 127, 43 - CTEXT "Please direct questions and comments to twinsock@cbme.unsw.EDU.AU", -1, 30, 83, 142, 22 + CTEXT "This Program Is Sponsored Free Software", -1, 33, 33, 127, 8 + LTEXT "See the license in the help file for conditions of redistribution.", -1, 33, 44, 127, 34 } DIAL_DLG DIALOG 24, 76, 153, 62 -STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | 4 CAPTION "Dial" FONT 8, "MS Sans Serif" { @@ -69,7 +85,7 @@ FONT 8, "MS Sans Serif" } PROTO_DLG DIALOG 18, 18, 142, 129 -STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU | 4 CAPTION "Protocol Summary" BEGIN RTEXT "Packets Sent:", -1, 4, 3, 73, 8, SS_RIGHT | WS_CHILD | WS_VISIBLE | WS_GROUP @@ -93,4 +109,38 @@ BEGIN CONTROL "", 108, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE | WS_BORDER | WS_GROUP, 81, 99, 28, 8 END - \ No newline at end of file +NS_DLG DIALOG 6, 15, 194, 121 +STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | 4 +CAPTION "Name Servers" +FONT 8, "MS Sans Serif" +{ + RTEXT "&Domain", -1, 3, 8, 49, 8 + EDITTEXT 101, 57, 6, 127, 12 + RTEXT "Name Server &1", -1, 3, 28, 51, 8 + EDITTEXT 111, 57, 27, 24, 12 + EDITTEXT 112, 91, 27, 24, 12 + EDITTEXT 113, 125, 27, 24, 12 + EDITTEXT 114, 159, 27, 24, 12 + LTEXT ".", -1, 85, 27, 2, 8 + LTEXT ".", -1, 117, 27, 2, 8 + LTEXT ".", -1, 153, 27, 2, 8 + RTEXT "Name Server &2", -1, 3, 48, 51, 8 + EDITTEXT 121, 57, 47, 24, 12 + EDITTEXT 122, 91, 46, 24, 12 + EDITTEXT 123, 125, 46, 24, 12 + EDITTEXT 124, 159, 46, 24, 12 + LTEXT ".", -1, 85, 47, 2, 8 + LTEXT ".", -1, 117, 46, 2, 8 + LTEXT ".", -1, 153, 46, 2, 8 + RTEXT "Name Server &3", -1, 3, 68, 51, 8 + EDITTEXT 131, 57, 67, 24, 12 + EDITTEXT 132, 91, 67, 24, 12 + EDITTEXT 133, 125, 67, 24, 12 + EDITTEXT 134, 159, 67, 24, 12 + LTEXT ".", -1, 85, 67, 2, 8 + LTEXT ".", -1, 117, 67, 2, 8 + LTEXT ".", -1, 153, 67, 2, 8 + CHECKBOX "O&verride Values Supplied By Host", 141, 7, 84, 175, 12, BS_AUTOCHECKBOX | WS_TABSTOP + DEFPUSHBUTTON "OK", 1, 46, 102, 50, 14 + PUSHBUTTON "Cancel", 2, 106, 102, 50, 14 +} diff --git a/twinsock.rtf b/twinsock.rtf new file mode 100644 index 0000000..a74bd82 --- /dev/null +++ b/twinsock.rtf @@ -0,0 +1,524 @@ +{\rtf1\ansi \deff0\deflang1024{\fonttbl{\f0\froman Times New Roman;}{\f1\froman Symbol;}{\f2\fswiss Arial;}{\f3\froman Tms Rmn;}{\f4\fswiss Helv;}{\f5\fmodern Courier New;}{\f6\fnil Crillee;}}{\colortbl;\red0\green0\blue0; +\red0\green0\blue255;\red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue127;\red0\green127\blue127;\red0\green127\blue0;\red127\green0\blue127; +\red127\green0\blue0;\red127\green127\blue0;\red127\green127\blue127;\red192\green192\blue192;}{\stylesheet{\s243\tqc\tx4320\tqr\tx8640 \f3\lang2057 \sbasedon0\snext243 header;}{\s244 \f3\fs16\up6\lang2057 \sbasedon0\snext0 footnote reference;}{\s245 +\f3\fs20\lang2057 \sbasedon0\snext245 footnote text;}{\s252\li360 \b\f3\lang2057 \sbasedon0\snext255 heading 3;}{\s253\sb120 \b\f4\lang2057 \sbasedon0\snext0 heading 2;}{\s254\sb240 \b\f4\ul\lang2057 \sbasedon0\snext0 heading 1;}{\s255\li720 \f3\lang2057 +\sbasedon0\snext255 Normal Indent;}{\f3\lang2057 \snext0 Normal;}{\s2\li567 \b\f3\lang2057 \sbasedon0\snext2 CRT;}{\s3\li567 \f3\lang2057 \sbasedon0\snext3 Example;}{\s4\fi-288\li576 \f3\lang2057 \sbasedon0\snext4 Level2;}{\s5\fi-144\li144 \f3\lang2057 +\sbasedon0\snext5 Level1;}{\s6\fi-288\li1152 \f3\lang2057 \sbasedon0\snext6 Level3;}{\s7\li144 \f3\lang2057 \sbasedon5\snext7 Follow1;}{\s8\li576 \f3\lang2057 \sbasedon4\snext8 Follow2;}{\s9\li1152 \f3\lang2057 \sbasedon6\snext9 Follow3;}}{\info +{\author Sycomp}{\operator Sycomp}{\creatim\yr1995\mo3\dy30\hr22\min5}{\revtim\yr1995\mo3\dy30\hr22\min5}{\printim\yr1995\mo11\dy4\hr15\min3}{\version2}{\edmins395}{\nofpages0}{\nofwords65536}{\nofchars65536}{\vern16417}} +\paperw11906\paperh16838\margl1800\margr1800\margt1440\margb1440\gutter0 \widowctrl\ftnbj \sectd \linex0\headery709\footery709\colsx709\endnhere \pard\plain \qc \f3\lang2057 {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Contents +}}{\b\fs16\up6 }{\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} TwinSock 1.4 Help Contents}}{\b\fs16\up6 }{\b\fs20\up6 {\pict\wmetafile8\picw952\pich952\picwgoal540\pichgoal540 +010009000003de0700000000ba0700000000050000000b0200000000050000000c022400240005000000090200000000050000000102ffffff000400000007010300ba070000430f2000cc000000240024000000000024002400000000002800000024000000240000000100180000000000300f0000000000000000000000 +00000000000000c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 +c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffff000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ff000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000808080ffffffc0c0c0c0c0c0c0c0c0 +c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000808080ffffff808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000ffffffff +ffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000808080ffffffffffffffffff808080ffffffc0c0c0c0c0c0c0c0c0ffffff000000ffffffffffffffffffffffffffffffffffff000000c0c0c0c0c0 +c0c0c0c0c0c0c0ffffffffffffffffff000000000000000000000000000000000000000000000000ffffff000000808080ffffffffffffffffffffffffffffff000000ffffffffffffffffff000000ffffffffffffffffffffffffffffffffffff000000808080c0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff808080808080 +808080808080808080808080808080808080808080000000ffffffffffffffffffffffffffffffffffff000000000000808080808080808080ffffffffffffffffffffffffffffffffffff000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 +c0c0808080000000ffffffffffffffffffffffff000000000000808080ffffffffffffffffffffffffffffffffffffffffffffffff000000808080c0c0c0ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffff0000 +00000000808080ffffffffffffffffff000000000000000000000000000000000000808080c0c0c0ffffff000000c0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffff000000808080ffffffffffffffffff000000808080 +808080808080808080808080000000808080ffffff000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffffff000000808080808080808080808080808080808080808080ffffff00 +0000ffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffff000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080808080000000ffffffc0c0c0c0c0c0c0c0c0c0c0 +c0808080ffffffc0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080000000ffffffffffffffffffffffff000000808080808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0808080 +000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffffffffffffffffffff000000808080808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0808080ffffffc0c0c0c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c080 +8080000000ffffffffffffffffffffffff000000808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffff808080ffffffc0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffff +ff000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffff808080ffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffff000000000000808080ffffffc0c0c0c0c0c0c0c0c0 +c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000ffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffff808080808080808080808080808080808080808080808080ffffffffffffffffffffffffffffffffffff000000000000808080ffffff808080ffffffc0c0c0c0c0c0c0c0c0c0c0c0c0c0c0ffffff000000ffffffff +ffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000000000808080ffffffffffffffffff808080ffffffc0c0c0c0c0c0c0c0c0ffffff000000ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffff +ffffffffffffffffffffffffffffffff000000000000000000000000000000000000000000000000ffffff000000808080ffffffffffffffffffffffffffffff000000ffffffffffffffffff000000ffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff808080808080 +808080808080808080808080808080808080808080000000ffffffffffffffffffffffffffffffffffff000000000000808080808080808080ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffff808080c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 +c0c0808080000000ffffffffffffffffffffffff000000000000808080ffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffff0000 +00000000808080ffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffff000000808080ffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0 +c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0808080000000c0c0c0c0c0c0c0c0c0808080000000c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffff +ff808080ffffffc0c0c0808080808080c0c0c0c0c0c0c0c0c0808080808080c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0c0c0c0c0c0c0808080 +000000000000c0c0c0c0c0c0c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffff808080ffffffc0c0c0c0c0c0c0c0c0808080000000000000c0c0c0c0c0c0c0c0c0c0c0c080 +8080000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffff808080ffffffc0c0c0c0c0c0808080808080808080c0c0c0c0c0c0c0c0c0808080000000ffffffffffffffffffffffffffffffffff +ffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffff808080ffffffffffffffffffffffffffffffffffffffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff +ffffffffffffffffffc0c0c0c0c0c0c0c0c0c0c0c0ffffffffffffffffffffffffffffffffffffffffff808080808080808080808080808080808080808080808080ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0c0c0c0c0c0c0c0c0c0 +c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0 +c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0c0030000000000}}{\b\fs36 +\par }{\b\fs36 TwinSoc}{\b\fs36 k 2.0}{\b\fs36\up6 +\par }{\b Troy's Windows Sockets}{\b +\par }{\b Copyright }{\field\flddirty{\*\fldinst {\b SYMBOL 211 }{\b \\}{\b f "Symbol"}}{\fldrslt }}{\b 1994-1995 Troy Rollo}{\b +\par }{\b Released November 1995}{\b +\par }\pard {\b\fs28 +\par }{\b TwinSock is an unsupported, free software product. Do not attempt to contact the authors or the authors' employers or businesses, or any of the program's sponsors for support or other assistance with TwinSock.}{\b +\par }{\b\fs28 +\par }{\b\fs28 TwinSock is sponsored by }{\b\fs28\uldb CorVu Pty Ltd}{\b\v\fs28 CorVu}{\b\fs28 +\par }{\b\fs28 +\par }{\b\fs28 Contents}{\b +\par }\tab {\uldb What's New?}{\v Changes20} +\par +\par \tab {\uldb Licensing}{\v Licensing} +\par \tab {\uldb What Is TwinSock?}{\v Whatis} +\par \tab {\uldb Installing TwinSock}{\v Installing} +\par +\par \tab {\uldb Starting TwinSock}{\v Starting} +\par \tab {\uldb Shutting Down Twinsock}{\v Shutdown} +\par +\par \tab {\uldb Using Port Remapping}{\v Remapping} +\par \tab {\uldb Using Scripting}{\v Scripting} +\par \tab {\uldb Setting Up Name Servers}{\v Resolver} +\par +\par \tab {\uldb Applications Known To Work With TwinSock 2.0}{\v apps} +\par +\par \tab {\uldb If you have problems}{\v problems} +\par \tab {\uldb Enhancements and Bug Reports}{\v Reports} +\par +\par \tab {\uldb TODO and Bugs}{\v TODO} +\par \tab {\uldb Revision History}{\v History} +\par \tab {\uldb Contributors}{\v Contributors} +\par +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Licensing}}{\b }{\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Licensing}}{\fs16\up6 }{\b +\par }\pard \qc {\b\fs32 Troy Rollo's "Sponsorware" License}{\b\fs32 +\par }\pard\plain \s253\sb120 \b\f4\lang2057 Synopsis +\par \pard\plain \f3\lang2057 How we can continue to provide software to you free of charge while still covering rising costs. +\par \pard\plain \s253\sb120 \b\f4\lang2057 Preamble +\par \pard\plain \f3\lang2057 +Ten years ago, it was easy to find free software for all environments. Today, finding free software for Windows is a difficult task. Most of the offerings on public archive sites are "shareware", requiring payment for continued use. +\par +\par Much of the move to shareware has been attributed to the rising costs of the production of this software. Development tools are more expensive, and expensive CD-ROM subscriptions are required to stay abreast of changes. +\par +\par In addition to these problems, new problems have arisen with the recent explosion of interest in the Internet. Every man and his dog is now able to publish, and at times the material published can be slanderous or wildly inaccurate. Producing software for + free means that the author is exposed to this sort of treatment without receiving any funds with which to fight it. +\par +\par A further area of concern is that of trademarks. While the trademark of a free sof +tware product does have the protection of law, the cost of pursuing a trademark abuse case in the courts is upwards of $US20,000, not including the travel costs required to proceed with a case on the other side of the world, and in order to claim compensa +tion (for instance, the cost of the proceedings), you must have the trademark registered in a jurisdiction recognised by the court (this means having registration in at least your own country, the USA, and at least one European country) - more money. + +\par +\par The sponsorware concept is aimed at providing an alternative to fund the costs of development without having to sacrifice the free nature of the software. Sponsorware may be either Free Software as defined by Richard Stallman, or public domain, the only d +ifference being that sponsorware is distributed with paid advertising material contained in it, and that any redistribution of the software in verbatim or modified form must contain that advertising until a stated date. There may also be an exclusion on i +ncluding advertising from vendors competing with existing advertisers. +\par +\par If you contact a company as a result of advertising in sponsorware, you should let the advertiser know the name of the program which contained the advertisement. By doing this you will encourage further advertising, which will mean more free software for +you. +\par +\par This license may be reproduced and applied to your own programs, either in verbatim or modified form, provided that this preamble remains intact. If you modify the license, you +should add a line at the top stating your name, that you have modified the license, and the date of the modification. +\par +\par \pard \qr Troy Rollo +\par October 1995 +\par \pard +\par \pard\plain \s253\sb120 \b\f4\lang2057 Conditions of the License +\par \pard\plain \f3\lang2057 +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 +1. The documentation for this software and/or the software itself contains advertising material. This advertising material and any links to that advertising material must be included unmodified in any redistribution of this software at least until the dat +e stated at the start of the advertisement. +\par +\par 2. Some advertisements may conta +in the text "Non competition clause applies" at the start. If this is the case, you may not include advertising for a product which competes with the product advertised until the advertisement expires as detailed in part 1 of this license. If you are unsu +re if a product competes with a product in such an advertisement, you should contact the advertiser for their opinion. +\par +\par 3. You are free to redistribute verbatim copies of this software including all existing files and no additional files. +\par +\par 4. You are free to redistribute modified copies of this software provided that: +\par +\par \pard\plain \s4\fi-288\li576 \f3\lang2057 i) you include the full source code to the modified version of the software. +\par ii) you include, at the start of the documentation, a notice stating that you have modified the software, stating your name and the release date of the modified version. +\par iii) you release the entire modified package under the terms of this license without any modification to its terms. +\par +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 \tab If you make significant enhancements you may also include additional advertising to help meet your costs, or remove any advertising which has expired. +\par +\par 5. You may not remove or modify any credits contained in this software or in its documentation. +\par +\par 6. As you have not signed this license, you are not obliged to accept it, however as nothing else gives you the right to redistribute and modify this software, doing so would be illegal. Consequently, your redistribution or modification of this software w +ill be construed as acceptance of this license. +\par +\par 7. Any person who violates this license loses the right to use, modify and redistribute this software and any software based on it, and may also be required to pay financial compensation to the authors of the software. +\par +\par 8. If you are unable to operate within the terms of this license, you are free to contact the authors to ask for their approval of modifications to it, provided the modifications do not go against the spirit of this license. +\par +\par 9. Because this program is supplied free of charge, it comes without any warranty, including the implied warranties of merchantability and fitness for a purpose. All risks related to the use of the software are assumed by you, the user. +\par +\par 10. Under no circumstances will anybody who contributes or redistributes this software be liable for any damages relating to your use, misuse or inability to use this software. +\par +\par \pard\plain \f3\lang2057 {\b \page }{\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Whatis}}{\b }{\b +\par }{\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} What Is TwinSock?}}{\b }{\b +\par }\pard \qc {\b\fs32 What Is TwinSock} +\par \pard TwinSock is a free implementation of proxy sockets for Windows. +\par +\par Other Windows Sockets drivers use a network card, or a well known Internet over serial lines protocol, such as SLIP, C-SLIP or PPP. These drivers may access the network card or communications card directly, or via a VxD or DOS based TCP/IP stack. their us +es are limited to cases where either the machine is directly connected to a network, or the host at the other end of the phone line supports the same serial line internet protocol. +\par +\par The other shortcoming of these drivers is that they require an official IP address to operate, and frequently you will not be able to connect very far beyond the host you connect directly to. +\par +\par TwinSock, on the other hand, makes use of the IP address of the host to provide socket services to the client. When an application running under Windows requests socket services of TwinSock, TwinSock will transparently pass these requests on to the TwinSo +ck Host program running on the remote machine for processing. The result is that you have all the same networking capabilities as you would if your Windows machine were physically connected to the network in place of the host machine. +\par +\par TwinSock is able to operate in the most restrictive of circumstances - it can get through even the most fussy of terminal servers and 7 bit lines. With TwinSock, if you have a UNIX shell account, you can have full Windows Sockets access to the Internet. + +\par +\par To take advantage of TwinSock, you will need to obtain some Windows Sockets applications. See the section {\uldb Applications Known To Work With TwinSock}{\v apps} + for a list of applications. Most of these are available from the popular internet FTP sites ftp.cica.indiana.edu and oak.oakland.edu. +\par +\par For more information on what TwinSock, refer to the{\uldb FAQ or newsgroups}{\v moreinfo}. +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} moreinfo}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} For More Information}} +\par \pard \qc {\b\fs32 For More Information on TwinSock} +\par \pard +\par To find out the latest information on TwinSock, check the following newsgroups: +\par +\par \tab {\b alt.dcom.slip-emulators}{\b +\par }{\b \tab }{\b comp.os.ms-windows.networking.tcp-ip}{\b +\par }{\b \tab }{\b comp.os.ms-windows.apps.comm}{\b +\par } +\par or see the TwinSock Web Pages and FAQ at: +\par +\par \tab {\b http://www.corvu.com.au/twinsock/}{\b +\par }\pard \qj +\par If you still have a problem, you may be able to obtain assistance by sending mail to {\b twinsock-helpers@corvu.com.au}. The availability of this service is subject to the availability of volunteers to field questions submitted to the list. +\par +\par Volunteers for the {\b twinsock-helpers} mailing list should send mail to {\b owner-twinsock-helpers@corvu.com.au}. {\b twinsock-helpers} will be acknowledged in the help files of future revisions of TwinSock, and in the TwinSock Web Pages +\par \pard \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Installing}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Installing TwinSock}} +\par \pard \qc {\b\fs32 Installing TwinSock} +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 1. Create an icon for {\b\f5 TWINSOCK.EXE}{\f5\fs20 }(Windows 3.x) or {\b\f5 TWNSCK32.EXE }(Windows 95 and NT) in the program manager using File...New...Program Item. +\par \pard\plain \f3\lang2057 +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 2. Copy the file WINSOCK.DLL to the WINDOWS directory, and if you are using Windows 95 or NT, copy the file WSOCK32.DLL to the WINDOWS\\ +SYSTEM directory. (Note: In previous versions you could safely omit this step. In version 2.0 you cannot - the DLLs must be installed to the correct location) +\par \pard\plain \f3\lang2057 +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 3. Copy the following files {\b\i and only} the following files to an empty directory on your UNIX host. +\par \pard\plain \f3\lang2057 +\par {\b\f5 \tab }{\b\f5 \tab }{\b\f5 build.sh}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 commands.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 getentry.c}{\b\f5 +\par }{\b\f5 \tab \tab }{\b\f5 getsock.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 mem.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 packet.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 packet.h}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 pterm.c}{\b\f5 +\par }{\b\f5 \tab \tab }{\b\f5 sockinfo.c}{\b\f5 +\par }{\b\f5 \tab \tab }{\b\f5 sockinfo.h}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 term.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 tshost.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 twinsock.h}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 tx.h}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 wserror.h}{\b\f5 +\par }{\b\f5\fs20 +\par }\pard\plain \s5\fi-144\li144 \f3\lang2057 4. Type "{\b\f5 sh build.sh} +" to build the server. build.sh will attempt to figure out what options it needs to use to compile on most 32 bit systems. 64 bit systems such as Alpha OSF may need significant porting work. +\par +\par The compilation is successful if a file called "tshost" is created and you can successfully run it (type Control-X 5 times to exit tshost). The compilation process will often display warnings. These warnings can be ignored (t +hat's why they're called "warnings", not "errors"). +\par \pard\plain \f3\lang2057 +\par \pard\plain \s7\li144 \f3\lang2057 If it doesn't compile first off, try to modify it until it does if you know enough about programming. The files you will probably need to touch are (in decreasing order of probability): +\par \pard\plain \f3\lang2057 +\par {\b\f5 \tab }{\b\f5 \tab }{\b\f5 term.c/pterm.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 tshost.c}{\b\f5 +\par }{\b\f5 \tab }{\b\f5 \tab }{\b\f5 commands.c}{\b\f5 +\par } +\par \pard\plain \s7\li144 \f3\lang2057 You should avoid touching packet.c if possible. +\par +\par If you are not able to correct problems yourself, check the {\uldb newsgroups and the FAQ}{\v moreinfo}. +\par \pard\plain \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Starting}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Starting TwinSock}} +\par \pard \qc {\b\fs32 Starting TwinSock} +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 {\b 1.} Start the TwinSock client (The {\b\f5 TWINSOCK.EXE} or {\b\f5 TWNSCK32.EXE} program you have added to the program manager). +\par +\par \pard\plain \s7\li144 \f3\lang2057 +If this is the first time you have started TwinSock, you may get a message indicating that COM1 could not be opened, followed by a box asking you to configure the communications port. If you do not, select Setup...Communications, and configure the communi +cations options to match your hardware. +\par +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 {\b 2.} You will now be in TwinSock terminal mode. If you need to dial the modem, select Connect...Dial, otherwise, press enter to get the UNIX prompt, and log in as if you were using a terminal. +\par +\par {\b 3.} When you have a UNIX prompt. Start "{\b\f5 tshost}" without any arguments. TwinSock should iconise and change its title to "Twinsock - {\i hostname}", where {\i hostname} + is the name of your UNIX host. At this point you can start your Windows sockets applications. +\par +\par \pard\plain \s7\li144 \f3\lang2057 You can also {\uldb start tshost with arguments}{\v tshost} to get higher throughput. +\par \pard\plain \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} tshost}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Starting tshost}} +\par \pard \qc {\b\fs32 Starting tshost}{\b\fs32 +\par } +\par \pard Starting tshost with no arguments results in TwinSock using a 6 bit rotation + protocol over the line. This means that TwinSock will work over just about any connection, but results in a 25% loss of speed. This situation can be improved by starting TwinSock in one of the following modes: +\par +\par \trowd \trgaph108\trleft-108 \cellx2660\cellx6854\cellx7857\pard \intbl {\b tshost command}{\b \cell }{\b Mode}{\b \cell }\pard \qr\intbl {\b Speed}{\b \cell }\pard \intbl \row \trowd \trgaph108\trleft-108 \cellx2660\cellx6854\cellx7857\pard \intbl +tshost -8\cell 8 Bit +\par \cell \pard \qr\intbl 133%\cell \pard \intbl \row \pard \intbl tshost -x\cell 8 Bit, ^S, ^Q escaped +\par \cell \pard \qr\intbl 132%\cell \pard \intbl \row \pard \intbl tshost -X\cell 8 Bit, ^S, ^Q escaped (both with and without bit 7)\cell \pard \qr\intbl 131%\cell \pard \intbl \row \pard \intbl tshost -n\cell 8 Bit, control characters escaped +\par \cell \pard \qr\intbl 118%\cell \pard \intbl \row \pard \intbl tshost -N\cell 7 Bit rotation (control characters with and without bit 7 avoided) +\par \cell \pard \qr\intbl 116%\cell \pard \intbl \row \trowd \trgaph108\trleft-108 \cellx2660\cellx6854\cellx7857\pard \intbl {\uldb tshost -e}{\v Explicit}\cell Explicit selection of escaped characters. +\par \cell \pard \qr\intbl Varies\cell \pard \intbl \row \pard The speed column indicates the speed relative to the default 6 bit rotation protocol. All these protocols require an 8 bit connection. +\par +\par The TwinSock client will automatically detect the protocol being used by TwinSock Host. +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} apps}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Applications Known To Work With TwinSock}} +\par {\b\fs32 Applications Known To Work With TwinSock} +\par The following applications have been tested by me and found to work with TwinSock 2.0: +\par +\par FTP +\par \tab WS_FTP +\par +\par IRC +\par \tab ircII 2.6 for Windows +\par \tab IRC4WIN +\par +\par Telnet +\par \tab yawtel +\par \tab Microsoft Telnet +\par \tab EWAN +\par +\par Mail +\par \tab Eudora +\par +\par News +\par \tab winvn +\par +\par World Wide Web +\par +\par \tab Netscape +\par \tab NCSA Mosaic +\par +\par X-Windows +\par \tab StarNet Micro-X (Also known as xwindemo) +\par +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Contributors}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Contributors}} +\par \pard \qc {\b\fs32 Contributors} +\par \trowd \trgaph108\trleft-108 \cellx2129\cellx8887\pard \intbl Troy Rollo\cell Concept, design, implementation - you name it.\cell \pard \intbl \row \trowd \trgaph108\trleft-108 \cellx2129\cellx8887\pard \intbl Jim Reuter\cell +Fixed a number of byte-swapping bugs\cell \pard \intbl \row \pard \intbl Frank Prindle\cell POSIX Terminals Code.\cell \pard \intbl \row \pard \intbl {\ul Tim Henrion}{\v thenrion}\cell Fixed lots of bugs.\cell \pard \intbl \row \pard \intbl +Douglas Wegscheid\cell Got it to work with 386BSD\cell \pard \intbl \row \pard \intbl Kenny Luk\cell Maintained the FAQ for versions 1.2 and 1.3.\cell \pard \intbl \row \pard \intbl Danny Levinson\cell Added the scripting capability to version 2.0\cell +\pard \intbl \row \trowd \trgaph108\trleft-108 \cellx2129\cellx8887\pard \intbl {\plain \lang2057 Samson }{\plain \lang2057 Chan}\cell twinsock-helpers list since 16 September 1995\cell \pard \intbl \row \pard +\par Thanks also go to everybody who has added their code, bug fixes and suggestions for TwinSock. +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Problems}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} If you have problems}} +\par \pard \qc {\b\fs32 If You Have Problems}{\fs32 +\par }\pard If your machine reboots while running the 16 bit version of TwinSock, and you are +running Windows 3.1, try adding the line "UseNotify=0" to the Config section of TWINSOCK.INI. This appears to fix the problem in all environments by stopping TwinSock from using the EnableCommNotify function. +\par +\par Some environments have a problem with the POSIX terminals code in {\b\f5 pterm.c} - you may get better results if you edit the Makefile, change {\b\f5 pterm.c} to {\b\f5 term.c} and run "make" again. +\par +\par If you cannot get TwinSock to work, check the {\uldb newsgroups and FAQ}{\v moreinfo} for more up to date information. +\par \pard \qc \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} shutdown}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Shutting Down TwinSock}} {\b\fs32 Shutting down TwinSock} +\par \pard\plain \s5\fi-144\li144 \f3\lang2057 1. Double click on the TwinSock icon. +\par +\par 2. Select Setup...Disconnect from the menu. +\par +\par 3. If TwinSock host does not shut down, wait 5 seconds, then type ^X five times. +\par \pard\plain \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Reports}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Enhancements and Bug Reports}} +\par \pard \qc {\b\fs32 Enhancements and Bug Reports} +\par \pard +\par Before submitting an enhancement request or bug report, check the {\uldb FAQ}{\v moreinfo} to make sure you are submitting something new. +\par +\par Enhancements and bug reports should be directed to: +\par +\par \tab \tab twinsock-dev@corvu.com.au +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} TODO}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} TODO and Bugs}} +\par \pard \qc {\b\fs32 TODO & Bugs}{\b\fs32 +\par }\pard +\par Out Of Band data should be handled properly. +\par +\par The internals don't clean up properly if an application exits without cleaning up itself. +\par +\par TwinSock Host should be ported to more hosts, including non UNIX hosts. +\par +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Explicit}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Using the Explicit Encoding Protocol}} +\par \pard \qc {\b\fs32 Using the Explicit Encoding Protocol} +\par \pard Note that due to the complexity of using an explicit encoding protocol, questions to the TwinSock mailing aliases about it are unlikely to be answered - If you use this, you are on your own. +\par +\par \pard \qj In TWINSOCK.INI, and in the UNIX file "$HOME/.twinsock", create a section called "Protocol". This section can have three entries. +\par +\par \pard\plain \s255\li720 \f3\lang2057 {\b\f5 [Protocol]}{\b\f5 +\par }{\b\f5 Escaped=}{\b\f5 \\}{\b\f5 236 ^S ^Q ^S! ^Q!}{\b\f5 +\par }{\b\f5 Ignored=}{\b\f5 \\}{\b\f5 000}{\b\f5 +\par }{\b\f5 Offset=64}{\b\f5 +\par }\pard\plain \qj \f3\lang2057 +\par The "Escaped Entry" specifies characters which should be escaped over the line, and the "Ignored" entry specifies characters which should be ignored completely when received. Both of these entries have the same format - a list of characters separated by s +paces. Characters can be represented in the following ways: +\par +\par \trowd \trgaph108\trleft1144 \cellx1991\cellx6432\pard \qj\intbl \\nnn\cell An octal number representing the character +\par \cell \pard \intbl \row \trowd \trgaph108\trleft1144 \cellx1991\cellx6432\pard \qj\intbl ^X\cell The control character, ^X +\par \cell \pard \intbl \row \trowd \trgaph108\trleft1144 \cellx1991\cellx6432\pard \qj\intbl ^X!\cell The control chararacter, ^X, with bit 7 set. +\par \cell \pard \intbl \row \pard \qj +\par The "Offset" entry specifies the value +which is added to a character to give its escaped representation. The default is 64. This must be chosen such that none of the characters you escape will have an escaped representation of either '^X' (ASCII code CAN) or the space character. +\par +\par Note that the host and client sides do not have to be identical - you can escape a character in one direction only if you wish. +\par \pard \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Remapping}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Using Port Remapping}} +\par \pard \qc {\b\fs32 Using Port Remapping} +\par \pard +\par \pard \qj +Port remapping allows you to have TwinSock host automatically remap a port your applications request to another port, or the first available port in a range of ports. This only applies to "server" applications, such as X-Windows servers and FTP servers. + +\par +\par To do this, you add entries to "$HOME/.twinsock" on your UNIX host. +\par +\par \pard\plain \s255\li720 \f3\lang2057 {\b\f5 [Mappings]}{\b\f5 +\par }{\b\f5 6000=6000,6010}{\b\f5 +\par }{\b\f5 }{\b\f5 +\par }{\b\f5 [PortNames]}{\b\f5 +\par }{\b\f5 6000=X Windows Display 0}{\b\f5 +\par }{\b\f5 6001=X Windows Display 1}{\b\f5 +\par }{\b\f5 6002=X Windows Display 2}{\b\f5 +\par }{\b\f5 6003=X Windows Display 3}{\b\f5 +\par }{\b\f5 6004=X Windows Display 4}{\b\f5 +\par }{\b\f5 6005=X Win}{\b\f5 dows Display 5}{\b\f5 +\par }{\b\f5 6006=X Windows Display 6}{\b\f5 +\par }{\b\f5 6007=X Windows Display 7}{\b\f5 +\par }{\b\f5 6008=X Windows Display 8}{\b\f5 +\par }{\b\f5 6009=X Windows Display 9}{\b\f5 +\par }\pard\plain \qj \f3\lang2057 +\par The "Mappings section" lists the port to be remapped on the left hand side, and a comma separated range of ports to remap to on the right hand side. In the example above, X Windows display 0 (":0.0" in X speak) could be mapped to any of displays 0 through + to 9 (":0.0" to ":9.0" in X speak). +\par +\par When the host end remaps a display, it sends a message back to the TwinSock Window saying what has been done, so if you know you have remapped something, you should check the TwinSock window after starting the app to see where it was mapped to. +\par +\par The "PortNames" section specifies a friendly name to be used for a port in notification messages. If no entry exists for a port in "PortNames", the port number will be used in the notification message. +\par +\par In the example above, you may get: +\par +\par \tab {\b\f5 X Windows Display 0 remapped to X Windows Display 3} +\par +\par \pard \qc \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Resolver}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Setting Up Name Servers}} {\b\fs32 Setting Up Name Servers} +\par \pard +\par \pard \qj +Normally TwinSock 2.0 will use the same name servers as your host system, however in some environments, notably Suns where NIS may be used rather than accessing name servers directly, TwinSock may be unable to find any name servers. The symptoms of this w +ill be that TwinSock will be unable to resolve any names. If you do not have this problem, then you should not set up name servers in TwinSock. If you do have this problem, you should follow the steps below: +\par +\par \pard\plain \s5\qj\fi-144\li144 \f3\lang2057 1. Before starting tshost, select Setup...Name Servers... from the menu. This will display the name server configuration box. +\par +\par 2. Place your domain name in the first edit box. The domain name is your fully qualified internet host name without the first part of the name. For example, if your host name is {\b\f5 myhost.some_domain.edu.us}, your domain name is {\b\f5 +some_domain.edu.us}{\plain \lang2057 .}{\plain \lang2057 +\par }{\plain \lang2057 +\par }{\plain \lang2057 3. Place the internet addresses of up to three name servers in the boxes provided. You may need to ask your service provider for the addresses of the name}{\plain \lang2057 servers.}{\plain \lang2057 +\par }{\plain \lang2057 +\par }{\plain \lang2057 4. Check the "Override Values Supplied By Host" box.}{\plain \lang2057 +\par }{\plain \lang2057 +\par }{\plain \lang2057 5. Click the OK button.}{\plain \lang2057 +\par }\pard\plain \qc \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Scripting}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Scripting}} {\b\fs32 Using Scripting}{\b +\par }\pard +\par TwinSock 2.0 includes a scripting facility which you can use to automate your login session. You can attach script to menu items and to function keys. +\par +\par For a formal definition of the format of the script file and how to use it, see the file script.txt in the TwinSock directory. +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} History}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Revision History}} +\par \pard \qc {\b\fs32 Revision History} +\par \pard +\par \tab 05-Nov-1994\tab Project initiated +\par \tab 14-Nov-1994\tab Version 1.0 released +\par \tab 20-Nov-1994\tab {\uldb Version 1.1}{\v Changes11} released +\par \tab 04-Dec-1994\tab {\uldb Version 1.2}{\v Changes12} released +\par \tab 23-Jan-1995\tab Version 1.3 beta +\par \tab 04-Feb-1995\tab {\uldb Version 1.3}{\v Changes13} released +\par \tab 25-Mar-1995\tab Version 1.4 beta +\par \tab 30-Mar-1995\tab {\uldb Version 1.4}{\v Changes14} released +\par \tab 12-Nov-1995\tab {\uldb Version 2.0}{\v Changes20} released +\par \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Changes11}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Changes in version 1.1}} +\par \pard \qc {\b\fs32 Changes in version 1.1} +\par \pard This version includes a number of bug fixes and usability enhancements. +\par +\par Bugs fixed from 1.0: +\par +\par \pard\plain \s8\li576 \f3\lang2057 Most of the WSAGetXbyY functions didn't work at all. +\par +\par Telnet applications won't drop typed characters anymore. +\par \pard\plain \f3\lang2057 +\par New features: +\par +\par \pard\plain \s8\li576 \f3\lang2057 The host end now tries to figure out what it needs to do to compile on your system. This ability is probably not complete yet, but should work for most 32 bit UNIX platforms. +\par +\par Now has a terminal interface. This means you can log in to your host and start TwinSock Host without needing a separate terminal program. +\par +\par Data received from the network is now "streamed" this means that if you are in the middle of a long file transfer, you can still get in to do other things while the transfer is still going. Also, when you abort a connection, the unwanted data is discarded + at the host end. +\par +\par TwinSock Host now sends a character sequence to TwinSock, which then automatically initiates the connection automatically. +\par \pard\plain \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Changes12}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Changes in Version 1.2}} +\par \pard \qc {\b\fs32 Changes in version 1.2} +\par \pard +\par Bugs fixed from 1.1: +\par \pard\plain \s8\li576 \f3\lang2057 A number of bugs to do with byte swapping have been fixed. Thanks go to Jim Reuter of DEC for his detective work on this. +\par +\par The setsockopt calls have been changed to have the last argument not passed by address. This was my error, not a SysV/POSIX/BSD difference as many have speculated. +\par \pard\plain \f3\lang2057 +\par Behaviour changes: +\par \pard\plain \s8\li576 \f3\lang2057 The default line settings have changed. TwinSock now uses DSR for handshaking. This can be changed back to the old behaviour by adding the line "OutxDsrFlow=0" to the config section of TWINSOCK.INI +\par +\par build.sh should now detect "-lnsl" and shouldn't incorrectly include mem.o in the compilation when using gcc (which has built-in prototypes). +\par +\par \pard\plain \f3\lang2057 New features: +\par \pard\plain \s8\li576 \f3\lang2057 The one packet positive Ack protocol has been changed to a four packet windowed protocol. This improves speed by a factor of four (no, making it an 8 packet windowed protocol will not give an 8 times improvement). +\par +\par You can now dial the modem from the menu, if you're averse to entering dial commands yourself. The dialing code will remember your most recently dialled + number, so for most people this means dialing will be a simple matter of selecting Setup...Dial...OK (after the first time). +\par +\par \pard\plain \f3\lang2057 There is now a menu option to send a break signal (Setup...Send Break Signal). The break signal will last for 1.5 seconds.\page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Changes13}} {\fs16\up6 $ +{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Changes in Version 1.3}} +\par \pard \qc {\b\fs32 Changes in version 1.3} +\par \pard +\par Bugs fixed from 1.2: +\par +\par \pard\plain \s8\li576 \f3\lang2057 Many bugs affecting overall reliability were fixed. They usually manifested themselves by one of the following: +\par \pard\plain \f3\lang2057 +\par \pard\plain \s9\li1152 \f3\lang2057 "Call to Undefined Dynalink" message. +\par General Protection Faults. +\par The protocol hanging. +\par \pard\plain \f3\lang2057 +\par \pard\plain \s8\li576 \f3\lang2057 The dial function should now work on all modems. +\par \pard\plain \f3\lang2057 +\par New features: +\par +\par \pard\plain \s8\li576 \f3\lang2057 There is now an 8 bit protocol, which should result in performance equivalent to SLIP. +\par +\par tshost should now compile (and work) on many more platforms (most notably, POSIX platforms, thanks to Frank Prindle) +\par +\par A new option is available on the menu to view a summary of protocol statistics. These statistics relate to the TwinSock protocol used over the line. +\par \pard\plain \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Changes14}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Changes in Version 1.4}} +\par \pard \qc {\b\fs32 Changes in Version 1.4} +\par \pard Bugs fixed from 1.3 +\par \pard\plain \s255\qj\li720 \f3\lang2057 build.sh should now detect OSF and not user POSIX terminals on it, and should detect SCO and not use select.h on that. +\par \pard \s255\li720 +\par \pard \s255\qj\li720 Absence of SO_ACCEPTCONN and SO_USELOOPBACK should not cause problems on Linux anymore. +\par +\par 386BSD should work - it has a strange-looking sockaddr_in. +\par +\par Speeds >19200 should now work and save OK in TWINSOCK.INI. +\par +\par the "Dial" function now only sends one write to the comm port, for those really fiddly configurations. +\par +\par The -8 protocol should now work with environments using POSIX terminals. +\par +\par A bug in Windows which causes communications notification messages not to be delivered should no longer affect TwinSock. +\par +\par More applications should work, including EWAN and CU-SeeMe. +\par +\par Applications which use UDP should now work. +\par +\par WS_FTP will now report realistic transfer rates for uploads. +\par +\par Eudora mail attachments will no longer cause the message to fail. +\par +\par There were still some byte-swap errors in one or two places - these are now fixed. +\par +\par Many changes have been made to errors returned by TwinSock to get it to pass more of WSAtest. +\par +\par Sending data will no longer slow down the received data rate by 50%. +\par +\par \pard\plain \f3\lang2057 New Features +\par \pard\plain \s255\qj\li720 \f3\lang2057 +\par Port remapping is now supported, so if you are using something like X-Windows and display 0 is taken, it can be remapped to display 1, 2 and so on. +\par +\par A ".twinsock" file on the host side, which has a format similar to a Windows INI file, stores parameters for the host end. +\par +\par Three new protocols: -X, which escapes XON and XOFF with and without bit 7 set, -N which avoids control characters with and without bit 7 set, and -e, which allows you to specify exactly which characters should be escaped. +\par +\par \pard\plain \qc \f3\lang2057 \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} Changes20}} {\fs16\up6 ${\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 $} Changes in Version 2.0}} {\b\fs32 Major Changes in Version 2.0 +} +\par \pard Substantial parts of TwinSock have been rewritten for version 2.0. This section is a summary of the major points. +\par +\par One sentence summary: TwinSock 2.0 should increase compatibility with applications to near 100%, adds some features and adds support for 32 bit applications under Windows 95 and Windows NT. +\par +\par Bugs fixed +\par \pard\plain \s255\li720 \f3\lang2057 Netscape should no longer produce "reentrant call to interrupt window" messages. +\par +\par The mysterious reboot problem has been solved. +\par +\par \pard\plain \f3\lang2057 New and improved features +\par \pard\plain \s255\li720 \f3\lang2057 The protocol used by TwinSock has been changed so that the client does more work and the server does less. This ena +bles TwinSock to have fewer deviations in behaviour from regular TCP/IP stacks, with the major difference being that TwinSock will only block "unexpectedly" on bind calls. The major difference to users is that data can continue to flow constantly without +being interrupted for certain types of operations. +\par +\par TwinSock now works with both 16 and 32 bit applications, in either 16 or 32 bit Windows. +\par +\par A scripting language has been added (Thanks to Danny Levinson). +\par +\par The communications setup box now offers the choice of configuring hardware hardware handshaking for a modem (RTS/CTS), for weird terminal lines (DSR/DTR) or not at all. +\par \pard\plain \f3\lang2057 +\par \pard \qj \page {\fs16\up6 #{\footnote \pard\plain \s245 \f3\fs20\lang2057 {\fs16\up6 #} thenrion}}thenrion@netcom.com (Tim Henrion) +\par +\par } \ No newline at end of file diff --git a/tx.h b/tx.h index 9bb1fbc..68281fe 100644 --- a/tx.h +++ b/tx.h @@ -23,6 +23,10 @@ struct tx_request }; #ifdef _Windows +#if defined(__FLAT__) && !defined(HTASK) +#define HTASK int +#endif + struct tx_queue { struct tx_request *ptxr; @@ -35,5 +39,38 @@ struct tx_queue enum Functions ft; HTASK htask; }; + +#ifdef __DLL__ +typedef struct __tws_client +{ + DWORD iid; + HSZ hszService; + HSZ hszTopic; + HSZ hszItem; + HCONV hconv; +} tws_client; +#define DC_ARGS tws_client *pClient, +#define DC_ARGS_ tws_client *pClient +#define DC_CI(x) pClient->x +#else +#define DC_ARGS +#define DC_ARGS_ void +#define DC_CI(x) x +#endif + +typedef struct __tws_hostinfo +{ + short nHosts; + char achHostName[256]; + char achDomainName[256]; + char aachHosts[4][30]; +} tws_hostinfo; + +void ResponseReceived(char *pchData, int iSize, long iFrom); +void SendDataTo(DC_ARGS char *pchData, int iBytes, long iTo); +BOOL StartDDE(DC_ARGS HINSTANCE hInst); +void StopDDE(DC_ARGS_); + +extern tws_hostinfo hostinfo; #endif - \ No newline at end of file + diff --git a/winsock.c b/winsock.c index d2bdc4a..922b21a 100644 --- a/winsock.c +++ b/winsock.c @@ -17,8 +17,11 @@ #include #include #include +#include #include "twinsock.h" #include "tx.h" +#include "sockinfo.h" +#include "dns.h" #ifdef __MSDOS__ #define PORTSWAP(x) ntohs(x) @@ -33,29 +36,46 @@ static struct per_task *pptList = 0; static struct per_socket *ppsList = 0; static struct tx_queue *ptxqList = 0; -HWND hwndManager = 0; -BOOL bEstablished = 0; +static HINSTANCE hInstance = 0; static void FireAsyncRequest(struct tx_queue *ptxq); +static void ContinueDNSQuery(struct per_socket *pps); +static void NextDNSServer( struct per_socket *pps); +static void NextDNSTry( struct per_socket *pps); -int FAR PASCAL +#pragma argsused +int CALLBACK LibMain(HINSTANCE hInst, WORD wOne, WORD wTwo, LPSTR lpstr) { + hInstance = hInst; return TRUE; } -void far pascal _export -RegisterManager(HWND hwnd) +#pragma argsused +int CALLBACK +WEP(int iExitType) { - hwndManager = hwnd; + return 1; } -void far pascal _export -SetInitialised(void) +#ifdef __FLAT__ +#pragma argsused +BOOL WINAPI +DllEntryPoint( HINSTANCE hinstDLL, + DWORD dwReason, + LPVOID lpvReserved) { - bEstablished = TRUE; -} + switch(dwReason) + { + case DLL_PROCESS_ATTACH: + return LibMain(hinstDLL, 0, 0, 0); + case DLL_PROCESS_DETACH: + return WEP(0); + } + return TRUE; +} +#endif void CopyDataIn( void *pvSource, @@ -132,7 +152,11 @@ GetAnotherTaskInfo(HTASK htask) static struct per_task * GetTaskInfo(void) { +#ifdef __FLAT__ + return GetAnotherTaskInfo(0); +#else return GetAnotherTaskInfo(GetCurrentTask()); +#endif } @@ -184,6 +208,7 @@ NewSocket(struct per_task *ppt, SOCKET s) ppsNew->ppsNext = ppsList; ppsNew->iEvents = 0; ppsNew->nOutstanding = 0; + ppsNew->pdnsi = 0; ppsList = ppsNew; return ppsNew; @@ -204,7 +229,7 @@ RemoveSocket(struct per_socket *pps) { if (!(ppsParent->iFlags & PSF_ACCEPT)) continue; - for (ppd = &ppsParent->pdIn; *ppd; ppd = &(*ppd)->pdNext) + for (ppd = &ppsParent->pdIn; *ppd;) { if ((*ppd)->pchData == (char *) pps) { @@ -212,6 +237,10 @@ RemoveSocket(struct per_socket *pps) *ppd = pd->pdNext; free(pd); } + else + { + ppd = &(*ppd)->pdNext; + } } } @@ -230,7 +259,6 @@ RemoveSocket(struct per_socket *pps) if (pps->iFlags & PSF_ACCEPT) { SendEarlyClose(((struct per_socket *) pd->pchData)->s); - RemoveSocket((struct per_socket *) pd->pchData); } else { @@ -238,6 +266,8 @@ RemoveSocket(struct per_socket *pps) } free(pd); } + if (!(((int) pps->s) & 1)) + ReleaseClientSocket(pps->s); free(pps); return; } @@ -298,7 +328,9 @@ FunctionReceived(SOCKET s, void *pvData, int nLen, enum Functions ft) ppt = GetAnotherTaskInfo(pps->htaskOwner); ppsNew = NewSocket(ppt, ns); pdNew->pchData = (char *) ppsNew; - ppsNew->iFlags |= PSF_CONNECT; + ppsNew->iFlags |= PSF_CONNECT | PSF_BOUND; + ppsNew->sinLocal = pps->sinLocal; + ppsNew->sinRemote = pdNew->sin; Notify(pps, FD_ACCEPT); } else @@ -306,12 +338,13 @@ FunctionReceived(SOCKET s, void *pvData, int nLen, enum Functions ft) pdNew->iLen = nLen; pdNew->pchData = (char *) malloc(nLen); if (pdNew->pchData == 0) - { pdNew->iLen = 0; /* Return EOF to the application */ - return; - } - memcpy(pdNew->pchData, pvData, nLen); - Notify(pps, nLen ? FD_READ : FD_CLOSE); + else + memcpy(pdNew->pchData, pvData, nLen); + if (pps->pdnsi) + ContinueDNSQuery(pps); + else + Notify(pps, nLen ? FD_READ : FD_CLOSE); } } @@ -337,15 +370,12 @@ EndBlocking(struct per_task *ppt) ppt->bBlocking = FALSE; } -static BOOL -FlushMessages(struct per_task *ppt) +BOOL CALLBACK _export +DefBlockFunc(void) { MSG msg; BOOL ret; - if (ppt->lpBlockFunc) - return ((BOOL (far pascal *)()) ppt->lpBlockFunc)(); - ret = (BOOL) PeekMessage(&msg,0,0,0,PM_REMOVE); if (ret) { @@ -356,11 +386,21 @@ FlushMessages(struct per_task *ppt) * *can* fail. */ if (msg.message == WM_QUIT) - ppt->bCancel = TRUE; + WSACancelBlockingCall(); } return ret; } +static BOOL +FlushMessages(struct per_task *ppt) +{ + + if (ppt->lpBlockFunc) + return ((BOOL (CALLBACK *)(void)) ppt->lpBlockFunc)(); + else + return DefBlockFunc(); +} + static void RemoveTXQ(struct tx_queue *ptxq) { @@ -383,24 +423,31 @@ RemoveTask(struct per_task *ppt) { struct per_task **pppt; + DestroyWindow(ppt->hwndDNS); for (pppt = &pptList; *pppt; pppt = &((*pppt)->pptNext)) { if (*pppt == ppt) { *pppt = ppt->pptNext; + free(ppt->pClient); free(ppt); break; } } }; -void far pascal _export -ResponseReceived(struct tx_request *ptxr) +#pragma argsused +void +ResponseReceived( char *pchData, + int iSize, + long iFrom) { int nLen; int id; struct tx_queue *ptxq; enum Functions ft; + struct tx_request *ptxr = (struct tx_request *) pchData; + struct sockaddr_in *psin; ft = (enum Functions) ntohs(ptxr->iType); id = ntohs(ptxr->id); @@ -421,7 +468,7 @@ ResponseReceived(struct tx_request *ptxr) return; } } - if (ft == FN_SendTo || ft == FN_Send || ft == FN_Connect) + if (ft == FN_SendTo || ft == FN_Send || ft == FN_Connect || ft == FN_Close) { int iOffset = 0; int iLen; @@ -441,6 +488,14 @@ ResponseReceived(struct tx_request *ptxr) case FN_Connect: nCode = 3; break; + + case FN_Close: + nCode = 0; + break; + + default: + nCode = -1; + break; } for (i = 0; i <= nCode; i++) @@ -449,6 +504,8 @@ ResponseReceived(struct tx_request *ptxr) iOffset += 2; iLen = ntohs(*(short *) (ptxr->pchData + iOffset)); iOffset += 2; + if (i == 1) + psin = (struct sockaddr_in *) (ptxr->pchData + iOffset); if (i == 0 || i == nCode) { if (at == AT_Int16) @@ -460,18 +517,30 @@ ResponseReceived(struct tx_request *ptxr) pps = GetSocketInfo(nValue); if (!pps) return; + if (ft == FN_Close) + { + RemoveSocket(pps); + } } else if (ft == FN_Connect) { if (nValue < 0) { + pps->iConnectResult = ntohs(ptxr->nError); NotifyError(pps, FD_CONNECT, ntohs(ptxr->nError)); } else { + pps->iConnectResult = 0; pps->iFlags |= PSF_CONNECT; Notify(pps, FD_CONNECT); Notify(pps, FD_WRITE); + if (!pps->iFlags & PSF_BOUND) + { + psin->sin_family = ntohs(psin->sin_family); + pps->sinLocal = *psin; + pps->iFlags |= PSF_BOUND; + } } } else @@ -502,6 +571,7 @@ TransmitFunction(struct transmit_function *ptf) struct tx_request *ptxr; struct tx_queue *ptxq, **pptxq; int iOffset; + struct per_task *ppt = GetTaskInfo(); for (i = 0; i < ptf->nArgs; i++) nSize += ptf->pfaList[i].iLen + sizeof(short) * 2; @@ -555,7 +625,7 @@ TransmitFunction(struct transmit_function *ptf) idNext++; for (pptxq = &ptxqList; *pptxq; pptxq = &((*pptxq)->ptxqNext)); *pptxq = ptxq; - SendMessage(hwndManager, WM_USER, nSize, (LPARAM) ptxr); + SendDataTo(ppt->pClient, (char *) ptxr, nSize, 0); return ptxq; }; @@ -707,8 +777,6 @@ CopyHostEntTo(struct per_task *ppt, char *pchData) char *pchOld; int nAlii; - CopyHostEnt(ppt); - phe = (struct hostent *) pchData; memcpy(phe, &ppt->he, sizeof(ppt->he)); @@ -851,7 +919,7 @@ CopyProtoEntTo(struct per_task *ppt, char *pchData) return (pchData - (char *) ppe); } -SOCKET pascal far _export +SOCKET CALLBACK _export accept(SOCKET s, struct sockaddr FAR *addr, int FAR *addrlen) { @@ -870,7 +938,6 @@ accept(SOCKET s, struct sockaddr FAR *addr, } if (!pps->pdIn && (pps->iFlags & PSF_NONBLOCK)) { - FlushMessages(ppt); /* Some apps will call this in a tight loop */ iErrno = WSAEWOULDBLOCK; return (INVALID_SOCKET); } @@ -904,7 +971,7 @@ accept(SOCKET s, struct sockaddr FAR *addr, return ppsNew->s; } -int pascal far _export +int CALLBACK _export bind(SOCKET s, const struct sockaddr FAR *addr, int namelen) { struct per_task *ppt; @@ -913,10 +980,11 @@ bind(SOCKET s, const struct sockaddr FAR *addr, int namelen) struct func_arg pfaReturn; struct transmit_function tf; struct sockaddr *psa; + struct per_socket *pps; if ((ppt = GetTaskInfo()) == 0) return -1; - if (!GetSocketInfo(s)) + if ((pps = GetSocketInfo(s)) == 0) return -1; if ((namelen < sizeof(*psa)) || IsBadReadPtr(addr, sizeof(*psa))) { @@ -933,38 +1001,42 @@ bind(SOCKET s, const struct sockaddr FAR *addr, int namelen) memcpy(psa, addr, namelen); psa->sa_family = htons(psa->sa_family); INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); - INIT_CARGS(pfaArgs[1], AT_GenPtr, psa, namelen ); + INIT_ARGS(pfaArgs[1], AT_GenPtr, psa, namelen ); INIT_ARGS(pfaArgs[2], AT_IntPtr, &namelen, sizeof(namelen) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); INIT_TF(tf, FN_Bind, 3, pfaArgs, pfaReturn); TransmitFunctionAndBlock(ppt, &tf); + if (nReturn != -1) + { + psa->sa_family = ntohs(psa->sa_family); + pps->sinLocal = *(struct sockaddr_in *) psa; + pps->iFlags |= PSF_BOUND; + } free(psa); return nReturn; } -int pascal far _export +int CALLBACK _export closesocket(SOCKET s) { - struct per_task *ppt; struct per_socket *pps; int nReturn; struct func_arg pfaArgs[1]; struct func_arg pfaReturn; struct transmit_function tf; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); INIT_TF(tf, FN_Close, 1, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); - RemoveSocket(pps); /* Assume success. Is this valid? */ - return nReturn; + RemoveTXQ(TransmitFunction(&tf)); + return 0; } -int pascal far _export +int CALLBACK _export connect(SOCKET s, const struct sockaddr FAR *name, int namelen) { struct per_task *ppt; @@ -979,6 +1051,24 @@ connect(SOCKET s, const struct sockaddr FAR *name, int namelen) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; + if (pps->iFlags & PSF_CONNECT) + { + if (pps->iFlags & PSF_CRUSED) + { + iErrno = WSAEISCONN; + return -1; + } + pps->iFlags |= PSF_CRUSED; + if (pps->iConnectResult) + { + iErrno = pps->iConnectResult; + return -1; + } + else + { + return 0; + } + } if ((namelen < sizeof(*psa)) || IsBadReadPtr(name, sizeof(*psa))) { iErrno = WSAEFAULT; @@ -992,35 +1082,44 @@ connect(SOCKET s, const struct sockaddr FAR *name, int namelen) return (SOCKET_ERROR); } memcpy(psa, name, namelen); + pps->sinRemote = *(struct sockaddr_in *) psa; psa->sa_family = htons(psa->sa_family); INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); - INIT_CARGS(pfaArgs[1], AT_GenPtr, psa, namelen ); + INIT_ARGS(pfaArgs[1], AT_GenPtr, psa, namelen ); INIT_ARGS(pfaArgs[2], AT_IntPtr, &namelen, sizeof(namelen) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); INIT_TF(tf, FN_Connect, 3, pfaArgs, pfaReturn); - if (pps->iEvents & FD_CONNECT) + if (pps->iFlags & PSF_NONBLOCK) { pps->iFlags |= PSF_CONNECTING; RemoveTXQ(TransmitFunction(&tf)); - nReturn = 0; + iErrno = WSAEWOULDBLOCK; + nReturn = -1; } else { TransmitFunctionAndBlock(ppt, &tf); if (nReturn != -1) + { pps->iFlags |= PSF_CONNECT; + if (!(pps->iFlags & PSF_BOUND)) + { + psa->sa_family = ntohs(psa->sa_family); + pps->sinLocal = *(struct sockaddr_in *) psa; + pps->iFlags |= PSF_BOUND | PSF_CRUSED; + } + } } free(psa); return nReturn; } -int pascal far _export +int CALLBACK _export ioctlsocket(SOCKET s, long cmd, u_long far * arg) { - struct per_task *ppt; struct per_socket *pps; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; @@ -1062,56 +1161,48 @@ ioctlsocket(SOCKET s, long cmd, u_long far * arg) return 0; } -int pascal far _export getpeername (SOCKET s, struct sockaddr FAR *name, +int CALLBACK _export getpeername (SOCKET s, struct sockaddr FAR *name, int FAR * namelen) { - struct per_task *ppt; - int nReturn; - struct func_arg pfaArgs[3]; - struct func_arg pfaReturn; - struct transmit_function tf; + struct per_socket *pps; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; - if (!GetSocketInfo(s)) + if ((pps = GetSocketInfo(s)) == 0) return -1; - INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); - INIT_ARGS(pfaArgs[1], AT_GenPtr, name, *namelen ); - INIT_ARGS(pfaArgs[2], AT_IntPtr, namelen, sizeof(*namelen) ); - INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); - INIT_TF(tf, FN_GetPeerName, 3, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); - if (nReturn != -1) - name->sa_family = ntohs(name->sa_family); - return nReturn; + if (!(pps->iFlags & PSF_CONNECT)) + { + iErrno = WSAENOTCONN; + return -1; + } + *namelen = sizeof(struct sockaddr_in); /* Just in case */ + memcpy(name, &pps->sinRemote, sizeof(struct sockaddr_in)); + return 0; } -int pascal far _export getsockname (SOCKET s, struct sockaddr FAR *name, +int CALLBACK _export getsockname (SOCKET s, struct sockaddr FAR *name, int FAR * namelen) { - struct per_task *ppt; - int nReturn; - struct func_arg pfaArgs[3]; - struct func_arg pfaReturn; - struct transmit_function tf; + struct per_socket *pps; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; - if (!GetSocketInfo(s)) + if ((pps = GetSocketInfo(s)) == 0) return -1; *namelen = sizeof(struct sockaddr_in); /* Just in case */ - INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); - INIT_ARGS(pfaArgs[1], AT_GenPtr, name, *namelen ); - INIT_ARGS(pfaArgs[2], AT_IntPtr, namelen, sizeof(*namelen) ); - INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); - INIT_TF(tf, FN_GetSockName, 3, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); - if (nReturn != -1) - name->sa_family = ntohs(name->sa_family); - return nReturn; + if (pps->iFlags & PSF_BOUND) + { + memcpy(name, &pps->sinLocal, sizeof(struct sockaddr_in)); + } + else + { + memset(name, 0, sizeof(struct sockaddr_in)); + ((struct sockaddr_in *) name)->sin_family = AF_INET; + } + return 0; } -int pascal far _export getsockopt (SOCKET s, int level, int optname, +int CALLBACK _export getsockopt (SOCKET s, int level, int optname, char FAR * optval, int FAR *optlen) { struct per_task *ppt; @@ -1158,7 +1249,7 @@ int pascal far _export getsockopt (SOCKET s, int level, int optname, return nReturn; } -u_long pascal far _export htonl (u_long hostlong) +u_long CALLBACK _export htonl (u_long hostlong) { char *pchValue = (char *) &hostlong; char c; @@ -1172,7 +1263,7 @@ u_long pascal far _export htonl (u_long hostlong) return hostlong; } -u_short pascal far _export htons (u_short hostshort) +u_short CALLBACK _export htons (u_short hostshort) { char *pchValue = (char *) &hostshort; char c; @@ -1183,41 +1274,38 @@ u_short pascal far _export htons (u_short hostshort) return hostshort; } -unsigned long pascal far _export inet_addr (const char FAR * cp) +unsigned long CALLBACK _export inet_addr (const char FAR * cp) { unsigned long iValue; char *pchValue = (char *) &iValue; + int iTmp; + int i; if (!GetTaskInfo()) return (INADDR_NONE); - pchValue[0] = atoi(cp); - cp = strchr(cp, '.'); - if (cp) + + for (i = 0; i < 4; i++) { - cp++; - pchValue[1] = atoi(cp); - cp = strchr(cp, '.'); - if (cp) + iTmp = 0; + if (!isdigit(*cp)) + return INADDR_NONE; + while (isdigit(*cp)) { + iTmp *= 10; + iTmp += *cp - '0'; cp++; - pchValue[2] = atoi(cp); - cp = strchr(cp, '.'); - if (cp) - { - cp++; - pchValue[3] = atoi(cp); - cp = strchr(cp, '.'); - if (!cp) - { - return iValue; - } - } } + if (iTmp > 255 || iTmp < 0) + return INADDR_NONE; + if (*cp != (i == 3 ? '\0' : '.')) + return INADDR_NONE; + cp++; + pchValue[i] = iTmp; } - return (INADDR_NONE); + return iValue; } -char FAR * pascal far _export inet_ntoa (struct in_addr in) +char FAR * CALLBACK _export inet_ntoa (struct in_addr in) { struct per_task *ppt; @@ -1232,16 +1320,15 @@ char FAR * pascal far _export inet_ntoa (struct in_addr in) return ppt->achAddress; } -int pascal far _export listen (SOCKET s, int backlog) +int CALLBACK _export listen (SOCKET s, int backlog) { - struct per_task *ppt; struct per_socket *pps; int nReturn; struct func_arg pfaArgs[2]; struct func_arg pfaReturn; struct transmit_function tf; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; @@ -1250,17 +1337,27 @@ int pascal far _export listen (SOCKET s, int backlog) iErrno = WSAEISCONN; return -1; } + if (!(pps->iFlags & PSF_BOUND)) + { + /* Bind first - we need to know the address */ + struct sockaddr_in sin; + + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + bind(s, (struct sockaddr *) &sin, sizeof(sin)); + } INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); INIT_ARGS(pfaArgs[1], AT_Int, &backlog, sizeof(backlog) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); INIT_TF(tf, FN_Listen, 2, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); - if (nReturn != -1) - pps->iFlags |= PSF_ACCEPT; - return nReturn; + RemoveTXQ(TransmitFunction(&tf)); + pps->iFlags |= PSF_ACCEPT; + return 0; } -u_long pascal far _export ntohl (u_long netlong) +u_long CALLBACK _export ntohl (u_long netlong) { char *pchValue = (char *) &netlong; char c; @@ -1274,7 +1371,7 @@ u_long pascal far _export ntohl (u_long netlong) return netlong; } -u_short pascal far _export ntohs (u_short netshort) +u_short CALLBACK _export ntohs (u_short netshort) { char *pchValue = (char *) &netshort; char c; @@ -1285,12 +1382,13 @@ u_short pascal far _export ntohs (u_short netshort) return netshort; } -int pascal far _export recv (SOCKET s, char FAR * buf, int len, int flags) +int CALLBACK _export recv (SOCKET s, char FAR * buf, int len, int flags) { return recvfrom(s, buf, len, flags, 0, 0); } -int pascal far _export recvfrom (SOCKET s, char FAR * buf, int len, int flags, +#pragma argsused +int CALLBACK _export recvfrom (SOCKET s, char FAR * buf, int len, int flags, struct sockaddr FAR *from, int FAR * fromlen) { struct per_task *ppt; @@ -1319,7 +1417,6 @@ int pascal far _export recvfrom (SOCKET s, char FAR * buf, int len, int flags, } if (!pps->pdIn && (pps->iFlags & PSF_NONBLOCK)) { - FlushMessages(ppt); /* Some apps will call this in a tight loop */ iErrno = WSAEWOULDBLOCK; return -1; } @@ -1359,6 +1456,7 @@ int pascal far _export recvfrom (SOCKET s, char FAR * buf, int len, int flags, return -1; } } + EndBlocking(ppt); pd = pps->pdIn; if (from) @@ -1383,7 +1481,6 @@ int pascal far _export recvfrom (SOCKET s, char FAR * buf, int len, int flags, Notify(pps, FD_READ); } - EndBlocking(ppt); return len; } @@ -1400,7 +1497,10 @@ GetPPS(fd_set *fds) pps = (struct per_socket **) malloc(sizeof(struct per_socket *) * fds->fd_count); if (pps == 0) - return (pps); + { + iErrno = WSAENOBUFS; + return PPS_ERROR; + } for (i = 0; i < fds->fd_count; i++) { pps[i] = GetSocketInfo(fds->fd_array[i]); @@ -1414,7 +1514,7 @@ GetPPS(fd_set *fds) } -int pascal far _export select (int nfds, fd_set *readfds, fd_set far *writefds, +int CALLBACK _export select (int nfds, fd_set *readfds, fd_set far *writefds, fd_set *exceptfds, const struct timeval far *timeout) { struct per_task *ppt; @@ -1441,25 +1541,27 @@ int pascal far _export select (int nfds, fd_set *readfds, fd_set far *writefds, ppsWrite = GetPPS(writefds); if (ppsWrite == PPS_ERROR) { - free(ppsRead); + if (ppsRead) + free(ppsRead); return -1; } ppsExcept = GetPPS(exceptfds); if (ppsExcept == PPS_ERROR) { - free(ppsRead); - free(ppsWrite); + if (ppsRead) + free(ppsRead); + if (ppsWrite) + free(ppsWrite); return -1; } while (!bOneOK && !bTimedOut && !ppt->bCancel) { - FlushMessages(ppt); if (ppsWrite) { for (i = 0; i < writefds->fd_count; i++) { - if (((!ppsWrite[i]->iFlags & PSF_CONNECTING) || + if ((!(ppsWrite[i]->iFlags & (PSF_CONNECTING | PSF_MUSTCONN)) || (ppsWrite[i]->iFlags & PSF_CONNECT)) && ppsWrite[i]->nOutstanding < MAX_OUTSTANDING) bOneOK = TRUE; @@ -1475,6 +1577,8 @@ int pascal far _export select (int nfds, fd_set *readfds, fd_set far *writefds, } if (timeout && GetTickCount() >= tExpire) bTimedOut = TRUE; + else if (!bOneOK) + FlushMessages(ppt); } nfds = 0; @@ -1498,7 +1602,7 @@ int pascal far _export select (int nfds, fd_set *readfds, fd_set far *writefds, if (iOld != iNew) writefds->fd_array[iNew] = writefds->fd_array[iOld]; - if (((!ppsWrite[iOld]->iFlags & PSF_CONNECTING) || + if ((!(ppsWrite[iOld]->iFlags & (PSF_CONNECTING | PSF_MUSTCONN)) || (ppsWrite[iOld]->iFlags & PSF_CONNECT)) && ppsWrite[iOld]->nOutstanding < MAX_OUTSTANDING) iNew++; @@ -1540,7 +1644,7 @@ int pascal far _export select (int nfds, fd_set *readfds, fd_set far *writefds, * This causes certain FTP clients to display phenomenal transfer rates. * They should be checking the transfer rates *after* closing their sockets. */ -int pascal far _export send (SOCKET s, const char FAR * buf, int len, int flags) +int CALLBACK _export send (SOCKET s, const char FAR * buf, int len, int flags) { struct per_task *ppt; struct per_socket *pps; @@ -1556,7 +1660,6 @@ int pascal far _export send (SOCKET s, const char FAR * buf, int len, int flags) if ((pps->iFlags & PSF_CONNECTING) && !(pps->iFlags & PSF_CONNECT)) { - FlushMessages(ppt); /* Some apps will call this in a tight loop */ iErrno = WSAEWOULDBLOCK; return -1; } @@ -1579,7 +1682,6 @@ int pascal far _export send (SOCKET s, const char FAR * buf, int len, int flags) { if (pps->iFlags & PSF_NONBLOCK) { - FlushMessages(ppt); /* Some apps will call this in a tight loop */ iErrno = WSAEWOULDBLOCK; return -1; } @@ -1611,7 +1713,7 @@ int pascal far _export send (SOCKET s, const char FAR * buf, int len, int flags) return len; } -int pascal far _export sendto (SOCKET s, const char FAR * buf, int len, int flags, +int CALLBACK _export sendto (SOCKET s, const char FAR * buf, int len, int flags, const struct sockaddr FAR *to, int tolen) { struct per_task *ppt; @@ -1630,7 +1732,6 @@ int pascal far _export sendto (SOCKET s, const char FAR * buf, int len, int flag { if (pps->iFlags & PSF_NONBLOCK) { - FlushMessages(ppt); /* Some apps will call this in a tight loop */ iErrno = WSAEWOULDBLOCK; return -1; } @@ -1696,10 +1797,9 @@ int pascal far _export sendto (SOCKET s, const char FAR * buf, int len, int flag return len; } -int pascal far _export setsockopt (SOCKET s, int level, int optname, +int CALLBACK _export setsockopt (SOCKET s, int level, int optname, const char FAR * optval, int optlen) { - struct per_task *ppt; int nReturn; struct func_arg pfaArgs[5]; struct func_arg pfaReturn; @@ -1709,7 +1809,7 @@ int pascal far _export setsockopt (SOCKET s, int level, int optname, iOptLen = sizeof(long); - if ((ppt = GetTaskInfo()) == 0) + if ( GetTaskInfo() == 0) return -1; if (!GetSocketInfo(s)) return -1; @@ -1744,16 +1844,15 @@ int pascal far _export setsockopt (SOCKET s, int level, int optname, return 0; } -int pascal far _export shutdown (SOCKET s, int how) +int CALLBACK _export shutdown (SOCKET s, int how) { - struct per_task *ppt; struct per_socket *pps; int nReturn; struct func_arg pfaArgs[2]; struct func_arg pfaReturn; struct transmit_function tf; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; @@ -1761,32 +1860,56 @@ int pascal far _export shutdown (SOCKET s, int how) INIT_ARGS(pfaArgs[1], AT_Int, &how, sizeof(how) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); INIT_TF(tf, FN_Shutdown, 2, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); - if (nReturn != -1 && (how == 0 || how == 2)) - pps->iFlags |= PSF_SHUTDOWN; - return nReturn; + RemoveTXQ(TransmitFunction(&tf)); + pps->iFlags |= PSF_SHUTDOWN; + return 0; } -SOCKET pascal far _export socket (int af, int type, int protocol) +SOCKET CALLBACK _export socket (int af, int type, int protocol) { struct per_task *ppt; int nReturn; - struct func_arg pfaArgs[3]; + struct func_arg pfaArgs[4]; struct func_arg pfaReturn; struct transmit_function tf; struct per_socket *pps; + int iSocket; + if (af != AF_INET) + { + iErrno = WSAEAFNOSUPPORT; + return (SOCKET) SOCKET_ERROR; + } + if (type != SOCK_STREAM && type != SOCK_DGRAM) + { + iErrno = WSAESOCKTNOSUPPORT; + return (SOCKET) SOCKET_ERROR; + } + if (protocol != 0 && + (type == SOCK_STREAM && protocol != 6) && + (type == SOCK_DGRAM && protocol != 17)) + { + iErrno = WSAEPROTONOSUPPORT; + return (SOCKET) SOCKET_ERROR; + } if ((ppt = GetTaskInfo()) == 0) return (INVALID_SOCKET); - INIT_ARGS(pfaArgs[0], AT_Int, &af, sizeof(af) ); - INIT_ARGS(pfaArgs[1], AT_Int, &type, sizeof(type) ); - INIT_ARGS(pfaArgs[2], AT_Int, &protocol, sizeof(protocol) ); + iSocket = GetClientSocket(); + if (iSocket == -1) + { + iErrno = WSAENOBUFS; + return -1; + } + INIT_ARGS(pfaArgs[0], AT_Int, &iSocket, sizeof(iSocket) ); + INIT_ARGS(pfaArgs[1], AT_Int, &af, sizeof(af) ); + INIT_ARGS(pfaArgs[2], AT_Int, &type, sizeof(type) ); + INIT_ARGS(pfaArgs[3], AT_Int, &protocol, sizeof(protocol) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); - INIT_TF(tf, FN_Socket, 3, pfaArgs, pfaReturn); - TransmitFunctionAndBlock(ppt, &tf); + INIT_TF(tf, FN_Socket, 4, pfaArgs, pfaReturn); + RemoveTXQ(TransmitFunction(&tf)); if (nReturn != -1) { - pps = NewSocket(ppt, nReturn); + pps = NewSocket(ppt, iSocket); switch(type) { case SOCK_STREAM: @@ -1801,80 +1924,330 @@ SOCKET pascal far _export socket (int af, int type, int protocol) break; } } - return nReturn; + return iSocket; } -struct hostent FAR * pascal far _export gethostbyaddr(const char FAR * addr, - int len, int type) +/* DNS Support */ + +#define DNS_MAXPACKET 1024 + +static void +NextDNSTry( struct per_socket *pps) { - struct per_task *ppt; + struct sockaddr_in sin; + struct per_task *ppt = GetAnotherTaskInfo(pps->htaskOwner); + + if (pps->pdnsi->iRetry++ == 5) + { + NextDNSServer(pps); + return; + } + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + sin.sin_port = htons(NAMESERVER_PORT); + memcpy(&sin.sin_addr.s_addr, + pps->pdnsi->aachTryNow[pps->pdnsi->iTryNow - 1], + 4); + sendto( pps->s, + pps->pdnsi->pchQuery, + pps->pdnsi->iQueryLen, + 0, + &sin, + sizeof(sin)); + SetTimer(ppt->hwndDNS, pps->s, 5000, 0); +} + +static void +NextDNSServer( struct per_socket *pps) +{ + if (pps->pdnsi->iTryNow == pps->pdnsi->nTryNow) + { + pps->pdnsi->bComplete = TRUE; + pps->pdnsi->iError = WSATRY_AGAIN; + return; + } + pps->pdnsi->iTryNow++; + pps->pdnsi->iRetry = 0; + NextDNSTry(pps); +} + +static void +StartDNSLevel( struct per_socket *pps, + char (*ppchAddresses)[4], + int nAddresses) +{ + int i; + + for (i = 0; i < nAddresses && i < MAX_DNS_SERVERS; i++) + memcpy(pps->pdnsi->aachTryNow[i], ppchAddresses[i], 4); + pps->pdnsi->nTryNow = i; + pps->pdnsi->iTryNow = 0; + NextDNSServer(pps); +} + +static struct per_socket * +SendDNSQuery( char const *pchName, + BOOL bNameToAddress) +{ + SOCKET s; + struct per_socket *pps; + dns_info *pdnsi; + struct sockaddr_in sin; + int iLen; + int nReturn; struct func_arg pfaArgs[3]; struct func_arg pfaReturn; struct transmit_function tf; + res_init(); + /* Create a socket, and bind it to a port. We don't care which + * port, so we don't wait for the result of the bind. + */ + memset(&sin, 0, sizeof(sin)); + sin.sin_family = AF_INET; + iLen = sizeof(sin); + s = socket(AF_INET, SOCK_DGRAM, 0); + INIT_ARGS(pfaArgs[0], AT_Int, &s, sizeof(s) ); + INIT_ARGS(pfaArgs[1], AT_GenPtr, &sin, iLen ); + INIT_ARGS(pfaArgs[2], AT_IntPtr, &iLen, sizeof(iLen) ); + INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); + INIT_TF(tf, FN_Bind, 3, pfaArgs, pfaReturn); + RemoveTXQ(TransmitFunction(&tf)); + pps = GetSocketInfo(s); + + pps->pdnsi = pdnsi = (dns_info *) malloc(sizeof(dns_info)); + pdnsi->bNameToAddress = bNameToAddress; + pdnsi->bVirtualCircuit = FALSE; + pdnsi->bComplete = FALSE; + pdnsi->hwndNotify = 0; + pdnsi->pchLocation = 0; + pdnsi->wMsg = 0; + pdnsi->idRequest = idNext++; + pdnsi->pchQuery = (char *) malloc(DNS_MAXPACKET); + pdnsi->iQueryLen = res_mkquery( QUERY, + pchName, + C_IN, + bNameToAddress ? T_A : T_PTR, + 0, 0, 0, + pdnsi->pchQuery, + DNS_MAXPACKET); + pdnsi->idSent = _res.id; + StartDNSLevel( pps, + _res.nsaddr_list, + _res.nscount); + return pps; +} + +/* We have received a response */ +static void +ContinueDNSQuery(struct per_socket *pps) +{ + struct data *pd = pps->pdIn; + dns_info *pdnsi = pps->pdnsi; + int i; + int iError; + struct per_task *ppt; + HEADER *ph = (HEADER *) pd->pchData; + int nLen; + + if (!pd || !pdnsi) + return; + ppt = GetAnotherTaskInfo(pps->htaskOwner); + pps->pdIn = pd->pdNext; + + KillTimer(ppt->hwndDNS, pps->s); + ph = (HEADER *) pd->pchData; + if (ntohs(ph->id) == pdnsi->idSent) + { + if (ph->rcode != NOERROR || ntohs(ph->ancount) == 0) + { + switch(ph->rcode) + { + case NXDOMAIN: + iError = WSAHOST_NOT_FOUND; + break; + + case SERVFAIL: + iError = WSATRY_AGAIN; + break; + + case NOERROR: + iError = WSANO_DATA; + break; + + case FORMERR: + case NOTIMP: + case REFUSED: + default: + iError = WSANO_RECOVERY; + break; + } + } + else + { + iError = 0; + getanswer((querybuf *) pd->pchData, + pd->iLen, + pdnsi->bNameToAddress ? 0 : 1, + &ppt->he, + ppt->achHostEnt, + sizeof(ppt->achHostEnt), + ppt->apchHostAddresses, + ppt->apchHostAlii, + &iError); + if (!iError) + { + if (!pdnsi->bNameToAddress) + { + memcpy(ppt->achRevAddress, pdnsi->achInput, 4); + ppt->he.h_addr_list = ppt->apchHostAddresses; + ppt->he.h_addr_list[0] = ppt->achRevAddress; + ppt->he.h_addr_list[1] = 0; + ppt->he.h_addrtype = PF_INET; + ppt->he.h_length = 4; + } + if (pdnsi->hwndNotify) + { + nLen = CopyHostEntTo(ppt, pdnsi->pchLocation); + PostMessage(pdnsi->hwndNotify, + pdnsi->wMsg, + pdnsi->idRequest | 0x4000, + WSAMAKEASYNCREPLY(nLen, 0)); + } + } + } + if (pdnsi->hwndNotify) + { + if (iError) + PostMessage(pdnsi->hwndNotify, + pdnsi->wMsg, + pdnsi->idRequest | 0x4000, + WSAMAKEASYNCREPLY(0, iError)); + free(pdnsi->pchQuery); + free(pdnsi); + pps->pdnsi = 0; + closesocket(pps->s); + } + else + { + pdnsi->bComplete = TRUE; + pdnsi->iError = iError; + } + } +} + +static char achDNSBuffer[1024]; + +struct hostent FAR * CALLBACK _export gethostbyaddr(const char FAR * addr, + int len, int type) +{ + struct per_task *ppt; + struct per_socket *pps; + struct hostent *phe; + int iError; + if ((ppt = GetTaskInfo()) == 0) return 0; + if (!StartBlocking(ppt)) + return 0; /* - * Sanity check the arguments. For the first two conditions - * of this check, the WINSOCK spec does not specify the correct - * iErrno value to return if they fail. Here we use EFAULT - * for everything. + * Sanity check the arguments. */ if ((type != PF_INET) || /* WINSOCK spec says this must be PF_INET */ (len != 4) || /* WINSOCK spec says must be 4 for PF_INET */ IsBadReadPtr(addr, len)) /* Can we read the host address */ { iErrno = WSAEFAULT; + EndBlocking(ppt); return 0; } - INIT_CARGS(pfaArgs[0], AT_GenPtr, addr, len ); - INIT_ARGS(pfaArgs[1], AT_Int, &len, sizeof(len) ); - INIT_ARGS(pfaArgs[2], AT_Int, &type, sizeof(type) ); - INIT_ARGS(pfaReturn, AT_GenPtr, ppt->achHostEnt,MAX_HOST_ENT ); - INIT_TF(tf, FN_HostByAddr, 3, pfaArgs, pfaReturn); - if (TransmitFunctionAndBlock(ppt, &tf)) + sprintf(achDNSBuffer, "%d.%d.%d.%d.in-addr.arpa", + (int) (unsigned char) addr[3], + (int) (unsigned char) addr[2], + (int) (unsigned char) addr[1], + (int) (unsigned char) addr[0]); + pps = SendDNSQuery(achDNSBuffer, FALSE); + memcpy(pps->pdnsi->achInput, addr, 4); + while (!pps->pdnsi->bComplete && !ppt->bCancel) + FlushMessages(ppt); + if (pps->pdnsi->bComplete) { - CopyHostEnt(ppt); - return &ppt->he; + iError = pps->pdnsi->iError; + if (pps->pdnsi->iError) + phe = 0; + else + phe = &ppt->he; } else { - return 0; + iError = WSAEINTR; + phe = 0; } + free(pps->pdnsi->pchQuery); + free(pps->pdnsi); + pps->pdnsi = 0; + closesocket(pps->s); + EndBlocking(ppt); + iErrno = iError; + return phe; } -struct hostent FAR * pascal far _export gethostbyname(const char FAR * name) +struct hostent FAR * CALLBACK _export gethostbyname(const char FAR * name) { struct per_task *ppt; - struct func_arg pfaArgs[1]; - struct func_arg pfaReturn; - struct transmit_function tf; + struct per_socket *pps; + struct hostent *phe; + int iError; + int iLen; if ((ppt = GetTaskInfo()) == 0) return 0; + if (!StartBlocking(ppt)) + return 0; /* * Sanity check the argument. */ if (IsBadReadPtr(name, 1)) /* Make sure we can read at least 1 byte */ { iErrno = WSAEFAULT; + EndBlocking(ppt); return 0; } - INIT_CARGS(pfaArgs[0], AT_String, name, strlen(name) + 1 ); - INIT_ARGS(pfaReturn, AT_GenPtr, ppt->achHostEnt,MAX_HOST_ENT ); - INIT_TF(tf, FN_HostByName, 1, pfaArgs, pfaReturn); - if (TransmitFunctionAndBlock(ppt, &tf)) + strcpy(achDNSBuffer, name); + if (!strchr(achDNSBuffer, '.')) { - CopyHostEnt(ppt); - return &ppt->he; + strcat(achDNSBuffer, "."); + strcat(achDNSBuffer, hostinfo.achDomainName); + } + iLen = strlen(achDNSBuffer); + if (iLen && achDNSBuffer[iLen - 1] == '.') + achDNSBuffer[iLen - 1] = 0; + pps = SendDNSQuery(achDNSBuffer, TRUE); + while (!pps->pdnsi->bComplete && !ppt->bCancel) + FlushMessages(ppt); + if (pps->pdnsi->bComplete) + { + iError = pps->pdnsi->iError; + if (pps->pdnsi->iError) + phe = 0; + else + phe = &ppt->he; } else { - return 0; + iError = WSAEINTR; + phe = 0; } + free(pps->pdnsi->pchQuery); + free(pps->pdnsi); + pps->pdnsi = 0; + closesocket(pps->s); + EndBlocking(ppt); + iErrno = iError; + return phe; } -struct servent FAR * pascal far _export getservbyport(int port, const char FAR * proto) +struct servent FAR * CALLBACK _export getservbyport(int port, const char FAR * proto) { struct per_task *ppt; struct func_arg pfaArgs[2]; @@ -1909,7 +2282,7 @@ struct servent FAR * pascal far _export getservbyport(int port, const char FAR * } } -struct servent FAR * pascal far _export getservbyname(const char FAR * name, +struct servent FAR * CALLBACK _export getservbyname(const char FAR * name, const char FAR * proto) { struct per_task *ppt; @@ -1936,7 +2309,7 @@ struct servent FAR * pascal far _export getservbyname(const char FAR * name, } } -struct protoent FAR * pascal far _export getprotobynumber(int proto) +struct protoent FAR * CALLBACK _export getprotobynumber(int proto) { struct per_task *ppt; struct func_arg pfaArgs[1]; @@ -1959,7 +2332,7 @@ struct protoent FAR * pascal far _export getprotobynumber(int proto) } } -struct protoent FAR * pascal far _export getprotobyname(const char FAR * name) +struct protoent FAR * CALLBACK _export getprotobyname(const char FAR * name) { struct per_task *ppt; struct func_arg pfaArgs[1]; @@ -1982,7 +2355,7 @@ struct protoent FAR * pascal far _export getprotobyname(const char FAR * name) } } -int pascal far _export +int CALLBACK _export gethostname(char *name, int namelen) { struct per_task *ppt; @@ -1990,9 +2363,28 @@ gethostname(char *name, int namelen) struct func_arg pfaArgs[2]; struct func_arg pfaReturn; struct transmit_function tf; + int nChars; if ((ppt = GetTaskInfo()) == 0) return -1; + + nChars = strlen(hostinfo.achHostName); + if (nChars) + { + if (namelen <= nChars) + { + iErrno = WSAEFAULT; + return -1; + } + memcpy(name, hostinfo.achHostName, nChars); + name[nChars] = 0; + return 0; + } + + /* Fallback - we didn't get it from tshost. This should never happen. + * If tshost doesn't transmit it, it is too old and won't work with + * this version of TwinSock anyway. + */ INIT_ARGS(pfaArgs[0], AT_String, name, namelen ); INIT_ARGS(pfaArgs[1], AT_Int, &namelen, sizeof(namelen) ); INIT_ARGS(pfaReturn, AT_Int, &nReturn, sizeof(nReturn) ); @@ -2001,44 +2393,97 @@ gethostname(char *name, int namelen) return nReturn; } -int pascal far _export WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData) +LRESULT CALLBACK _export +TimerWindowProc(HWND hWnd, + UINT wMsg, + WPARAM wParam, + LPARAM lParam) +{ + if (wMsg == WM_TIMER) + { + struct per_socket *pps; + + KillTimer(hWnd, wParam); + pps = GetSocketInfo(wParam); + NextDNSTry(pps); + return 0; + } + return DefWindowProc(hWnd, wMsg, wParam, lParam); +} + +int CALLBACK _export WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData) { struct per_task *pptNew; + tws_client *pClient = (tws_client *) malloc(sizeof(tws_client)); + BOOL bOK; + WNDCLASS wc; lpWSAData->wVersion = 0x0101; lpWSAData->wHighVersion = 0x0101; strcpy(lpWSAData->szDescription, - "TwinSock 1.4 - Proxy sockets system. " - "Copyright 1994-1995 Troy Rollo. " - "TwinSock is free software. " - "See the file \"COPYING\" from the " - "distribution for details."); - if (!hwndManager) - strcpy(lpWSAData->szSystemStatus, "Not Initialised."); - else if (bEstablished) - strcpy(lpWSAData->szSystemStatus, "Ready."); + "TwinSock 2.0"); + bOK = StartDDE(pClient, hInstance); + if (bOK) + { + strcpy(lpWSAData->szSystemStatus, "Ready"); + } else - strcpy(lpWSAData->szSystemStatus, "Initialising."); + { + free(pClient); + strcpy(lpWSAData->szSystemStatus, "Not Ready"); + } lpWSAData->iMaxSockets = 256; lpWSAData->iMaxUdpDg = 512; lpWSAData->lpVendorInfo = 0; if (wVersionRequired == 0x0001) return WSAVERNOTSUPPORTED; - if (!bEstablished) + if (!bOK) return WSASYSNOTREADY; pptNew = malloc(sizeof(struct per_task)); if (pptNew == 0) return (WSAENOBUFS); + + memset(&wc, 0, sizeof(wc)); + wc.style = 0; + wc.lpfnWndProc = TimerWindowProc; + wc.cbWndExtra = sizeof(struct per_task *); + wc.hInstance = hInstance; + wc.lpszClassName = "TwinSock Timer Window"; + RegisterClass(&wc); + + pptNew->hwndDNS = CreateWindow( "TwinSock Timer Window", + "", + WS_OVERLAPPEDWINDOW, + 0, + 0, + 100, + 100, + 0, + 0, + hInstance, + 0 + ); + if (!pptNew->hwndDNS) + { + free(pptNew); + return 0; + } + +#ifdef __FLAT__ + pptNew->htask = 0; +#else pptNew->htask = GetCurrentTask(); +#endif pptNew->pptNext = pptList; - pptNew->lpBlockFunc = 0; + pptNew->lpBlockFunc = DefBlockFunc; pptNew->bCancel = FALSE; pptNew->bBlocking = FALSE; + pptNew->pClient = pClient; pptList = pptNew; return 0; } -int pascal far _export WSACleanup(void) +int CALLBACK _export WSACleanup(void) { struct per_task *ppt; @@ -2049,23 +2494,24 @@ int pascal far _export WSACleanup(void) iErrno = WSAEINPROGRESS; return -1; } + StopDDE(ppt->pClient); RemoveTask(ppt); return 0; } -void pascal far _export WSASetLastError(int iError) +void CALLBACK _export WSASetLastError(int iError) { if (!GetTaskInfo()) return; iErrno = iError; } -int pascal far _export WSAGetLastError(void) +int CALLBACK _export WSAGetLastError(void) { return iErrno; } -BOOL pascal far _export WSAIsBlocking(void) +BOOL CALLBACK _export WSAIsBlocking(void) { struct per_task *ppt; @@ -2074,17 +2520,17 @@ BOOL pascal far _export WSAIsBlocking(void) return ppt->bBlocking; } -int pascal far _export WSAUnhookBlockingHook(void) +int CALLBACK _export WSAUnhookBlockingHook(void) { struct per_task *ppt; if ((ppt = GetTaskInfo()) == 0) return -1; - ppt->lpBlockFunc = 0; + ppt->lpBlockFunc = DefBlockFunc; return 0; } -FARPROC pascal far _export WSASetBlockingHook(FARPROC lpBlockFunc) +FARPROC CALLBACK _export WSASetBlockingHook(FARPROC lpBlockFunc) { struct per_task *ppt; FARPROC oldfunc; @@ -2097,7 +2543,7 @@ FARPROC pascal far _export WSASetBlockingHook(FARPROC lpBlockFunc) return (oldfunc); /* Return the previous value */ } -int pascal far _export WSACancelBlockingCall(void) +int CALLBACK _export WSACancelBlockingCall(void) { struct per_task *ppt; @@ -2148,8 +2594,7 @@ FireAsyncRequest(struct tx_queue *ptxq) { case FN_HostByName: case FN_HostByAddr: - memcpy(ppt->achHostEnt, pchData, MAX_HOST_ENT); - nLen = CopyHostEntTo(ppt, ptxq->pchLocation); + /* It doesn't come here anymore */ break; case FN_ServByName: @@ -2170,7 +2615,8 @@ FireAsyncRequest(struct tx_queue *ptxq) RemoveTXQ(ptxq); } -HANDLE pascal far _export WSAAsyncGetServByName(HWND hWnd, u_int wMsg, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetServByName(HWND hWnd, u_int wMsg, const char FAR * name, const char FAR * proto, char FAR * buf, int buflen) @@ -2195,10 +2641,11 @@ HANDLE pascal far _export WSAAsyncGetServByName(HWND hWnd, u_int wMsg, txq->wMsg = wMsg; txq->ft = FN_ServByName; txq->htask = ppt->htask; - return (txq->id | 0x4000); + return (HANDLE) (txq->id | 0x4000); } -HANDLE pascal far _export WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port, const char FAR * proto, char FAR * buf, int buflen) { @@ -2223,10 +2670,11 @@ HANDLE pascal far _export WSAAsyncGetServByPort(HWND hWnd, u_int wMsg, int port, txq->wMsg = wMsg; txq->ft = FN_ServByPort; txq->htask = ppt->htask; - return (txq->id | 0x4000); + return (HANDLE) (txq->id | 0x4000); } -HANDLE pascal far _export WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, const char FAR * name, char FAR * buf, int buflen) { @@ -2247,10 +2695,11 @@ HANDLE pascal far _export WSAAsyncGetProtoByName(HWND hWnd, u_int wMsg, txq->wMsg = wMsg; txq->ft = FN_ProtoByName; txq->htask = ppt->htask; - return (txq->id | 0x4000); + return (HANDLE) (txq->id | 0x4000); } -HANDLE pascal far _export WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, int number, char FAR * buf, int buflen) { @@ -2271,64 +2720,92 @@ HANDLE pascal far _export WSAAsyncGetProtoByNumber(HWND hWnd, u_int wMsg, txq->wMsg = wMsg; txq->ft = FN_ProtoByNumber; txq->htask = ppt->htask; - return (txq->id | 0x4000); + return (HANDLE) (txq->id | 0x4000); } -HANDLE pascal far _export WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetHostByName(HWND hWnd, u_int wMsg, const char FAR * name, char FAR * buf, int buflen) { struct per_task *ppt; - struct func_arg pfaArgs[1]; - struct func_arg pfaReturn; - struct transmit_function tf; - struct tx_queue *txq; + struct per_socket *pps; + struct hostent *phe; + int iError; + int iLen; + dns_info *pdnsi; if ((ppt = GetTaskInfo()) == 0) return 0; - INIT_CARGS(pfaArgs[0], AT_GenPtr, name, strlen(name) + 1 ); - INIT_ARGS(pfaReturn, AT_GenPtr, ppt->achHostEnt,MAX_HOST_ENT ); - INIT_TF(tf, FN_HostByName, 1, pfaArgs, pfaReturn); - txq = TransmitFunction(&tf); - txq->hwnd = hWnd; - txq->pchLocation = buf; - txq->wMsg = wMsg; - txq->ft = FN_HostByName; - txq->htask = ppt->htask; - return (txq->id | 0x4000); + /* + * Sanity check the argument. + */ + if (IsBadReadPtr(name, 1)) /* Make sure we can read at least 1 byte */ + { + iErrno = WSAEFAULT; + return 0; + } + strcpy(achDNSBuffer, name); + if (!strchr(achDNSBuffer, '.')) + { + strcat(achDNSBuffer, "."); + strcat(achDNSBuffer, hostinfo.achDomainName); + } + iLen = strlen(achDNSBuffer); + if (iLen && achDNSBuffer[iLen - 1] == '.') + achDNSBuffer[iLen - 1] = 0; + pps = SendDNSQuery(achDNSBuffer, TRUE); + pdnsi = pps->pdnsi; + pdnsi->hwndNotify = hWnd; + pdnsi->pchLocation = buf; + pdnsi->wMsg = wMsg; + return (HANDLE) (pdnsi->idRequest | 0x4000); } -HANDLE pascal far _export WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, +#pragma argsused +HANDLE CALLBACK _export WSAAsyncGetHostByAddr(HWND hWnd, u_int wMsg, const char FAR * addr, int len, int type, char FAR * buf, int buflen) { struct per_task *ppt; - struct func_arg pfaArgs[3]; - struct func_arg pfaReturn; - struct transmit_function tf; - struct tx_queue *txq; + struct per_socket *pps; + struct hostent *phe; + int iError; + dns_info *pdnsi; if ((ppt = GetTaskInfo()) == 0) return 0; - INIT_CARGS(pfaArgs[0], AT_GenPtr, addr, len ); - INIT_CARGS(pfaArgs[1], AT_Int, &len, sizeof(len) ); - INIT_CARGS(pfaArgs[2], AT_Int, &type, sizeof(type) ); - INIT_ARGS(pfaReturn, AT_GenPtr, ppt->achHostEnt,MAX_HOST_ENT ); - INIT_TF(tf, FN_HostByAddr, 3, pfaArgs, pfaReturn); - txq = TransmitFunction(&tf); - txq->hwnd = hWnd; - txq->pchLocation = buf; - txq->wMsg = wMsg; - txq->ft = FN_HostByAddr; - txq->htask = ppt->htask; - return (txq->id | 0x4000); + /* + * Sanity check the arguments. + */ + if ((type != PF_INET) || /* WINSOCK spec says this must be PF_INET */ + (len != 4) || /* WINSOCK spec says must be 4 for PF_INET */ + IsBadReadPtr(addr, len)) /* Can we read the host address */ + { + iErrno = WSAEFAULT; + return 0; + } + sprintf(achDNSBuffer, "%d.%d.%d.%d.in-addr.arpa", + (int) (unsigned char) addr[3], + (int) (unsigned char) addr[2], + (int) (unsigned char) addr[1], + (int) (unsigned char) addr[0]); + pps = SendDNSQuery(achDNSBuffer, FALSE); + pdnsi = pps->pdnsi; + memcpy(pdnsi->achInput, addr, 4); + pdnsi->hwndNotify = hWnd; + pdnsi->pchLocation = buf; + pdnsi->wMsg = wMsg; + return (HANDLE) (pdnsi->idRequest | 0x4000); } -int pascal far _export WSACancelAsyncRequest(HANDLE hAsyncTaskHandle) +int CALLBACK _export WSACancelAsyncRequest(HANDLE hAsyncTaskHandle) { struct tx_queue *ptxq; + struct per_socket *pps; + struct per_task *ppt; - if (!GetTaskInfo()) + if ((ppt = GetTaskInfo()) == 0) return -1; for (ptxq = ptxqList; ptxq; ptxq = ptxq->ptxqNext) @@ -2339,17 +2816,30 @@ int pascal far _export WSACancelAsyncRequest(HANDLE hAsyncTaskHandle) return 0; } } + for (pps = ppsList; pps; pps++) + { + if (pps->htaskOwner == ppt->htask && + pps->pdnsi && + (HANDLE) (pps->pdnsi->idRequest | 0x4000) == hAsyncTaskHandle) + { + KillTimer(ppt->hwndDNS, pps->s); + free(pps->pdnsi->pchQuery); + free(pps->pdnsi); + pps->pdnsi = 0; + closesocket(pps->s); + return 0; + } + } iErrno = WSAEINVAL; return -1; } -int pascal far _export WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, +int CALLBACK _export WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, long lEvent) { - struct per_task *ppt; struct per_socket *pps; - if ((ppt = GetTaskInfo()) == 0) + if (GetTaskInfo() == 0) return -1; if ((pps = GetSocketInfo(s)) == 0) return -1; @@ -2370,7 +2860,7 @@ int pascal far _export WSAAsyncSelect(SOCKET s, HWND hWnd, u_int wMsg, return 0; } -int FAR PASCAL _export __WSAFDIsSet(SOCKET s, fd_set FAR *pfds) +int CALLBACK _export __WSAFDIsSet(SOCKET s, fd_set FAR *pfds) { u_short i; diff --git a/winsock.def b/winsock.def index ef358ec..2ee2cfb 100644 --- a/winsock.def +++ b/winsock.def @@ -50,9 +50,8 @@ EXPORTS WSASTARTUP @115 WSACLEANUP @116 __WSAFDISSET @151 - RESPONSERECEIVED @200 - REGISTERMANAGER @201 - SETINITIALISED @202 - WEP @203 - LIBMAIN @204 + + WEP @1000 + LIBMAIN @1001 + DDEPROC @1002 diff --git a/winsock.lib b/winsock.lib new file mode 100644 index 0000000..b7062d3 Binary files /dev/null and b/winsock.lib differ diff --git a/wsock32.def b/wsock32.def new file mode 100644 index 0000000..753d804 --- /dev/null +++ b/wsock32.def @@ -0,0 +1,60 @@ +LIBRARY WSOCK32 + +DESCRIPTION 'BSD Socket API for Windows ' + +DATA MULTIPLE NONSHARED + +EXPORTS + accept @1 + bind @2 + closesocket @3 + connect @4 + getpeername @5 + getsockname @6 + getsockopt @7 + htonl @8 + htons @9 + inet_addr @10 + inet_ntoa @11 + ioctlsocket @12 + listen @13 + ntohl @14 + ntohs @15 + recv @16 + recvfrom @17 + select @18 + send @19 + sendto @20 + setsockopt @21 + shutdown @22 + socket @23 + gethostbyaddr @51 + gethostbyname @52 + getprotobyname @53 + getprotobynumber @54 + getservbyname @55 + getservbyport @56 + gethostname @57 + WSAAsyncSelect @101 + WSAAsyncGetHostByAddr @102 + WSAAsyncGetHostByName @103 + WSAAsyncGetProtoByNumber @104 + WSAAsyncGetProtoByName @105 + WSAAsyncGetServByPort @106 + WSAAsyncGetServByName @107 + WSACancelAsyncRequest @108 + WSASetBlockingHook @109 + WSAUnhookBlockingHook @110 + WSAGetLastError @111 + WSASetLastError @112 + WSACancelBlockingCall @113 + WSAIsBlocking @114 + WSAStartup @115 + WSACleanup @116 + __WSAFDIsSet @151 + + WEP @1000 + LibMain @1001 + DdeProc @1002 + DllEntryPoint @1003 +