From 14834f4f3eb5982dac86b05ed0ae6da14bb6577c Mon Sep 17 00:00:00 2001 From: Brian Bruns Date: Fri, 12 Oct 2001 23:28:40 +0000 Subject: [PATCH] Initial revision --- AUTHORS | 58 + BUGS | 44 + COPYING | 340 +++ COPYING.LIB | 481 ++++ ChangeLog | 193 ++ INSTALL | 239 ++ Makefile.am | 22 + Makefile.in | 355 +++ NEWS | 0 PWD | 17 + README | 91 + TODO | 21 + aclocal.m4 | 535 +++++ config.guess | 886 +++++++ config.sub | 954 ++++++++ configure | 2608 ++++++++++++++++++++ configure.in | 170 ++ freetds.conf | 78 + include/Makefile.am | 19 + include/Makefile.in | 247 ++ include/README | 4 + include/bkpublic.h | 44 + include/cspublic.h | 550 +++++ include/cstypes.h | 40 + include/ctlib.h | 57 + include/ctpublic.h | 39 + include/dblib.h | 47 + include/sqldb.h | 31 + include/sqlfront.h | 30 + include/sybdb.h | 490 ++++ include/syberror.h | 39 + include/sybfront.h | 40 + include/tds.h | 608 +++++ include/tds.h.in | 608 +++++ include/tds_configs.h | 39 + include/tds_configs.h.in | 38 + include/tdsconvert.h | 46 + include/tdsodbc.h | 61 + include/tdsutil.h | 85 + include/tdsver.h | 29 + include/tdsver.h.in | 29 + install-sh | 250 ++ interfaces | 41 + ltconfig | 3017 +++++++++++++++++++++++ ltmain.sh | 3975 +++++++++++++++++++++++++++++++ missing | 188 ++ mkinstalldirs | 40 + samples/debug.c | 62 + src/Makefile.am | 5 + src/Makefile.in | 288 +++ src/ctlib/Makefile.am | 9 + src/ctlib/Makefile.in | 406 ++++ src/ctlib/blk.c | 53 + src/ctlib/cs.c | 105 + src/ctlib/ct.c | 1279 ++++++++++ src/ctlib/ctutil.c | 78 + src/ctlib/unittests/Makefile.am | 11 + src/ctlib/unittests/Makefile.in | 371 +++ src/ctlib/unittests/common.c | 171 ++ src/ctlib/unittests/common.h | 14 + src/ctlib/unittests/t0001.c | 35 + src/ctlib/unittests/t0002.c | 124 + src/ctlib/unittests/t0003.c | 158 ++ src/ctlib/unittests/t0004.c | 120 + src/dblib/Makefile.am | 9 + src/dblib/Makefile.in | 414 ++++ src/dblib/bcp.c | 577 +++++ src/dblib/dblib.c | 2077 ++++++++++++++++ src/dblib/dbutil.c | 126 + src/dblib/rpc.c | 45 + src/dblib/unittests/Makefile.am | 27 + src/dblib/unittests/Makefile.in | 500 ++++ src/dblib/unittests/README | 21 + src/dblib/unittests/common.c | 199 ++ src/dblib/unittests/common.h | 33 + src/dblib/unittests/pwd.c | 35 + src/dblib/unittests/t0001.c | 200 ++ src/dblib/unittests/t0002.c | 222 ++ src/dblib/unittests/t0003.c | 201 ++ src/dblib/unittests/t0004.c | 203 ++ src/dblib/unittests/t0005.c | 226 ++ src/dblib/unittests/t0006.c | 231 ++ src/dblib/unittests/t0007.c | 225 ++ src/dblib/unittests/t0008.c | 189 ++ src/dblib/unittests/t0009.c | 182 ++ src/dblib/unittests/t0010.c | 182 ++ src/dblib/unittests/t0011.c | 169 ++ src/dblib/unittests/t0012.c | 118 + src/dblib/unittests/t0013.c | 269 +++ src/dblib/unittests/t0014.c | 290 +++ src/dblib/unittests/t0015.c | 238 ++ src/dblib/unittests/t0016.c | 157 ++ src/dblib/unittests/t0017.c | 156 ++ src/dblib/unittests/t0018.c | 233 ++ src/dblib/unittests/t0020.c | 107 + src/dblib/xact.c | 65 + src/odbc/Makefile.am | 14 + src/odbc/Makefile.in | 343 +++ src/odbc/connectparams.c | 447 ++++ src/odbc/connectparams.h | 42 + src/odbc/odbc.c | 1425 +++++++++++ src/server/Makefile.am | 14 + src/server/Makefile.in | 328 +++ src/server/login.c | 111 + src/server/query.c | 40 + src/server/server.c | 285 +++ src/tds/Makefile.am | 5 + src/tds/Makefile.in | 417 ++++ src/tds/config.c | 705 ++++++ src/tds/convert.c | 849 +++++++ src/tds/login.c | 566 +++++ src/tds/mem.c | 383 +++ src/tds/numeric.c | 193 ++ src/tds/query.c | 151 ++ src/tds/read.c | 365 +++ src/tds/token.c | 1528 ++++++++++++ src/tds/unittests/Makefile.am | 13 + src/tds/unittests/Makefile.in | 389 +++ src/tds/unittests/common.c | 94 + src/tds/unittests/common.h | 14 + src/tds/unittests/t0001.c | 44 + src/tds/unittests/t0002.c | 116 + src/tds/unittests/t0003.c | 72 + src/tds/unittests/t0004.c | 134 ++ src/tds/unittests/t0005.c | 149 ++ src/tds/unittests/t0006.c | 238 ++ src/tds/util.c | 355 +++ src/tds/write.c | 189 ++ 128 files changed, 39056 insertions(+) create mode 100644 AUTHORS create mode 100644 BUGS create mode 100644 COPYING create mode 100644 COPYING.LIB create mode 100644 ChangeLog create mode 100644 INSTALL create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 PWD create mode 100644 README create mode 100644 TODO create mode 100644 aclocal.m4 create mode 100755 config.guess create mode 100755 config.sub create mode 100755 configure create mode 100644 configure.in create mode 100644 freetds.conf create mode 100644 include/Makefile.am create mode 100644 include/Makefile.in create mode 100644 include/README create mode 100644 include/bkpublic.h create mode 100644 include/cspublic.h create mode 100644 include/cstypes.h create mode 100644 include/ctlib.h create mode 100644 include/ctpublic.h create mode 100644 include/dblib.h create mode 100644 include/sqldb.h create mode 100644 include/sqlfront.h create mode 100644 include/sybdb.h create mode 100644 include/syberror.h create mode 100644 include/sybfront.h create mode 100644 include/tds.h create mode 100644 include/tds.h.in create mode 100644 include/tds_configs.h create mode 100644 include/tds_configs.h.in create mode 100644 include/tdsconvert.h create mode 100644 include/tdsodbc.h create mode 100644 include/tdsutil.h create mode 100644 include/tdsver.h create mode 100644 include/tdsver.h.in create mode 100755 install-sh create mode 100644 interfaces create mode 100755 ltconfig create mode 100644 ltmain.sh create mode 100755 missing create mode 100755 mkinstalldirs create mode 100644 samples/debug.c create mode 100644 src/Makefile.am create mode 100644 src/Makefile.in create mode 100644 src/ctlib/Makefile.am create mode 100644 src/ctlib/Makefile.in create mode 100644 src/ctlib/blk.c create mode 100644 src/ctlib/cs.c create mode 100644 src/ctlib/ct.c create mode 100644 src/ctlib/ctutil.c create mode 100644 src/ctlib/unittests/Makefile.am create mode 100644 src/ctlib/unittests/Makefile.in create mode 100644 src/ctlib/unittests/common.c create mode 100644 src/ctlib/unittests/common.h create mode 100644 src/ctlib/unittests/t0001.c create mode 100644 src/ctlib/unittests/t0002.c create mode 100644 src/ctlib/unittests/t0003.c create mode 100644 src/ctlib/unittests/t0004.c create mode 100644 src/dblib/Makefile.am create mode 100644 src/dblib/Makefile.in create mode 100644 src/dblib/bcp.c create mode 100644 src/dblib/dblib.c create mode 100644 src/dblib/dbutil.c create mode 100644 src/dblib/rpc.c create mode 100644 src/dblib/unittests/Makefile.am create mode 100644 src/dblib/unittests/Makefile.in create mode 100644 src/dblib/unittests/README create mode 100644 src/dblib/unittests/common.c create mode 100644 src/dblib/unittests/common.h create mode 100644 src/dblib/unittests/pwd.c create mode 100644 src/dblib/unittests/t0001.c create mode 100644 src/dblib/unittests/t0002.c create mode 100644 src/dblib/unittests/t0003.c create mode 100644 src/dblib/unittests/t0004.c create mode 100644 src/dblib/unittests/t0005.c create mode 100644 src/dblib/unittests/t0006.c create mode 100644 src/dblib/unittests/t0007.c create mode 100644 src/dblib/unittests/t0008.c create mode 100644 src/dblib/unittests/t0009.c create mode 100644 src/dblib/unittests/t0010.c create mode 100644 src/dblib/unittests/t0011.c create mode 100644 src/dblib/unittests/t0012.c create mode 100644 src/dblib/unittests/t0013.c create mode 100644 src/dblib/unittests/t0014.c create mode 100644 src/dblib/unittests/t0015.c create mode 100644 src/dblib/unittests/t0016.c create mode 100644 src/dblib/unittests/t0017.c create mode 100644 src/dblib/unittests/t0018.c create mode 100644 src/dblib/unittests/t0020.c create mode 100644 src/dblib/xact.c create mode 100644 src/odbc/Makefile.am create mode 100644 src/odbc/Makefile.in create mode 100644 src/odbc/connectparams.c create mode 100644 src/odbc/connectparams.h create mode 100644 src/odbc/odbc.c create mode 100644 src/server/Makefile.am create mode 100644 src/server/Makefile.in create mode 100644 src/server/login.c create mode 100644 src/server/query.c create mode 100644 src/server/server.c create mode 100644 src/tds/Makefile.am create mode 100644 src/tds/Makefile.in create mode 100644 src/tds/config.c create mode 100644 src/tds/convert.c create mode 100644 src/tds/login.c create mode 100644 src/tds/mem.c create mode 100644 src/tds/numeric.c create mode 100644 src/tds/query.c create mode 100644 src/tds/read.c create mode 100644 src/tds/token.c create mode 100644 src/tds/unittests/Makefile.am create mode 100644 src/tds/unittests/Makefile.in create mode 100644 src/tds/unittests/common.c create mode 100644 src/tds/unittests/common.h create mode 100644 src/tds/unittests/t0001.c create mode 100644 src/tds/unittests/t0002.c create mode 100644 src/tds/unittests/t0003.c create mode 100644 src/tds/unittests/t0004.c create mode 100644 src/tds/unittests/t0005.c create mode 100644 src/tds/unittests/t0006.c create mode 100644 src/tds/util.c create mode 100644 src/tds/write.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..776b64b6e --- /dev/null +++ b/AUTHORS @@ -0,0 +1,58 @@ +Brian Bruns +Started this crazy thing + +Gregg Jensen +Message handlers and extra datatype support and some sybperl stuff? + +Arno Pedusaar +Donated his TDS4.2 code to the cause + +Mihai Ibanescu +GNUified the packet + +Craig Spannring +JDBC driver and CVS repository. + +Mark Schaal +Cleaned up message handling, bug fixes, ctlib unittests + +Kevin Lyons +Various TDS bug fixes + +Sam Tetherow +Various TDS bug fixes + +Geoff Winkless +Lost connection stuff + +Ken Seymour +ODBC Driver Fixes + +Scott Gray +TDS 7.0 numeric support and bug fixes + +Bob Kline +NTEXT support + +Koscheev Andrey +negative money patch + +Dennis Nicklaus +vxWorks port and fixes for dbdata() and SYBVARBINARY + +Brandon M. Reynolds +fix for arbitrarily large queries under dblib. + +Steve Langasek +off by one fixes and autoconf byte size thing. + +Mark J. Lilback +implementation of dbstrlen and dbstrcpy + +John F. Dumas +patch to fix memory leaks. + +Thanks go to the folks at A2i, Inc. (http://www.a2i.com) for funding the +development of dblib host file bulk copy and writetext support, and to Dave +Poyourow there for helping with the debugging. + diff --git a/BUGS b/BUGS new file mode 100644 index 000000000..2f1d74db7 --- /dev/null +++ b/BUGS @@ -0,0 +1,44 @@ +Recently Fixed +-------------- +1. Bug under SQL 7 with large (> 512 bytes) queries. (default block size + is changed by the server) +2. ct_cancel/dbcancel doesn't work right +3. Negative smallmoney values not working +4. change in dbsqlexec has broken query pending client msg under dblib +5. Core dump on failed login see dblib/unittests/t0001 + (return from dbproc() not checked, but should it coredump?) +6. make clean doesn't do obdc or unittests directories +7. make dist doesn't work right. +8. Check int sizes in autoconf + +Believed Fixed +-------------- +1. missing digit on numeric/float types under some clients +2. text values getting truncated to 255 bytes under TDS 7. (can someone + provide more detail?) +3. code to send COL_NAME and COL_INFO tokens are not in the server stuff. + +Needs Fixing +------------ +1. Text values not being handled for ctlib/dblib, tds works + (I think dblib works, but ctlib needs work) +2. Fix formatting of dbprhead/dbprrow...its a little off + (Anybody care?) +3. Stored procedure return statuses not propagated + (more detail?) +4. text/image does not work for row buffering under dblib. +5. Intermittant crash with PHP apache module. (Unknown marker messages + appear in the log...) +6. dbwritetext() and friends do not work under TDS 7.0 +7. tds_get_*int() and tds_put_*int() should handle either endianess on any + platform. Breaks TDS 7.0 under big end machines. +8. There is a bug with the order of returns from ct_results() such that rows + affected doesn't show up in sqsh. +9. dbsqlexec() needs a dbresults() loop on error and shouldn't +10. freetds.conf requires server names to be lower case. + +Reported but not confirmed +-------------------------- +1. Insert/Update queries reported not to work on TDS 7. (couldn't confirm) +2. make distclean doesn't handle unittest directories. + diff --git a/COPYING b/COPYING new file mode 100644 index 000000000..eeb586b39 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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. diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 000000000..eb685a5ec --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,481 @@ + 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! diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..aa9668f04 --- /dev/null +++ b/ChangeLog @@ -0,0 +1,193 @@ +- tdspool now working for big endian systems +- Fixed mem leak in ctlib +- Added some descriptive text to the PWD file +- EINTR handling during login (Kostya Ivanov) +- Added support for TLI style interfaces files (thanks Michael for explaining) +- Added 'text size' config option which changes textsize on connect +- Added preliminary TDS 8.0 support (no new datatypes supported though) +- Added 'emulate little endian' config flag +- Some TDS5 placeholder stuff. Not ready for primetime yet. +- Fixed interfaces handling seg fault + +* Jul 2001 Brian Bruns +- Version 0.52 +- Mem leak fixes in dbloginfree() and tds_free_env() (John Dumas) +- Added support for new configuration format (freetds.conf) +- unixODBC now working +- Fixed error in two's complement function for money types +- Added support for nullable bits (BITN) +- checked in work on tds connection pooling server +- added preliminary userguide (James Lowden and me) +- a lot of work on ODBC driver, now works with PHP +- added config options for iodbc/unixodbc (unixODBC doesn't actually work yet) +- image -> char now works (verified with ctlib only) +- varbinary -> char now works with destlen of -1 +- New config routines +- Free socket on login fail +- 64bit patches +- off by one error +- numeric problem with 7.0 fixed +- digit cutoff on numerics/floats fixed + +* Nov 2000 Brian Bruns +- Version 0.51 +- removed all the old unittests from the samples directory +- endian detection fixed +- 'make check' and ctlib unittests (Mark) +- TDS 7.0 fixes, numerics et al. (Scott) +- dead connection handling (Geoff) +- query timeout stuff (Jeff) + +* Dec 1999 Brian Bruns +- Version 0.50 +- Added TDS 7.0 support for MS SQL 7 +- Added hostfile bulk copy for dblib +- Added writetext support for dblib +- Added CS_CON_STATUS property to ctlib +- Fixed bugs for ctlib version of PHP 3/4 +- Many changes to text/image handling +- New script for running the unittests +- dbcancel/ct_cancel now working properly +- inserts/updates now return proper rowcount +- Numerous bug fixes + +* Sep 1999 Brian Bruns +- Version 0.47 +- Added workaround for SQL 7.0 bug handling datetime/money + for big endian (testing/bug report - Paul Schaap) +- Added TDS 7.0 login function (untested) +- Fixed many big endian bugs +- Fixed some bus errors on Sparc +- Fixed big endian detection +- DBD::Sybase 0.19 now passes all tests +- Fixed date bug working with PHP 3.x +- binary/varbinary support added +- Fixed Text datatypes in tds layer +- More conversions implemented (Mark Schaal) +- Fix make install for not overwriting interfaces (Michael Peppler) +- CS_USERDATA now works +- Numerous bug fixes (many people) + +* Thu Aug xx 1999 Brian Bruns +- Version 0.46 +- Fixed floating type support +- Fixed lots of little datatype conversion bugs +- Fixed 5.0 login acknowledgement bug +- Message processing was cleaned up (Mark Schaal) +- Fixed login bug for SQL Server 7.0 +- DBD::Sybase 0.19 now compiles and partially works (very partially) +- Fixed Solaris #define clash +- Numerous bug fixes + +* Thu Jun 03 1999 Brian Bruns +- Version 0.45 +- Capabilities added to ctlib code +- Numeric support working +- MONEY to string conversions now support > 32 bit values +- Fixed underread in message handling +- Fixed various buffer overflow problems +- Fixed NULL handling +- Added support for length binding (copied arguement to ct_bind) +- Converted ODBC to use iODBC driver manager +- SQSH 1.7 runs +- PHP 3.0.x with ctlib now runs + +* Thu Jan 14 1999 Brian Bruns +- Version 0.41 +- Better row buffering (Craig Spannring) +- CT-Lib code improved greatly +- Closer behaviour to real dblib +- Commonized datatype conversions +- Server side code is running somewhat. +- SQSH 1.6 running +- More ODBC functionality +- Many bug fixes +- Lots of other stuff I've already forgotten + +* Sun Nov 22 1998 Brian Bruns +- Version 0.40 +- Row buffering is now supported for dblib. +- Better row handling (side effect of above) +- Improved conversion code +- Preliminary ODBC layer +- PHP now runs basic scripts, maybe more +- Many many bug fixes +- General cleanup (better error handling, C++ friendly headers, etc...) + +* Fri Sep 04 1998 Mihai Ibanescu +- Version 0.31 +- By default the install dir is /usr/local/freetds +- The Makefile in the samples dir is automatically built from Makefile.am. + The samples dir is not installed, only packaged in the distribution. + +* Wed Sep 02 1998 Brian Bruns +- Version 0.3 +- Updated the AUTHORS file +- FIXME Brian (added by misa) + +* Mon Aug 31 1998 Mihai Ibanescu +- Version 0.21 +- GNUified +- Fixed a couple of the TODO issues: byte order is automatically determined, + and the TDS version is a configurable option +- Modified the README file to reflect the new directory structure + +Pre-GNUification log by Brian : + +2/8/98 Should be able to send the first packet to a server soon, my output is + only slightly different than open clients. + This codes pretty crappy right now. I need to clean up alot of stuff, + remove hardcode values, etc...but I'm anxious to see something work! +2/7/98 Broke the code up a bit, tds.c now handles all wire level stuff, + dblib.c handles dblib specific stuff. So, in the future there can be + ctlib.c and obdc.c can also sit on top of tds.c to handle the other CLIs +3/16/98 Been working on the code here and there...We can now send a query to + the server, dbnumcols() and dbcolname() both work. Almost ready to get + some data back. I put in a dummy dbbind to just handle strings so, + I could do some work on dbnextrow(). However, we will have revisit + almost everything later. +3/23/98 Haven't been able to work on it lately. Still trying to decide on the + best way to propagate the row data from tds.c to dblib.c to the calling + func. Not that hard, but nothing strikes me as the "Right Way" (tm). +4/2/98 Ok we are ready to release 0.01 (marked by the fact that a simple dblib + program actually works!) +5/1/98 Haven't updated in quite a while. A few more dblib commands are + supported. dbconvert() support is preliminary. Fixed alot of bugs. A + little bit of cleanup. dbbind() sorta works now, needs work still. + At least one mem leak that I know of (haven't gotten around to fixing + it. Wish I had more time to work on it... +5/2/98 Decided to release what I have. executing sp_who seems to mostly work.. + a step in the right direction. Version 0.02. Seem to have generated a + little interest after mentioning it in a usenet post. +5/6/98 Can compile against sqsh!!! Did a reorg on tds.c, all dblib func that + read data now go through tds_process_messages() which read the marker + and calls other routines as necessary. sqsh's output is a little screwy + (well I don't have a real dbprrow() yet, but the number of result sets + coming back is too many). So, anyway Version 0.04 +5/9/98 Decided to upload some new code, mostly just stubs. Sybperl compiles + I can't get my perl to work with it. (I need to download perl and link + statically, the one that comes on the system won't do). Anyway, + most of dblib is present in stub form. +5/17/98 Managed to scrape up some time and release new code. Duplicate result + sets went away, and handling of more datatypes (money, bit, more int + stuff). Also, improved dbprhead()/row() function. +5/26/98 Ok, I'm doing the long overdue cleaning up of the code. All the kludges + should be gone. Thanks, to everyone who contributed + code/idea/corrections. +6/3/98 The majority of the overhaul is done...still some work to do, but this + is much better than before. I'm bumping the version to 0.1 signifying + that I actually use sqsh compiled against it on a regular basis. +6/5/98 TDS 4.2 support seems to be working properly +6/26/98 Gregg Jenson has added support for err and msg handling among other + things. I've added some prelimary ctlib support (nothing working yet) +7/3/98 I think we are about ready to release 0.2. Gregg sent some datetime code + which appears to work great. I added TDS 4.6 support (small changes + really) and tested all the byte order issues on an RS/6000. Also, ctlib + code will run the unittest.c and will compile all modules in sqsh 1.6, + however there are many missing functions before it will link! +7/10/98 Haven't been able to work on it lately (moved this week). Anyway, + trying to add some functions to server. +7/13/98 Tom Poindexter made some changes to get sybtcl to work. +8/8/98 Haven't had much time lately (again), however some small stuff has + been fixed and the protocol version stuff has (mostly) been moved to a + runtime option. sybperl is supposedly running for simple stuff. diff --git a/INSTALL b/INSTALL new file mode 100644 index 000000000..f2a24d3c7 --- /dev/null +++ b/INSTALL @@ -0,0 +1,239 @@ +Basic Installation +================== + +--------- + + Until these instructions are more specific, try the following: + + $ ./configure [--prefix=] [--with-tdsver=] [--enable-msdblib] [--enable-dbmfix] + the default prefix is /usr/local/freetds + The default TDS version is 5.0, use 4.2 for MS-SQL or Sybase < 10.0 + Use 7.0 to get support for unicode and large varchars under SQL + Server 7.0 + $ gmake + $ gmake install + + Now set the SYBASE environment variable to the install directory and then +add $SYBASE/lib to your LD_LIBRARY_PATH or LIBPATH depending on your system: + for sh/ksh/bash: + + $ SYBASE=/usr/local/freetds + $ LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:$SYBASE/lib + $ export SYBASE LD_LIBRARY_PATH + for csh: + $ setenv SYBASE /usr/local/freetds + $ setenv LD_LIBRARY_PATH ${LD_LIBRARY_PATH}:$SYBASE/lib + + When running apache use the SetEnv directive in the httpd.conf file: + + SetEnv SYBASE /usr/local/freetds + + Edit the $SYBASE/interfaces file to add your servers. If you are not familiar +with the Sybase interfaces file, copy one of the examples and change the IP +address and port number to that of your server. + + To compile DB-Lib programs link with the libsybdb.a library exactly as you +would with the OpenClient(tm) libraries. + + To compile CT-Lib programs link with the libct.a library. Note: This is +different than OpenClient(tm) libraries, which require several libraries in +addition to -lct. This will probably stay this way as some of the library +names clash with other libraries (tcl for instance). + + The --enable-msdblib flag will force freetds to use the Microsoft style API +for dblib (the two diverge in some areas). This is helpful when porting dblib +code coming from a Windows environment. In general do not use if you are using +Sybase derived tools to connect to SQL Server (PHP, DBD::Sybase, etc...) + + The --enable-dbmfix flag will rename dbopen() to tdsdbopen() to allow the +dblib library to be linked into the same executable with dbm. However, this +means references to 'dbopen' must be changed in the client application. Check +the FreeTDS website (http://www.freetds.org) for patches for PHP 4. + +To run the test programs, edit the file "PWD" and run 'make check'. +Note that some test programs mail may fail even though TDS is fine. + dblib/unittests/t0009 - equality check incorrect? + dblib/unittests/t0013 - expects arguments + dblib/unittests/t0014 - expects arguments + +------ + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, a file +`config.cache' that saves the results of its tests to speed up +reconfiguring, and a file `config.log' containing compiler output +(useful mainly for debugging `configure'). + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If at some point `config.cache' +contains results you don't want to keep, you may remove or edit it. + + The file `configure.in' is used to create `configure' by a program +called `autoconf'. You only need `configure.in' if you want to change +it or regenerate `configure' using a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. Type ./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. (Note- FreeBSD users need to + use 'gmake' instead of the standard Berkeley make program.) + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. You can give `configure' +initial values for variables by setting them in the environment. Using +a Bourne-compatible shell, you can do that on the command line like +this: + CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure + +Or on systems that have the `env' program, you can do it like this: + env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not supports the `VPATH' +variable, you have to compile the package for one architecture at a time +in the source code directory. After you have installed the package for +one architecture, use `make distclean' before reconfiguring for another +architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' can not figure out +automatically, but needs to determine by the type of host the package +will run on. Usually `configure' can figure that out, but if it prints +a message saying it can not guess the host type, give it the +`--host=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name with three fields: + CPU-COMPANY-SYSTEM + +See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the host type. + + If you are building compiler tools for cross-compiling, you can also +use the `--target=TYPE' option to select the type of system they will +produce code for and the `--build=TYPE' option to select the type of +system on which you are compiling the package. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Operation Controls +================== + + `configure' recognizes the following options to control how it +operates. + +`--cache-file=FILE' + Use and save the results of the tests in FILE instead of + `./config.cache'. Set FILE to `/dev/null' to disable caching, for + debugging `configure'. + +`--help' + Print a summary of the options to `configure', and exit. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`--version' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`configure' also accepts some other, not widely useful, options. diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000..4cb67ed94 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,22 @@ +SUBDIRS = include src + +EXTRA_DIST = interfaces freetds.conf samples/debug.c PWD BUGS + +DEFDIR = $(prefix) +ETC = $(sysconfdir) + +install-data-local: + $(mkinstalldirs) $(DEFDIR) $(ETC) + if [ -f $(DEFDIR)/interfaces ]; \ + then :; \ + else \ + $(INSTALL_DATA) interfaces $(DEFDIR); \ + fi + if [ -f $(ETC)/freetds.conf ]; \ + then :; \ + else \ + $(INSTALL_DATA) freetds.conf $(ETC)/freetds.conf; \ + fi + +test: + @echo "The 'make test' option has been replaced with 'make check'"; diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 000000000..e607fb11f --- /dev/null +++ b/Makefile.in @@ -0,0 +1,355 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = . + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +SUBDIRS = include src + +EXTRA_DIST = interfaces freetds.conf samples/debug.c PWD BUGS + +DEFDIR = $(prefix) +ETC = $(sysconfdir) +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +DIST_COMMON = README AUTHORS COPYING COPYING.LIB ChangeLog INSTALL \ +Makefile.am Makefile.in NEWS TODO aclocal.m4 config.guess config.sub \ +configure configure.in install-sh ltconfig ltmain.sh missing \ +mkinstalldirs + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(ACLOCAL_M4): configure.in + cd $(srcdir) && $(ACLOCAL) + +config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + $(SHELL) ./config.status --recheck +$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES) + cd $(srcdir) && $(AUTOCONF) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(PACKAGE)-$(VERSION) +top_distdir = $(distdir) + +# This target untars the dist file and tries a VPATH configuration. Then +# it guarantees that the distribution is self-contained by making another +# tarfile. +distcheck: dist + -rm -rf $(distdir) + GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz + mkdir $(distdir)/=build + mkdir $(distdir)/=inst + dc_install_base=`cd $(distdir)/=inst && pwd`; \ + cd $(distdir)/=build \ + && ../configure --srcdir=.. --prefix=$$dc_install_base \ + && $(MAKE) $(AM_MAKEFLAGS) \ + && $(MAKE) $(AM_MAKEFLAGS) dvi \ + && $(MAKE) $(AM_MAKEFLAGS) check \ + && $(MAKE) $(AM_MAKEFLAGS) install \ + && $(MAKE) $(AM_MAKEFLAGS) installcheck \ + && $(MAKE) $(AM_MAKEFLAGS) dist + -rm -rf $(distdir) + @banner="$(distdir).tar.gz is ready for distribution"; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes" +dist: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +dist-all: distdir + -chmod -R a+r $(distdir) + GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir) + -rm -rf $(distdir) +distdir: $(DISTFILES) + -rm -rf $(distdir) + mkdir $(distdir) + -chmod 777 $(distdir) + $(mkinstalldirs) $(distdir)/samples + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: install-data-local +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + -rm -f config.status + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + -rm -f config.status + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-local install-data-am install-data install-am \ +install uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +install-data-local: + $(mkinstalldirs) $(DEFDIR) $(ETC) + if [ -f $(DEFDIR)/interfaces ]; \ + then :; \ + else \ + $(INSTALL_DATA) interfaces $(DEFDIR); \ + fi + if [ -f $(ETC)/freetds.conf ]; \ + then :; \ + else \ + $(INSTALL_DATA) freetds.conf $(ETC)/freetds.conf; \ + fi + +test: + @echo "The 'make test' option has been replaced with 'make check'"; + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/NEWS b/NEWS new file mode 100644 index 000000000..e69de29bb diff --git a/PWD b/PWD new file mode 100644 index 000000000..188f75ac9 --- /dev/null +++ b/PWD @@ -0,0 +1,17 @@ +# This file was taken from DBD::Sybase :-) It is used by 'make check' to test +# the installation +# +# UID: the username of a user to connect with +# PWD: the password for that user +# SRV: the symbolic server name from the freetds.conf (or interfaces) file. +# Note: if you use a hostname/IP here instead, freetds will attempt to +# connect using the compiletime default port (4000 for TDS 5.0, 1433 for +# 4.2 or 7.0) which is usually not right. +# DB: Database in which to create tables used in the tests. For those new to +# Sybase or MS SQL server, there may be many database per server. tempdb +# is a good default choice if unsure. +# +UID=guest +PWD=sybase +SRV=JDBC +DB=tempdb diff --git a/README b/README new file mode 100644 index 000000000..9127cf51d --- /dev/null +++ b/README @@ -0,0 +1,91 @@ + +This is FreeTDS 0.53 + + FreeTDS is a free (open source) implementation of Sybase's db-lib, +ct-lib, and ODBC libraries. Currently, dblib and ctlib are most mature. Both +of these libraries have several programs known to compile and run against them. +ODBC is not quite as mature, but may work depending on your needs. + + Submissions of test programs (self-contained programs that demonstrate +functionality or problems) are greatly appreciated. They should create any +tables needed (since we obviously don't have access to your database) and +populate them. One possible exception is test code that works against the +pubs2 database. Unit tests for any of the libraries is appreciated + + FreeTDS will run at protocol versions 4.2, 5.0 and 7.0 and thus can +access both Sybase and Microsoft SQL-Servers. Note: Microsoft SQL servers +do not support TDS version 5.0 and need to be configured with the +--with-tdsver=4.2 flag. + +Support for TDS 7.0 (the version used by MS SQL Server 7.0) is now included. +It is not as mature as the other protocol versions, but is required to access +large (more than 255 character) char/varchar fields. That said, TDS 7.0 +support can be configured by using the --with-tdsver=7.0 when running +configure. + +FreeTDS is licensed under the Gnu LGPL license. See COPYING.LIB for details. + +To build look at the INSTALL file. + +Note to FreeBSD users- You must use 'gmake' to build this package. + +Bug submissions +--------------- + +If you want your bugs actually fixed in a timely manner (and who doesn't!?), +any bug submissions (to the mailing list or the bug tracking system) should +include the following. + +1) a small program demonstrating the problem. This can be in C, PHP, Perl, or + simply the SQL if it is reproducable in SQSH. +2) The DDL for your table(s) from the SQL above. A lot of bugs can be + particular to one datatype and without this information it'll be hard to + determine your problem. A simple list of column names, datatypes, and + lengths would also be acceptable if you can't get or don't know how to + produce the DDL. (output from sp_help will do this nicely) +3) The version of FreeTDS you are running, but in general try to get the + lastest snapshot or CVS version before reporting a bug. +4) The TDS protocol version. It's the --with-tdsver flag you configured with + 5.0 is the default. Many bugs are protocol specific and you may just get + a 'works for me' if you don't say which version. +5) Your platform e.g. Redhat 7.0, Solaris 2.6, Linux 2.2.14...anything close + will do. This is especially important if you are on a big endian platform + (Power/PowerPC, Sparc, etc...), a 64bit platform (Alpha), or you are + experiencing an bus error because of unaligned access (Sparc mostly). + 'uname -a' should produce this info. +6) The type and version of the server you are connecting to. You can send + the query 'select @@version' to get this information. + +Also, be sure to check the FAQ (http://www.freetds.org/faq.html) and mailing +list archive (http://franklin.oit.unc.edu/cgi-bin/lyris.pl?enter=freetds) + +Notes to developers +------------------- + +The code is split into several pieces. + +1) tds directory is the wire level stuff, it should be independant of the +library using it, this will allow DB-Lib, CT-Lib, and ODBC to sit on top. + +2) dblib directory. This is the actual dblib code which runs on top of tds. + +3) ctlib directory. This is the ctlib code which runs on top of tds. + +4) server directory. This will be a set of server routines basically to +impersonate a dataserver, functions like send_login_ack() etc... + +5) odbc directory. ODBC implementation over tds. Uses iODBC or unixODBC as a driver manager. You need to have one of those if you are using the ODBC CLI. + +6) unittests directories. Test harness code for ctlib, dblib and tds. + +6) samples directories. Sample code for getting started with Perl, PHP, etc... + +7) pool directory. A connection pooling server for TDS. Useful if you have a + connection limited license. Needs some hacking to get configured but is + quite stable once configured correctly. Contact the list if interested in + how to use it. + +Please look at doc/getting_started.txt for a description of what is going on +in the code. + +Side note: I, as many free software authors, appreciate postcards from all over. So if you live someplace neat (read: not Michigan) and want to send one, email me (camber@ais.org) for my current snail mail address. diff --git a/TODO b/TODO new file mode 100644 index 000000000..d8e36f84a --- /dev/null +++ b/TODO @@ -0,0 +1,21 @@ +To Do List +------------ +. Add bcp support to tds/dblib/ctlib. (started in dblib) +. Array binding for ctlib not working +. RPC stuff not implemented +. All manner of unimplemented functions +. Need a way to track problems with running apache/PHP, may have many apache + children going. +. ct_dynamic and friends needed for DBD::Sybase placeholder support +. Server API needs more work, especially for TDS 5.0/7.0 +. Add support for TDS 8.0 +. Domain support for MS SQL +. TDS 7 support on big endian clients +. add textsize option for TDS 7 to freetds.conf +. TDS 7 Unicode to native charset conversion using iconv +. tdsping program for testing purposes +. autoconf the connection pooling stuff +. Make pool configuration a non-recompile process +. Add missing constants needed for python and verify working +. Add missing constants needed for Gnome-DB and verify working +. Someone broke early binding in ODBC diff --git a/aclocal.m4 b/aclocal.m4 new file mode 100644 index 000000000..7a4723e8c --- /dev/null +++ b/aclocal.m4 @@ -0,0 +1,535 @@ +dnl aclocal.m4 generated automatically by aclocal 1.4 + +dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +dnl This program is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without +dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A +dnl PARTICULAR PURPOSE. + +# Do all the work for Automake. This macro actually does too much -- +# some checks are only needed if your package does certain things. +# But this isn't really a big deal. + +# serial 1 + +dnl Usage: +dnl AM_INIT_AUTOMAKE(package,version, [no-define]) + +AC_DEFUN(AM_INIT_AUTOMAKE, +[AC_REQUIRE([AC_PROG_INSTALL]) +PACKAGE=[$1] +AC_SUBST(PACKAGE) +VERSION=[$2] +AC_SUBST(VERSION) +dnl test to see if srcdir already configured +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + AC_MSG_ERROR([source directory already configured; run "make distclean" there first]) +fi +ifelse([$3],, +AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package]) +AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])) +AC_REQUIRE([AM_SANITY_CHECK]) +AC_REQUIRE([AC_ARG_PROGRAM]) +dnl FIXME This is truly gross. +missing_dir=`cd $ac_aux_dir && pwd` +AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir) +AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir) +AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir) +AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir) +AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir) +AC_REQUIRE([AC_PROG_MAKE_SET])]) + +# +# Check to make sure that the build environment is sane. +# + +AC_DEFUN(AM_SANITY_CHECK, +[AC_MSG_CHECKING([whether build environment is sane]) +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "[$]*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "[$]*" != "X $srcdir/configure conftestfile" \ + && test "[$]*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken +alias in your environment]) + fi + + test "[$]2" = conftestfile + ) +then + # Ok. + : +else + AC_MSG_ERROR([newly created file is older than distributed files! +Check your system clock]) +fi +rm -f conftest* +AC_MSG_RESULT(yes)]) + +dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY) +dnl The program must properly implement --version. +AC_DEFUN(AM_MISSING_PROG, +[AC_MSG_CHECKING(for working $2) +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if ($2 --version) < /dev/null > /dev/null 2>&1; then + $1=$2 + AC_MSG_RESULT(found) +else + $1="$3/missing $2" + AC_MSG_RESULT(missing) +fi +AC_SUBST($1)]) + + +# serial 40 AC_PROG_LIBTOOL +AC_DEFUN(AC_PROG_LIBTOOL, +[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl + +# Save cache, so that ltconfig can load it +AC_CACHE_SAVE + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \ +|| AC_MSG_ERROR([libtool configure failed]) + +# Reload cache, that may have been modified by ltconfig +AC_CACHE_LOAD + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' +AC_SUBST(LIBTOOL)dnl + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log +]) + +AC_DEFUN(AC_LIBTOOL_SETUP, +[AC_PREREQ(2.13)dnl +AC_REQUIRE([AC_ENABLE_SHARED])dnl +AC_REQUIRE([AC_ENABLE_STATIC])dnl +AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +AC_REQUIRE([AC_PROG_RANLIB])dnl +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_PROG_LD])dnl +AC_REQUIRE([AC_PROG_NM])dnl +AC_REQUIRE([AC_PROG_LN_S])dnl +dnl + +case "$target" in +NONE) lt_target="$host" ;; +*) lt_target="$target" ;; +esac + +# Check for any special flags to pass to ltconfig. +# +# the following will cause an existing older ltconfig to fail, so +# we ignore this at the expense of the cache file... Checking this +# will just take longer ... bummer! +#libtool_flags="--cache-file=$cache_file" +# +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" +ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN], +[libtool_flags="$libtool_flags --enable-dlopen"]) +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[libtool_flags="$libtool_flags --enable-win32-dll"]) +AC_ARG_ENABLE(libtool-lock, + [ --disable-libtool-lock avoid locking (might break parallel builds)]) +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$lt_target" in +*-*-irix6*) + # Find out which ABI we are using. + echo '[#]line __oline__ "configure"' > conftest.$ac_ext + if AC_TRY_EVAL(ac_compile); then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf, + [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])]) + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + +ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL], +[*-*-cygwin* | *-*-mingw*) + AC_CHECK_TOOL(DLLTOOL, dlltool, false) + AC_CHECK_TOOL(AS, as, false) + AC_CHECK_TOOL(OBJDUMP, objdump, false) + ;; +]) +esac +]) + +# AC_LIBTOOL_DLOPEN - enable checks for dlopen support +AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])]) + +# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's +AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])]) + +# AC_ENABLE_SHARED - implement the --enable-shared flag +# Usage: AC_ENABLE_SHARED[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_SHARED, [dnl +define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(shared, +changequote(<<, >>)dnl +<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl +]) + +# AC_DISABLE_SHARED - set the default shared flag to --disable-shared +AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_SHARED(no)]) + +# AC_ENABLE_STATIC - implement the --enable-static flag +# Usage: AC_ENABLE_STATIC[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_STATIC, [dnl +define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(static, +changequote(<<, >>)dnl +<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_static=AC_ENABLE_STATIC_DEFAULT)dnl +]) + +# AC_DISABLE_STATIC - set the default static flag to --disable-static +AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_STATIC(no)]) + + +# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag +# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)] +# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to +# `yes'. +AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl +define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl +AC_ARG_ENABLE(fast-install, +changequote(<<, >>)dnl +<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT], +changequote([, ])dnl +[p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac], +enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl +]) + +# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install +AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl +AC_ENABLE_FAST_INSTALL(no)]) + +# AC_PROG_LD - find the path to the GNU or non-GNU linker +AC_DEFUN(AC_PROG_LD, +[AC_ARG_WITH(gnu-ld, +[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]], +test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no) +AC_REQUIRE([AC_PROG_CC])dnl +AC_REQUIRE([AC_CANONICAL_HOST])dnl +AC_REQUIRE([AC_CANONICAL_BUILD])dnl +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + AC_MSG_CHECKING([for ld used by GCC]) + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. +changequote(,)dnl + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' +changequote([,])dnl + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + AC_MSG_CHECKING([for GNU ld]) +else + AC_MSG_CHECKING([for non-GNU ld]) +fi +AC_CACHE_VAL(ac_cv_path_LD, +[if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi]) +LD="$ac_cv_path_LD" +if test -n "$LD"; then + AC_MSG_RESULT($LD) +else + AC_MSG_RESULT(no) +fi +test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH]) +AC_PROG_LD_GNU +]) + +AC_DEFUN(AC_PROG_LD_GNU, +[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld, +[# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi]) +]) + +# AC_PROG_NM - find the path to a BSD-compatible name lister +AC_DEFUN(AC_PROG_NM, +[AC_MSG_CHECKING([for BSD-compatible nm]) +AC_CACHE_VAL(ac_cv_path_NM, +[if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi]) +NM="$ac_cv_path_NM" +AC_MSG_RESULT([$NM]) +]) + +# AC_CHECK_LIBM - check for math library +AC_DEFUN(AC_CHECK_LIBM, +[AC_REQUIRE([AC_CANONICAL_HOST])dnl +LIBM= +case "$lt_target" in +*-*-beos* | *-*-cygwin*) + # These system don't have libm + ;; +*-ncr-sysv4.3*) + AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw") + AC_CHECK_LIB(m, main, LIBM="$LIBM -lm") + ;; +*) + AC_CHECK_LIB(m, main, LIBM="-lm") + ;; +esac +]) + +# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl convenience library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-convenience to the +# configure arguments. Note that LIBLTDL and INCLTDL are not +# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not +# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed +# with '${top_builddir}/' and INCLTDL will be prefixed with +# '${top_srcdir}/' (note the single quotes!). If your package is not +# flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + case "$enable_ltdl_convenience" in + no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;; + "") enable_ltdl_convenience=yes + ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;; + esac + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) +]) + +# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for +# the libltdl installable library and INCLTDL to the include flags for +# the libltdl header and adds --enable-ltdl-install to the configure +# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is +# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed +# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will +# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed +# with '${top_srcdir}/' (note the single quotes!). If your package is +# not flat and you're not using automake, define top_builddir and +# top_srcdir appropriately in the Makefiles. +# In the future, this macro may have to be called after AC_PROG_LIBTOOL. +AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl + AC_CHECK_LIB(ltdl, main, + [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no], + [if test x"$enable_ltdl_install" = xno; then + AC_MSG_WARN([libltdl not installed, but installation disabled]) + else + enable_ltdl_install=yes + fi + ]) + if test x"$enable_ltdl_install" = x"yes"; then + ac_configure_args="$ac_configure_args --enable-ltdl-install" + LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la + INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl']) + else + ac_configure_args="$ac_configure_args --enable-ltdl-install=no" + LIBLTDL="-lltdl" + INCLTDL= + fi +]) + +dnl old names +AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl +AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl +AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl +AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl +AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl +AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl +AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl + +dnl This is just to silence aclocal about the macro not being used +ifelse([AC_DISABLE_FAST_INSTALL])dnl + +# Define a conditional. + +AC_DEFUN(AM_CONDITIONAL, +[AC_SUBST($1_TRUE) +AC_SUBST($1_FALSE) +if $2; then + $1_TRUE= + $1_FALSE='#' +else + $1_TRUE='#' + $1_FALSE= +fi]) + diff --git a/config.guess b/config.guess new file mode 100755 index 000000000..6e39d7813 --- /dev/null +++ b/config.guess @@ -0,0 +1,886 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# The master version of this file is at the FSF in /home/gd/gnu/lib. +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit system type (host/target name). +# +# Only a few systems have been added to this list; please add others +# (but try to keep the structure clean). +# + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15 + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <dummy.s + .globl main + .ent main +main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]` + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-cbm-sysv4 + exit 0;; + amiga:NetBSD:*:*) + echo m68k-cbm-netbsd${UNAME_RELEASE} + exit 0 ;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + arm32:NetBSD:*:*) + echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + SR2?01:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:*|MIS*:OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:NetBSD:*:*) + echo m68k-atari-netbsd${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:NetBSD:*:*) + echo m68k-sun-netbsd${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:NetBSD:*:*) + echo m68k-apple-netbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:* | :"Mac OS":*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >dummy.c + int main (argc, argv) int argc; char **argv; { + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + ${CC-cc} dummy.c -o dummy \ + && ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \ + -o ${TARGET_BINARY_INTERFACE}x = x ] ; then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:4) + if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=4.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[3478]??:HP-UX:*:*) + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/7?? | 9000/8?[1679] ) HP_ARCH=hppa1.1 ;; + 9000/8?? ) HP_ARCH=hppa1.0 ;; + esac + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + ${CC-cc} dummy.c -o dummy && ./dummy && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F300:UNIX_System_V:*:*) + FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + F301:UNIX_System_V:*:*) + echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'` + exit 0 ;; + hp3[0-9][05]:NetBSD:*:*) + echo m68k-hp-netbsd${UNAME_RELEASE} + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:NetBSD:*:*) + echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo i386-pc-cygwin32 + exit 0 ;; + i*:MINGW*:*) + echo i386-pc-mingw32 + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin32 + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. + ld_help_string=`ld --help 2>&1` + ld_supported_emulations=`echo $ld_help_string \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) echo "${UNAME_MACHINE}-pc-linux-gnuaout" ; exit 0 ;; + i?86coff) echo "${UNAME_MACHINE}-pc-linux-gnucoff" ; exit 0 ;; + sparclinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + m68klinux) echo "${UNAME_MACHINE}-unknown-linux-gnuaout" ; exit 0 ;; + elf32ppc) echo "powerpc-unknown-linux-gnu" ; exit 0 ;; + esac + + if test "${UNAME_MACHINE}" = "alpha" ; then + sed 's/^ //' <dummy.s + .globl main + .ent main + main: + .frame \$30,0,\$26,0 + .prologue 0 + .long 0x47e03d80 # implver $0 + lda \$2,259 + .long 0x47e20c21 # amask $2,$1 + srl \$1,8,\$2 + sll \$2,2,\$2 + sll \$0,3,\$0 + addl \$1,\$0,\$0 + addl \$2,\$0,\$0 + ret \$31,(\$26),1 + .end main +EOF + LIBC="" + ${CC-cc} dummy.s -o dummy 2>/dev/null + if test "$?" = 0 ; then + ./dummy + case "$?" in + 7) + UNAME_MACHINE="alpha" + ;; + 15) + UNAME_MACHINE="alphaev5" + ;; + 14) + UNAME_MACHINE="alphaev56" + ;; + 10) + UNAME_MACHINE="alphapca56" + ;; + 16) + UNAME_MACHINE="alphaev6" + ;; + esac + + objdump --private-headers dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f dummy.s dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0 + elif test "${UNAME_MACHINE}" = "mips" ; then + cat >dummy.c </dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + else + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + echo "$ld_help_string" | grep >/dev/null 2>&1 "supported emulations:" + test $? != 0 && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >dummy.c < +main(argc, argv) + int argc; + char *argv[]; +{ +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0 + rm -f dummy.c dummy + fi ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + pc:*:*:*) + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:*:6*) + echo mips-sony-newsos6 + exit 0 ;; + R3000:*System_V*:*:* | R4000:UNIX_SYSV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +#if !defined (ultrix) + printf ("vax-dec-bsd\n"); exit (0); +#else + printf ("vax-dec-ultrix\n"); exit (0); +#endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0 +rm -f dummy.c dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +#echo '(Unable to guess system type)' 1>&2 + +exit 1 diff --git a/config.sub b/config.sub new file mode 100755 index 000000000..94a92b66d --- /dev/null +++ b/config.sub @@ -0,0 +1,954 @@ +#! /bin/sh +# Configuration validation subroutine script, version 1.1. +# Copyright (C) 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc. +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +if [ x$1 = x ] +then + echo Configuration name missing. 1>&2 + echo "Usage: $0 CPU-MFR-OPSYS" 1>&2 + echo "or $0 ALIAS" 1>&2 + echo where ALIAS is a recognized configuration type. 1>&2 + exit 1 +fi + +# First pass through any local machine types. +case $1 in + *local*) + echo $1 + exit 0 + ;; + *) + ;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + linux-gnu*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple) + os= + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \ + | arme[lb] | pyramid | mn10200 | mn10300 \ + | tron | a29k | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 \ + | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \ + | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \ + | mips64 | mipsel | mips64el | mips64orion | mips64orionel \ + | mipstx39 | mipstx39el \ + | sparc | sparclet | sparclite | sparc64 | v850) + basic_machine=$basic_machine-unknown + ;; + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[3456]86) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + vax-* | tahoe-* | i[3456]86-* | i860-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \ + | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* \ + | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \ + | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \ + | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mipstx39-* | mipstx39el-* \ + | f301-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-cbm + ;; + amigaos | amigados) + basic_machine=m68k-cbm + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-cbm + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [ctj]90-cray) + basic_machine=c90-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k7[0-9][0-9] | hp7[0-9][0-9] | hp9k8[0-9]7 | hp8[0-9]7) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + os=-mvs + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[3456]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[3456]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[3456]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[3456]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + miniframe) + basic_machine=m68000-convergent + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + np1) + basic_machine=np1-gould + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5) + basic_machine=i586-intel + ;; + pentiumpro | p6) + basic_machine=i686-intel + ;; + pentium-* | p5-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + k5) + # We don't have specific support for AMD's K5 yet, so just call it a Pentium + basic_machine=i586-amd + ;; + nexen) + # We don't have specific support for Nexgen yet, so just call it a Pentium + basic_machine=i586-nexgen + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=rs6000-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sparc) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin32* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -darwin*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -xenix) + os=-xenix + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-semi) + os=-aout + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-ibm) + os=-aix + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f301-fujitsu) + os=-uxpv + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -hpux*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os diff --git a/configure b/configure new file mode 100755 index 000000000..c9a743301 --- /dev/null +++ b/configure @@ -0,0 +1,2608 @@ +#! /bin/sh + +# Guess values for system-dependent variables and create Makefiles. +# Generated automatically using autoconf version 2.13 +# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. +# +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. + +# Defaults: +ac_help= +ac_default_prefix=/usr/local +# Any additions from configure.in: +ac_default_prefix=/usr/local/freetds +ac_help="$ac_help + --enable-shared[=PKGS] build shared libraries [default=yes]" +ac_help="$ac_help + --enable-static[=PKGS] build static libraries [default=yes]" +ac_help="$ac_help + --enable-fast-install[=PKGS] optimize for fast installation [default=yes]" +ac_help="$ac_help + --with-gnu-ld assume the C compiler uses GNU ld [default=no]" +ac_help="$ac_help + --disable-libtool-lock avoid locking (might break parallel builds)" +ac_help="$ac_help + --with-tdsver=VERSION specify the TDS version to use \ +(4.2/4.6/5.0/7.0/8.0) [5.0]" +ac_help="$ac_help + --with-iodbc=/path/to/iodbc build odbc driver against iODBC" +ac_help="$ac_help + --with-unixodbc=/path/to/unixodbc build odbc driver against unixODBC" +ac_help="$ac_help + --enable-msdblib For MS style dblib." +ac_help="$ac_help + --enable-dbmfix Fix conflict with the dbm dbopen." + +# Initialize some variables set by options. +# The variables have the same names as the options, with +# dashes changed to underlines. +build=NONE +cache_file=./config.cache +exec_prefix=NONE +host=NONE +no_create= +nonopt=NONE +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +target=NONE +verbose= +x_includes=NONE +x_libraries=NONE +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datadir='${prefix}/share' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +libdir='${exec_prefix}/lib' +includedir='${prefix}/include' +oldincludedir='/usr/include' +infodir='${prefix}/info' +mandir='${prefix}/man' + +# Initialize some other variables. +subdirs= +MFLAGS= MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} +# Maximum number of lines to put in a shell here document. +ac_max_here_lines=12 + +ac_prev= +for ac_option +do + + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval "$ac_prev=\$ac_option" + ac_prev= + continue + fi + + case "$ac_option" in + -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) ac_optarg= ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case "$ac_option" in + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir="$ac_optarg" ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build="$ac_optarg" ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file="$ac_optarg" ;; + + -datadir | --datadir | --datadi | --datad | --data | --dat | --da) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \ + | --da=*) + datadir="$ac_optarg" ;; + + -disable-* | --disable-*) + ac_feature=`echo $ac_option|sed -e 's/-*disable-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + eval "enable_${ac_feature}=no" ;; + + -enable-* | --enable-*) + ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; } + fi + ac_feature=`echo $ac_feature| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "enable_${ac_feature}='$ac_optarg'" ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix="$ac_optarg" ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he) + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat << EOF +Usage: configure [options] [host] +Options: [defaults in brackets after descriptions] +Configuration: + --cache-file=FILE cache test results in FILE + --help print this message + --no-create do not create output files + --quiet, --silent do not print \`checking...' messages + --version print the version of autoconf that created configure +Directory and file names: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [same as prefix] + --bindir=DIR user executables in DIR [EPREFIX/bin] + --sbindir=DIR system admin executables in DIR [EPREFIX/sbin] + --libexecdir=DIR program executables in DIR [EPREFIX/libexec] + --datadir=DIR read-only architecture-independent data in DIR + [PREFIX/share] + --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data in DIR + [PREFIX/com] + --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var] + --libdir=DIR object code libraries in DIR [EPREFIX/lib] + --includedir=DIR C header files in DIR [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include] + --infodir=DIR info documentation in DIR [PREFIX/info] + --mandir=DIR man documentation in DIR [PREFIX/man] + --srcdir=DIR find the sources in DIR [configure dir or ..] + --program-prefix=PREFIX prepend PREFIX to installed program names + --program-suffix=SUFFIX append SUFFIX to installed program names + --program-transform-name=PROGRAM + run sed PROGRAM on installed program names +EOF + cat << EOF +Host type: + --build=BUILD configure for building on BUILD [BUILD=HOST] + --host=HOST configure for HOST [guessed] + --target=TARGET configure for TARGET [TARGET=HOST] +Features and packages: + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --x-includes=DIR X include files are in DIR + --x-libraries=DIR X library files are in DIR +EOF + if test -n "$ac_help"; then + echo "--enable and --with options recognized:$ac_help" + fi + exit 0 ;; + + -host | --host | --hos | --ho) + ac_prev=host ;; + -host=* | --host=* | --hos=* | --ho=*) + host="$ac_optarg" ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir="$ac_optarg" ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir="$ac_optarg" ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir="$ac_optarg" ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir="$ac_optarg" ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst \ + | --locals | --local | --loca | --loc | --lo) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* \ + | --locals=* | --local=* | --loca=* | --loc=* | --lo=*) + localstatedir="$ac_optarg" ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir="$ac_optarg" ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir="$ac_optarg" ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix="$ac_optarg" ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix="$ac_optarg" ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix="$ac_optarg" ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name="$ac_optarg" ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir="$ac_optarg" ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir="$ac_optarg" ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site="$ac_optarg" ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir="$ac_optarg" ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir="$ac_optarg" ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target="$ac_optarg" ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers) + echo "configure generated by autoconf version 2.13" + exit 0 ;; + + -with-* | --with-*) + ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + case "$ac_option" in + *=*) ;; + *) ac_optarg=yes ;; + esac + eval "with_${ac_package}='$ac_optarg'" ;; + + -without-* | --without-*) + ac_package=`echo $ac_option|sed -e 's/-*without-//'` + # Reject names that are not valid shell variable names. + if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then + { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; } + fi + ac_package=`echo $ac_package| sed 's/-/_/g'` + eval "with_${ac_package}=no" ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes="$ac_optarg" ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries="$ac_optarg" ;; + + -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; } + ;; + + *) + if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then + echo "configure: warning: $ac_option: invalid host type" 1>&2 + fi + if test "x$nonopt" != xNONE; then + { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; } + fi + nonopt="$ac_option" + ;; + + esac +done + +if test -n "$ac_prev"; then + { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; } +fi + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 6 checking for... messages and results +# 5 compiler messages saved in config.log +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>./config.log + +echo "\ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. +" 1>&5 + +# Strip out --no-create and --no-recursion so they do not pile up. +# Also quote any args containing shell metacharacters. +ac_configure_args= +for ac_arg +do + case "$ac_arg" in + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c) ;; + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;; + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ac_configure_args="$ac_configure_args '$ac_arg'" ;; + *) ac_configure_args="$ac_configure_args $ac_arg" ;; + esac +done + +# NLS nuisances. +# Only set these to C if already set. These must not be set unconditionally +# because not all systems understand e.g. LANG=C (notably SCO). +# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +# Non-C LC_CTYPE values break the ctype check. +if test "${LANG+set}" = set; then LANG=C; export LANG; fi +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -rf conftest* confdefs.h +# AIX cpp loses on an empty file, so make sure it contains at least a newline. +echo > confdefs.h + +# A filename unique to this package, relative to the directory that +# configure is in, which we can look for to find out if srcdir is correct. +ac_unique_file=src/dblib/dblib.c + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then its parent. + ac_prog=$0 + ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'` + test "x$ac_confdir" = "x$ac_prog" && ac_confdir=. + srcdir=$ac_confdir + if test ! -r $srcdir/$ac_unique_file; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r $srcdir/$ac_unique_file; then + if test "$ac_srcdir_defaulted" = yes; then + { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; } + else + { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; } + fi +fi +srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'` + +# Prefer explicitly selected file to automatically selected ones. +if test -z "$CONFIG_SITE"; then + if test "x$prefix" != xNONE; then + CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site" + else + CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site" + fi +fi +for ac_site_file in $CONFIG_SITE; do + if test -r "$ac_site_file"; then + echo "loading site script $ac_site_file" + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +ac_exeext= +ac_objext=o +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + + +ac_aux_dir= +for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/install-sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f $ac_dir/install.sh; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; } +fi +ac_config_guess=$ac_aux_dir/config.guess +ac_config_sub=$ac_aux_dir/config.sub +ac_configure=$ac_aux_dir/configure # This should be Cygnus configure. + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:578: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6 +echo "configure:631: checking whether build environment is sane" >&5 +# Just in case +sleep 1 +echo timestamp > conftestfile +# Do `set' in a subshell so we don't clobber the current shell's +# arguments. Must try -L first in case configure is actually a +# symlink; some systems play weird games with the mod time of symlinks +# (eg FreeBSD returns the mod time of the symlink's containing +# directory). +if ( + set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null` + if test "$*" = "X"; then + # -L didn't work. + set X `ls -t $srcdir/configure conftestfile` + fi + if test "$*" != "X $srcdir/configure conftestfile" \ + && test "$*" != "X conftestfile $srcdir/configure"; then + + # If neither matched, then we have a broken ls. This can happen + # if, for instance, CONFIG_SHELL is bash and it inherits a + # broken ls alias from the environment. This has actually + # happened. Such a system could not be considered "sane". + { echo "configure: error: ls -t appears to fail. Make sure there is not a broken +alias in your environment" 1>&2; exit 1; } + fi + + test "$2" = conftestfile + ) +then + # Ok. + : +else + { echo "configure: error: newly created file is older than distributed files! +Check your system clock" 1>&2; exit 1; } +fi +rm -f conftest* +echo "$ac_t""yes" 1>&6 +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:688: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + + +PACKAGE=freetds + +VERSION=0.53 + +if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then + { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; } +fi +cat >> confdefs.h <> confdefs.h <&6 +echo "configure:734: checking for working aclocal" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (aclocal --version) < /dev/null > /dev/null 2>&1; then + ACLOCAL=aclocal + echo "$ac_t""found" 1>&6 +else + ACLOCAL="$missing_dir/missing aclocal" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoconf""... $ac_c" 1>&6 +echo "configure:747: checking for working autoconf" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoconf --version) < /dev/null > /dev/null 2>&1; then + AUTOCONF=autoconf + echo "$ac_t""found" 1>&6 +else + AUTOCONF="$missing_dir/missing autoconf" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working automake""... $ac_c" 1>&6 +echo "configure:760: checking for working automake" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (automake --version) < /dev/null > /dev/null 2>&1; then + AUTOMAKE=automake + echo "$ac_t""found" 1>&6 +else + AUTOMAKE="$missing_dir/missing automake" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working autoheader""... $ac_c" 1>&6 +echo "configure:773: checking for working autoheader" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (autoheader --version) < /dev/null > /dev/null 2>&1; then + AUTOHEADER=autoheader + echo "$ac_t""found" 1>&6 +else + AUTOHEADER="$missing_dir/missing autoheader" + echo "$ac_t""missing" 1>&6 +fi + +echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6 +echo "configure:786: checking for working makeinfo" >&5 +# Run test in a subshell; some versions of sh will print an error if +# an executable is not found, even if stderr is redirected. +# Redirect stdin to placate older versions of autoconf. Sigh. +if (makeinfo --version) < /dev/null > /dev/null 2>&1; then + MAKEINFO=makeinfo + echo "$ac_t""found" 1>&6 +else + MAKEINFO="$missing_dir/missing makeinfo" + echo "$ac_t""missing" 1>&6 +fi + + + + +# Extract the first word of "gcc", so it can be a program name with args. +set dummy gcc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:804: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="gcc" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test -z "$CC"; then + # Extract the first word of "cc", so it can be a program name with args. +set dummy cc; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:834: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_prog_rejected=no + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue + fi + ac_cv_prog_CC="cc" + break + fi + done + IFS="$ac_save_ifs" +if test $ac_prog_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $ac_cv_prog_CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same basename, so the bogon will be chosen + # first if we set CC to just the basename; use the full file name. + shift + set dummy "$ac_dir/$ac_word" "$@" + shift + ac_cv_prog_CC="$@" + fi +fi +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + if test -z "$CC"; then + case "`uname -s`" in + *win32* | *WIN32*) + # Extract the first word of "cl", so it can be a program name with args. +set dummy cl; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:885: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$CC"; then + ac_cv_prog_CC="$CC" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_CC="cl" + break + fi + done + IFS="$ac_save_ifs" +fi +fi +CC="$ac_cv_prog_CC" +if test -n "$CC"; then + echo "$ac_t""$CC" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + ;; + esac + fi + test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; } +fi + +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 +echo "configure:917: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 + +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +cat > conftest.$ac_ext << EOF + +#line 928 "configure" +#include "confdefs.h" + +main(){return(0);} +EOF +if { (eval echo configure:933: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + ac_cv_prog_cc_works=yes + # If we can't run a trivial program, we are probably using a cross compiler. + if (./conftest; exit) 2>/dev/null; then + ac_cv_prog_cc_cross=no + else + ac_cv_prog_cc_cross=yes + fi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + ac_cv_prog_cc_works=no +fi +rm -fr conftest* +ac_ext=c +# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. +ac_cpp='$CPP $CPPFLAGS' +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5' +ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5' +cross_compiling=$ac_cv_prog_cc_cross + +echo "$ac_t""$ac_cv_prog_cc_works" 1>&6 +if test $ac_cv_prog_cc_works = no; then + { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } +fi +echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 +echo "configure:959: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 +cross_compiling=$ac_cv_prog_cc_cross + +echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 +echo "configure:964: checking whether we are using GNU C" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + ac_cv_prog_gcc=yes +else + ac_cv_prog_gcc=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gcc" 1>&6 + +if test $ac_cv_prog_gcc = yes; then + GCC=yes +else + GCC= +fi + +ac_test_CFLAGS="${CFLAGS+set}" +ac_save_CFLAGS="$CFLAGS" +CFLAGS= +echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 +echo "configure:992: checking whether ${CC-cc} accepts -g" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + echo 'void f(){}' > conftest.c +if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then + ac_cv_prog_cc_g=yes +else + ac_cv_prog_cc_g=no +fi +rm -f conftest* + +fi + +echo "$ac_t""$ac_cv_prog_cc_g" 1>&6 +if test "$ac_test_CFLAGS" = set; then + CFLAGS="$ac_save_CFLAGS" +elif test $ac_cv_prog_cc_g = yes; then + if test "$GCC" = yes; then + CFLAGS="-g -O2" + else + CFLAGS="-g" + fi +else + if test "$GCC" = yes; then + CFLAGS="-O2" + else + CFLAGS= + fi +fi + +echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 +echo "configure:1024: checking how to run the C preprocessor" >&5 +# On Suns, sometimes $CPP names a directory. +if test -n "$CPP" && test -d "$CPP"; then + CPP= +fi +if test -z "$CPP"; then +if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # This must be in double quotes, not single quotes, because CPP may get + # substituted into the Makefile and "${CC-cc}" will confuse make. + CPP="${CC-cc} -E" + # On the NeXT, cc -E runs the code through the compiler's parser, + # not just through cpp. + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -E -traditional-cpp" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1062: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP="${CC-cc} -nologo -E" + cat > conftest.$ac_ext < +Syntax Error +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1079: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + : +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + CPP=/lib/cpp +fi +rm -f conftest* +fi +rm -f conftest* +fi +rm -f conftest* + ac_cv_prog_CPP="$CPP" +fi + CPP="$ac_cv_prog_CPP" +else + ac_cv_prog_CPP="$CPP" +fi +echo "$ac_t""$CPP" 1>&6 + +echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 +echo "configure:1104: checking whether ${MAKE-make} sets \${MAKE}" >&5 +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftestmake <<\EOF +all: + @echo 'ac_maketemp="${MAKE}"' +EOF +# GNU make sometimes prints "make[1]: Entering...", which would confuse us. +eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=` +if test -n "$ac_maketemp"; then + eval ac_cv_prog_make_${ac_make}_set=yes +else + eval ac_cv_prog_make_${ac_make}_set=no +fi +rm -f conftestmake +fi +if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then + echo "$ac_t""yes" 1>&6 + SET_MAKE= +else + echo "$ac_t""no" 1>&6 + SET_MAKE="MAKE=${MAKE-make}" +fi + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# ./install, which can be erroneously created by make from ./install.sh. +echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 +echo "configure:1142: checking for a BSD compatible install" >&5 +if test -z "$INSTALL"; then +if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":" + for ac_dir in $PATH; do + # Account for people who put trailing slashes in PATH elements. + case "$ac_dir/" in + /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + if test -f $ac_dir/$ac_prog; then + if test $ac_prog = install && + grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + else + ac_cv_path_install="$ac_dir/$ac_prog -c" + break 2 + fi + fi + done + ;; + esac + done + IFS="$ac_save_IFS" + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL="$ac_cv_path_install" + else + # As a last resort, use the slow shell script. We don't cache a + # path for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the path is relative. + INSTALL="$ac_install_sh" + fi +fi +echo "$ac_t""$INSTALL" 1>&6 + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + +# Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 +echo "configure:1197: checking for $ac_word" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":" + ac_dummy="$PATH" + for ac_dir in $ac_dummy; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/$ac_word; then + ac_cv_prog_RANLIB="ranlib" + break + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":" +fi +fi +RANLIB="$ac_cv_prog_RANLIB" +if test -n "$RANLIB"; then + echo "$ac_t""$RANLIB" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + +if test "$program_transform_name" = s,x,x,; then + program_transform_name= +else + # Double any \ or $. echo might interpret backslashes. + cat <<\EOF_SED > conftestsed +s,\\,\\\\,g; s,\$,$$,g +EOF_SED + program_transform_name="`echo $program_transform_name|sed -f conftestsed`" + rm -f conftestsed +fi +test "$program_prefix" != NONE && + program_transform_name="s,^,${program_prefix},; $program_transform_name" +# Use a double $ so make ignores it. +test "$program_suffix" != NONE && + program_transform_name="s,\$\$,${program_suffix},; $program_transform_name" + +# sed with no file args requires a program. +test "$program_transform_name" = "" && program_transform_name="s,x,x," + +# Check whether --enable-shared or --disable-shared was given. +if test "${enable_shared+set}" = set; then + enableval="$enable_shared" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_shared=yes ;; +no) enable_shared=no ;; +*) + enable_shared=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_shared=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_shared=yes +fi + +# Check whether --enable-static or --disable-static was given. +if test "${enable_static+set}" = set; then + enableval="$enable_static" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_static=yes ;; +no) enable_static=no ;; +*) + enable_static=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_static=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_static=yes +fi + +# Check whether --enable-fast-install or --disable-fast-install was given. +if test "${enable_fast_install+set}" = set; then + enableval="$enable_fast_install" + p=${PACKAGE-default} +case "$enableval" in +yes) enable_fast_install=yes ;; +no) enable_fast_install=no ;; +*) + enable_fast_install=no + # Look at the argument we got. We use all the common list separators. + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:," + for pkg in $enableval; do + if test "X$pkg" = "X$p"; then + enable_fast_install=yes + fi + done + IFS="$ac_save_ifs" + ;; +esac +else + enable_fast_install=yes +fi + + +# Make sure we can run config.sub. +if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then : +else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } +fi + +echo $ac_n "checking host system type""... $ac_c" 1>&6 +echo "configure:1319: checking host system type" >&5 + +host_alias=$host +case "$host_alias" in +NONE) + case $nonopt in + NONE) + if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then : + else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; } + fi ;; + *) host_alias=$nonopt ;; + esac ;; +esac + +host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias` +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$host" 1>&6 + +echo $ac_n "checking build system type""... $ac_c" 1>&6 +echo "configure:1340: checking build system type" >&5 + +build_alias=$build +case "$build_alias" in +NONE) + case $nonopt in + NONE) build_alias=$host_alias ;; + *) build_alias=$nonopt ;; + esac ;; +esac + +build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias` +build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` +echo "$ac_t""$build" 1>&6 + +# Check whether --with-gnu-ld or --without-gnu-ld was given. +if test "${with_gnu_ld+set}" = set; then + withval="$with_gnu_ld" + test "$withval" = no || with_gnu_ld=yes +else + with_gnu_ld=no +fi + +ac_prog=ld +if test "$ac_cv_prog_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6 +echo "configure:1369: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we aren't using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac +elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 +echo "configure:1393: checking for GNU ld" >&5 +else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 +echo "configure:1396: checking for non-GNU ld" >&5 +fi +if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + ac_cv_path_LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" +else + ac_cv_path_LD="$LD" # Let the user override the test with a path. +fi +fi + +LD="$ac_cv_path_LD" +if test -n "$LD"; then + echo "$ac_t""$LD" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } +echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 +echo "configure:1431: checking if the linker ($LD) is GNU ld" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + # I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + ac_cv_prog_gnu_ld=yes +else + ac_cv_prog_gnu_ld=no +fi +fi + +echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6 + + +echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 +echo "configure:1447: checking for BSD-compatible nm" >&5 +if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test -n "$NM"; then + # Let the user override the test. + ac_cv_path_NM="$NM" +else + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}" + for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + ac_cv_path_NM="$ac_dir/nm -p" + break + else + ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm +fi +fi + +NM="$ac_cv_path_NM" +echo "$ac_t""$NM" 1>&6 + +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1483: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + + +case "$target" in +NONE) lt_target="$host" ;; +*) lt_target="$target" ;; +esac + +# Check for any special flags to pass to ltconfig. +# +# the following will cause an existing older ltconfig to fail, so +# we ignore this at the expense of the cache file... Checking this +# will just take longer ... bummer! +#libtool_flags="--cache-file=$cache_file" +# +test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared" +test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static" +test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install" +test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc" +test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld" + + +# Check whether --enable-libtool-lock or --disable-libtool-lock was given. +if test "${enable_libtool_lock+set}" = set; then + enableval="$enable_libtool_lock" + : +fi + +test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock" +test x"$silent" = xyes && libtool_flags="$libtool_flags --silent" + +# Some flags need to be propagated to the compiler or linker for good +# libtool support. +case "$lt_target" in +*-*-irix6*) + # Find out which ABI we are using. + echo '#line 1537 "configure"' > conftest.$ac_ext + if { (eval echo configure:1538: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + case "`/usr/bin/file conftest.o`" in + *32-bit*) + LD="${LD-ld} -32" + ;; + *N32*) + LD="${LD-ld} -n32" + ;; + *64-bit*) + LD="${LD-ld} -64" + ;; + esac + fi + rm -rf conftest* + ;; + +*-*-sco3.2v5*) + # On SCO OpenServer 5, we need -belf to get full-featured binaries. + SAVE_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -belf" + echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 +echo "configure:1559: checking whether the C compiler needs -belf" >&5 +if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + lt_cv_cc_needs_belf=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + lt_cv_cc_needs_belf=no +fi +rm -f conftest* +fi + +echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6 + if test x"$lt_cv_cc_needs_belf" != x"yes"; then + # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf + CFLAGS="$SAVE_CFLAGS" + fi + ;; + + +esac + + +# Save cache, so that ltconfig can load it +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + + +# Actually configure libtool. ac_aux_dir is where install-sh is found. +CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \ +LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \ +LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \ +DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \ +${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \ +$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \ +|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; } + +# Reload cache, that may have been modified by ltconfig +if test -r "$cache_file"; then + echo "loading cache $cache_file" + . $cache_file +else + echo "creating cache $cache_file" + > $cache_file +fi + + +# This can be used to rebuild libtool when needed +LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh" + +# Always use our own libtool. +LIBTOOL='$(SHELL) $(top_builddir)/libtool' + +# Redirect the config.log output again, so that the ltconfig log is not +# clobbered by the next message. +exec 5>>./config.log + + +echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 +echo "configure:1674: checking for socket in -lsocket" >&5 +ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lsocket $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + NETWORK_LIBS="$NETWORK_LIBS -lsocket" +else + echo "$ac_t""no" 1>&6 +fi + + + + +echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 +echo "configure:1717: checking for ANSI C header files" >&5 +if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +#include +#include +#include +EOF +ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo configure:1730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + ac_cv_header_stdc=yes +else + echo "$ac_err" >&5 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +if test $ac_cv_header_stdc = yes; then + # SunOS 4.x string.h does not declare mem*, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "memchr" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. +cat > conftest.$ac_ext < +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "free" >/dev/null 2>&1; then + : +else + rm -rf conftest* + ac_cv_header_stdc=no +fi +rm -f conftest* + +fi + +if test $ac_cv_header_stdc = yes; then + # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. +if test "$cross_compiling" = yes; then + : +else + cat > conftest.$ac_ext < +#define ISLOWER(c) ('a' <= (c) && (c) <= 'z') +#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) +#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) +int main () { int i; for (i = 0; i < 256; i++) +if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); +exit (0); } + +EOF +if { (eval echo configure:1797: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + : +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_header_stdc=no +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_header_stdc" 1>&6 +if test $ac_cv_header_stdc = yes; then + cat >> confdefs.h <<\EOF +#define STDC_HEADERS 1 +EOF + +fi + + +echo $ac_n "checking size of char""... $ac_c" 1>&6 +echo "configure:1822: checking size of char" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(char)); + exit(0); +} +EOF +if { (eval echo configure:1841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_char=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_char=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_char" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1861: checking size of short" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short)); + exit(0); +} +EOF +if { (eval echo configure:1880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1900: checking size of long" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(long)); + exit(0); +} +EOF +if { (eval echo configure:1919: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_long=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_long=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_long" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1939: checking size of int" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(int)); + exit(0); +} +EOF +if { (eval echo configure:1958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_int=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_int=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_int" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1978: checking size of float" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(float)); + exit(0); +} +EOF +if { (eval echo configure:1997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_float=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_float=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_float" 1>&6 +cat >> confdefs.h <&6 +echo "configure:2017: checking size of double" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(double)); + exit(0); +} +EOF +if { (eval echo configure:2036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_double=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_double=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_double" 1>&6 +cat >> confdefs.h <&2; exit 1; } +esac + +case 8 in +$ac_cv_sizeof_float) float=float;; +$ac_cv_sizeof_double) float=double;; +*) { echo "configure: error: No 64-bit float found." 1>&2; exit 1; } +esac + + + + + + + + +echo $ac_n "checking is FIONBIO defined""... $ac_c" 1>&6 +echo "configure:2086: checking is FIONBIO defined" >&5 +cat > conftest.$ac_ext < +#ifdef FIONBIO + yes +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + rm -rf conftest* + echo "$ac_t""yes" 1>&6 +else + rm -rf conftest* + cat > conftest.$ac_ext < +#ifdef FIONBIO + yes +#endif + +EOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + egrep "yes" >/dev/null 2>&1; then + rm -rf conftest* + cat >> confdefs.h <<\EOF +#define BSD_COMP 1 +EOF + echo "$ac_t""need -DBSD_COMP" 1>&6 +else + rm -rf conftest* + echo "$ac_t""no" 1>&6 +fi +rm -f conftest* + + +fi +rm -f conftest* + + +echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 +echo "configure:2131: checking whether byte ordering is bigendian" >&5 +if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_c_bigendian=unknown +# See if sys/param.h defines the BYTE_ORDER macro. +cat > conftest.$ac_ext < +#include +int main() { + +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN + bogus endian macros +#endif +; return 0; } +EOF +if { (eval echo configure:2149: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + # It does; now see whether it defined to BIG_ENDIAN or not. +cat > conftest.$ac_ext < +#include +int main() { + +#if BYTE_ORDER != BIG_ENDIAN + not big endian +#endif +; return 0; } +EOF +if { (eval echo configure:2164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + ac_cv_c_bigendian=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_c_bigendian=no +fi +rm -f conftest* +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 +fi +rm -f conftest* +if test $ac_cv_c_bigendian = unknown; then +if test "$cross_compiling" = yes; then + { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_c_bigendian=no +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_c_bigendian=yes +fi +rm -fr conftest* +fi + +fi +fi + +echo "$ac_t""$ac_cv_c_bigendian" 1>&6 +if test $ac_cv_c_bigendian = yes; then + cat >> confdefs.h <<\EOF +#define WORDS_BIGENDIAN 1 +EOF + +fi + + + + + +# Check whether --with-tdsver or --without-tdsver was given. +if test "${with_tdsver+set}" = set; then + withval="$with_tdsver" + : +fi + +if test "$with_tdsver" = "4.2"; then + CFLAGS="$CFLAGS -DTDS42" +elif test "$with_tdsver" = "4.6"; then + CFLAGS="$CFLAGS -DTDS46" +elif test "$with_tdsver" = "7.0"; then + CFLAGS="$CFLAGS -DTDS70" +elif test "$with_tdsver" = "8.0"; then + CFLAGS="$CFLAGS -DTDS80" +else + CFLAGS="$CFLAGS -DTDS50" +fi + +# Check whether --with-iodbc or --without-iodbc was given. +if test "${with_iodbc+set}" = set; then + withval="$with_iodbc" + : +fi + +if test "$with_iodbc"; then + CFLAGS="$CFLAGS -DIODBC"; + ODBC_INC=$with_iodbc/include; + odbc=true +fi + +# Check whether --with-iodbc or --without-iodbc was given. +if test "${with_iodbc+set}" = set; then + withval="$with_iodbc" + : +fi + +if test "$with_unixodbc"; then + CFLAGS="$CFLAGS -DUNIXODBC" + ODBC_INC=$with_unixodbc/include + odbc=true +fi + + +if test x$odbc = xtrue; then + ODBC_TRUE= + ODBC_FALSE='#' +else + ODBC_TRUE='#' + ODBC_FALSE= +fi + + + +# Check whether --enable-msdblib or --disable-msdblib was given. +if test "${enable_msdblib+set}" = set; then + enableval="$enable_msdblib" + : +fi + + +if test "$enable_msdblib" = "yes" ; then + CFLAGS="$CFLAGS -DMSDBLIB" +fi + +# Check whether --enable-dbmfix or --disable-dbmfix was given. +if test "${enable_dbmfix+set}" = set; then + enableval="$enable_dbmfix" + : +fi + + +if test "$enable_dbmfix" = "yes" ; then + CFLAGS="$CFLAGS -DDBMFIX" +fi + + +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15 + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Any assignment to VPATH causes Sun make to only execute +# the first set of double-colon rules, so remove it if not needed. +# If there is a colon in the path, we need to keep it. +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d' +fi + +trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15 + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +cat > conftest.defs <<\EOF +s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g +s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g +s%\[%\\&%g +s%\]%\\&%g +s%\$%$$%g +EOF +DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '` +rm -f conftest.defs + + +# Without the "./", some shells look in PATH for config.status. +: ${CONFIG_STATUS=./config.status} + +echo creating $CONFIG_STATUS +rm -f $CONFIG_STATUS +cat > $CONFIG_STATUS </dev/null | sed 1q`: +# +# $0 $ac_configure_args +# +# Compiler output produced by configure, useful for debugging +# configure, is in ./config.log if it exists. + +ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]" +for ac_option +do + case "\$ac_option" in + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" + exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; + -version | --version | --versio | --versi | --vers | --ver | --ve | --v) + echo "$CONFIG_STATUS generated by autoconf version 2.13" + exit 0 ;; + -help | --help | --hel | --he | --h) + echo "\$ac_cs_usage"; exit 0 ;; + *) echo "\$ac_cs_usage"; exit 1 ;; + esac +done + +ac_given_srcdir=$srcdir +ac_given_INSTALL="$INSTALL" + +trap 'rm -fr `echo "include/tdsver.h include/tds.h \ + Makefile \ + include/Makefile \ + src/Makefile \ + src/tds/Makefile src/tds/unittests/Makefile \ + src/dblib/Makefile src/dblib/unittests/Makefile \ + src/ctlib/Makefile src/ctlib/unittests/Makefile \ + src/server/Makefile \ + src/odbc/Makefile +" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15 +EOF +cat >> $CONFIG_STATUS < conftest.subs <<\\CEOF +$ac_vpsub +$extrasub +s%@SHELL@%$SHELL%g +s%@CFLAGS@%$CFLAGS%g +s%@CPPFLAGS@%$CPPFLAGS%g +s%@CXXFLAGS@%$CXXFLAGS%g +s%@FFLAGS@%$FFLAGS%g +s%@DEFS@%$DEFS%g +s%@LDFLAGS@%$LDFLAGS%g +s%@LIBS@%$LIBS%g +s%@exec_prefix@%$exec_prefix%g +s%@prefix@%$prefix%g +s%@program_transform_name@%$program_transform_name%g +s%@bindir@%$bindir%g +s%@sbindir@%$sbindir%g +s%@libexecdir@%$libexecdir%g +s%@datadir@%$datadir%g +s%@sysconfdir@%$sysconfdir%g +s%@sharedstatedir@%$sharedstatedir%g +s%@localstatedir@%$localstatedir%g +s%@libdir@%$libdir%g +s%@includedir@%$includedir%g +s%@oldincludedir@%$oldincludedir%g +s%@infodir@%$infodir%g +s%@mandir@%$mandir%g +s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g +s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g +s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@PACKAGE@%$PACKAGE%g +s%@VERSION@%$VERSION%g +s%@ACLOCAL@%$ACLOCAL%g +s%@AUTOCONF@%$AUTOCONF%g +s%@AUTOMAKE@%$AUTOMAKE%g +s%@AUTOHEADER@%$AUTOHEADER%g +s%@MAKEINFO@%$MAKEINFO%g +s%@SET_MAKE@%$SET_MAKE%g +s%@CC@%$CC%g +s%@CPP@%$CPP%g +s%@RANLIB@%$RANLIB%g +s%@host@%$host%g +s%@host_alias@%$host_alias%g +s%@host_cpu@%$host_cpu%g +s%@host_vendor@%$host_vendor%g +s%@host_os@%$host_os%g +s%@build@%$build%g +s%@build_alias@%$build_alias%g +s%@build_cpu@%$build_cpu%g +s%@build_vendor@%$build_vendor%g +s%@build_os@%$build_os%g +s%@LN_S@%$LN_S%g +s%@LIBTOOL@%$LIBTOOL%g +s%@NETWORK_LIBS@%$NETWORK_LIBS%g +s%@smallint@%$smallint%g +s%@int@%$int%g +s%@real@%$real%g +s%@float@%$float%g +s%@ODBC_TRUE@%$ODBC_TRUE%g +s%@ODBC_FALSE@%$ODBC_FALSE%g +s%@ODBC@%$ODBC%g +s%@ODBC_INC@%$ODBC_INC%g + +CEOF +EOF + +cat >> $CONFIG_STATUS <<\EOF + +# Split the substitutions into bite-sized pieces for seds with +# small command number limits, like on Digital OSF/1 and HP-UX. +ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script. +ac_file=1 # Number of current file. +ac_beg=1 # First line for current file. +ac_end=$ac_max_sed_cmds # Line after last line for current file. +ac_more_lines=: +ac_sed_cmds="" +while $ac_more_lines; do + if test $ac_beg -gt 1; then + sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file + else + sed "${ac_end}q" conftest.subs > conftest.s$ac_file + fi + if test ! -s conftest.s$ac_file; then + ac_more_lines=false + rm -f conftest.s$ac_file + else + if test -z "$ac_sed_cmds"; then + ac_sed_cmds="sed -f conftest.s$ac_file" + else + ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file" + fi + ac_file=`expr $ac_file + 1` + ac_beg=$ac_end + ac_end=`expr $ac_end + $ac_max_sed_cmds` + fi +done +if test -z "$ac_sed_cmds"; then + ac_sed_cmds=cat +fi +EOF + +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF +for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then + # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in". + case "$ac_file" in + *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'` + ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;; + *) ac_file_in="${ac_file}.in" ;; + esac + + # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories. + + # Remove last slash and all that follows it. Not all systems have dirname. + ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'` + if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then + # The file is in a subdirectory. + test ! -d "$ac_dir" && mkdir "$ac_dir" + ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`" + # A "../" for each directory in $ac_dir_suffix. + ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'` + else + ac_dir_suffix= ac_dots= + fi + + case "$ac_given_srcdir" in + .) srcdir=. + if test -z "$ac_dots"; then top_srcdir=. + else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;; + /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;; + *) # Relative path. + srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix" + top_srcdir="$ac_dots$ac_given_srcdir" ;; + esac + + case "$ac_given_INSTALL" in + [/$]*) INSTALL="$ac_given_INSTALL" ;; + *) INSTALL="$ac_dots$ac_given_INSTALL" ;; + esac + + echo creating "$ac_file" + rm -f "$ac_file" + configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure." + case "$ac_file" in + *Makefile*) ac_comsub="1i\\ +# $configure_input" ;; + *) ac_comsub= ;; + esac + + ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"` + sed -e "$ac_comsub +s%@configure_input@%$configure_input%g +s%@srcdir@%$srcdir%g +s%@top_srcdir@%$top_srcdir%g +s%@INSTALL@%$INSTALL%g +" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file +fi; done +rm -f conftest.s* + +EOF +cat >> $CONFIG_STATUS <> $CONFIG_STATUS <<\EOF + +exit 0 +EOF +chmod +x $CONFIG_STATUS +rm -fr confdefs* $ac_clean_files +test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1 + diff --git a/configure.in b/configure.in new file mode 100644 index 000000000..40b0fd8e7 --- /dev/null +++ b/configure.in @@ -0,0 +1,170 @@ +dnl Process this file with autoconf to produce a configure script. + +dnl ------------------------------------------------------------ +dnl Initialization +dnl ------------------------------------------------------------ +AC_INIT(src/dblib/dblib.c) +AM_INIT_AUTOMAKE(freetds, 0.53) +AC_PREFIX_DEFAULT(/usr/local/freetds) + +dnl ------------------------------------------------------------ +dnl Checks for programs. +dnl ------------------------------------------------------------ +AC_PROG_CC +AC_PROG_CPP +AC_PROG_MAKE_SET +AC_PROG_INSTALL +AC_PROG_RANLIB +AC_ARG_PROGRAM +AM_PROG_LIBTOOL + +dnl ------------------------------------------------------------ +dnl Checks for libraries. +dnl ------------------------------------------------------------ +AC_CHECK_LIB(socket, socket, NETWORK_LIBS="$NETWORK_LIBS -lsocket") +AC_SUBST(NETWORK_LIBS) + + +dnl ------------------------------------------------------------ +dnl Checks for header files. +dnl ------------------------------------------------------------ +AC_HEADER_STDC + +dnl ------------------------------------------------------------ +dnl Checks for integers/floats of different sizes +dnl ------------------------------------------------------------ +AC_CHECK_SIZEOF(char) +AC_CHECK_SIZEOF(short) +AC_CHECK_SIZEOF(long) +AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(float) +AC_CHECK_SIZEOF(double) + +case 2 in +$ac_cv_sizeof_short) smallint=short;; +$ac_cv_sizeof_int) smallint=int;; +esac +case 4 in +$ac_cv_sizeof_short) int=short;; +$ac_cv_sizeof_int) int=int;; +$ac_cv_sizeof_long) int=long;; +esac + +case 4 in +$ac_cv_sizeof_float) real=float;; +$ac_cv_sizeof_double) real=double;; +*) AC_ERROR(No 32-bit float found.) +esac + +case 8 in +$ac_cv_sizeof_float) float=float;; +$ac_cv_sizeof_double) float=double;; +*) AC_ERROR(No 64-bit float found.) +esac + +AC_SUBST(smallint) +AC_SUBST(int) +AC_SUBST(real) + +AC_SUBST(float) + +dnl ------------------------------------------------------------ +dnl Checks for typedefs and structures +dnl ------------------------------------------------------------ + +dnl ---- Solaris needs -DBSD_COMP to get FIONBIO defined ---- +AC_MSG_CHECKING(is FIONBIO defined) +AC_EGREP_CPP(yes, +[#include +#ifdef FIONBIO + yes +#endif +], + AC_MSG_RESULT(yes), + [ AC_EGREP_CPP(yes, +[#define BSD_COMP +#include +#ifdef FIONBIO + yes +#endif +], + AC_DEFINE(BSD_COMP) AC_MSG_RESULT(need -DBSD_COMP), + AC_MSG_RESULT(no)) + ]) + +dnl ------------------------------------------------------------ +dnl Checks for compiler characteristics. +dnl ------------------------------------------------------------ +AC_C_BIGENDIAN + +dnl ------------------------------------------------------------ +dnl Checks for library functions. +dnl ------------------------------------------------------------ + + +dnl ------------------------------------------------------------ +dnl Compile time options +dnl ------------------------------------------------------------ + +AC_ARG_WITH(tdsver, +[ --with-tdsver=VERSION specify the TDS version to use \ +(4.2/4.6/5.0/7.0/8.0) [5.0]]) +if test "$with_tdsver" = "4.2"; then + CFLAGS="$CFLAGS -DTDS42" +elif test "$with_tdsver" = "4.6"; then + CFLAGS="$CFLAGS -DTDS46" +elif test "$with_tdsver" = "7.0"; then + CFLAGS="$CFLAGS -DTDS70" +elif test "$with_tdsver" = "8.0"; then + CFLAGS="$CFLAGS -DTDS80" +else + CFLAGS="$CFLAGS -DTDS50" +fi + +AC_ARG_WITH(iodbc, +[ --with-iodbc=/path/to/iodbc build odbc driver against iODBC]) +if test "$with_iodbc"; then + CFLAGS="$CFLAGS -DIODBC"; + ODBC_INC=$with_iodbc/include; + odbc=true +fi + +AC_ARG_WITH(iodbc, +[ --with-unixodbc=/path/to/unixodbc build odbc driver against unixODBC]) +if test "$with_unixodbc"; then + CFLAGS="$CFLAGS -DUNIXODBC" + ODBC_INC=$with_unixodbc/include + odbc=true +fi +AM_CONDITIONAL(ODBC, test x$odbc = xtrue) +AC_SUBST(ODBC) +AC_SUBST(ODBC_INC) + +AC_ARG_ENABLE(msdblib, + [ --enable-msdblib For MS style dblib.]) + +if test "$enable_msdblib" = "yes" ; then + CFLAGS="$CFLAGS -DMSDBLIB" +fi + +AC_ARG_ENABLE(dbmfix, + [ --enable-dbmfix Fix conflict with the dbm dbopen.]) + +if test "$enable_dbmfix" = "yes" ; then + CFLAGS="$CFLAGS -DDBMFIX" +fi + + +dnl ------------------------------------------------------------ +dnl Final output +dnl ------------------------------------------------------------ +AC_OUTPUT(include/tdsver.h include/tds.h \ + Makefile \ + include/Makefile \ + src/Makefile \ + src/tds/Makefile src/tds/unittests/Makefile \ + src/dblib/Makefile src/dblib/unittests/Makefile \ + src/ctlib/Makefile src/ctlib/unittests/Makefile \ + src/server/Makefile \ + src/odbc/Makefile +) diff --git a/freetds.conf b/freetds.conf new file mode 100644 index 000000000..acdf7e961 --- /dev/null +++ b/freetds.conf @@ -0,0 +1,78 @@ +# +# The freetds.conf file is a replacement for the original interfaces file +# developed by Sybase. You may use either this or the intefaces file, but not +# both. +# +# FreeTDS will search for a file in the following order: +# +# 1) Check if a file was set programatically via dbsetifile() and is in .conf +# format, if so use that. +# 2) Look in ~/.freetds.conf +# 3) Look in @sysconfdir@/freetds.conf +# +# If freetds has found no suitable conf file it will then search for an +# an interfaces file: +# +# 1) Check if a file was set programatically via dbsetifile() and is in +# interfaces format, if so use that. +# 2) Look in ~/.interfaces +# 3) Look in $SYBASE/interfaces +# +# Only hostname, port number, and protocol version can be specified using the +# interfaces format. +# +# The conf file format follows a modified Windows INI style (or Samba style if +# you prefer to think of it that way). There is a [global] section which will +# affect all dataservers or basic program behaviour, and a section headed with +# the dataserver's name which will have settings which override the global ones. +# +# the complete list of settings and their defaults follows: +# + +# any value here may be overridden in the dataserver specific section +[global] + tds version = 4.2 + initial block size = 512 + swap broken dates = no + swap broken money = no +# if both server and domain logins are enabled freetds will try domain login +# first if a domain is specified, and then fallback to server logins. + try server login = yes + try domain login = no +# the default domain can be overridden by using the DOMAIN\username format. +; nt domain = WORKGROUP +# if the server responds with different domain try that one? + cross domain login = no +; dump file = /tmp/freetds.log +; debug level = 10 +; timeout = 10; +; connect timeout = 10; + +# This is a sybase hosted dataserver, if you are directly on the net you can +# use it to test. +[JDBC] + host = 192.138.151.39 + port = 4444 + tds version = 5.0 + +# a typical MS SQL 7.0 configuration +;[MyServer70] +; host = ntmachine.domain.com +; port = 1433 +; tds version = 7.0 + +# a typical MS SQL 7.0 configuration using domain logins +;[MyServer70] +; host = ntmachine.domain.com +; port = 1433 +; tds version = 7.0 +; try domain logins = yes +; try server logins = no +; nt domain = MYDOMAIN + +# a typical MS SQL 6.x configuration +;[MyServer65] +; host = ntmachine.domain.com +; port = 1433 +; tds version = 4.2 + diff --git a/include/Makefile.am b/include/Makefile.am new file mode 100644 index 000000000..72693e2ab --- /dev/null +++ b/include/Makefile.am @@ -0,0 +1,19 @@ +include_HEADERS = cspublic.h ctpublic.h sybdb.h sybfront.h \ + tdsutil.h bkpublic.h cstypes.h dblib.h syberror.h \ + ctlib.h sqldb.h sqlfront.h \ + tds.h tdsver.h tdsconvert.h tds_configs.h tdsodbc.h + +EXTRA_DIST = tds_configs.h.in + +all-local: tds_configs.h + +tds_configs.h: tds_configs.h.in Makefile + @$(RM) $@ + @echo "Making $@" + @echo "/* Generated from tds_configs.h.in on `date` */" > $@; \ + sed \ + -e 's;%SYSCONFDIR%;$(sysconfdir);' \ + tds_configs.h.in >> $@; \ + chmod 444 $@ + + diff --git a/include/Makefile.in b/include/Makefile.in new file mode 100644 index 000000000..601dbd255 --- /dev/null +++ b/include/Makefile.in @@ -0,0 +1,247 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +include_HEADERS = cspublic.h ctpublic.h sybdb.h sybfront.h tdsutil.h bkpublic.h cstypes.h dblib.h syberror.h ctlib.h sqldb.h sqlfront.h tds.h tdsver.h tdsconvert.h tds_configs.h tdsodbc.h + + +EXTRA_DIST = tds_configs.h.in +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = tdsver.h tds.h +HEADERS = $(include_HEADERS) + +DIST_COMMON = README Makefile.am Makefile.in tds.h.in tdsver.h.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps include/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +tdsver.h: $(top_builddir)/config.status tdsver.h.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status +tds.h: $(top_builddir)/config.status tds.h.in + cd $(top_builddir) && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = include + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(HEADERS) all-local +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: uninstall-includeHEADERS install-includeHEADERS tags \ +mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \ +distdir info-am info dvi-am dvi check check-am installcheck-am \ +installcheck install-exec-am install-exec install-data-am install-data \ +install-am install uninstall-am uninstall all-local all-redirect all-am \ +all installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +all-local: tds_configs.h + +tds_configs.h: tds_configs.h.in Makefile + @$(RM) $@ + @echo "Making $@" + @echo "/* Generated from tds_configs.h.in on `date` */" > $@; \ + sed \ + -e 's;%SYSCONFDIR%;$(sysconfdir);' \ + tds_configs.h.in >> $@; \ + chmod 444 $@ + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/include/README b/include/README new file mode 100644 index 000000000..ef7ea36bd --- /dev/null +++ b/include/README @@ -0,0 +1,4 @@ +The files isql.h, isqlext.h, odbc_funcs.h, and odbc_types.h come from iODBC +and/or FreeODBC (I got them from the FreeODBC driver stub, which in turn got +them from iODBC?). + diff --git a/include/bkpublic.h b/include/bkpublic.h new file mode 100644 index 000000000..93d03da3d --- /dev/null +++ b/include/bkpublic.h @@ -0,0 +1,44 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _bkpublic_h_ +#define _bkpublic_h_ + +static char rcsid_bkpublic_h [ ] = + "$Id: bkpublic.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_bkpublic_h_warn[]={rcsid_bkpublic_h, no_unused_bkpublic_h_warn}; + +/* seperate this stuff out later */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* buld properties start with 1 i guess */ +#define BLK_IDENTITY 1 + +#ifdef __cplusplus +} +#endif + + +#endif + diff --git a/include/cspublic.h b/include/cspublic.h new file mode 100644 index 000000000..5b2730d6a --- /dev/null +++ b/include/cspublic.h @@ -0,0 +1,550 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _cspublic_h_ +#define _cspublic_h_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_cspublic_h [ ] = + "$Id: cspublic.h,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_cspublic_h_warn[]={rcsid_cspublic_h, no_unused_cspublic_h_warn}; + +typedef int CS_RETCODE ; + +#define CS_PUBLIC +#define CS_STATIC static + +typedef TDS_INT CS_INT; +typedef TDS_SMALLINT CS_SMALLINT; +typedef TDS_TINYINT CS_TINYINT; +typedef TDS_CHAR CS_CHAR; +typedef TDS_UCHAR CS_BYTE; +typedef TDS_NUMERIC CS_NUMERIC; +typedef float CS_REAL; +typedef double CS_FLOAT; +typedef char CS_BOOL; +typedef void CS_VOID; +typedef TDS_VARBINARY CS_VARBINARY; + +#define CS_FAIL TDS_FAIL +#define CS_SUCCEED TDS_SUCCEED +#define CS_SIZEOF(x) sizeof(x) + +/* FIX ME */ +#define CS_NUMBER(x) (x & 0xFF) +#define CS_ORIGIN(x) ((x >> 8) & 0xFF) +#define CS_LAYER(x) ((x >> 16) & 0xFF) +#define CS_SEVERITY(x) ((x >> 24) & 0xFF) + +typedef struct cs_context +{ + CS_INT date_convert_fmt; + int (*_clientmsg_cb)(); + int (*_servermsg_cb)(); +} CS_CONTEXT; + +typedef struct cs_locale { + char *language; + char *charset; + char *time; + char *collate; +} CS_LOCALE; + +typedef struct cs_connection +{ + CS_CONTEXT *ctx; + void *tds_login; + TDSSOCKET *tds_socket; + int (*_clientmsg_cb)(); + int (*_servermsg_cb)(); + void *userdata; + int userdata_len; + CS_LOCALE *locale; +} CS_CONNECTION; + +typedef struct cs_command +{ + CS_CHAR *query; + int cmd_done; + CS_CONNECTION *con; + void *userdata; + int userdata_len; + short empty_res_hack; + short dynamic_cmd; + char *dyn_id; +} CS_COMMAND; + +#define CS_MAX_MSG 1024 +#define CS_MAX_NAME 132 +#define CS_MAX_PREC 77 /* used by php */ +#define CS_OBJ_NAME 132 /* ? */ +#define CS_TP_SIZE 16 /* ? */ + +typedef struct cs_datafmt { + int datatype; + int format; + int maxlength; + int count; + CS_LOCALE *locale; + int precision; + int scale; + int namelen; + char name[CS_MAX_NAME]; + int status; + int usertype; +} CS_DATAFMT; + +typedef struct cs_money { + int dummy; +} CS_MONEY; + +typedef struct cs_money4 { + int dummy; +} CS_MONEY4; + +typedef TDS_DATETIME CS_DATETIME; + +typedef TDS_DATETIME4 CS_DATETIME4; + +typedef struct cs_daterec { + CS_INT datesecond; + CS_INT dateminute; + CS_INT datehour; + CS_INT datedmonth; + CS_INT datedyear; + CS_INT datemonth; + CS_INT dateyear; + CS_INT dateweek; + CS_INT datedweek; + CS_INT datemsecond; + CS_INT datetzone; +} CS_DATEREC; + +typedef struct cs_clientmsg { + int severity; + int msgnumber; + char msgstring[CS_MAX_MSG]; + int msgstringlen; + long osnumber; + int osstringlen; + char osstring[CS_MAX_MSG]; +} CS_CLIENTMSG; + +typedef struct cs_servermsg { + int severity; + int msgnumber; + int state; + int line; + int svrnlen; + char svrname[CS_MAX_NAME]; + int proclen; + char proc[CS_MAX_NAME]; + char text[CS_MAX_MSG]; + int status; +} CS_SERVERMSG; + +/* status bits for CS_SERVERMSG */ +#define CS_HASEED 0x01 + +typedef struct cs_blkdesc { + int dummy; +} CS_BLKDESC; + +typedef struct cs_iodesc { + CS_INT iotype; + CS_INT datatype; + CS_LOCALE *locale; + CS_INT usertype; + CS_INT total_txtlen; + CS_INT offset; + CS_BOOL log_on_update; + CS_CHAR name[CS_OBJ_NAME]; + CS_INT namelen; + CS_BYTE textptr[CS_TP_SIZE]; + CS_INT textptrlen; +} CS_IODESC; + +/* CS_CAP_REQUEST values */ +#define CS_CON_INBAND 1 +#define CS_CON_OOB 2 +#define CS_CSR_ABS 3 +#define CS_CSR_FIRST 4 +#define CS_CSR_LAST 5 +#define CS_CSR_MULTI 6 +#define CS_CSR_PREV 7 +#define CS_CSR_REL 8 +#define CS_DATA_BIN 9 +#define CS_DATA_VBIN 10 +#define CS_DATA_LBIN 11 +#define CS_DATA_BIT 12 +#define CS_DATA_BITN 13 +#define CS_DATA_BOUNDARY 14 +#define CS_DATA_CHAR 15 +#define CS_DATA_VCHAR 16 +#define CS_DATA_LCHAR 17 +#define CS_DATA_DATE4 18 +#define CS_DATA_DATE8 19 +#define CS_DATA_DATETIMEN 20 +#define CS_DATA_DEC 21 +#define CS_DATA_FLT4 22 +#define CS_DATA_FLT8 23 +#define CS_DATA_FLTN 24 +#define CS_DATA_IMAGE 25 +#define CS_DATA_INT1 26 +#define CS_DATA_INT2 27 +#define CS_DATA_INT4 28 +#define CS_DATA_INTN 29 +#define CS_DATA_MNY4 30 +#define CS_DATA_MNY8 31 +#define CS_DATA_MONEYN 32 +#define CS_DATA_NUM 33 +#define CS_DATA_SENSITIVITY 34 +#define CS_DATA_TEXT 35 +#define CS_OPTION_GET 36 +#define CS_PROTO_BULK 37 +#define CS_PROTO_DYNAMIC 38 +#define CS_PROTO_DYNPROC 39 +#define CS_REQ_BCP 40 +#define CS_REQ_CURSOR 41 +#define CS_REQ_DYN 42 +#define CS_REQ_LANG 43 +#define CS_REQ_MSG 44 +#define CS_REQ_MSTMT 45 +#define CS_REQ_NOTIF 46 +#define CS_REQ_PARAM 47 +#define CS_REQ_URGNOTIF 48 +#define CS_REQ_RPC 49 +#define CS_DATA_INT8 50 +#define CS_DATA_VOID 51 +#define CS_CON_LOGICAL 52 +#define CS_PROTO_TEXT 53 + +/* CS_CAP_RESPONSE values */ +#define CS_DATA_NOBOUNDARY 1 +#define CS_DATA_NOTDSDEBUG 2 +#define CS_RES_NOSTRIPBLANKS 3 +#define CS_DATA_NOINT8 4 +#define CS_DATA_NOINTN 5 +#define CS_DATA_NODATETIMEN 6 +#define CS_DATA_NOMONEYN 7 +#define CS_CON_NOOOB 8 +#define CS_CON_NOINBAND 9 +#define CS_PROTO_NOTEXT 10 +#define CS_PROTO_NOBULK 11 +#define CS_DATA_NOSENSITIVITY 12 +#define CS_DATA_NOFLT4 13 +#define CS_DATA_NOFLT8 14 +#define CS_DATA_NONUM 15 +#define CS_DATA_NOTEXT 16 +#define CS_DATA_NOIMAGE 17 +#define CS_DATA_NODEC 18 +#define CS_DATA_NOLCHAR 19 +#define CS_DATA_NOLBIN 20 +#define CS_DATA_NOCHAR 21 +#define CS_DATA_NOVCHAR 22 +#define CS_DATA_NOBIN 23 +#define CS_DATA_NOVBIN 24 +#define CS_DATA_NOMNY8 25 +#define CS_DATA_NOMNY4 26 +#define CS_DATA_NODATE8 27 +#define CS_DATA_NODATE4 28 +#define CS_RES_NOMSG 29 +#define CS_RES_NOEED 30 +#define CS_RES_NOPARAM 31 +#define CS_DATA_NOINT1 32 +#define CS_DATA_NOINT2 33 +#define CS_DATA_NOINT4 34 +#define CS_DATA_NOBIT 35 + +/* Properties */ +enum { + CS_USERNAME = 1, + CS_PASSWORD, + CS_APPNAME, + CS_HOSTNAME, + CS_PACKETSIZE, + CS_SEC_ENCRYPTION, + CS_LOC_PROP, + CS_SEC_CHALLENGE, + CS_SEC_NEGOTIATE, + CS_TDS_VERSION, + CS_NETIO, + CS_IFILE, + CS_USERDATA, + CS_SEC_APPDEFINED, + CS_CHARSETCNV, + CS_ANSI_BINDS, + CS_VER_STRING +}; + +/* Arbitrary precision math operators */ +enum { + CS_ADD = 1, + CS_SUB, + CS_MULT, + CS_DIV +}; + +enum { + CS_TDS_40 = 1, + CS_TDS_42, + CS_TDS_46, + CS_TDS_495, + CS_TDS_50, + CS_TDS_70, +}; + +/* fields used by CS_DATAFMT.status */ +#define CS_CANBENULL (1) +#define CS_HIDDEN (1 << 1) +#define CS_IDENTITY (1 << 2) +#define CS_KEY (1 << 3) +#define CS_VERSION_KEY (1 << 4) +#define CS_TIMESTAMP (1 << 5) +#define CS_UPDATABLE (1 << 6) + +/* DBD::Sybase compares indicator to CS_NULLDATA so this is -1 +** (the documentation states -1) */ +#define CS_NULLDATA (-1) + +/* CS_CON_STATUS read-only property bit mask values */ +#define CS_CONSTAT_CONNECTED 0x01 +#define CS_CONSTAT_DEAD 0x02 + +/* options accepted by ct_options() */ +#define CS_OPT_ANSINULL 1 +#define CS_OPT_ANSIPERM 2 +#define CS_OPT_ARITHABORT 3 +#define CS_OPT_ARITHIGNORE 4 +#define CS_OPT_AUTHOFF 5 +#define CS_OPT_AUTHON 6 +#define CS_OPT_CHAINXACTS 7 +#define CS_OPT_CURCLOSEONXACT 8 +#define CS_OPT_CURREAD 9 +#define CS_OPT_CURWRITE 10 +#define CS_OPT_DATEFIRST 11 +#define CS_OPT_DATEFORMAT 12 +#define CS_OPT_FIPSFLAG 13 +#define CS_OPT_FORCEPLAN 14 +#define CS_OPT_FORMATONLY 15 +#define CS_OPT_GETDATA 16 +#define CS_OPT_IDENTITYOFF 17 +#define CS_OPT_IDENTITYON 18 +#define CS_OPT_ISOLATION 19 +#define CS_OPT_NOCOUNT 20 +#define CS_OPT_NOEXEC 21 +#define CS_OPT_PARSEONLY 22 +#define CS_OPT_QUOTED_IDENT 23 +#define CS_OPT_RESTREES 24 +#define CS_OPT_ROWCOUNT 25 +#define CS_OPT_SHOWPLAN 26 +#define CS_OPT_STATS_IO 27 +#define CS_OPT_STATS_TIME 28 +#define CS_OPT_STR_RTRUNC 29 +#define CS_OPT_TEXTSIZE 30 +#define CS_OPT_TRUNCIGNORE 31 + +/* bind formats, should be mapped to TDS types */ +enum { + CS_FMT_UNUSED = 0, + CS_FMT_NULLTERM, + CS_FMT_PADBLANK, + CS_FMT_PADNULL +}; + +/* other */ +#define CS_NULLTERM 2 +#define CS_SET 4 +#define CS_UNUSED 5 +#define CS_LANG_CMD 7 +#define CS_ROW_FAIL 9 +#define CS_END_DATA 10 +#define CS_CMD_SUCCEED 12 +#define CS_CMD_FAIL 13 +#define CS_CMD_DONE 14 +#define CS_END_RESULTS 15 +#define CS_VERSION_100 16 +#define CS_FORCE_EXIT 17 +#define CS_MESSAGE_CB 18 +#define CS_CLIENTMSG_CB 19 +#define CS_SERVERMSG_CB 20 +#define CS_NOTIF_CB 21 +#define CS_GET 25 +#define CS_CON_STATUS 26 +#define CS_FORCE_CLOSE 27 +#define CS_SYNC_IO 29 +#define CS_LC_ALL 37 +#define CS_SYB_LANG 38 +#define CS_SYB_CHARSET 39 +#define CS_SV_COMM_FAIL 41 +#define CS_BULK_LOGIN 42 +#define BLK_VERSION_100 CS_VERSION_100 +#define CS_BLK_IN 43 +#define CS_BLK_OUT 44 +#define CS_BLK_BATCH 45 +#define CS_BLK_ALL 46 +#define CS_BLK_CANCEL 47 +#define CS_CANCEL_ALL 48 +#define CS_NUMDATA 49 +#define CS_CANCEL_ATTN 50 +#define CS_PARENT_HANDLE 51 +#define CS_COMP_ID 52 +#define CS_BYLIST_LEN 53 +#define CS_COMP_BYLIST 54 +#define CS_COMP_OP 55 +#define CS_COMP_COLID 56 +#define CS_NO_COUNT 57 +#define CS_ROW_COUNT 59 +#define CS_OP_SUM 60 +#define CS_OP_AVG 61 +#define CS_OP_MIN 62 +#define CS_OP_MAX 63 +#define CS_OP_COUNT 64 +#define CS_CANCEL_CURRENT 67 +#define CS_CAPREQUEST 73 +#define CS_NO_LIMIT 74 +#define CS_EED_CMD 77 +#define CS_LOGIN_TIMEOUT 78 +#define CS_CAP_REQUEST 79 +#define CS_DESCRIBE_INPUT 80 +#define CS_PREPARE 81 +#define CS_EXECUTE 82 +#define CS_DEALLOC 83 +#define CS_CAP_RESPONSE 84 +#define CS_RPC_CMD 85 +#define CS_INPUTVALUE 86 +#define CS_GOODDATA 87 +#define CS_RETURN 88 +#define CS_CMD_NUMBER 89 +#define CS_BROWSE_INFO 90 +#define CS_NUMORDERCOLS 91 +#define CS_NUM_COMPUTES 92 +#define CS_NODATA 96 +#define CS_DESCIN 98 +#define CS_DESCOUT 99 +#define CS_UPDATECOL 100 +#define CS_NODEFAULT 102 +#define CS_FMT_JUSTIFY_RT 106 +#define CS_TRANS_STATE 107 +#define CS_TRAN_IN_PROGRESS 108 +#define CS_TRAN_COMPLETED 109 +#define CS_TRAN_STMT_FAIL 110 +#define CS_TRAN_FAIL 111 +#define CS_TRAN_UNDEFINED 112 +#define CS_SV_RETRY_FAIL 114 +#define CS_TIMEOUT 115 +#define CS_CANCELED 116 +#define CS_NO_RECOMPILE 117 +#define CS_COLUMN_DATA 118 +#define CS_SEND_DATA_CMD 119 + +/* result_types */ +#define CS_COMPUTE_RESULT 1 +#define CS_CURSOR_RESULT 2 +#define CS_PARAM_RESULT 3 +#define CS_ROW_RESULT 4 +#define CS_STATUS_RESULT 5 +#define CS_COMPUTEFMT_RESULT 6 +#define CS_ROWFMT_RESULT 7 +#define CS_MSG_RESULT 8 +#define CS_DESCRIBE_RESULT 9 + +/* bind types */ +#define CS_CHAR_TYPE 1 +#define CS_INT_TYPE 2 +#define CS_SMALLINT_TYPE 3 +#define CS_TINYINT_TYPE 4 +#define CS_MONEY_TYPE 5 +#define CS_DATETIME_TYPE 6 +#define CS_NUMERIC_TYPE 7 +#define CS_DECIMAL_TYPE 8 +#define CS_DATETIME4_TYPE 9 +#define CS_MONEY4_TYPE 10 +#define CS_IMAGE_TYPE 11 +#define CS_BINARY_TYPE 12 +#define CS_BIT_TYPE 13 +#define CS_REAL_TYPE 14 +#define CS_FLOAT_TYPE 15 +#define CS_TEXT_TYPE 16 +#define CS_VARCHAR_TYPE 17 +#define CS_VARBINARY_TYPE 18 +#define CS_LONGCHAR_TYPE 19 +#define CS_LONGBINARY_TYPE 20 +#define CS_LONG_TYPE 21 +#define CS_ILLEGAL_TYPE 22 +#define CS_SENSITIVITY_TYPE 23 +#define CS_BOUNDARY_TYPE 24 +#define CS_VOID_TYPE 25 +#define CS_USHORT_TYPE 26 + +/* cs_dt_info type values */ +enum { + CS_MONTH = 1, + CS_SHORTMONTH, + CS_DAYNAME, + CS_DATEORDER, + CS_12HOUR, + CS_DT_CONVFMT +}; + +/* DT_CONVFMT types */ +enum { + CS_DATES_HMS = 1, + CS_DATES_SHORT, + CS_DATES_LONG, + CS_DATES_MDY1, + CS_DATES_MYD1, + CS_DATES_DMY1, + CS_DATES_DYM1, + CS_DATES_YDM1, + CS_DATES_YMD2, + CS_DATES_MDY1_YYYY, + CS_DATES_DMY1_YYYY, + CS_DATES_YMD2_YYYY, + CS_DATES_DMY2, + CS_DATES_YMD1, + CS_DATES_DMY2_YYYY, + CS_DATES_YMD1_YYYY, + CS_DATES_DMY4, + CS_DATES_DMY4_YYYY, + CS_DATES_MDY2, + CS_DATES_MDY2_YYYY, + CS_DATES_DMY3, + CS_DATES_MDY3, + CS_DATES_DMY3_YYYY, + CS_DATES_MDY3_YYYY, + CS_DATES_YMD3, + CS_DATES_YMD3_YYYY +}; + +/* */ +#define CS_FALSE 0 +#define CS_TRUE 1 + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/cstypes.h b/include/cstypes.h new file mode 100644 index 000000000..d459408ed --- /dev/null +++ b/include/cstypes.h @@ -0,0 +1,40 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _cstypes_h_ +#define _cstypes_h_ + +/* seperate this stuff out later */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_cstypes_h [ ] = + "$Id: cstypes.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_cstypes_h_warn[]={rcsid_cstypes_h, no_unused_cstypes_h_warn}; + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/ctlib.h b/include/ctlib.h new file mode 100644 index 000000000..30546b5e5 --- /dev/null +++ b/include/ctlib.h @@ -0,0 +1,57 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ctlib_h_ +#define _ctlib_h_ +/* +** Internal (not part of the exposed API) prototypes and such. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_ctlib_h [ ] = + "$Id: ctlib.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_ctlib_h_warn[]={rcsid_ctlib_h, no_unused_ctlib_h_warn}; + +#include + +#define DBLIB_INFO_MSG_TYPE 0 +#define DBLIB_ERROR_MSG_TYPE 1 + +/* +** internal typedefs +*/ +typedef struct ctcolinfo +{ + TDS_SMALLINT *indicator; +} CT_COLINFO; + +/* +** internal prototypes +*/ +int ctlib_handle_info_message(void *aStruct); +int ctlib_handle_err_message(void *aStruct); +int _ct_get_server_type(int datatype); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/ctpublic.h b/include/ctpublic.h new file mode 100644 index 000000000..f056c5d2c --- /dev/null +++ b/include/ctpublic.h @@ -0,0 +1,39 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ctpublic_h_ +#define _ctpublic_h_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_ctpublic_h [ ] = + "$Id: ctpublic.h,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_ctpublic_h_warn[]={rcsid_ctpublic_h, no_unused_ctpublic_h_warn}; + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/dblib.h b/include/dblib.h new file mode 100644 index 000000000..1a127430e --- /dev/null +++ b/include/dblib.h @@ -0,0 +1,47 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _dblib_h_ +#define _dblib_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_dblib_h [ ] = + "$Id: dblib.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_dblib_h_warn[]={rcsid_dblib_h, no_unused_dblib_h_warn}; + + +#define DBLIB_INFO_MSG_TYPE 0 +#define DBLIB_ERROR_MSG_TYPE 1 + +/* +** internal prototypes +*/ +int dblib_handle_info_message(void *aStruct); +int dblib_handle_err_message(void *aStruct); +DBINT _convert_char(int srctype,BYTE *src,int destype,BYTE *dest,DBINT destlen); +DBINT _convert_intn(int srctype,BYTE *src,int destype,BYTE *dest,DBINT destlen); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sqldb.h b/include/sqldb.h new file mode 100644 index 000000000..a86f001e3 --- /dev/null +++ b/include/sqldb.h @@ -0,0 +1,31 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SQLDB_h +#define SQLDB_h + +#include + + +static char rcsid_sqldb_h [ ] = + "$Id: sqldb.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_sqldb_h_warn[]={rcsid_sqldb_h, no_unused_sqldb_h_warn}; + + +#endif diff --git a/include/sqlfront.h b/include/sqlfront.h new file mode 100644 index 000000000..4ffbc5bbd --- /dev/null +++ b/include/sqlfront.h @@ -0,0 +1,30 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SQLFRONT_h +#define SQLFRONT_h + +#include + +static char rcsid_sqlfront_h [ ] = + "$Id: sqlfront.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_sqlfront_h_warn[]={rcsid_sqlfront_h, no_unused_sqlfront_h_warn}; + + +#endif diff --git a/include/sybdb.h b/include/sybdb.h new file mode 100644 index 000000000..a0c96d343 --- /dev/null +++ b/include/sybdb.h @@ -0,0 +1,490 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _sybdb_h_ +#define _sybdb_h_ + +#include "tds.h" + +#ifdef __cplusplus +extern "C" { +#if 0 +} +#endif +#endif + +static char rcsid_sybdb_h [ ] = +"$Id: sybdb.h,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_sybdb_h_warn[]={rcsid_sybdb_h, no_unused_sybdb_h_warn}; + +#ifdef FALSE +#undef FALSE +#endif +#ifdef TRUE +#undef TRUE +#endif +#define FALSE 0 +#define TRUE 1 + +#define DBSAVE 1 +#define DBNOSAVE 0 +#define DBNOERR -1 + +#define INT_EXIT 0 +#define INT_CANCEL 2 + +#define DBMAXNUMLEN 33 +#define MAXNAME 30 + +#define DBVERSION_UNKNOWN 0 +#define DBVERSION_46 1 +#define DBVERSION_100 2 +#define DBVERSION_42 3 +#define DBVERSION_70 4 + +#define SYBAOPCNT 0x4b +#define SYBAOPCNTU 0x4c +#define SYBAOPSUM 0x4d +#define SYBAOPSUMU 0x4e +#define SYBAOPAVG 0x4f +#define SYBAOPAVGU 0x50 +#define SYBAOPMIN 0x51 +#define SYBAOPMAX 0x52 + +#define DBTXPLEN 16 + +typedef int RETCODE; + +#ifndef __INCvxWorksh +/* VxWorks already defines STATUS and BOOL. Compiler gets mad if you +** redefine them. */ +/* __INCvxWorksh will get #defined by std. include files included from tds.h +*/ +typedef int STATUS; +typedef unsigned char BOOL ; +#endif + +typedef unsigned char DBBOOL ; +typedef TDS_CHAR DBCHAR ; +typedef unsigned char DBTINYINT ; +typedef TDS_SMALLINT DBSMALLINT ; +typedef TDS_INT DBINT ; +typedef unsigned char DBBINARY ; +typedef TDS_REAL DBREAL ; +typedef TDS_FLOAT DBFLT8 ; +typedef unsigned short DBUSMALLINT ; +typedef TDS_NUMERIC DBNUMERIC ; +typedef TDS_MONEY DBMONEY ; +typedef TDS_MONEY4 DBMONEY4 ; +typedef TDS_DATETIME DBDATETIME ; +typedef TDS_DATETIME4 DBDATETIME4 ; + +#ifdef MSDBLIB +#define SQLCHAR SYBCHAR +#endif + +typedef struct { +void *tds_login ; +} LOGINREC; + +typedef unsigned char BYTE; + +typedef struct tag_DBPROC_ROWBUF +{ + int buffering_on; /* (boolean) is row buffering turned on? */ + int first_in_buf; /* result set row number of first row in buf */ + int next_row; /* result set row number of next row */ + int newest; /* index of most recent item in queue */ + int oldest; /* index of least recent item in queue */ + int elcount; /* max element count that buffer can hold */ + int element_size; /* size in bytes of each element in queue */ + int rows_in_buf; /* # of rows currently in buffer */ + void *rows; /* pointer to the row storage */ +} DBPROC_ROWBUF; + +typedef struct { + int column; + int datatype; + int prefix_len; + DBINT column_len; + BYTE *terminator; + int term_len; + long data_size; + BYTE *data; + int txptr_offset; + /* fields below here comes from 'insert bulk' result set */ + char db_name[256]; /* column name */ + TDS_SMALLINT db_minlen; + TDS_SMALLINT db_maxlen; + TDS_SMALLINT db_colcnt; /* I dont know what this does */ + TDS_TINYINT db_type; + TDS_INT db_length; /* size of field according to database */ + TDS_TINYINT db_status; + TDS_SMALLINT db_offset; + TDS_TINYINT db_default; + TDS_TINYINT db_prec; + TDS_TINYINT db_scale; +} BCP_COLINFO; + +typedef struct { + TDSSOCKET *tds_socket ; + + DBPROC_ROWBUF row_buf; + + int noautofree; + int more_results; /* boolean. Are we expecting results? */ + BYTE *user_data; /* see dbsetuserdata() and dbgetuserdata() */ + unsigned char *dbbuf; /* is dynamic! */ + int dbbufsz; + int empty_res_hack; + TDS_INT text_size; + TDS_INT text_sent; + TDS_CHAR *bcp_hostfile; + TDS_CHAR *bcp_errorfile; + TDS_CHAR *bcp_tablename; + TDS_INT bcp_direction; + TDS_INT bcp_colcount; + BCP_COLINFO **bcp_columns; +} DBPROCESS; + +typedef struct dbdaterec +{ +#ifndef MSDBLIB + DBINT dateyear; + DBINT datemonth; + DBINT datedmonth; + DBINT datedyear; + DBINT datedweek; + DBINT datehour; + DBINT dateminute; + DBINT datesecond; + DBINT datemsecond; + DBINT datetzone; +#else + DBINT year; + DBINT month; + DBINT day; + DBINT dayofyear; + DBINT weekday; + DBINT hour; + DBINT minute; + DBINT second; + DBINT millisecond; + DBINT tzone; +#endif +} DBDATEREC; + +typedef struct dbtypeinfo +{ + DBINT precision; + DBINT scale; +} DBTYPEINFO; + +typedef int (*EHANDLEFUNC) (DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr); + +typedef int (*MHANDLEFUNC) (DBPROCESS *dbproc, int msgno, int msgstate, int severity, char *msgtext, char *srvname, char *proc, int line); + +enum { + DBPADOFF, + DBPADON +}; +/* a large list of options, DBTEXTSIZE is needed by sybtcl */ +#define DBPARSEONLY 0 +#define DBESTIMATE 1 +#define DBSHOWPLAN 2 +#define DBNOEXEC 3 +#define DBARITHIGNORE 4 +#define DBNOCOUNT 5 +#define DBARITHABORT 6 +#define DBTEXTLIMIT 7 +#define DBBROWSE 8 +#define DBOFFSET 9 +#define DBSTAT 10 +#define DBERRLVL 11 +#define DBCONFIRM 12 +#define DBSTORPROCID 13 +#define DBBUFFER 14 +#define DBNOAUTOFREE 15 +#define DBROWCOUNT 16 +#define DBTEXTSIZE 17 +#define DBNATLANG 18 +#define DBDATEFORMAT 19 +#define DBPRPAD 20 +#define DBPRCOLSEP 21 +#define DBPRLINELEN 22 +#define DBPRLINESEP 23 +#define DBLFCONVERT 24 +#define DBDATEFIRST 25 +#define DBCHAINXACTS 26 +#define DBFIPSFLAG 27 +#define DBISOLATION 28 +#define DBAUTH 29 +#define DBIDENTITY 30 + +#define DBNUMOPTIONS 31 + +#define DBPRPADON 1 +#define DBPRPADOFF 0 + +/* dbpoll() result codes, sybtcl needs DBRESULT */ +#define DBRESULT 1 +#define DBNOTIFICATION 2 +#define DBTIMEOUT 3 +#define DBINTERRUPT 4 + +/* more sybtcl needs: */ +#define DBTXTSLEN 8 + +/* bind types */ +#define CHARBIND 0 +#define STRINGBIND 1 +#define NTBSTRINGBIND 2 +#define VARYCHARBIND 3 +#define TINYBIND 6 +#define SMALLBIND 7 +#define INTBIND 8 +#define FLT8BIND 9 +#define REALBIND 10 +#define DATETIMEBIND 11 +#define SMALLDATETIMEBIND 12 +#define MONEYBIND 13 +#define SMALLMONEYBIND 14 +#define BINARYBIND 15 +#define BITBIND 16 +#define NUMERICBIND 17 +#define DECIMALBIND 18 + +#define DBPRCOLSEP 21 +#define DBPRLINELEN 22 +#define DBRPCRETURN 1 + +#define REG_ROW -1 +#define MORE_ROWS -1 +#define NO_MORE_ROWS -2 +#define BUF_FULL -3 +#define NO_MORE_RESULTS 2 +#define SUCCEED 1 +#define FAIL 0 + +#define DB_IN 1 +#define DB_OUT 2 +#define IN 1 +#define OUT 2 + +#define DBSINGLE 0 +#define DBDOUBLE 1 +#define DBBOTH 2 + +extern RETCODE dbinit(); +extern LOGINREC *dblogin(); +extern RETCODE DBSETLPACKET(LOGINREC *login, short packet_size); +extern RETCODE DBSETLPWD(LOGINREC *login, char *password); +extern RETCODE DBSETLUSER(LOGINREC *login, char *username); +extern RETCODE DBSETLHOST(LOGINREC *login, char *hostname); +extern RETCODE DBSETLAPP(LOGINREC *login, char *application); +#ifdef DBMFIX +extern DBPROCESS *tdsdbopen(LOGINREC *login,char *server); +#define dbopen(x,y) tdsdbopen(x,y) +#else +extern DBPROCESS *dbopen(LOGINREC *login,char *server); +#endif +extern RETCODE dbclose(DBPROCESS *dbprocess); +extern DBINT dbconvert(DBPROCESS *dbproc, int srctype, + BYTE *src, DBINT srclen, int desttype, BYTE *dest, + DBINT destlen); +extern void dbexit(); +extern RETCODE DBCMDROW(DBPROCESS *dbproc); +extern RETCODE dbsetdeflang(char *language); +extern int dbgetpacket(DBPROCESS *dbproc); +extern RETCODE dbsetmaxprocs(int maxprocs); +extern RETCODE dbsettime(int seconds); +extern RETCODE dbsetlogintime(int seconds); +extern RETCODE dbresults(DBPROCESS *dbproc); +extern RETCODE dbnextrow(DBPROCESS *dbproc); +extern RETCODE dbgetrow(DBPROCESS *dbproc, DBINT row); +extern DBINT dbretstatus(DBPROCESS *dbproc); +extern DBBOOL dbhasretstat(DBPROCESS *dbproc); +extern DBINT dbdatlen(DBPROCESS *dbproc, int column); +extern char *dbcolsource(DBPROCESS *dbproc,int colnum); +extern int dbcoltype(DBPROCESS *dbproc,int column); +extern DBINT DBCOUNT(DBPROCESS *dbproc); +extern DBINT DBLASTROW(DBPROCESS *dbproc); +extern void dbclrbuf(DBPROCESS *dbproc, DBINT n); +extern DBBOOL dbwillconvert(int srctype, int desttype); +extern int dbaltcolid(DBPROCESS *dbproc, int computeid, int column); +extern DBINT dbadlen(DBPROCESS *dbproc,int computeid, int column); +extern int dbalttype(DBPROCESS *dbproc, int computeid, int column); +extern BYTE *dbadata(DBPROCESS *dbproc, int computeid, int column); +extern int dbaltop(DBPROCESS *dbproc, int computeid, int column); +extern RETCODE dbsetopt(DBPROCESS *dbproc, int option, char *char_param, + int int_param); +extern void dbsetinterrupt(DBPROCESS *dbproc, + int (*ckintr)(),int (*hndlintr)()); +extern RETCODE dbcancel(DBPROCESS *dbproc); +extern int dbnumrets(DBPROCESS *dbproc); +extern char *dbretname(DBPROCESS *dbproc, int retnum); +extern BYTE *dbretdata(DBPROCESS *dbproc, int retnum); +extern int dbretlen(DBPROCESS *dbproc, int retnum); +extern RETCODE dbsqlok(DBPROCESS *dbproc); +extern void dbprrow(DBPROCESS *dbproc); +extern void dbprhead(DBPROCESS *dbproc); +extern void dbloginfree(LOGINREC *login); +extern int dbnumalts(DBPROCESS *dbproc,int computeid); +extern BYTE *dbbylist(DBPROCESS *dbproc, int computeid, int size); +extern RETCODE dbrpcinit(DBPROCESS *dbproc,char *rpcname, + DBSMALLINT options); +extern RETCODE dbrpcparam(DBPROCESS *dbproc, char *paramname, BYTE status, + int type, DBINT maxlen, DBINT datalen, + BYTE *value); +extern RETCODE dbrpcsend(DBPROCESS *dbproc); +extern RETCODE dbuse(DBPROCESS *dbproc,char *dbname); +extern DBBOOL DBDEAD(DBPROCESS *dbproc); + +extern int (*dbmsghandle( int (*handler)() )) (); +extern int (*dberrhandle( int (*handler)() )) (); + +extern RETCODE BCP_SETL(LOGINREC *login, DBBOOL enable); +extern RETCODE bcp_init(DBPROCESS *dbproc, char *tblname, char *hfile, + char *errfile, int direction); +extern RETCODE bcp_collen(DBPROCESS *dbproc, DBINT varlen, + int table_column); +extern RETCODE bcp_columns(DBPROCESS *dbproc, int host_colcount); +extern RETCODE bcp_colfmt(DBPROCESS *dbproc, int host_colnum, + int host_type, int host_prefixlen, + DBINT host_collen, BYTE *host_term, + int host_termlen, int table_colnum); +extern RETCODE bcp_colfmt_ps(DBPROCESS *dbproc, int host_colnum, + int host_type, int host_prefixlen, + DBINT host_collen, BYTE *host_term, + int host_termlen, int table_colnum, + DBTYPEINFO *typeinfo); +extern RETCODE bcp_control(DBPROCESS *dbproc, int field, DBINT value); +extern RETCODE bcp_colptr(DBPROCESS *dbproc, BYTE *colptr, + int table_column); +extern DBBOOL bcp_getl(LOGINREC *login); +extern RETCODE bcp_exec(DBPROCESS *dbproc, DBINT *rows_copied); +extern RETCODE bcp_readfmt(DBPROCESS *dbproc, char *filename); +extern RETCODE bcp_writefmt(DBPROCESS *dbproc, char *filename); +extern RETCODE bcp_sendrow(DBPROCESS *dbproc); +extern RETCODE bcp_moretext(DBPROCESS *dbproc, DBINT size, BYTE *text); +extern RETCODE bcp_batch(DBPROCESS *dbproc); +extern RETCODE bcp_done(DBPROCESS *dbproc); +extern RETCODE bcp_bind(DBPROCESS *dbproc, BYTE *varaddr, int prefixlen, + DBINT varlen, BYTE *terminator, int termlen, + int type, int table_column); +extern RETCODE dbmnyadd(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, + DBMONEY *sum); +extern RETCODE dbmnysub(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, + DBMONEY *diff); +extern RETCODE dbmnymul(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, + DBMONEY *prod); +extern RETCODE dbmnydivide(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, + DBMONEY *quotient); +extern RETCODE dbmnycmp(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2); +extern RETCODE dbmnyscale(DBPROCESS *dbproc, DBMONEY *dest,int multiplier, + int addend); +extern RETCODE dbmnyzero(DBPROCESS *dbproc, DBMONEY *dest); +extern RETCODE dbmnymaxpos(DBPROCESS *dbproc, DBMONEY *dest); +extern RETCODE dbmnymaxneg(DBPROCESS *dbproc, DBMONEY *dest); +extern RETCODE dbmnyndigit(DBPROCESS *dbproc, DBMONEY *mnyptr, + DBCHAR *value, DBBOOL *zero); +extern RETCODE dbmnyinit(DBPROCESS *dbproc,DBMONEY *mnyptr, int trim, + DBBOOL *negative); +extern RETCODE dbmnydown(DBPROCESS *dbproc,DBMONEY *mnyptr, int divisor, + int *remainder); +extern RETCODE dbmnyinc(DBPROCESS *dbproc,DBMONEY *mnyptr); +extern RETCODE dbmnydec(DBPROCESS *dbproc,DBMONEY *mnyptr); +extern RETCODE dbmnyminus(DBPROCESS *dbproc,DBMONEY *src, DBMONEY *dest); +extern RETCODE dbmny4cmp(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2); +extern RETCODE dbmny4minus(DBPROCESS *dbproc, DBMONEY4 *src, + DBMONEY4 *dest); +extern RETCODE dbmny4zero(DBPROCESS *dbproc, DBMONEY4 *dest); +extern RETCODE dbmny4add(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, + DBMONEY4 *sum); +extern RETCODE dbmny4sub(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, + DBMONEY4 *diff); +extern RETCODE dbmny4mul(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, + DBMONEY4 *prod); +extern RETCODE dbmny4divide(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, + DBMONEY4 *quotient); +extern RETCODE dbmny4cmp(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2); +extern RETCODE dbdatecmp(DBPROCESS *dbproc, DBDATETIME *d1, + DBDATETIME *d2); +extern RETCODE dbdatecrack(DBPROCESS *dbproc, DBDATEREC *dateinfo, + DBDATETIME *datetime); +extern void dbrpwclr(LOGINREC *login); +extern RETCODE dbrpwset(LOGINREC *login, char *srvname, char *password, + int pwlen); +extern void build_xact_string(char *xact_name, char *service_name, + DBINT commid, char *result); +extern RETCODE remove_xact(DBPROCESS *connect, DBINT commid, int n); +extern RETCODE abort_xact(DBPROCESS *connect, DBINT commid); +extern void close_commit(DBPROCESS *connect); +extern RETCODE commit_xact(DBPROCESS *connect, DBINT commid); +extern DBPROCESS *open_commit(LOGINREC *login, char *servername); +extern RETCODE scan_xact(DBPROCESS *connect, DBINT commid); +extern DBINT start_xact(DBPROCESS *connect, char *application_name, + char *xact_name, int site_count); +extern DBINT stat_xact(DBPROCESS *connect, DBINT commid); +extern int dbspid(DBPROCESS *dbproc); +extern char *dbmonthname(DBPROCESS *dbproc,char *language,int monthnum, + DBBOOL shortform); +extern char *dbname(DBPROCESS *dbproc); +extern BYTE *dbdata(DBPROCESS *dbproc,int column); +extern char *dbcolname(DBPROCESS *dbproc,int column); +extern DBBINARY *dbtxptr(DBPROCESS *dbproc,int column); +extern DBBINARY *dbtxtimestamp(DBPROCESS *dbproc, int column); +extern RETCODE dbwritetext(DBPROCESS *dbproc,char *objname, + DBBINARY *textptr, DBTINYINT textptrlen, + DBBINARY *timestamp, DBBOOL log, + DBINT size, BYTE *text); +extern void dbfreebuf(DBPROCESS *dbproc); +extern RETCODE dbcmd(DBPROCESS *dbproc, char *cmdstring); +extern RETCODE dbsqlexec(DBPROCESS *dbproc); +extern int dbnumcols(DBPROCESS *dbproc); +extern DBINT dbcollen(DBPROCESS *dbproc, int column); +extern char *dbprtype(int token); +extern RETCODE dbbind(DBPROCESS *dbproc, int column, int vartype, + DBINT varlen, BYTE *varaddr); +extern RETCODE dbnullbind(DBPROCESS *dbproc, int column, DBINT *indicator); +extern RETCODE dbsqlsend(DBPROCESS *dbproc); +extern RETCODE dbaltutype(DBPROCESS *dbproc, int computeid, int column); +extern RETCODE dbaltlen(DBPROCESS *dbproc, int computeid, int column); +extern RETCODE dbpoll(DBPROCESS *dbproc, long milliseconds, + DBPROCESS **ready_dbproc, int *return_reason); + +extern int DBIORDESC(DBPROCESS *dbproc); +extern int DBIOWDESC(DBPROCESS *dbproc); + +extern DBINT dbspr1rowlen(DBPROCESS *dbproc); +extern RETCODE dbspr1row(DBPROCESS *dbproc, char *buffer, DBINT buf_len); +extern RETCODE dbsprline(DBPROCESS *dbproc,char *buffer, DBINT buf_len, + DBCHAR line_char); +extern RETCODE dbsprhead(DBPROCESS *dbproc,char *buffer, DBINT buf_len); +extern char *dbversion(); +extern RETCODE dbcanquery(DBPROCESS *dbproc); + +#ifdef __cplusplus +#if 0 +{ +#endif +} +#endif + +#endif diff --git a/include/syberror.h b/include/syberror.h new file mode 100644 index 000000000..b604c92bd --- /dev/null +++ b/include/syberror.h @@ -0,0 +1,39 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _syberror_h_ +#define _syberror_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_syberror_h [ ] = + "$Id: syberror.h,v 1.1 2001-10-12 23:28:56 brianb Exp $"; +static void *no_unused_syberror_h_warn[]={rcsid_syberror_h, no_unused_syberror_h_warn}; + + + +#define EXSERVER 5 + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/sybfront.h b/include/sybfront.h new file mode 100644 index 000000000..cb99a55a4 --- /dev/null +++ b/include/sybfront.h @@ -0,0 +1,40 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef SYBFRONT_h +#define SYBFRONT_h + +#include "sybdb.h" + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_sybfront_h [ ] = + "$Id: sybfront.h,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_sybfront_h_warn[]={rcsid_sybfront_h, no_unused_sybfront_h_warn}; + + + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/include/tds.h b/include/tds.h new file mode 100644 index 000000000..4ee3e8ae6 --- /dev/null +++ b/include/tds.h @@ -0,0 +1,608 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tds_h_ +#define _tds_h_ + +static char rcsid_tds_h[]= + "$Id: tds.h,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_tds_h_warn[]={rcsid_tds_h, no_unused_tds_h_warn}; + +#include "tds_configs.h" + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef WIN32 +#include +#include +#endif + +#ifdef __INCvxWorksh +#include +#include /* for FIONBIO */ +#else +#include +#include +#include +#include +#include +#include +/* FIX ME -- use autoconf for the existance of malloc.h */ +#ifndef __APPLE__ +#include +#endif +#include +#endif + +#ifndef WIN32 +#include +#endif + +#include "tdsver.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** this is where platform specific changes need to be made. +** I've tried to change all references to data that goes to +** or comes off the wire to use these typedefs. I've probably +** missed a bunch, but the idea is we can do an ifdef here +** to set the appropriately sized native type. +** +** If you have problems on 64bit machines and the code is +** using a native datatype, please change the code to use +** these. (In the TDS layer only, the API layers have their +** own typedefs which equate to these). +*/ +typedef char TDS_CHAR; /* 8 bit char */ +typedef unsigned char TDS_UCHAR; /* 8 bit uchar */ +typedef unsigned char TDS_TINYINT; /* 8 bit int */ +typedef short TDS_SMALLINT; /* 16 bit int */ +typedef unsigned short TDS_USMALLINT; /* 16 bit unsigned */ +typedef int TDS_INT; /* 32 bit int */ +typedef unsigned int TDS_UINT; /* 32 bit unsigned */ +typedef float TDS_REAL; /* 32 bit float */ +typedef double TDS_FLOAT; /* 64 bit float */ +typedef struct tdsnumeric +{ + unsigned char precision; + unsigned char scale; + unsigned char array[33]; +} TDS_NUMERIC; +typedef struct tdsmoney +{ + TDS_INT mnyhigh; + TDS_INT mnylow; +} TDS_MONEY; +typedef struct tdsmoney4 +{ + TDS_INT mny4; +} TDS_MONEY4; +typedef struct tdsdatetime +{ + TDS_INT dtdays; + TDS_INT dttime; +} TDS_DATETIME; +typedef struct tdsdatetime4 +{ + TDS_USMALLINT days; + TDS_USMALLINT minutes; +} TDS_DATETIME4; +typedef struct tdsvarbinary +{ + TDS_INT len; + TDS_CHAR array[256]; +} TDS_VARBINARY; +typedef struct tdsvarchar +{ + TDS_INT len; + TDS_CHAR array[256]; +} TDS_VARCHAR; + +#define TDS_NO_MORE_ROWS -2 +#define TDS_SUCCEED 1 +#define TDS_FAIL 0 +#define TDS_NO_MORE_RESULTS 2 +/* +** TDS_ERROR indicates a successful processing, but an TDS_ERR_TOKEN or +** TDS_EED_TOKEN error was encountered, whereas TDS_FAIL indicates an +** unrecoverable failure. +*/ +#define TDS_ERROR 3 +#define TDS_DONT_RETURN 42 + +#define TDS5_DYN_TOKEN 231 /* 0xE7 TDS 5.0 only */ +#define TDS5_DYNRES_TOKEN 236 /* 0xEC TDS 5.0 only */ +#define TDS5_DYN3_TOKEN 215 /* 0xD7 TDS 5.0 only */ +#define TDS_LANG_TOKEN 33 /* 0x21 TDS 5.0 only */ +#define TDS_CLOSE_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */ +#define TDS_RET_STAT_TOKEN 121 /* 0x79 */ +#define TDS_124_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */ +#define TDS7_RESULT_TOKEN 129 /* 0x81 TDS 7.0 only */ +#define TDS_COL_NAME_TOKEN 160 /* 0xA0 TDS 4.2 only */ +#define TDS_COL_INFO_TOKEN 161 /* 0xA1 TDS 4.2 only - TDS_COLFMT */ +/*#define TDS_TABNAME 164 */ +/*#define TDS_COL_INFO 165 */ +#define TDS_167_TOKEN 167 /* 0xA7 */ +#define TDS_168_TOKEN 168 /* 0xA8 */ +#define TDS_ORDER_BY_TOKEN 169 /* 0xA9 TDS_ORDER */ +#define TDS_ERR_TOKEN 170 /* 0xAA */ +#define TDS_MSG_TOKEN 171 /* 0xAB */ +#define TDS_PARAM_TOKEN 172 /* 0xAC RETURNVALUE? */ +#define TDS_LOGIN_ACK_TOKEN 173 /* 0xAD */ +#define TDS_174_TOKEN 174 /* 0xAE TDS_CONTROL */ +#define TDS_ROW_TOKEN 209 /* 0xD1 */ +#define TDS_CMP_ROW_TOKEN 211 /* 0xD3 */ +#define TDS_CAP_TOKEN 226 /* 0xE2 */ +#define TDS_ENV_CHG_TOKEN 227 /* 0xE3 */ +#define TDS_EED_TOKEN 229 /* 0xE5 */ +#define TDS_AUTH_TOKEN 237 /* 0xED */ +#define TDS_RESULT_TOKEN 238 /* 0xEE */ +#define TDS_DONE_TOKEN 253 /* 0xFD TDS_DONE */ +#define TDS_DONEPROC_TOKEN 254 /* 0xFE TDS_DONEPROC */ +#define TDS_DONEINPROC_TOKEN 255 /* 0xFF TDS_DONEINPROC */ + +/* states for tds_process_messages() */ +#define PROCESS_ROWS 0 +#define PROCESS_RESULTS 1 +#define CANCEL 2 +#define GOTO_1ST_ROW 3 +#define LOGIN 4 + +/* environment type field */ +#define TDS_ENV_DATABASE 1 +#define TDS_ENV_CHARSET 3 +#define TDS_ENV_BLOCKSIZE 4 + +/* + Sybase does an awful job of this stuff, non null ints of size 1 2 +and 4 have there own codes but nullable ints are lumped into INTN +sheesh! +*/ +#define SYBCHAR 47 /* 0x2F */ +#define SYBVARCHAR 39 /* 0x27 */ +#define SYBINTN 38 /* 0x26 */ +#define SYBINT1 48 /* 0x30 */ +#define SYBINT2 52 /* 0x34 */ +#define SYBINT4 56 /* 0x38 */ +#define SYBINT8 127 /* 0x7F */ +#define SYBFLT8 62 /* 0x3E */ +#define SYBDATETIME 61 /* 0x3D */ +#define SYBBIT 50 /* 0x32 */ +#define SYBTEXT 35 /* 0x23 */ +#define SYBNTEXT 99 /* 0x63 */ +#define SYBIMAGE 34 /* 0x22 */ +#define SYBMONEY4 122 /* 0x7A */ +#define SYBMONEY 60 /* 0x3C */ +#define SYBDATETIME4 58 /* 0x3A */ +#define SYBREAL 59 /* 0x3B */ +#define SYBBINARY 45 /* 0x2D */ +#define SYBVOID 31 /* 0x1F */ +#define SYBVARBINARY 37 /* 0x25 */ +#define SYBNVARCHAR 103 /* 0x67 */ +#define SYBBITN 104 /* 0x68 */ +#define SYBNUMERIC 108 /* 0x6C */ +#define SYBDECIMAL 106 /* 0x6A */ +#define SYBFLTN 109 /* 0x6D */ +#define SYBMONEYN 110 /* 0x6E */ +#define SYBDATETIMN 111 /* 0x6F */ +#define XSYBCHAR 167 /* 0xA7 */ +#define XSYBVARCHAR 175 /* 0xAF */ +#define XSYBNVARCHAR 231 /* 0xE7 */ +#define XSYBNCHAR 239 /* 0xEF */ +#define SYBUNIQUE 0x24 +#define SYBVARIANT 0x62 + +#define TDS_ZERO_FREE(x) {free((x)); (x) = NULL;} + +#define TDS_BYTE_SWAP16(value) \ + (((((unsigned short)value)<<8) & 0xFF00) | \ + ((((unsigned short)value)>>8) & 0x00FF)) + +#define TDS_BYTE_SWAP32(value) \ + (((((unsigned long)value)<<24) & 0xFF000000) | \ + ((((unsigned long)value)<< 8) & 0x00FF0000) | \ + ((((unsigned long)value)>> 8) & 0x0000FF00) | \ + ((((unsigned long)value)>>24) & 0x000000FF)) + +#define is_end_token(x) (x==TDS_DONE_TOKEN || \ + x==TDS_DONEPROC_TOKEN || \ + x==TDS_DONEINPROC_TOKEN) + +#define is_hard_end_token(x) (x==TDS_DONE_TOKEN || \ + x==TDS_DONEPROC_TOKEN) + +#define is_msg_token(x) (x==TDS_MSG_TOKEN || \ + x==TDS_ERR_TOKEN || \ + x==TDS_EED_TOKEN) + +#define is_result_token(x) (x==TDS_RESULT_TOKEN || \ + x==TDS7_RESULT_TOKEN || \ + x==TDS_COL_INFO_TOKEN || \ + x==TDS_COL_NAME_TOKEN) + +/* FIX ME -- not a complete list */ +#define is_fixed_type(x) (x==SYBINT1 || \ + x==SYBINT2 || \ + x==SYBINT4 || \ + x==SYBINT8 || \ + x==SYBREAL || \ + x==SYBFLT8 || \ + x==SYBDATETIME || \ + x==SYBDATETIME4 || \ + x==SYBBIT || \ + x==SYBMONEY || \ + x==SYBMONEY4 || \ + x==SYBUNIQUE) +#define is_nullable_type(x) (x==SYBINTN || \ + x==SYBFLTN || \ + x==SYBDATETIMN || \ + x==SYBVARCHAR || \ + x==SYBVARBINARY || \ + x==SYBMONEYN || \ + x==SYBTEXT || \ + x==SYBNTEXT || \ + x==SYBBITN || \ + x==SYBIMAGE) +#define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE || x==SYBNTEXT) +/* large type means it has a two byte size field */ +#define is_large_type(x) (x>128) +#define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL) +#define is_unicode(x) (x==XSYBNVARCHAR || x==XSYBNCHAR) + +#define TDS_MAX_CAPABILITY 18 +#define MAXPRECISION 50 +#define TDS_MAX_CONN 4096 +#define TDS_MAX_DYNID_LEN 30 + +/* defaults to use if no others are found */ +#define TDS_DEF_SERVER "SYBASE" +#define TDS_DEF_BLKSZ 512 +#define TDS_DEF_CHARSET "iso_1" +#define TDS_DEF_LANG "us_english" +#if TDS42 +#define TDS_DEF_MAJOR 4 +#define TDS_DEF_MINOR 2 +#define TDS_DEF_PORT 1433 +#elif TDS46 +#define TDS_DEF_MAJOR 4 +#define TDS_DEF_MINOR 6 +#define TDS_DEF_PORT 4000 +#elif TDS70 +#define TDS_DEF_MAJOR 7 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 1433 +#elif TDS80 +#define TDS_DEF_MAJOR 8 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 1433 +#else +#define TDS_DEF_MAJOR 5 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 4000 +#endif + +/* normalized strings from freetds.conf file */ +#define TDS_STR_VERSION "tds version" +#define TDS_STR_BLKSZ "initial block size" +#define TDS_STR_SWAPDT "swap broken dates" +#define TDS_STR_SWAPMNY "tds version" +#define TDS_STR_TRYSVR "try server login" +#define TDS_STR_TRYDOM "try domain login" +#define TDS_STR_DOMAIN "nt domain" +#define TDS_STR_XDOMAUTH "cross domain auth" +#define TDS_STR_DUMPFILE "dump file" +#define TDS_STR_DEBUGLVL "debug level" +#define TDS_STR_TIMEOUT "timeout" +#define TDS_STR_CONNTMOUT "connect timeout" +#define TDS_STR_HOSTNAME "hostname" +#define TDS_STR_HOST "host" +#define TDS_STR_PORT "port" +#define TDS_STR_TEXTSZ "text size" +/* for big endian hosts */ +#define TDS_STR_EMUL_LE "emulate little endian" +#define TDS_STR_CHARSET "charset" +#define TDS_STR_LANGUAGE "language" + +#define TDS_MAX_LOGIN_STR_SZ 30 +typedef struct tds_login { + TDS_CHAR host_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR user_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR password[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_TINYINT bulk_copy; + TDS_CHAR app_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR server_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_TINYINT major_version; /* TDS version */ + TDS_TINYINT minor_version; /* TDS version */ + TDS_CHAR library[11]; /* Ct-Library or DB-Library */ + TDS_CHAR language[TDS_MAX_LOGIN_STR_SZ+1]; /* ie us-english */ + TDS_TINYINT encrypted; + TDS_CHAR char_set[TDS_MAX_LOGIN_STR_SZ+1]; /* ie iso_1 */ + TDS_SMALLINT block_size; + TDS_TINYINT suppress_language; + TDS_INT connect_timeout; + TDS_INT query_timeout; + TDS_INT longquery_timeout; + void (*longquery_func)(long lHint); + long longquery_param; + unsigned char capabilities[TDS_MAX_CAPABILITY]; + int port; +} TDSLOGIN; + +typedef struct tds_config_info { + char *server_name; + char *host; + char *ip_addr; + int port; + TDS_SMALLINT minor_version; + TDS_SMALLINT major_version; + int block_size; + char *language; + char *char_set; + char *database; + char *dump_file; + int broken_dates; + int broken_money; + int timeout; + int connect_timeout; + char *host_name; + char *default_domain; + int try_server_login; + int try_domain_login; + int xdomain_auth; + int debug_level; + int emul_little_endian; + int text_size; + char *app_name; + char *user_name; + char *password; + char *library; + int bulk_copy; + int suppress_language; + int encrypted; +} TDSCONFIGINFO; + +/* structure for storing data about regular and compute rows */ +typedef struct tds_column_info { + TDS_SMALLINT column_type; + TDS_SMALLINT column_xtype; + TDS_SMALLINT column_usertype; + TDS_INT column_size; + TDS_INT column_offset; + TDS_CHAR column_name[256]; + TDS_SMALLINT column_bindtype; + TDS_SMALLINT column_bindfmt; + TDS_UINT column_bindlen; + TDS_CHAR *column_nullbind; + TDS_CHAR *varaddr; + TDS_CHAR *column_lenbind; + TDS_SMALLINT column_prec; + TDS_SMALLINT column_scale; + TDS_INT column_textsize; + TDS_INT column_textpos; + TDS_CHAR column_textptr[16]; + TDS_CHAR column_timestamp[8]; + TDS_CHAR *column_textvalue; +} TDSCOLINFO; + +typedef struct tds_result_info { + TDS_SMALLINT rows_exist; + TDS_INT row_count; + TDS_INT row_size; + TDS_SMALLINT num_cols; + TDS_TINYINT more_results; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSRESULTINFO; + +/* values for tds->state */ +enum { + TDS_QUERYING, + TDS_PENDING, + TDS_COMPLETED, + TDS_CANCELED, + TDS_DEAD +}; + +#define TDS_DBG_FUNC 7 +#define TDS_DBG_INFO2 6 +#define TDS_DBG_INFO1 5 +#define TDS_DBG_NETWORK 4 +#define TDS_DBG_WARN 3 +#define TDS_DBG_ERROR 2 +#define TDS_DBG_SEVERE 1 + +typedef struct tds_compute_info { + TDS_SMALLINT num_cols; + TDS_INT row_size; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSCOMPUTEINFO; + +typedef struct tds_param_info { + TDS_SMALLINT num_cols; + TDS_INT row_size; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSPARAMINFO; + +typedef struct tds_msg_info { + TDS_SMALLINT priv_msg_type; + TDS_SMALLINT line_number; + TDS_SMALLINT msg_number; + TDS_SMALLINT msg_state; + TDS_SMALLINT msg_level; + TDS_CHAR *server; + TDS_CHAR *message; + TDS_CHAR *proc_name; + TDS_CHAR *sql_state; +} TDSMSGINFO; + +/* +** This is the current environment as reported by the server +*/ +typedef struct tds_env_info { + int block_size; + char *language; + char *charset; + char *database; +} TDSENVINFO; + +typedef struct tds_dynamic { + char id[30]; + int dyn_state; + TDSRESULTINFO *res_info; +} TDSDYNAMIC; + +typedef struct tds_socket { + /* fixed and connect time */ + int s; + TDS_SMALLINT major_version; + TDS_SMALLINT minor_version; + unsigned char capabilities[TDS_MAX_CAPABILITY]; + unsigned char broken_dates; + /* in/out buffers */ + unsigned char *in_buf; + unsigned char *out_buf; + unsigned int in_buf_max; + unsigned in_pos; + unsigned out_pos; + unsigned in_len; + unsigned out_len; + unsigned char out_flag; + unsigned char last_packet; + void *parent; + /* info about current query */ + TDSRESULTINFO *res_info; + TDSCOMPUTEINFO *comp_info; + TDSPARAMINFO *param_info; + TDS_TINYINT has_status; + TDS_INT ret_status; + TDSMSGINFO *msg_info; + TDS_TINYINT state; + int rows_affected; + /* timeout stuff from Jeff */ + TDS_INT timeout; + TDS_INT longquery_timeout; + void (*longquery_func)(long lHint); + long longquery_param; + time_t queryStarttime; + TDSENVINFO *env; + /* dynamic placeholder stuff */ + int num_dyns; + int cur_dyn_elem; + TDSDYNAMIC **dyns; + int emul_little_endian; +} TDSSOCKET; + +typedef struct tds_context { + TDSSOCKET *connection_list[TDS_MAX_CONN]; +} TDSCONTEXT; + +void tds_set_longquery_handler(TDSLOGIN * tds_login, void * longquery_func, long longquery_param); +void tds_set_timeouts(TDSLOGIN *tds_login, int connect, int query, int longquery); +extern int tds_write_packet(TDSSOCKET *tds,unsigned char final); +extern int tds_init_write_buf(TDSSOCKET *tds); +extern void tds_free_result_info(TDSRESULTINFO *info); +extern void tds_free_socket(TDSSOCKET *tds); +extern void tds_free_config(TDSCONFIGINFO *config); +extern void tds_free_all_results(TDSSOCKET *tds); +extern void tds_free_results(TDSRESULTINFO *res_info); +extern void tds_free_param_results(TDSPARAMINFO *param_info); +extern void tds_free_column(TDSCOLINFO *column); +extern void tds_free_msg(TDSMSGINFO *msg_info); +extern int tds_put_n(TDSSOCKET *tds, unsigned char *buf, int n); +extern int tds_put_string(TDSSOCKET *tds, unsigned char *buf, int n); +extern int tds_put_int(TDSSOCKET *tds, TDS_INT i); +extern int tds_put_smallint(TDSSOCKET *tds, TDS_SMALLINT si); +extern int tds_put_tinyint(TDSSOCKET *tds, TDS_TINYINT ti); +extern int tds_put_byte(TDSSOCKET *tds, unsigned char c); +extern unsigned char tds_get_byte(TDSSOCKET *tds); +extern void tds_unget_byte(TDSSOCKET *tds); +extern TDS_INT tds_get_int(TDSSOCKET *tds); +extern TDS_SMALLINT tds_get_smallint(TDSSOCKET *tds); +extern char *tds_get_n(TDSSOCKET *tds, void *dest, int n); +extern char *tds_get_string(TDSSOCKET *tds, void *dest, int n); +extern TDSRESULTINFO *tds_alloc_results(int num_cols); +extern TDSCOMPUTEINFO *tds_alloc_compute_results(int num_cols); +extern TDSSOCKET *tds_alloc_socket(int bufsize); +extern TDSCONFIGINFO *tds_get_config(TDSSOCKET *tds, TDSLOGIN *login); +extern void *tds_alloc_row(TDSRESULTINFO *res_info); +extern char *tds_msg_get_proc_name(TDSSOCKET *tds); +extern TDSLOGIN *tds_alloc_login(); +extern TDSCONFIGINFO *tds_alloc_config(); +extern TDSSOCKET *tds_connect(TDSLOGIN *login); +extern void tds_set_packet(TDSLOGIN *tds_login, short packet_size); +extern void tds_set_port(TDSLOGIN *tds_login, int port); +extern void tds_set_passwd(TDSLOGIN *tds_login, char *password); +extern void tds_set_bulk(TDSLOGIN *tds_login, TDS_TINYINT enabled); +extern void tds_set_user(TDSLOGIN *tds_login, char *username); +extern void tds_set_app(TDSLOGIN *tds_login, char *application); +extern void tds_set_host(TDSLOGIN *tds_login, char *hostname); +extern void tds_set_library(TDSLOGIN *tds_login, char *library); +extern void tds_set_server(TDSLOGIN *tds_login, char *server); +extern void tds_set_charset(TDSLOGIN *tds_login, char *charset); +extern void tds_set_language(TDSLOGIN *tds_login, char *language); +extern void tds_set_version(TDSLOGIN *tds_login, short major_ver, short minor_ver); +extern void tds_set_capabilities(TDSLOGIN *tds_login, unsigned char *capabilities, int size); +extern int tds_submit_query(TDSSOCKET *tds, char *query); +extern int tds_process_result_tokens(TDSSOCKET *tds); +extern int tds_process_row_tokens(TDSSOCKET *tds); +extern int tds_process_env_chg(TDSSOCKET *tds); +extern int tds_process_default_tokens(TDSSOCKET *tds, int marker); +extern TDS_INT tds_process_end(TDSSOCKET *tds, int marker, int *more, int *canceled); +extern int tds_client_msg(TDSSOCKET *tds, int msgnum, int level, int state, int line, char *message); +extern int tds_reset_msg_info(TDSSOCKET *tds); +extern void tds_set_parent(TDSSOCKET* tds, void* the_parent); +extern void* tds_get_parent(TDSSOCKET* tds); +extern void tds_set_null(unsigned char *current_row, int column); +extern void tds_clr_null(unsigned char *current_row, int column); +extern int tds_get_null(unsigned char *current_row, int column); +extern int tds7_send_login(TDSSOCKET *tds, TDSCONFIGINFO *config); +extern char *tds7_ascii2unicode(const char *in_string, char *out_string, int maxlen); +extern char *tds7_unicode2ascii(const char *in_string, char *out_string, int len); +extern char *tds7_crypt_pass(const unsigned char *clear_pass, int len, unsigned char *crypt_pass); + + +#define IS_TDS42(x) (x->major_version==4 && x->minor_version==2) +#define IS_TDS46(x) (x->major_version==4 && x->minor_version==6) +#define IS_TDS50(x) (x->major_version==5 && x->minor_version==0) +#define IS_TDS70(x) (x->major_version==7 && x->minor_version==0) +#define IS_TDS80(x) (x->major_version==8 && x->minor_version==0) + + +#ifdef __cplusplus +} +#endif + +#endif /* _tds_h_ */ diff --git a/include/tds.h.in b/include/tds.h.in new file mode 100644 index 000000000..7bce79150 --- /dev/null +++ b/include/tds.h.in @@ -0,0 +1,608 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tds_h_ +#define _tds_h_ + +static char rcsid_tds_h[]= + "$Id: tds.h.in,v 1.1 2001-10-12 23:28:54 brianb Exp $"; +static void *no_unused_tds_h_warn[]={rcsid_tds_h, no_unused_tds_h_warn}; + +#include "tds_configs.h" + +#ifndef WIN32 +#include +#include +#include +#include +#include +#include +#include +#endif + +#ifdef WIN32 +#include +#include +#endif + +#ifdef __INCvxWorksh +#include +#include /* for FIONBIO */ +#else +#include +#include +#include +#include +#include +#include +/* FIX ME -- use autoconf for the existance of malloc.h */ +#ifndef __APPLE__ +#include +#endif +#include +#endif + +#ifndef WIN32 +#include +#endif + +#include "tdsver.h" + + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** this is where platform specific changes need to be made. +** I've tried to change all references to data that goes to +** or comes off the wire to use these typedefs. I've probably +** missed a bunch, but the idea is we can do an ifdef here +** to set the appropriately sized native type. +** +** If you have problems on 64bit machines and the code is +** using a native datatype, please change the code to use +** these. (In the TDS layer only, the API layers have their +** own typedefs which equate to these). +*/ +typedef char TDS_CHAR; /* 8 bit char */ +typedef unsigned char TDS_UCHAR; /* 8 bit uchar */ +typedef unsigned char TDS_TINYINT; /* 8 bit int */ +typedef @smallint@ TDS_SMALLINT; /* 16 bit int */ +typedef unsigned @smallint@ TDS_USMALLINT; /* 16 bit unsigned */ +typedef @int@ TDS_INT; /* 32 bit int */ +typedef unsigned @int@ TDS_UINT; /* 32 bit unsigned */ +typedef @real@ TDS_REAL; /* 32 bit float */ +typedef @float@ TDS_FLOAT; /* 64 bit float */ +typedef struct tdsnumeric +{ + unsigned char precision; + unsigned char scale; + unsigned char array[33]; +} TDS_NUMERIC; +typedef struct tdsmoney +{ + TDS_INT mnyhigh; + TDS_INT mnylow; +} TDS_MONEY; +typedef struct tdsmoney4 +{ + TDS_INT mny4; +} TDS_MONEY4; +typedef struct tdsdatetime +{ + TDS_INT dtdays; + TDS_INT dttime; +} TDS_DATETIME; +typedef struct tdsdatetime4 +{ + TDS_USMALLINT days; + TDS_USMALLINT minutes; +} TDS_DATETIME4; +typedef struct tdsvarbinary +{ + TDS_INT len; + TDS_CHAR array[256]; +} TDS_VARBINARY; +typedef struct tdsvarchar +{ + TDS_INT len; + TDS_CHAR array[256]; +} TDS_VARCHAR; + +#define TDS_NO_MORE_ROWS -2 +#define TDS_SUCCEED 1 +#define TDS_FAIL 0 +#define TDS_NO_MORE_RESULTS 2 +/* +** TDS_ERROR indicates a successful processing, but an TDS_ERR_TOKEN or +** TDS_EED_TOKEN error was encountered, whereas TDS_FAIL indicates an +** unrecoverable failure. +*/ +#define TDS_ERROR 3 +#define TDS_DONT_RETURN 42 + +#define TDS5_DYN_TOKEN 231 /* 0xE7 TDS 5.0 only */ +#define TDS5_DYNRES_TOKEN 236 /* 0xEC TDS 5.0 only */ +#define TDS5_DYN3_TOKEN 215 /* 0xD7 TDS 5.0 only */ +#define TDS_LANG_TOKEN 33 /* 0x21 TDS 5.0 only */ +#define TDS_CLOSE_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */ +#define TDS_RET_STAT_TOKEN 121 /* 0x79 */ +#define TDS_124_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */ +#define TDS7_RESULT_TOKEN 129 /* 0x81 TDS 7.0 only */ +#define TDS_COL_NAME_TOKEN 160 /* 0xA0 TDS 4.2 only */ +#define TDS_COL_INFO_TOKEN 161 /* 0xA1 TDS 4.2 only - TDS_COLFMT */ +/*#define TDS_TABNAME 164 */ +/*#define TDS_COL_INFO 165 */ +#define TDS_167_TOKEN 167 /* 0xA7 */ +#define TDS_168_TOKEN 168 /* 0xA8 */ +#define TDS_ORDER_BY_TOKEN 169 /* 0xA9 TDS_ORDER */ +#define TDS_ERR_TOKEN 170 /* 0xAA */ +#define TDS_MSG_TOKEN 171 /* 0xAB */ +#define TDS_PARAM_TOKEN 172 /* 0xAC RETURNVALUE? */ +#define TDS_LOGIN_ACK_TOKEN 173 /* 0xAD */ +#define TDS_174_TOKEN 174 /* 0xAE TDS_CONTROL */ +#define TDS_ROW_TOKEN 209 /* 0xD1 */ +#define TDS_CMP_ROW_TOKEN 211 /* 0xD3 */ +#define TDS_CAP_TOKEN 226 /* 0xE2 */ +#define TDS_ENV_CHG_TOKEN 227 /* 0xE3 */ +#define TDS_EED_TOKEN 229 /* 0xE5 */ +#define TDS_AUTH_TOKEN 237 /* 0xED */ +#define TDS_RESULT_TOKEN 238 /* 0xEE */ +#define TDS_DONE_TOKEN 253 /* 0xFD TDS_DONE */ +#define TDS_DONEPROC_TOKEN 254 /* 0xFE TDS_DONEPROC */ +#define TDS_DONEINPROC_TOKEN 255 /* 0xFF TDS_DONEINPROC */ + +/* states for tds_process_messages() */ +#define PROCESS_ROWS 0 +#define PROCESS_RESULTS 1 +#define CANCEL 2 +#define GOTO_1ST_ROW 3 +#define LOGIN 4 + +/* environment type field */ +#define TDS_ENV_DATABASE 1 +#define TDS_ENV_CHARSET 3 +#define TDS_ENV_BLOCKSIZE 4 + +/* + Sybase does an awful job of this stuff, non null ints of size 1 2 +and 4 have there own codes but nullable ints are lumped into INTN +sheesh! +*/ +#define SYBCHAR 47 /* 0x2F */ +#define SYBVARCHAR 39 /* 0x27 */ +#define SYBINTN 38 /* 0x26 */ +#define SYBINT1 48 /* 0x30 */ +#define SYBINT2 52 /* 0x34 */ +#define SYBINT4 56 /* 0x38 */ +#define SYBINT8 127 /* 0x7F */ +#define SYBFLT8 62 /* 0x3E */ +#define SYBDATETIME 61 /* 0x3D */ +#define SYBBIT 50 /* 0x32 */ +#define SYBTEXT 35 /* 0x23 */ +#define SYBNTEXT 99 /* 0x63 */ +#define SYBIMAGE 34 /* 0x22 */ +#define SYBMONEY4 122 /* 0x7A */ +#define SYBMONEY 60 /* 0x3C */ +#define SYBDATETIME4 58 /* 0x3A */ +#define SYBREAL 59 /* 0x3B */ +#define SYBBINARY 45 /* 0x2D */ +#define SYBVOID 31 /* 0x1F */ +#define SYBVARBINARY 37 /* 0x25 */ +#define SYBNVARCHAR 103 /* 0x67 */ +#define SYBBITN 104 /* 0x68 */ +#define SYBNUMERIC 108 /* 0x6C */ +#define SYBDECIMAL 106 /* 0x6A */ +#define SYBFLTN 109 /* 0x6D */ +#define SYBMONEYN 110 /* 0x6E */ +#define SYBDATETIMN 111 /* 0x6F */ +#define XSYBCHAR 167 /* 0xA7 */ +#define XSYBVARCHAR 175 /* 0xAF */ +#define XSYBNVARCHAR 231 /* 0xE7 */ +#define XSYBNCHAR 239 /* 0xEF */ +#define SYBUNIQUE 0x24 +#define SYBVARIANT 0x62 + +#define TDS_ZERO_FREE(x) {free((x)); (x) = NULL;} + +#define TDS_BYTE_SWAP16(value) \ + (((((unsigned short)value)<<8) & 0xFF00) | \ + ((((unsigned short)value)>>8) & 0x00FF)) + +#define TDS_BYTE_SWAP32(value) \ + (((((unsigned long)value)<<24) & 0xFF000000) | \ + ((((unsigned long)value)<< 8) & 0x00FF0000) | \ + ((((unsigned long)value)>> 8) & 0x0000FF00) | \ + ((((unsigned long)value)>>24) & 0x000000FF)) + +#define is_end_token(x) (x==TDS_DONE_TOKEN || \ + x==TDS_DONEPROC_TOKEN || \ + x==TDS_DONEINPROC_TOKEN) + +#define is_hard_end_token(x) (x==TDS_DONE_TOKEN || \ + x==TDS_DONEPROC_TOKEN) + +#define is_msg_token(x) (x==TDS_MSG_TOKEN || \ + x==TDS_ERR_TOKEN || \ + x==TDS_EED_TOKEN) + +#define is_result_token(x) (x==TDS_RESULT_TOKEN || \ + x==TDS7_RESULT_TOKEN || \ + x==TDS_COL_INFO_TOKEN || \ + x==TDS_COL_NAME_TOKEN) + +/* FIX ME -- not a complete list */ +#define is_fixed_type(x) (x==SYBINT1 || \ + x==SYBINT2 || \ + x==SYBINT4 || \ + x==SYBINT8 || \ + x==SYBREAL || \ + x==SYBFLT8 || \ + x==SYBDATETIME || \ + x==SYBDATETIME4 || \ + x==SYBBIT || \ + x==SYBMONEY || \ + x==SYBMONEY4 || \ + x==SYBUNIQUE) +#define is_nullable_type(x) (x==SYBINTN || \ + x==SYBFLTN || \ + x==SYBDATETIMN || \ + x==SYBVARCHAR || \ + x==SYBVARBINARY || \ + x==SYBMONEYN || \ + x==SYBTEXT || \ + x==SYBNTEXT || \ + x==SYBBITN || \ + x==SYBIMAGE) +#define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE || x==SYBNTEXT) +/* large type means it has a two byte size field */ +#define is_large_type(x) (x>128) +#define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL) +#define is_unicode(x) (x==XSYBNVARCHAR || x==XSYBNCHAR) + +#define TDS_MAX_CAPABILITY 18 +#define MAXPRECISION 50 +#define TDS_MAX_CONN 4096 +#define TDS_MAX_DYNID_LEN 30 + +/* defaults to use if no others are found */ +#define TDS_DEF_SERVER "SYBASE" +#define TDS_DEF_BLKSZ 512 +#define TDS_DEF_CHARSET "iso_1" +#define TDS_DEF_LANG "us_english" +#if TDS42 +#define TDS_DEF_MAJOR 4 +#define TDS_DEF_MINOR 2 +#define TDS_DEF_PORT 1433 +#elif TDS46 +#define TDS_DEF_MAJOR 4 +#define TDS_DEF_MINOR 6 +#define TDS_DEF_PORT 4000 +#elif TDS70 +#define TDS_DEF_MAJOR 7 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 1433 +#elif TDS80 +#define TDS_DEF_MAJOR 8 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 1433 +#else +#define TDS_DEF_MAJOR 5 +#define TDS_DEF_MINOR 0 +#define TDS_DEF_PORT 4000 +#endif + +/* normalized strings from freetds.conf file */ +#define TDS_STR_VERSION "tds version" +#define TDS_STR_BLKSZ "initial block size" +#define TDS_STR_SWAPDT "swap broken dates" +#define TDS_STR_SWAPMNY "tds version" +#define TDS_STR_TRYSVR "try server login" +#define TDS_STR_TRYDOM "try domain login" +#define TDS_STR_DOMAIN "nt domain" +#define TDS_STR_XDOMAUTH "cross domain auth" +#define TDS_STR_DUMPFILE "dump file" +#define TDS_STR_DEBUGLVL "debug level" +#define TDS_STR_TIMEOUT "timeout" +#define TDS_STR_CONNTMOUT "connect timeout" +#define TDS_STR_HOSTNAME "hostname" +#define TDS_STR_HOST "host" +#define TDS_STR_PORT "port" +#define TDS_STR_TEXTSZ "text size" +/* for big endian hosts */ +#define TDS_STR_EMUL_LE "emulate little endian" +#define TDS_STR_CHARSET "charset" +#define TDS_STR_LANGUAGE "language" + +#define TDS_MAX_LOGIN_STR_SZ 30 +typedef struct tds_login { + TDS_CHAR host_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR user_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR password[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_TINYINT bulk_copy; + TDS_CHAR app_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_CHAR server_name[TDS_MAX_LOGIN_STR_SZ+1]; + TDS_TINYINT major_version; /* TDS version */ + TDS_TINYINT minor_version; /* TDS version */ + TDS_CHAR library[11]; /* Ct-Library or DB-Library */ + TDS_CHAR language[TDS_MAX_LOGIN_STR_SZ+1]; /* ie us-english */ + TDS_TINYINT encrypted; + TDS_CHAR char_set[TDS_MAX_LOGIN_STR_SZ+1]; /* ie iso_1 */ + TDS_SMALLINT block_size; + TDS_TINYINT suppress_language; + TDS_INT connect_timeout; + TDS_INT query_timeout; + TDS_INT longquery_timeout; + void (*longquery_func)(long lHint); + long longquery_param; + unsigned char capabilities[TDS_MAX_CAPABILITY]; + int port; +} TDSLOGIN; + +typedef struct tds_config_info { + char *server_name; + char *host; + char *ip_addr; + int port; + TDS_SMALLINT minor_version; + TDS_SMALLINT major_version; + int block_size; + char *language; + char *char_set; + char *database; + char *dump_file; + int broken_dates; + int broken_money; + int timeout; + int connect_timeout; + char *host_name; + char *default_domain; + int try_server_login; + int try_domain_login; + int xdomain_auth; + int debug_level; + int emul_little_endian; + int text_size; + char *app_name; + char *user_name; + char *password; + char *library; + int bulk_copy; + int suppress_language; + int encrypted; +} TDSCONFIGINFO; + +/* structure for storing data about regular and compute rows */ +typedef struct tds_column_info { + TDS_SMALLINT column_type; + TDS_SMALLINT column_xtype; + TDS_SMALLINT column_usertype; + TDS_INT column_size; + TDS_INT column_offset; + TDS_CHAR column_name[256]; + TDS_SMALLINT column_bindtype; + TDS_SMALLINT column_bindfmt; + TDS_UINT column_bindlen; + TDS_CHAR *column_nullbind; + TDS_CHAR *varaddr; + TDS_CHAR *column_lenbind; + TDS_SMALLINT column_prec; + TDS_SMALLINT column_scale; + TDS_INT column_textsize; + TDS_INT column_textpos; + TDS_CHAR column_textptr[16]; + TDS_CHAR column_timestamp[8]; + TDS_CHAR *column_textvalue; +} TDSCOLINFO; + +typedef struct tds_result_info { + TDS_SMALLINT rows_exist; + TDS_INT row_count; + TDS_INT row_size; + TDS_SMALLINT num_cols; + TDS_TINYINT more_results; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSRESULTINFO; + +/* values for tds->state */ +enum { + TDS_QUERYING, + TDS_PENDING, + TDS_COMPLETED, + TDS_CANCELED, + TDS_DEAD +}; + +#define TDS_DBG_FUNC 7 +#define TDS_DBG_INFO2 6 +#define TDS_DBG_INFO1 5 +#define TDS_DBG_NETWORK 4 +#define TDS_DBG_WARN 3 +#define TDS_DBG_ERROR 2 +#define TDS_DBG_SEVERE 1 + +typedef struct tds_compute_info { + TDS_SMALLINT num_cols; + TDS_INT row_size; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSCOMPUTEINFO; + +typedef struct tds_param_info { + TDS_SMALLINT num_cols; + TDS_INT row_size; + TDSCOLINFO **columns; + int null_info_size; + unsigned char *current_row; +} TDSPARAMINFO; + +typedef struct tds_msg_info { + TDS_SMALLINT priv_msg_type; + TDS_SMALLINT line_number; + TDS_SMALLINT msg_number; + TDS_SMALLINT msg_state; + TDS_SMALLINT msg_level; + TDS_CHAR *server; + TDS_CHAR *message; + TDS_CHAR *proc_name; + TDS_CHAR *sql_state; +} TDSMSGINFO; + +/* +** This is the current environment as reported by the server +*/ +typedef struct tds_env_info { + int block_size; + char *language; + char *charset; + char *database; +} TDSENVINFO; + +typedef struct tds_dynamic { + char id[30]; + int dyn_state; + TDSRESULTINFO *res_info; +} TDSDYNAMIC; + +typedef struct tds_socket { + /* fixed and connect time */ + int s; + TDS_SMALLINT major_version; + TDS_SMALLINT minor_version; + unsigned char capabilities[TDS_MAX_CAPABILITY]; + unsigned char broken_dates; + /* in/out buffers */ + unsigned char *in_buf; + unsigned char *out_buf; + unsigned int in_buf_max; + unsigned in_pos; + unsigned out_pos; + unsigned in_len; + unsigned out_len; + unsigned char out_flag; + unsigned char last_packet; + void *parent; + /* info about current query */ + TDSRESULTINFO *res_info; + TDSCOMPUTEINFO *comp_info; + TDSPARAMINFO *param_info; + TDS_TINYINT has_status; + TDS_INT ret_status; + TDSMSGINFO *msg_info; + TDS_TINYINT state; + int rows_affected; + /* timeout stuff from Jeff */ + TDS_INT timeout; + TDS_INT longquery_timeout; + void (*longquery_func)(long lHint); + long longquery_param; + time_t queryStarttime; + TDSENVINFO *env; + /* dynamic placeholder stuff */ + int num_dyns; + int cur_dyn_elem; + TDSDYNAMIC **dyns; + int emul_little_endian; +} TDSSOCKET; + +typedef struct tds_context { + TDSSOCKET *connection_list[TDS_MAX_CONN]; +} TDSCONTEXT; + +void tds_set_longquery_handler(TDSLOGIN * tds_login, void * longquery_func, long longquery_param); +void tds_set_timeouts(TDSLOGIN *tds_login, int connect, int query, int longquery); +extern int tds_write_packet(TDSSOCKET *tds,unsigned char final); +extern int tds_init_write_buf(TDSSOCKET *tds); +extern void tds_free_result_info(TDSRESULTINFO *info); +extern void tds_free_socket(TDSSOCKET *tds); +extern void tds_free_config(TDSCONFIGINFO *config); +extern void tds_free_all_results(TDSSOCKET *tds); +extern void tds_free_results(TDSRESULTINFO *res_info); +extern void tds_free_param_results(TDSPARAMINFO *param_info); +extern void tds_free_column(TDSCOLINFO *column); +extern void tds_free_msg(TDSMSGINFO *msg_info); +extern int tds_put_n(TDSSOCKET *tds, unsigned char *buf, int n); +extern int tds_put_string(TDSSOCKET *tds, unsigned char *buf, int n); +extern int tds_put_int(TDSSOCKET *tds, TDS_INT i); +extern int tds_put_smallint(TDSSOCKET *tds, TDS_SMALLINT si); +extern int tds_put_tinyint(TDSSOCKET *tds, TDS_TINYINT ti); +extern int tds_put_byte(TDSSOCKET *tds, unsigned char c); +extern unsigned char tds_get_byte(TDSSOCKET *tds); +extern void tds_unget_byte(TDSSOCKET *tds); +extern TDS_INT tds_get_int(TDSSOCKET *tds); +extern TDS_SMALLINT tds_get_smallint(TDSSOCKET *tds); +extern char *tds_get_n(TDSSOCKET *tds, void *dest, int n); +extern char *tds_get_string(TDSSOCKET *tds, void *dest, int n); +extern TDSRESULTINFO *tds_alloc_results(int num_cols); +extern TDSCOMPUTEINFO *tds_alloc_compute_results(int num_cols); +extern TDSSOCKET *tds_alloc_socket(int bufsize); +extern TDSCONFIGINFO *tds_get_config(TDSSOCKET *tds, TDSLOGIN *login); +extern void *tds_alloc_row(TDSRESULTINFO *res_info); +extern char *tds_msg_get_proc_name(TDSSOCKET *tds); +extern TDSLOGIN *tds_alloc_login(); +extern TDSCONFIGINFO *tds_alloc_config(); +extern TDSSOCKET *tds_connect(TDSLOGIN *login); +extern void tds_set_packet(TDSLOGIN *tds_login, short packet_size); +extern void tds_set_port(TDSLOGIN *tds_login, int port); +extern void tds_set_passwd(TDSLOGIN *tds_login, char *password); +extern void tds_set_bulk(TDSLOGIN *tds_login, TDS_TINYINT enabled); +extern void tds_set_user(TDSLOGIN *tds_login, char *username); +extern void tds_set_app(TDSLOGIN *tds_login, char *application); +extern void tds_set_host(TDSLOGIN *tds_login, char *hostname); +extern void tds_set_library(TDSLOGIN *tds_login, char *library); +extern void tds_set_server(TDSLOGIN *tds_login, char *server); +extern void tds_set_charset(TDSLOGIN *tds_login, char *charset); +extern void tds_set_language(TDSLOGIN *tds_login, char *language); +extern void tds_set_version(TDSLOGIN *tds_login, short major_ver, short minor_ver); +extern void tds_set_capabilities(TDSLOGIN *tds_login, unsigned char *capabilities, int size); +extern int tds_submit_query(TDSSOCKET *tds, char *query); +extern int tds_process_result_tokens(TDSSOCKET *tds); +extern int tds_process_row_tokens(TDSSOCKET *tds); +extern int tds_process_env_chg(TDSSOCKET *tds); +extern int tds_process_default_tokens(TDSSOCKET *tds, int marker); +extern TDS_INT tds_process_end(TDSSOCKET *tds, int marker, int *more, int *canceled); +extern int tds_client_msg(TDSSOCKET *tds, int msgnum, int level, int state, int line, char *message); +extern int tds_reset_msg_info(TDSSOCKET *tds); +extern void tds_set_parent(TDSSOCKET* tds, void* the_parent); +extern void* tds_get_parent(TDSSOCKET* tds); +extern void tds_set_null(unsigned char *current_row, int column); +extern void tds_clr_null(unsigned char *current_row, int column); +extern int tds_get_null(unsigned char *current_row, int column); +extern int tds7_send_login(TDSSOCKET *tds, TDSCONFIGINFO *config); +extern char *tds7_ascii2unicode(const char *in_string, char *out_string, int maxlen); +extern char *tds7_unicode2ascii(const char *in_string, char *out_string, int len); +extern char *tds7_crypt_pass(const unsigned char *clear_pass, int len, unsigned char *crypt_pass); + + +#define IS_TDS42(x) (x->major_version==4 && x->minor_version==2) +#define IS_TDS46(x) (x->major_version==4 && x->minor_version==6) +#define IS_TDS50(x) (x->major_version==5 && x->minor_version==0) +#define IS_TDS70(x) (x->major_version==7 && x->minor_version==0) +#define IS_TDS80(x) (x->major_version==8 && x->minor_version==0) + + +#ifdef __cplusplus +} +#endif + +#endif /* _tds_h_ */ diff --git a/include/tds_configs.h b/include/tds_configs.h new file mode 100644 index 000000000..df1dc8b86 --- /dev/null +++ b/include/tds_configs.h @@ -0,0 +1,39 @@ +/* Generated from tds_configs.h.in on Thu Sep 27 08:02:52 EDT 2001 */ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tds_configs_h_ +#define _tds_configs_h_ + +static char rcsid_tds_configs_h[]= + "$Id: tds_configs.h,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_tds_configs_h_warn[]={rcsid_tds_configs_h, no_unused_tds_configs_h_warn}; + +#ifdef __cplusplus +extern "C" { +#endif + +#define FREETDS_SYSCONFDIR "/usr/local/freetds/etc" +#define FREETDS_SYSCONFFILE "/usr/local/freetds/etc/freetds.conf" + +#ifdef __cplusplus +} +#endif + +#endif /* _tds_configs_h_ */ diff --git a/include/tds_configs.h.in b/include/tds_configs.h.in new file mode 100644 index 000000000..76bb87948 --- /dev/null +++ b/include/tds_configs.h.in @@ -0,0 +1,38 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tds_configs_h_ +#define _tds_configs_h_ + +static char rcsid_tds_configs_h[]= + "$Id: tds_configs.h.in,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_tds_configs_h_warn[]={rcsid_tds_configs_h, no_unused_tds_configs_h_warn}; + +#ifdef __cplusplus +extern "C" { +#endif + +#define FREETDS_SYSCONFDIR "%SYSCONFDIR%" +#define FREETDS_SYSCONFFILE "%SYSCONFDIR%/freetds.conf" + +#ifdef __cplusplus +} +#endif + +#endif /* _tds_configs_h_ */ diff --git a/include/tdsconvert.h b/include/tdsconvert.h new file mode 100644 index 000000000..78ecace22 --- /dev/null +++ b/include/tdsconvert.h @@ -0,0 +1,46 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef TDSCONVERT_h +#define TDSCONVERT_h + +static char rcsid_tdsconvert_h [ ] = + "$Id: tdsconvert.h,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_tdsconvert_h_warn[]={rcsid_tdsconvert_h, + no_unused_tdsconvert_h_warn}; + + + +extern TDS_INT _convert_money(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_bit(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_int1(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_int2(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_int4(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_flt8(int srctype,unsigned char *src,int desttype,unsigned char *dest,TDS_INT destlen); +extern TDS_INT _convert_datetime(int srctype,unsigned char *src,int desttype,unsigned char *dest,TDS_INT destlen); +extern int _get_conversion_type(int srctype, int colsize); +TDS_INT tds_convert(int srctype, TDS_CHAR *src, TDS_UINT srclen, + int desttype, TDS_CHAR *dest, TDS_UINT destlen); + +#endif diff --git a/include/tdsodbc.h b/include/tdsodbc.h new file mode 100644 index 000000000..ba351a768 --- /dev/null +++ b/include/tdsodbc.h @@ -0,0 +1,61 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _sql_h_ +#define _sql_h_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +static char rcsid_sql_h [ ] = + "$Id: tdsodbc.h,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_sql_h_warn[]={rcsid_sql_h, no_unused_sql_h_warn}; + +struct _henv { +}; +struct _hdbc { + struct _henv *henv; + void *tds_login; + void *tds_socket; +}; +struct _hstmt { + struct _hdbc *hdbc; + /* reminder to self: the following is here for testing purposes. + * please make dynamic before checking in + */ + char query[4096]; + struct _sql_bind_info *bind_head; +}; + +struct _sql_bind_info { + int column_number; + int column_bindtype; + int column_bindlen; + char *varaddr; + struct _sql_bind_info *next; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/tdsutil.h b/include/tdsutil.h new file mode 100644 index 000000000..e074d919c --- /dev/null +++ b/include/tdsutil.h @@ -0,0 +1,85 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tdsutil_h_ +#define _tdsutil_h_ + +#include "tds.h" + +#include +#include /* Jeff's hack */ +#ifndef __INCvxWorksh /* vxWorks doesn't have a sys/time.h */ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#if 0 +} /* keep the paren matcher and indenter happy */ +#endif +#endif + + +static char rcsid_tdsutil_h [ ] = +"$Id: tdsutil.h,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_tdsutil_h_warn[]={rcsid_tdsutil_h, no_unused_tdsutil_h_warn}; + + +#define MAXPATH 256 + +extern TDS_SMALLINT tds_get_smallint(TDSSOCKET *tds); +extern unsigned char tds_get_byte(TDSSOCKET *tds); +extern unsigned char tds_peek(TDSSOCKET *tds); +extern void tds_unget_byte(TDSSOCKET *tds); +extern char *tds_get_n(TDSSOCKET *tds, void *dest, int n); +extern int tds_read_packet (TDSSOCKET *tds); +extern int set_interfaces_file_loc(char *interfloc); +extern int get_server_info(char *server, char *ip_addr, char *ip_port, char *tds_ver); +extern int get_size_by_type(int servertype); +extern int tds_flush_packet(TDSSOCKET *tds); +extern int tds_send_login(TDSSOCKET *tds, TDSCONFIGINFO *config); +extern int tds_process_login_tokens(TDSSOCKET *tds); +extern int tds_put_buf(TDSSOCKET *tds, unsigned char *buf, int dsize, int ssize); + +extern void tds_free_compute_results(TDSCOMPUTEINFO *comp_info); + +extern int tdsdump_open(const char *filename); +extern void tdsdump_off(); +extern void tdsdump_on(); +extern void tdsdump_close(); +extern void tdsdump_log(int dbg_lvl, const char *fmt, ...); + +extern int tds_is_result_row(TDSSOCKET *tds); +extern int tds_is_result_set(TDSSOCKET *tds); +extern int tds_is_end_of_results(TDSSOCKET *tds); +extern int tds_is_error(TDSSOCKET *tds); +extern int tds_is_message(TDSSOCKET *tds); +extern int tds_is_doneinproc(TDSSOCKET *tds); +extern int tds_is_control(TDSSOCKET *tds); + +extern int tds_msleep(long usecs); +#ifdef __cplusplus +#if 0 +{ /* keep the paren matcher and indenter happy */ +#endif +} +#endif + +#endif + diff --git a/include/tdsver.h b/include/tdsver.h new file mode 100644 index 000000000..0e8fc7180 --- /dev/null +++ b/include/tdsver.h @@ -0,0 +1,29 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tdsver_h_ +#define _tdsver_h_ + +#define VERSION_NO "freetds v0.53" + +static char rcsid_tdsver_h [ ] = + "$Header: /tmp/gitout/git/../freetds/freetds/include/Attic/tdsver.h,v 1.1 2001-10-12 23:28:57 brianb Exp $"; +static void *no_unused_tdsver_h_warn[]={rcsid_tdsver_h, no_unused_tdsver_h_warn}; + +#endif diff --git a/include/tdsver.h.in b/include/tdsver.h.in new file mode 100644 index 000000000..6d2be193e --- /dev/null +++ b/include/tdsver.h.in @@ -0,0 +1,29 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _tdsver_h_ +#define _tdsver_h_ + +#define VERSION_NO "@PACKAGE@ v@VERSION@" + +static char rcsid_tdsver_h [ ] = + "$Header: /tmp/gitout/git/../freetds/freetds/include/tdsver.h.in,v 1.1 2001-10-12 23:28:55 brianb Exp $"; +static void *no_unused_tdsver_h_warn[]={rcsid_tdsver_h, no_unused_tdsver_h_warn}; + +#endif diff --git a/install-sh b/install-sh new file mode 100755 index 000000000..e8436696c --- /dev/null +++ b/install-sh @@ -0,0 +1,250 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/interfaces b/interfaces new file mode 100644 index 000000000..1175517a1 --- /dev/null +++ b/interfaces @@ -0,0 +1,41 @@ +# +# This format of the interfaces file is this: +# +# The entry starts with the servername beginning in the first column (no +# whitespace preceding it). +# +# Next comes the services lines. They must be preceded by some whitespace +# (preferably a tab). There are five fields in the services line. +# +# 1) The service. Currently only "query" means anything "master" is present +# for historical reasons only. +# 2) The transport. Currently ignored by FreeTDS, it should be "tcp". When +# ipv6 support is added a second option of "tcp6" will +# probably be available. +# 3) Physical layer. Sybase uses this field for a description of the physical +# layer (usually "ether"), FreeTDS can also use it to +# specify the version of the protocol to use when connecting +# to this server. +# 4) Hostname. May be a hostname or IP address of the server machine. +# 5) Port. The TCP port of the dataserver. MS SQL defaults to 1433 +# +# So putting it all together, let's say you have an NT box running a SQL Server +# named "myserver" at ip address 10.0.2.1 and we are connecting using version +# 4.2 of the protocol, your interfaces entry would look +# like this: (without the comments) +# +#myserver +# query tcp 4.2 10.0.2.1 1433 +# + +JDBC + query tcp 5.0 192.138.151.39 4444 + master tcp 5.0 192.138.151.39 4444 + +myserver + query tcp ether 127.0.0.1 4000 + master tcp ether 127.0.0.1 4000 + +myserver2 + query tcp ether 127.0.0.1 4001 + master tcp ether 127.0.0.1 4001 diff --git a/ltconfig b/ltconfig new file mode 100755 index 000000000..65ec6f65d --- /dev/null +++ b/ltconfig @@ -0,0 +1,3017 @@ +#! /bin/sh + +# ltconfig - Create a system-specific libtool. +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# A lot of this script is taken from autoconf-2.10. + +# Check that we are running under the correct shell. +SHELL=${CONFIG_SHELL-/bin/sh} +echo=echo +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell. + exec "$SHELL" "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat </dev/null`} + case X$UNAME in + *-DOS) PATH_SEPARATOR=';' ;; + *) PATH_SEPARATOR=':' ;; + esac +fi + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +if test "X${echo_test_string+set}" != "Xset"; then + # find a string as large as possible, as long as the shell can cope with it + for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do + # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... + if (echo_test_string="`eval $cmd`") 2>/dev/null && + echo_test_string="`eval $cmd`" && + (test "X$echo_test_string" = "X$echo_test_string") 2>/dev/null; then + break + fi + done +fi + +if test "X`($echo '\t') 2>/dev/null`" != 'X\t' || + test "X`($echo "$echo_test_string") 2>/dev/null`" != X"$echo_test_string"; then + # The Solaris, AIX, and Digital Unix default echo programs unquote + # backslashes. This makes it impossible to quote backslashes using + # echo "$something" | sed 's/\\/\\\\/g' + # + # So, first we look for a working echo in the user's PATH. + + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH /usr/ucb; do + if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && + test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($dir/echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$dir/echo" + break + fi + done + IFS="$save_ifs" + + if test "X$echo" = Xecho; then + # We didn't find a better echo, so look for alternatives. + if test "X`(print -r '\t') 2>/dev/null`" = 'X\t' && + test "X`(print -r "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # This shell has a builtin print -r that does the trick. + echo='print -r' + elif (test -f /bin/ksh || test -f /bin/ksh$ac_exeext) && + test "X$CONFIG_SHELL" != X/bin/ksh; then + # If we have ksh, try running ltconfig again with it. + ORIGINAL_CONFIG_SHELL="${CONFIG_SHELL-/bin/sh}" + export ORIGINAL_CONFIG_SHELL + CONFIG_SHELL=/bin/ksh + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$0" --no-reexec ${1+"$@"} + else + # Try using printf. + echo='printf "%s\n"' + if test "X`($echo '\t') 2>/dev/null`" = 'X\t' && + test "X`($echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + # Cool, printf works + : + elif test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$ORIGINAL_CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + CONFIG_SHELL="$ORIGINAL_CONFIG_SHELL" + export CONFIG_SHELL + SHELL="$CONFIG_SHELL" + export SHELL + echo="$CONFIG_SHELL $0 --fallback-echo" + elif test "X`("$CONFIG_SHELL" "$0" --fallback-echo '\t') 2>/dev/null`" = 'X\t' && + test "X`("$CONFIG_SHELL" "$0" --fallback-echo "$echo_test_string") 2>/dev/null`" = X"$echo_test_string"; then + echo="$CONFIG_SHELL $0 --fallback-echo" + else + # maybe with a smaller string... + prev=: + + for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do + if (test "X$echo_test_string" = "X`eval $cmd`") 2>/dev/null; then + break + fi + prev="$cmd" + done + + if test "$prev" != 'sed 50q "$0"'; then + echo_test_string=`eval $prev` + export echo_test_string + exec "${ORIGINAL_CONFIG_SHELL}" "$0" ${1+"$@"} + else + # Oops. We lost completely, so just stick with echo. + echo=echo + fi + fi + fi + fi +fi + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e s/^X//' +sed_quote_subst='s/\([\\"\\`$\\\\]\)/\\\1/g' + +# Same as above, but do not quote variable references. +double_quote_subst='s/\([\\"\\`\\\\]\)/\\\1/g' + +# Sed substitution to delay expansion of an escaped shell variable in a +# double_quote_subst'ed string. +delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' + +# The name of this program. +progname=`$echo "X$0" | $Xsed -e 's%^.*/%%'` + +# Constants: +PROGRAM=ltconfig +PACKAGE=libtool +VERSION=1.3.3 +TIMESTAMP=" (1.385.2.181 1999/07/02 15:49:11)" +ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.c 1>&5' +ac_link='${CC-cc} -o conftest $CFLAGS $CPPFLAGS $LDFLAGS conftest.c $LIBS 1>&5' +rm="rm -f" + +help="Try \`$progname --help' for more information." + +# Global variables: +default_ofile=libtool +can_build_shared=yes +enable_shared=yes +# All known linkers require a `.a' archive for static linking (except M$VC, +# which needs '.lib'). +enable_static=yes +enable_fast_install=yes +enable_dlopen=unknown +enable_win32_dll=no +ltmain= +silent= +srcdir= +ac_config_guess= +ac_config_sub= +host= +nonopt= +ofile="$default_ofile" +verify_host=yes +with_gcc=no +with_gnu_ld=no +need_locks=yes +ac_ext=c +objext=o +libext=a +exeext= +cache_file= + +old_AR="$AR" +old_CC="$CC" +old_CFLAGS="$CFLAGS" +old_CPPFLAGS="$CPPFLAGS" +old_LDFLAGS="$LDFLAGS" +old_LD="$LD" +old_LN_S="$LN_S" +old_LIBS="$LIBS" +old_NM="$NM" +old_RANLIB="$RANLIB" +old_DLLTOOL="$DLLTOOL" +old_OBJDUMP="$OBJDUMP" +old_AS="$AS" + +# Parse the command line options. +args= +prev= +for option +do + case "$option" in + -*=*) optarg=`echo "$option" | sed 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + eval "$prev=\$option" + prev= + continue + fi + + case "$option" in + --help) cat <&2 + echo "$help" 1>&2 + exit 1 + ;; + + *) + if test -z "$ltmain"; then + ltmain="$option" + elif test -z "$host"; then +# This generates an unnecessary warning for sparc-sun-solaris4.1.3_U1 +# if test -n "`echo $option| sed 's/[-a-z0-9.]//g'`"; then +# echo "$progname: warning \`$option' is not a valid host type" 1>&2 +# fi + host="$option" + else + echo "$progname: too many arguments" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac +done + +if test -z "$ltmain"; then + echo "$progname: you must specify a LTMAIN file" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +if test ! -f "$ltmain"; then + echo "$progname: \`$ltmain' does not exist" 1>&2 + echo "$help" 1>&2 + exit 1 +fi + +# Quote any args containing shell metacharacters. +ltconfig_args= +for arg +do + case "$arg" in + *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*) + ltconfig_args="$ltconfig_args '$arg'" ;; + *) ltconfig_args="$ltconfig_args $arg" ;; + esac +done + +# A relevant subset of AC_INIT. + +# File descriptor usage: +# 0 standard input +# 1 file creation +# 2 errors and warnings +# 3 some systems may open it to /dev/tty +# 4 used on the Kubota Titan +# 5 compiler messages saved in config.log +# 6 checking for... messages and results +if test "$silent" = yes; then + exec 6>/dev/null +else + exec 6>&1 +fi +exec 5>>./config.log + +# NLS nuisances. +# Only set LANG and LC_ALL to C if already set. +# These must not be set unconditionally because not all systems understand +# e.g. LANG=C (notably SCO). +if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +if test "${LANG+set}" = set; then LANG=C; export LANG; fi + +if test -n "$cache_file" && test -r "$cache_file"; then + echo "loading cache $cache_file within ltconfig" + . $cache_file +fi + +if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then + # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu. + if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then + ac_n= ac_c=' +' ac_t=' ' + else + ac_n=-n ac_c= ac_t= + fi +else + ac_n= ac_c='\c' ac_t= +fi + +if test -z "$srcdir"; then + # Assume the source directory is the same one as the path to LTMAIN. + srcdir=`$echo "X$ltmain" | $Xsed -e 's%/[^/]*$%%'` + test "$srcdir" = "$ltmain" && srcdir=. +fi + +trap "$rm conftest*; exit 1" 1 2 15 +if test "$verify_host" = yes; then + # Check for config.guess and config.sub. + ac_aux_dir= + for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do + if test -f $ac_dir/config.guess; then + ac_aux_dir=$ac_dir + break + fi + done + if test -z "$ac_aux_dir"; then + echo "$progname: cannot find config.guess in $srcdir $srcdir/.. $srcdir/../.." 1>&2 + echo "$help" 1>&2 + exit 1 + fi + ac_config_guess=$ac_aux_dir/config.guess + ac_config_sub=$ac_aux_dir/config.sub + + # Make sure we can run config.sub. + if $SHELL $ac_config_sub sun4 >/dev/null 2>&1; then : + else + echo "$progname: cannot run $ac_config_sub" 1>&2 + echo "$help" 1>&2 + exit 1 + fi + + echo $ac_n "checking host system type""... $ac_c" 1>&6 + + host_alias=$host + case "$host_alias" in + "") + if host_alias=`$SHELL $ac_config_guess`; then : + else + echo "$progname: cannot guess host type; you must specify one" 1>&2 + echo "$help" 1>&2 + exit 1 + fi ;; + esac + host=`$SHELL $ac_config_sub $host_alias` + echo "$ac_t$host" 1>&6 + + # Make sure the host verified. + test -z "$host" && exit 1 + +elif test -z "$host"; then + echo "$progname: you must specify a host type if you use \`--no-verify'" 1>&2 + echo "$help" 1>&2 + exit 1 +else + host_alias=$host +fi + +# Transform linux* to *-*-linux-gnu*, to support old configure scripts. +case "$host_os" in +linux-gnu*) ;; +linux*) host=`echo $host | sed 's/^\(.*-.*-linux\)\(.*\)$/\1-gnu\2/'` +esac + +host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'` +host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'` +host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'` + +case "$host_os" in +aix3*) + # AIX sometimes has problems with the GCC collect2 program. For some + # reason, if we set the COLLECT_NAMES environment variable, the problems + # vanish in a puff of smoke. + if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES + fi + ;; +esac + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR cru $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + +# Set a sane default for `AR'. +test -z "$AR" && AR=ar + +# Set a sane default for `OBJDUMP'. +test -z "$OBJDUMP" && OBJDUMP=objdump + +# If RANLIB is not set, then run the test. +if test "${RANLIB+set}" != "set"; then + result=no + + echo $ac_n "checking for ranlib... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/ranlib || test -f $dir/ranlib$ac_exeext; then + RANLIB="ranlib" + result="ranlib" + break + fi + done + IFS="$save_ifs" + + echo "$ac_t$result" 1>&6 +fi + +if test -n "$RANLIB"; then + old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" + old_postinstall_cmds="\$RANLIB \$oldlib~$old_postinstall_cmds" +fi + +# Set sane defaults for `DLLTOOL', `OBJDUMP', and `AS', used on cygwin. +test -z "$DLLTOOL" && DLLTOOL=dlltool +test -z "$OBJDUMP" && OBJDUMP=objdump +test -z "$AS" && AS=as + +# Check to see if we are using GCC. +if test "$with_gcc" != yes || test -z "$CC"; then + # If CC is not set, then try to find GCC or a usable CC. + if test -z "$CC"; then + echo $ac_n "checking for gcc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/gcc || test -f $dir/gcc$ac_exeext; then + CC="gcc" + break + fi + done + IFS="$save_ifs" + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + fi + + # Not "gcc", so try "cc", rejecting "/usr/ucb/cc". + if test -z "$CC"; then + echo $ac_n "checking for cc... $ac_c" 1>&6 + IFS="${IFS= }"; save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + cc_rejected=no + for dir in $PATH; do + test -z "$dir" && dir=. + if test -f $dir/cc || test -f $dir/cc$ac_exeext; then + if test "$dir/cc" = "/usr/ucb/cc"; then + cc_rejected=yes + continue + fi + CC="cc" + break + fi + done + IFS="$save_ifs" + if test $cc_rejected = yes; then + # We found a bogon in the path, so make sure we never use it. + set dummy $CC + shift + if test $# -gt 0; then + # We chose a different compiler from the bogus one. + # However, it has the same name, so the bogon will be chosen + # first if we set CC to just the name; use the full file name. + shift + set dummy "$dir/cc" "$@" + shift + CC="$@" + fi + fi + + if test -n "$CC"; then + echo "$ac_t$CC" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$CC"; then + echo "$progname: error: no acceptable cc found in \$PATH" 1>&2 + exit 1 + fi + fi + + # Now see if the compiler is really GCC. + with_gcc=no + echo $ac_n "checking whether we are using GNU C... $ac_c" 1>&6 + echo "$progname:581: checking whether we are using GNU C" >&5 + + $rm conftest.c + cat > conftest.c <&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then + with_gcc=yes + fi + $rm conftest.c + echo "$ac_t$with_gcc" 1>&6 +fi + +# Allow CC to be a program name with arguments. +set dummy $CC +compiler="$2" + +echo $ac_n "checking for object suffix... $ac_c" 1>&6 +$rm conftest* +echo 'int i = 1;' > conftest.c +echo "$progname:603: checking for object suffix" >& 5 +if { (eval echo $progname:604: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c) ;; + *) objext=`echo $ac_file | sed -e s/conftest.//` ;; + esac + done +else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 +fi +$rm conftest* +echo "$ac_t$objext" 1>&6 + +echo $ac_n "checking for executable suffix... $ac_c" 1>&6 +if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_cv_exeext="no" + $rm conftest* + echo 'main () { return 0; }' > conftest.c + echo "$progname:629: checking for executable suffix" >& 5 + if { (eval echo $progname:630: \"$ac_link\") 1>&5; (eval $ac_link) 2>conftest.err; }; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + for ac_file in conftest.*; do + case $ac_file in + *.c | *.err | *.$objext ) ;; + *) ac_cv_exeext=.`echo $ac_file | sed -e s/conftest.//` ;; + esac + done + else + cat conftest.err 1>&5 + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* +fi +if test "X$ac_cv_exeext" = Xno; then + exeext="" +else + exeext="$ac_cv_exeext" +fi +echo "$ac_t$ac_cv_exeext" 1>&6 + +echo $ac_n "checking for $compiler option to produce PIC... $ac_c" 1>&6 +pic_flag= +special_shlib_compile_flags= +wl= +link_static_flag= +no_builtin_flag= + +if test "$with_gcc" = yes; then + wl='-Wl,' + link_static_flag='-static' + + case "$host_os" in + beos* | irix5* | irix6* | osf3* | osf4*) + # PIC is the default for these OSes. + ;; + aix*) + # Below there is a dirty hack to force normal static linking with -ldl + # The problem is because libdl dynamically linked with both libc and + # libC (AIX C++ library), which obviously doesn't included in libraries + # list by gcc. This cause undefined symbols with -static flags. + # This hack allows C programs to be linked with "-static -ldl", but + # we not sure about C++ programs. + link_static_flag="$link_static_flag ${wl}-lC" + ;; + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + amigaos*) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the `-m68020' flag to GCC prevents building anything better, + # like `-m68040'. + pic_flag='-m68020 -resident32 -malways-restore-a4' + ;; + sysv4*MP*) + if test -d /usr/nec; then + pic_flag=-Kconform_pic + fi + ;; + *) + pic_flag='-fPIC' + ;; + esac +else + # PORTME Check for PIC flags for the system compiler. + case "$host_os" in + aix3* | aix4*) + # All AIX code is PIC. + link_static_flag='-bnso -bI:/lib/syscalls.exp' + ;; + + hpux9* | hpux10* | hpux11*) + # Is there a better link_static_flag that works with the bundled CC? + wl='-Wl,' + link_static_flag="${wl}-a ${wl}archive" + pic_flag='+Z' + ;; + + irix5* | irix6*) + wl='-Wl,' + link_static_flag='-non_shared' + # PIC (with -KPIC) is the default. + ;; + + cygwin* | mingw* | os2*) + # We can build DLLs from non-PIC. + ;; + + osf3* | osf4*) + # All OSF/1 code is PIC. + wl='-Wl,' + link_static_flag='-non_shared' + ;; + + sco3.2v5*) + pic_flag='-Kpic' + link_static_flag='-dn' + special_shlib_compile_flags='-belf' + ;; + + solaris*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + sunos4*) + pic_flag='-PIC' + link_static_flag='-Bstatic' + wl='-Qoption ld ' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + pic_flag='-KPIC' + link_static_flag='-Bstatic' + wl='-Wl,' + ;; + + uts4*) + pic_flag='-pic' + link_static_flag='-Bstatic' + ;; + sysv4*MP*) + if test -d /usr/nec ;then + pic_flag='-Kconform_pic' + link_static_flag='-Bstatic' + fi + ;; + *) + can_build_shared=no + ;; + esac +fi + +if test -n "$pic_flag"; then + echo "$ac_t$pic_flag" 1>&6 + + # Check to make sure the pic_flag actually works. + echo $ac_n "checking if $compiler PIC flag $pic_flag works... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS $pic_flag -DPIC" + echo "$progname:776: checking if $compiler PIC flag $pic_flag works" >&5 + if { (eval echo $progname:777: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.$objext; then + # Append any warnings to the config.log. + cat conftest.err 1>&5 + + case "$host_os" in + hpux9* | hpux10* | hpux11*) + # On HP-UX, both CC and GCC only warn that PIC is supported... then they + # create non-PIC objects. So, if there were any warnings, we assume that + # PIC is not supported. + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + can_build_shared=no + pic_flag= + else + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + fi + ;; + *) + echo "$ac_t"yes 1>&6 + pic_flag=" $pic_flag" + ;; + esac + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + can_build_shared=no + pic_flag= + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + echo "$ac_t"none 1>&6 +fi + +# Check to see if options -o and -c are simultaneously supported by compiler +echo $ac_n "checking if $compiler supports -c -o file.o... $ac_c" 1>&6 +$rm -r conftest 2>/dev/null +mkdir conftest +cd conftest +$rm conftest* +echo "int some_variable = 0;" > conftest.c +mkdir out +# According to Tom Tromey, Ian Lance Taylor reported there are C compilers +# that will create temporary files in the current directory regardless of +# the output directory. Thus, making CWD read-only will cause this test +# to fail, enabling locking or at least warning the user not to do parallel +# builds. +chmod -w . +save_CFLAGS="$CFLAGS" +CFLAGS="$CFLAGS -o out/conftest2.o" +echo "$progname:829: checking if $compiler supports -c -o file.o" >&5 +if { (eval echo $progname:830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>out/conftest.err; } && test -s out/conftest2.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s out/conftest.err; then + echo "$ac_t"no 1>&6 + compiler_c_o=no + else + echo "$ac_t"yes 1>&6 + compiler_c_o=yes + fi +else + # Append any errors to the config.log. + cat out/conftest.err 1>&5 + compiler_c_o=no + echo "$ac_t"no 1>&6 +fi +CFLAGS="$save_CFLAGS" +chmod u+w . +$rm conftest* out/* +rmdir out +cd .. +rmdir conftest +$rm -r conftest 2>/dev/null + +if test x"$compiler_c_o" = x"yes"; then + # Check to see if we can write to a .lo + echo $ac_n "checking if $compiler supports -c -o file.lo... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -c -o conftest.lo" + echo "$progname:862: checking if $compiler supports -c -o file.lo" >&5 +if { (eval echo $progname:863: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.lo; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_o_lo=no + else + echo "$ac_t"yes 1>&6 + compiler_o_lo=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_o_lo=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* +else + compiler_o_lo=no +fi + +# Check to see if we can do hard links to lock some files if needed +hard_links="nottested" +if test "$compiler_c_o" = no && test "$need_locks" != no; then + # do not overwrite the value of need_locks provided by the user + echo $ac_n "checking if we can lock with hard links... $ac_c" 1>&6 + hard_links=yes + $rm conftest* + ln conftest.a conftest.b 2>/dev/null && hard_links=no + touch conftest.a + ln conftest.a conftest.b 2>&5 || hard_links=no + ln conftest.a conftest.b 2>/dev/null && hard_links=no + echo "$ac_t$hard_links" 1>&6 + $rm conftest* + if test "$hard_links" = no; then + echo "*** WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2 + need_locks=warn + fi +else + need_locks=no +fi + +if test "$with_gcc" = yes; then + # Check to see if options -fno-rtti -fno-exceptions are supported by compiler + echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions ... $ac_c" 1>&6 + $rm conftest* + echo "int some_variable = 0;" > conftest.c + save_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -fno-rtti -fno-exceptions -c conftest.c" + echo "$progname:914: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 + if { (eval echo $progname:915: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>conftest.err; } && test -s conftest.o; then + + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + echo "$ac_t"no 1>&6 + compiler_rtti_exceptions=no + else + echo "$ac_t"yes 1>&6 + compiler_rtti_exceptions=yes + fi + else + # Append any errors to the config.log. + cat conftest.err 1>&5 + compiler_rtti_exceptions=no + echo "$ac_t"no 1>&6 + fi + CFLAGS="$save_CFLAGS" + $rm conftest* + + if test "$compiler_rtti_exceptions" = "yes"; then + no_builtin_flag=' -fno-builtin -fno-rtti -fno-exceptions' + else + no_builtin_flag=' -fno-builtin' + fi + +fi + +# Check for any special shared library compilation flags. +if test -n "$special_shlib_compile_flags"; then + echo "$progname: warning: \`$CC' requires \`$special_shlib_compile_flags' to build shared libraries" 1>&2 + if echo "$old_CC $old_CFLAGS " | egrep -e "[ ]$special_shlib_compile_flags[ ]" >/dev/null; then : + else + echo "$progname: add \`$special_shlib_compile_flags' to the CC or CFLAGS env variable and reconfigure" 1>&2 + can_build_shared=no + fi +fi + +echo $ac_n "checking if $compiler static flag $link_static_flag works... $ac_c" 1>&6 +$rm conftest* +echo 'main(){return(0);}' > conftest.c +save_LDFLAGS="$LDFLAGS" +LDFLAGS="$LDFLAGS $link_static_flag" +echo "$progname:958: checking if $compiler static flag $link_static_flag works" >&5 +if { (eval echo $progname:959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + echo "$ac_t$link_static_flag" 1>&6 +else + echo "$ac_t"none 1>&6 + link_static_flag= +fi +LDFLAGS="$save_LDFLAGS" +$rm conftest* + +if test -z "$LN_S"; then + # Check to see if we can use ln -s, or we need hard links. + echo $ac_n "checking whether ln -s works... $ac_c" 1>&6 + $rm conftest.dat + if ln -s X conftest.dat 2>/dev/null; then + $rm conftest.dat + LN_S="ln -s" + else + LN_S=ln + fi + if test "$LN_S" = "ln -s"; then + echo "$ac_t"yes 1>&6 + else + echo "$ac_t"no 1>&6 + fi +fi + +# Make sure LD is an absolute path. +if test -z "$LD"; then + ac_prog=ld + if test "$with_gcc" = yes; then + # Check if gcc -print-prog-name=ld gives a path. + echo $ac_n "checking for ld used by GCC... $ac_c" 1>&6 + echo "$progname:991: checking for ld used by GCC" >&5 + ac_prog=`($CC -print-prog-name=ld) 2>&5` + case "$ac_prog" in + # Accept absolute paths. + [\\/]* | [A-Za-z]:[\\/]*) + re_direlt='/[^/][^/]*/\.\./' + # Canonicalize the path of ld + ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'` + while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do + ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"` + done + test -z "$LD" && LD="$ac_prog" + ;; + "") + # If it fails, then pretend we are not using GCC. + ac_prog=ld + ;; + *) + # If it is relative, then search for the first ld in PATH. + with_gnu_ld=unknown + ;; + esac + elif test "$with_gnu_ld" = yes; then + echo $ac_n "checking for GNU ld... $ac_c" 1>&6 + echo "$progname:1015: checking for GNU ld" >&5 + else + echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 + echo "$progname:1018: checking for non-GNU ld" >&5 + fi + + if test -z "$LD"; then + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH; do + test -z "$ac_dir" && ac_dir=. + if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then + LD="$ac_dir/$ac_prog" + # Check to see if the program is GNU ld. I'd rather use --version, + # but apparently some GNU ld's only accept -v. + # Break only if it was the GNU/non-GNU ld that we prefer. + if "$LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then + test "$with_gnu_ld" != no && break + else + test "$with_gnu_ld" != yes && break + fi + fi + done + IFS="$ac_save_ifs" + fi + + if test -n "$LD"; then + echo "$ac_t$LD" 1>&6 + else + echo "$ac_t"no 1>&6 + fi + + if test -z "$LD"; then + echo "$progname: error: no acceptable ld found in \$PATH" 1>&2 + exit 1 + fi +fi + +# Check to see if it really is or is not GNU ld. +echo $ac_n "checking if the linker ($LD) is GNU ld... $ac_c" 1>&6 +# I'd rather use --version here, but apparently some GNU ld's only accept -v. +if $LD -v 2>&1 &5; then + with_gnu_ld=yes +else + with_gnu_ld=no +fi +echo "$ac_t$with_gnu_ld" 1>&6 + +# See if the linker supports building shared libraries. +echo $ac_n "checking whether the linker ($LD) supports shared libraries... $ac_c" 1>&6 + +allow_undefined_flag= +no_undefined_flag= +need_lib_prefix=unknown +need_version=unknown +# when you set need_version to no, make sure it does not cause -set_version +# flags to be left without arguments +archive_cmds= +archive_expsym_cmds= +old_archive_from_new_cmds= +export_dynamic_flag_spec= +whole_archive_flag_spec= +thread_safe_flag_spec= +hardcode_libdir_flag_spec= +hardcode_libdir_separator= +hardcode_direct=no +hardcode_minus_L=no +hardcode_shlibpath_var=unsupported +runpath_var= +always_export_symbols=no +export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | sed '\''s/.* //'\'' | sort | uniq > $export_symbols' +# include_expsyms should be a list of space-separated symbols to be *always* +# included in the symbol list +include_expsyms= +# exclude_expsyms can be an egrep regular expression of symbols to exclude +# it will be wrapped by ` (' and `)$', so one must not match beginning or +# end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', +# as well as any symbol that contains `d'. +exclude_expsyms="_GLOBAL_OFFSET_TABLE_" +# Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out +# platforms (ab)use it in PIC code, but their linkers get confused if +# the symbol is explicitly referenced. Since portable code cannot +# rely on this symbol name, it's probably fine to never include it in +# preloaded symbol tables. + +case "$host_os" in +cygwin* | mingw*) + # FIXME: the MSVC++ port hasn't been tested in a loooong time + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + if test "$with_gcc" != yes; then + with_gnu_ld=no + fi + ;; + +esac + +ld_shlibs=yes +if test "$with_gnu_ld" = yes; then + # If archive_cmds runs LD, not CC, wlarc should be empty + wlarc='${wl}' + + # See if GNU ld supports shared libraries. + case "$host_os" in + aix3* | aix4*) + # On AIX, the GNU linker is very broken + ld_shlibs=no + cat <&2 + +*** Warning: the GNU linker, at least up to release 2.9.1, is reported +*** to be unable to reliably create shared libraries on AIX. +*** Therefore, libtool is disabling shared libraries support. If you +*** really care for shared libraries, you may want to modify your PATH +*** so that a non-GNU linker is found, and then restart. + +EOF + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + + # Samuel A. Falvo II reports + # that the semantics of dynamic libraries on AmigaOS, at least up + # to version 4, is to share data among multiple programs linked + # with the same dynamic library. Since this doesn't match the + # behavior of shared libraries on other platforms, we can use + # them. + ld_shlibs=no + ;; + + beos*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + allow_undefined_flag=unsupported + # Joseph Beckenbach says some releases of gcc + # support --undefined. This deserves some investigation. FIXME + archive_cmds='$CC -nostart $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + else + ld_shlibs=no + fi + ;; + + cygwin* | mingw*) + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec='-L$libdir' + allow_undefined_flag=unsupported + always_export_symbols=yes + + # Extract the symbol export list from an `--export-all' def file, + # then regenerate the def file from the symbol export list, so that + # the compiled dll only exports the symbol export list. + export_symbols_cmds='test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $DLLTOOL --export-all --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --output-def $objdir/$soname-def $objdir/$soname-ltdll.$objext $libobjs $convenience~ + sed -e "1,/EXPORTS/d" -e "s/ @ [0-9]* ; *//" < $objdir/$soname-def > $export_symbols' + + archive_expsym_cmds='echo EXPORTS > $objdir/$soname-def~ + _lt_hint=1; + for symbol in `cat $export_symbols`; do + echo " \$symbol @ \$_lt_hint ; " >> $objdir/$soname-def; + _lt_hint=`expr 1 + \$_lt_hint`; + done~ + test -f $objdir/$soname-ltdll.c || sed -e "/^# \/\* ltdll\.c starts here \*\//,/^# \/\* ltdll.c ends here \*\// { s/^# //; p; }" -e d < $0 > $objdir/$soname-ltdll.c~ + test -f $objdir/$soname-ltdll.$objext || (cd $objdir && $CC -c $soname-ltdll.c)~ + $CC -Wl,--base-file,$objdir/$soname-base -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC -Wl,--base-file,$objdir/$soname-base $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts~ + $DLLTOOL --as=$AS --dllname $soname --exclude-symbols DllMain@12,_cygwin_dll_entry@12,_cygwin_noncygwin_dll_entry@12 --def $objdir/$soname-def --base-file $objdir/$soname-base --output-exp $objdir/$soname-exp~ + $CC $objdir/$soname-exp -Wl,--dll -nostartfiles -Wl,-e,__cygwin_dll_entry@12 -o $lib $objdir/$soname-ltdll.$objext $libobjs $deplibs $linkopts' + + old_archive_from_new_cmds='$DLLTOOL --as=$AS --dllname $soname --def $objdir/$soname-def --output-lib $objdir/$libname.a' + ;; + + netbsd*) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + archive_cmds='$LD -Bshareable $libobjs $deplibs $linkopts -o $lib' + # can we support soname and/or expsyms with a.out? -oliva + fi + ;; + + solaris*) + if $LD -v 2>&1 | egrep 'BFD 2\.8' > /dev/null; then + ld_shlibs=no + cat <&2 + +*** Warning: The releases 2.8.* of the GNU linker cannot reliably +*** create shared libraries on Solaris systems. Therefore, libtool +*** is disabling shared libraries support. We urge you to upgrade GNU +*** binutils to release 2.9.1 or newer. Another option is to modify +*** your PATH or compiler configuration so that the native linker is +*** used, and then restart. + +EOF + elif $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linkopts' + wlarc= + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + *) + if $LD --help 2>&1 | egrep ': supported targets:.* elf' > /dev/null; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' + else + ld_shlibs=no + fi + ;; + esac + + if test "$ld_shlibs" = yes; then + runpath_var=LD_RUN_PATH + hardcode_libdir_flag_spec='${wl}--rpath ${wl}$libdir' + export_dynamic_flag_spec='${wl}--export-dynamic' + case $host_os in + cygwin* | mingw*) + # dlltool doesn't understand --whole-archive et. al. + whole_archive_flag_spec= + ;; + *) + whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' + ;; + esac + fi +else + # PORTME fill in a description of your system's linker (not GNU ld) + case "$host_os" in + aix3*) + allow_undefined_flag=unsupported + always_export_symbols=yes + archive_expsym_cmds='$LD -o $objdir/$soname $libobjs $deplibs $linkopts -bE:$export_symbols -T512 -H512 -bM:SRE~$AR cru $lib $objdir/$soname' + # Note: this linker hardcodes the directories in LIBPATH if there + # are no directories specified by -L. + hardcode_minus_L=yes + if test "$with_gcc" = yes && test -z "$link_static_flag"; then + # Neither direct hardcoding nor static linking is supported with a + # broken collect2. + hardcode_direct=unsupported + fi + ;; + + aix4*) + hardcode_libdir_flag_spec='${wl}-b ${wl}nolibpath ${wl}-b ${wl}libpath:$libdir:/usr/lib:/lib' + hardcode_libdir_separator=':' + if test "$with_gcc" = yes; then + collect2name=`${CC} -print-prog-name=collect2` + if test -f "$collect2name" && \ + strings "$collect2name" | grep resolve_lib_name >/dev/null + then + # We have reworked collect2 + hardcode_direct=yes + else + # We have old collect2 + hardcode_direct=unsupported + # It fails to find uninstalled libraries when the uninstalled + # path is not listed in the libpath. Setting hardcode_minus_L + # to unsupported forces relinking + hardcode_minus_L=yes + hardcode_libdir_flag_spec='-L$libdir' + hardcode_libdir_separator= + fi + shared_flag='-shared' + else + shared_flag='${wl}-bM:SRE' + hardcode_direct=yes + fi + allow_undefined_flag=' ${wl}-berok' + archive_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bexpall ${wl}-bnoentry${allow_undefined_flag}' + archive_expsym_cmds="\$CC $shared_flag"' -o $objdir/$soname $libobjs $deplibs $linkopts ${wl}-bE:$export_symbols ${wl}-bnoentry${allow_undefined_flag}' + case "$host_os" in aix4.[01]|aix4.[01].*) + # According to Greg Wooledge, -bexpall is only supported from AIX 4.2 on + always_export_symbols=yes ;; + esac + ;; + + amigaos*) + archive_cmds='$rm $objdir/a2ixlibrary.data~$echo "#define NAME $libname" > $objdir/a2ixlibrary.data~$echo "#define LIBRARY_ID 1" >> $objdir/a2ixlibrary.data~$echo "#define VERSION $major" >> $objdir/a2ixlibrary.data~$echo "#define REVISION $revision" >> $objdir/a2ixlibrary.data~$AR cru $lib $libobjs~$RANLIB $lib~(cd $objdir && a2ixlibrary -32)' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + # see comment about different semantics on the GNU ld section + ld_shlibs=no + ;; + + cygwin* | mingw*) + # When not using gcc, we currently assume that we are using + # Microsoft Visual C++. + # hardcode_libdir_flag_spec is actually meaningless, as there is + # no search path for DLLs. + hardcode_libdir_flag_spec=' ' + allow_undefined_flag=unsupported + # Tell ltmain to make .lib files, not .a files. + libext=lib + # FIXME: Setting linknames here is a bad hack. + archive_cmds='$CC -o $lib $libobjs $linkopts `echo "$deplibs" | sed -e '\''s/ -lc$//'\''` -link -dll~linknames=' + # The linker will automatically build a .lib file if we build a DLL. + old_archive_from_new_cmds='true' + # FIXME: Should let the user specify the lib program. + old_archive_cmds='lib /OUT:$oldlib$oldobjs' + fix_srcfile_path='`cygpath -w $srcfile`' + ;; + + freebsd1*) + ld_shlibs=no + ;; + + # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor + # support. Future versions do this automatically, but an explicit c++rt0.o + # does not break anything, and helps significantly (at the cost of a little + # extra space). + freebsd2.2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts /usr/lib/c++rt0.o' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + # Unfortunately, older versions of FreeBSD 2 do not have this feature. + freebsd2*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + # FreeBSD 3 and greater uses gcc -shared to do shared libraries. + freebsd*) + archive_cmds='$CC -shared -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + hpux9* | hpux10* | hpux11*) + case "$host_os" in + hpux9*) archive_cmds='$rm $objdir/$soname~$LD -b +b $install_libdir -o $objdir/$soname $libobjs $deplibs $linkopts~test $objdir/$soname = $lib || mv $objdir/$soname $lib' ;; + *) archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linkopts' ;; + esac + hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' + hardcode_libdir_separator=: + hardcode_direct=yes + hardcode_minus_L=yes # Not in the search PATH, but as the default + # location of the library. + export_dynamic_flag_spec='${wl}-E' + ;; + + irix5* | irix6*) + if test "$with_gcc" = yes; then + archive_cmds='$CC -shared $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + archive_cmds='$LD -shared $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + netbsd*) + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' # a.out + else + archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linkopts' # ELF + fi + hardcode_libdir_flag_spec='${wl}-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + openbsd*) + archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_direct=yes + hardcode_shlibpath_var=no + ;; + + os2*) + hardcode_libdir_flag_spec='-L$libdir' + hardcode_minus_L=yes + allow_undefined_flag=unsupported + archive_cmds='$echo "LIBRARY $libname INITINSTANCE" > $objdir/$libname.def~$echo "DESCRIPTION \"$libname\"" >> $objdir/$libname.def~$echo DATA >> $objdir/$libname.def~$echo " SINGLE NONSHARED" >> $objdir/$libname.def~$echo EXPORTS >> $objdir/$libname.def~emxexp $libobjs >> $objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $linkopts $objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $objdir/$libname.a $objdir/$libname.def' + ;; + + osf3* | osf4*) + if test "$with_gcc" = yes; then + allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' + archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $linkopts ${wl}-soname ${wl}$soname `test -n "$verstring" && echo ${wl}-set_version ${wl}$verstring` ${wl}-update_registry ${wl}${objdir}/so_locations -o $lib' + else + allow_undefined_flag=' -expect_unresolved \*' + archive_cmds='$LD -shared${allow_undefined_flag} $libobjs $deplibs $linkopts -soname $soname `test -n "$verstring" && echo -set_version $verstring` -update_registry ${objdir}/so_locations -o $lib' + fi + hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' + hardcode_libdir_separator=: + ;; + + sco3.2v5*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ;; + + solaris*) + no_undefined_flag=' -z text' + # $CC -shared without GNU ld will not create a library from C++ + # object files and a static libstdc++, better avoid it by now + archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linkopts' + archive_expsym_cmds='$echo "{ global:" > $lib.exp~cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $lib.exp~$echo "local: *; };" >> $lib.exp~ + $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linkopts~$rm $lib.exp' + hardcode_libdir_flag_spec='-R$libdir' + hardcode_shlibpath_var=no + case "$host_os" in + solaris2.[0-5] | solaris2.[0-5].*) ;; + *) # Supported since Solaris 2.6 (maybe 2.5.1?) + whole_archive_flag_spec='-z allextract$convenience -z defaultextract' ;; + esac + ;; + + sunos4*) + archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_direct=yes + hardcode_minus_L=yes + hardcode_shlibpath_var=no + ;; + + sysv4) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + runpath_var='LD_RUN_PATH' + hardcode_shlibpath_var=no + hardcode_direct=no #Motorola manual says yes, but my tests say they lie + ;; + + sysv4.3*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_shlibpath_var=no + export_dynamic_flag_spec='-Bexport' + ;; + + uts4*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + dgux*) + archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linkopts' + hardcode_libdir_flag_spec='-L$libdir' + hardcode_shlibpath_var=no + ;; + + sysv4*MP*) + if test -d /usr/nec ;then + # archive_cmds='$LD -G -z text -h $soname -o $lib$libobjs$deplibs' + archive_cmds='$LD -G -h $soname -o $lib$libobjs$deplibs' + hardcode_shlibpath_var=no + runpath_var=LD_RUN_PATH + hardcode_runpath_var=yes + ld_shlibs=yes + fi + ;; + + *) + ld_shlibs=no + ;; + esac +fi +echo "$ac_t$ld_shlibs" 1>&6 +test "$ld_shlibs" = no && can_build_shared=no + +if test -z "$NM"; then + echo $ac_n "checking for BSD-compatible nm... $ac_c" 1>&6 + case "$NM" in + [\\/]* | [A-Za-z]:[\\/]*) ;; # Let the user override the test with a path. + *) + IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR}" + for ac_dir in $PATH /usr/ucb /usr/ccs/bin /bin; do + test -z "$ac_dir" && ac_dir=. + if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext; then + # Check to see if the nm accepts a BSD-compat flag. + # Adding the `sed 1q' prevents false positives on HP-UX, which says: + # nm: unknown option "B" ignored + if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -B" + break + elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then + NM="$ac_dir/nm -p" + break + else + NM=${NM="$ac_dir/nm"} # keep the first match, but + continue # so that we can try to find one that supports BSD flags + fi + fi + done + IFS="$ac_save_ifs" + test -z "$NM" && NM=nm + ;; + esac + echo "$ac_t$NM" 1>&6 +fi + +# Check for command to grab the raw symbol name followed by C symbol from nm. +echo $ac_n "checking command to parse $NM output... $ac_c" 1>&6 + +# These are sane defaults that work on at least a few old systems. +# [They come from Ultrix. What could be older than Ultrix?!! ;)] + +# Character class describing NM global symbol codes. +symcode='[BCDEGRST]' + +# Regexp to match symbols that can be accessed directly from C. +sympat='\([_A-Za-z][_A-Za-z0-9]*\)' + +# Transform the above into a raw symbol and a C symbol. +symxfrm='\1 \2\3 \3' + +# Transform an extracted symbol line into a proper C declaration +global_symbol_to_cdecl="sed -n -e 's/^. .* \(.*\)$/extern char \1;/p'" + +# Define system-specific variables. +case "$host_os" in +aix*) + symcode='[BCDT]' + ;; +cygwin* | mingw*) + symcode='[ABCDGISTW]' + ;; +hpux*) # Its linker distinguishes data from code symbols + global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern char \1();/p' -e 's/^. .* \(.*\)$/extern char \1;/p'" + ;; +irix*) + symcode='[BCDEGRST]' + ;; +solaris*) + symcode='[BDT]' + ;; +sysv4) + symcode='[DFNSTU]' + ;; +esac + +# If we're using GNU nm, then use its standard symbol codes. +if $NM -V 2>&1 | egrep '(GNU|with BFD)' > /dev/null; then + symcode='[ABCDGISTW]' +fi + +# Try without a prefix undercore, then with it. +for ac_symprfx in "" "_"; do + + # Write the raw and C identifiers. + global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode\)[ ][ ]*\($ac_symprfx\)$sympat$/$symxfrm/p'" + + # Check to see that the pipe works correctly. + pipe_works=no + $rm conftest* + cat > conftest.c <&5 + if { (eval echo $progname:1593: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } && test -s conftest.$objext; then + # Now try to grab the symbols. + nlist=conftest.nm + if { echo "$progname:1596: eval \"$NM conftest.$objext | $global_symbol_pipe > $nlist\"" >&5; eval "$NM conftest.$objext | $global_symbol_pipe > $nlist 2>&5"; } && test -s "$nlist"; then + + # Try sorting and uniquifying the output. + if sort "$nlist" | uniq > "$nlist"T; then + mv -f "$nlist"T "$nlist" + else + rm -f "$nlist"T + fi + + # Make sure that we snagged all the symbols we need. + if egrep ' nm_test_var$' "$nlist" >/dev/null; then + if egrep ' nm_test_func$' "$nlist" >/dev/null; then + cat < conftest.c +#ifdef __cplusplus +extern "C" { +#endif + +EOF + # Now generate the symbol file. + eval "$global_symbol_to_cdecl"' < "$nlist" >> conftest.c' + + cat <> conftest.c +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{ +EOF + sed 's/^. \(.*\) \(.*\)$/ {"\2", (lt_ptr_t) \&\2},/' < "$nlist" >> conftest.c + cat <<\EOF >> conftest.c + {0, (lt_ptr_t) 0} +}; + +#ifdef __cplusplus +} +#endif +EOF + # Now try linking the two files. + mv conftest.$objext conftstm.$objext + save_LIBS="$LIBS" + save_CFLAGS="$CFLAGS" + LIBS="conftstm.$objext" + CFLAGS="$CFLAGS$no_builtin_flag" + if { (eval echo $progname:1648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest; then + pipe_works=yes + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + LIBS="$save_LIBS" + else + echo "cannot find nm_test_func in $nlist" >&5 + fi + else + echo "cannot find nm_test_var in $nlist" >&5 + fi + else + echo "cannot run $global_symbol_pipe" >&5 + fi + else + echo "$progname: failed program was:" >&5 + cat conftest.c >&5 + fi + $rm conftest* conftst* + + # Do not use the global_symbol_pipe unless it works. + if test "$pipe_works" = yes; then + break + else + global_symbol_pipe= + fi +done +if test "$pipe_works" = yes; then + echo "${ac_t}ok" 1>&6 +else + echo "${ac_t}failed" 1>&6 +fi + +if test -z "$global_symbol_pipe"; then + global_symbol_to_cdecl= +fi + +# Check hardcoding attributes. +echo $ac_n "checking how to hardcode library paths into programs... $ac_c" 1>&6 +hardcode_action= +if test -n "$hardcode_libdir_flag_spec" || \ + test -n "$runpath_var"; then + + # We can hardcode non-existant directories. + if test "$hardcode_direct" != no && + # If the only mechanism to avoid hardcoding is shlibpath_var, we + # have to relink, otherwise we might link with an installed library + # when we should be linking with a yet-to-be-installed one + ## test "$hardcode_shlibpath_var" != no && + test "$hardcode_minus_L" != no; then + # Linking always hardcodes the temporary library directory. + hardcode_action=relink + else + # We can link without hardcoding, and we can hardcode nonexisting dirs. + hardcode_action=immediate + fi +else + # We cannot hardcode anything, or else we can only hardcode existing + # directories. + hardcode_action=unsupported +fi +echo "$ac_t$hardcode_action" 1>&6 + + +reload_flag= +reload_cmds='$LD$reload_flag -o $output$reload_objs' +echo $ac_n "checking for $LD option to reload object files... $ac_c" 1>&6 +# PORTME Some linkers may need a different reload flag. +reload_flag='-r' +echo "$ac_t$reload_flag" 1>&6 +test -n "$reload_flag" && reload_flag=" $reload_flag" + +# PORTME Fill in your ld.so characteristics +library_names_spec= +libname_spec='lib$name' +soname_spec= +postinstall_cmds= +postuninstall_cmds= +finish_cmds= +finish_eval= +shlibpath_var= +shlibpath_overrides_runpath=unknown +version_type=none +dynamic_linker="$host_os ld.so" +sys_lib_dlsearch_path_spec="/lib /usr/lib" +sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" +file_magic_cmd= +file_magic_test_file= +deplibs_check_method='unknown' +# Need to set the preceding variable on all platforms that support +# interlibrary dependencies. +# 'none' -- dependencies not supported. +# `unknown' -- same as none, but documents that we really don't know. +# 'pass_all' -- all dependencies passed with no checks. +# 'test_compile' -- check by making test program. +# 'file_magic [regex]' -- check by looking for files in library path +# which responds to the $file_magic_cmd with a given egrep regex. +# If you have `file' or equivalent on your system and you're not sure +# whether `pass_all' will *always* work, you probably want this one. +echo $ac_n "checking dynamic linker characteristics... $ac_c" 1>&6 +case "$host_os" in +aix3*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix $libname.a' + shlibpath_var=LIBPATH + + # AIX has no versioning support, so we append a major version to the name. + soname_spec='${libname}${release}.so$major' + ;; + +aix4*) + version_type=linux + # AIX has no versioning support, so currently we can not hardcode correct + # soname into executable. Probably we can add versioning support to + # collect2, so additional links can be useful in future. + # We preserve .a as extension for shared libraries though AIX4.2 + # and later linker supports .so + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.a' + shlibpath_var=LIBPATH + deplibs_check_method=pass_all + ;; + +amigaos*) + library_names_spec='$libname.ixlibrary $libname.a' + # Create ${libname}_ixlibrary.a entries in /sys/libs. + finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$echo "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $rm /sys/libs/${libname}_ixlibrary.a; $show "(cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a)"; (cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a) || exit 1; done' + ;; + +beos*) + library_names_spec='${libname}.so' + dynamic_linker="$host_os ld.so" + shlibpath_var=LIBRARY_PATH + deplibs_check_method=pass_all + lt_cv_dlopen="load_add_on" + lt_cv_dlopen_libs= + lt_cv_dlopen_self=yes + ;; + +bsdi4*) + version_type=linux + library_names_spec='${libname}.so$major ${libname}.so' + soname_spec='${libname}.so' + finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" + sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" + # the default ld.so.conf also contains /usr/contrib/lib and + # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow + # libtool to hard-code these into programs + ;; + +cygwin* | mingw*) + version_type=windows + need_version=no + need_lib_prefix=no + if test "$with_gcc" = yes; then + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.a' + else + library_names_spec='${libname}`echo ${release} | sed -e 's/[.]/-/g'`${versuffix}.dll $libname.lib' + fi + dynamic_linker='Win32 ld.exe' + deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' + file_magic_cmd='${OBJDUMP} -f' + # FIXME: first we should search . and the directory the executable is in + shlibpath_var=PATH + lt_cv_dlopen="LoadLibrary" + lt_cv_dlopen_libs= + ;; + +freebsd1*) + dynamic_linker=no + ;; + +freebsd*) + objformat=`test -x /usr/bin/objformat && /usr/bin/objformat || echo aout` + version_type=freebsd-$objformat + case "$version_type" in + freebsd-elf*) + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB shared object' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + need_version=no + need_lib_prefix=no + ;; + freebsd-*) + deplibs_check_method=unknown + library_names_spec='${libname}${release}.so$versuffix $libname.so$versuffix' + need_version=yes + ;; + esac + finish_cmds='PATH="\$PATH:/sbin" OBJFORMAT="'"$objformat"'" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + case "$host_os" in + freebsd2* | freebsd3.[01]*) + shlibpath_overrides_runpath=yes + ;; + *) # from 3.2 on + shlibpath_overrides_runpath=no + ;; + esac + ;; + +gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so${major} ${libname}.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +hpux9* | hpux10* | hpux11*) + # Give a soname corresponding to the major version so that dld.sl refuses to + # link against other versions. + dynamic_linker="$host_os dld.sl" + version_type=sunos + need_lib_prefix=no + need_version=no + shlibpath_var=SHLIB_PATH + shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH + library_names_spec='${libname}${release}.sl$versuffix ${libname}${release}.sl$major $libname.sl' + soname_spec='${libname}${release}.sl$major' + # HP-UX runs *really* slowly unless shared libraries are mode 555. + postinstall_cmds='chmod 555 $lib' + ;; + +irix5* | irix6*) + version_type=irix + need_lib_prefix=no + need_version=no + soname_spec='${libname}${release}.so.$major' + library_names_spec='${libname}${release}.so.$versuffix ${libname}${release}.so.$major ${libname}${release}.so $libname.so' + case "$host_os" in + irix5*) + libsuff= shlibsuff= + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF 32-bit MSB dynamic lib MIPS - version 1" + ;; + *) + case "$LD" in # libtool.m4 will add one of these switches to LD + *-32|*"-32 ") libsuff= shlibsuff= libmagic=32-bit;; + *-n32|*"-n32 ") libsuff=32 shlibsuff=N32 libmagic=N32;; + *-64|*"-64 ") libsuff=64 shlibsuff=64 libmagic=64-bit;; + *) libsuff= shlibsuff= libmagic=never-match;; + esac + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method="file_magic ELF ${libmagic} MSB mips-[1234] dynamic lib MIPS - version 1" + ;; + esac + shlibpath_var=LD_LIBRARY${shlibsuff}_PATH + shlibpath_overrides_runpath=no + sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" + sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib${libsuff}/libc.so*` + deplibs_check_method='pass_all' + ;; + +# No shared lib support for Linux oldld, aout, or coff. +linux-gnuoldld* | linux-gnuaout* | linux-gnucoff*) + dynamic_linker=no + ;; + +# This must be Linux ELF. +linux-gnu*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /lib/libc.so* /lib/libc-*.so` + + if test -f /lib/ld.so.1; then + dynamic_linker='GNU ld.so' + else + # Only the GNU ld.so supports shared libraries on MkLinux. + case "$host_cpu" in + powerpc*) dynamic_linker=no ;; + *) dynamic_linker='Linux ld.so' ;; + esac + fi + ;; + +netbsd*) + version_type=sunos + if echo __ELF__ | $CC -E - | grep __ELF__ >/dev/null; then + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + dynamic_linker='NetBSD (a.out) ld.so' + else + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major ${libname}${release}.so ${libname}.so' + soname_spec='${libname}${release}.so$major' + dynamic_linker='NetBSD ld.elf_so' + fi + shlibpath_var=LD_LIBRARY_PATH + ;; + +openbsd*) + version_type=sunos + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + need_version=no + fi + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' + shlibpath_var=LD_LIBRARY_PATH + ;; + +os2*) + libname_spec='$name' + need_lib_prefix=no + library_names_spec='$libname.dll $libname.a' + dynamic_linker='OS/2 ld.exe' + shlibpath_var=LIBPATH + ;; + +osf3* | osf4*) + version_type=osf + need_version=no + soname_spec='${libname}${release}.so' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so $libname.so' + shlibpath_var=LD_LIBRARY_PATH + # this will be overridden with pass_all, but let us keep it just in case + deplibs_check_method='file_magic COFF format alpha shared library' + file_magic_cmd=/usr/bin/file + file_magic_test_file=/shlib/libc.so + deplibs_check_method='pass_all' + sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" + sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" + ;; + +sco3.2v5*) + version_type=osf + soname_spec='${libname}${release}.so$major' + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + shlibpath_var=LD_LIBRARY_PATH + ;; + +solaris*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + # ldd complains unless libraries are executable + postinstall_cmds='chmod +x $lib' + deplibs_check_method="file_magic ELF [0-9][0-9]-bit [LM]SB dynamic lib" + file_magic_cmd=/usr/bin/file + file_magic_test_file=/lib/libc.so + ;; + +sunos4*) + version_type=sunos + library_names_spec='${libname}${release}.so$versuffix ${libname}.so$versuffix' + finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=yes + if test "$with_gnu_ld" = yes; then + need_lib_prefix=no + fi + need_version=yes + ;; + +sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + case "$host_vendor" in + ncr) + deplibs_check_method='pass_all' + ;; + motorola) + need_lib_prefix=no + need_version=no + shlibpath_overrides_runpath=no + sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' + deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' + file_magic_cmd=/usr/bin/file + file_magic_test_file=`echo /usr/lib/libc.so*` + ;; + esac + ;; + +uts4*) + version_type=linux + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +dgux*) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='${libname}${release}.so$versuffix ${libname}${release}.so$major $libname.so' + soname_spec='${libname}${release}.so$major' + shlibpath_var=LD_LIBRARY_PATH + ;; + +sysv4*MP*) + if test -d /usr/nec ;then + version_type=linux + library_names_spec='$libname.so.$versuffix $libname.so.$major $libname.so' + soname_spec='$libname.so.$major' + shlibpath_var=LD_LIBRARY_PATH + fi + ;; + +*) + dynamic_linker=no + ;; +esac +echo "$ac_t$dynamic_linker" 1>&6 +test "$dynamic_linker" = no && can_build_shared=no + +# Report the final consequences. +echo "checking if libtool supports shared libraries... $can_build_shared" 1>&6 + +# Only try to build win32 dlls if AC_LIBTOOL_WIN32_DLL was used in +# configure.in, otherwise build static only libraries. +case "$host_os" in +cygwin* | mingw* | os2*) + if test x$can_build_shared = xyes; then + test x$enable_win32_dll = xno && can_build_shared=no + echo "checking if package supports dlls... $can_build_shared" 1>&6 + fi +;; +esac + +if test -n "$file_magic_test_file" && test -n "$file_magic_cmd"; then + case "$deplibs_check_method" in + "file_magic "*) + file_magic_regex="`expr \"$deplibs_check_method\" : \"file_magic \(.*\)\"`" + if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | + egrep "$file_magic_regex" > /dev/null; then + : + else + cat <&2 + +*** Warning: the command libtool uses to detect shared libraries, +*** $file_magic_cmd, produces output that libtool cannot recognize. +*** The result is that libtool may fail to recognize shared libraries +*** as such. This will affect the creation of libtool libraries that +*** depend on shared libraries, but programs linked with such libtool +*** libraries will work regardless of this problem. Nevertheless, you +*** may want to report the problem to your system manager and/or to +*** bug-libtool@gnu.org + +EOF + fi ;; + esac +fi + +echo $ac_n "checking whether to build shared libraries... $ac_c" 1>&6 +test "$can_build_shared" = "no" && enable_shared=no + +# On AIX, shared libraries and static libraries use the same namespace, and +# are all built from PIC. +case "$host_os" in +aix3*) + test "$enable_shared" = yes && enable_static=no + if test -n "$RANLIB"; then + archive_cmds="$archive_cmds~\$RANLIB \$lib" + postinstall_cmds='$RANLIB $lib' + fi + ;; + +aix4*) + test "$enable_shared" = yes && enable_static=no + ;; +esac + +echo "$ac_t$enable_shared" 1>&6 + +# Make sure either enable_shared or enable_static is yes. +test "$enable_shared" = yes || enable_static=yes + +echo "checking whether to build static libraries... $enable_static" 1>&6 + +if test "$hardcode_action" = relink; then + # Fast installation is not supported + enable_fast_install=no +elif test "$shlibpath_overrides_runpath" = yes || + test "$enable_shared" = no; then + # Fast installation is not necessary + enable_fast_install=needless +fi + +echo $ac_n "checking for objdir... $ac_c" 1>&6 +rm -f .libs 2>/dev/null +mkdir .libs 2>/dev/null +if test -d .libs; then + objdir=.libs +else + # MS-DOS does not allow filenames that begin with a dot. + objdir=_libs +fi +rmdir .libs 2>/dev/null +echo "$ac_t$objdir" 1>&6 + +if test "x$enable_dlopen" != xyes; then + enable_dlopen=unknown + enable_dlopen_self=unknown + enable_dlopen_self_static=unknown +else +if eval "test \"`echo '$''{'lt_cv_dlopen'+set}'`\" != set"; then + lt_cv_dlopen=no lt_cv_dlopen_libs= +echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 +echo "$progname:2170: checking for dlopen in -ldl" >&5 +ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldl $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dlopen""... $ac_c" 1>&6 +echo "$progname:2207: checking for dlopen" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char dlopen(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_dlopen) || defined (__stub___dlopen) +choke me +#else +dlopen(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_dlopen=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_dlopen=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dlopen" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 +echo "$progname:2251: checking for dld_link in -ldld" >&5 +ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load""... $ac_c" 1>&6 +echo "$progname:2288: checking for shl_load" >&5 +if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char shl_load(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_shl_load) || defined (__stub___shl_load) +choke me +#else +shl_load(); +#endif + +; return 0; } +EOF +if { (eval echo $progname:2315: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_shl_load=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_shl_load=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" +else + echo "$ac_t""no" 1>&6 +echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 +echo "$progname:2333: checking for shl_load in -ldld" >&5 +ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-ldld $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" +else + echo "$ac_t""no" 1>&6 +fi + + +fi + + +fi + + +fi + + +fi + +fi + + if test "x$lt_cv_dlopen" != xno; then + enable_dlopen=yes + fi + + case "$lt_cv_dlopen" in + dlopen) +for ac_hdr in dlfcn.h; do +ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` +echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 +echo "$progname:2395: checking for $ac_hdr" >&5 +if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +int fnord = 0; +EOF +ac_try="$ac_compile conftest.$ac_ext >/dev/null 2>conftest.out" +{ (eval echo $progname:2405: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` +if test -z "$ac_err"; then + rm -rf conftest* + eval "ac_cv_header_$ac_safe=yes" +else + echo "$ac_err" >&5 + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_header_$ac_safe=no" +fi +rm -f conftest* +fi +if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi +done + + if test "x$ac_cv_header_dlfcn_h" = xyes; then + CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" + fi + eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" + LIBS="$lt_cv_dlopen_libs $LIBS" + + echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2433: checking whether a program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2487: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self" 1>&6 + + if test "$lt_cv_dlopen_self" = yes; then + LDFLAGS="$LDFLAGS $link_static_flag" + echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 +echo "$progname:2506: checking whether a statically linked program can dlopen itself" >&5 +if test "${lt_cv_dlopen_self_static+set}" = set; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + if test "$cross_compiling" = yes; then + lt_cv_dlopen_self_static=cross + else + cat > conftest.c < +#endif + +#include + +#ifdef RTLD_GLOBAL +# define LTDL_GLOBAL RTLD_GLOBAL +#else +# ifdef DL_GLOBAL +# define LTDL_GLOBAL DL_GLOBAL +# else +# define LTDL_GLOBAL 0 +# endif +#endif + +/* We may have to define LTDL_LAZY_OR_NOW in the command line if we + find out it does not work in some platform. */ +#ifndef LTDL_LAZY_OR_NOW +# ifdef RTLD_LAZY +# define LTDL_LAZY_OR_NOW RTLD_LAZY +# else +# ifdef DL_LAZY +# define LTDL_LAZY_OR_NOW DL_LAZY +# else +# ifdef RTLD_NOW +# define LTDL_LAZY_OR_NOW RTLD_NOW +# else +# ifdef DL_NOW +# define LTDL_LAZY_OR_NOW DL_NOW +# else +# define LTDL_LAZY_OR_NOW 0 +# endif +# endif +# endif +# endif +#endif + +fnord() { int i=42;} +main() { void *self, *ptr1, *ptr2; self=dlopen(0,LTDL_GLOBAL|LTDL_LAZY_OR_NOW); + if(self) { ptr1=dlsym(self,"fnord"); ptr2=dlsym(self,"_fnord"); + if(ptr1 || ptr2) { dlclose(self); exit(0); } } exit(1); } + +EOF +if { (eval echo $progname:2560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest && (./conftest; exit) 2>/dev/null +then + lt_cv_dlopen_self_static=yes +else + echo "$progname: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + lt_cv_dlopen_self_static=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$lt_cv_dlopen_self_static" 1>&6 +fi + ;; + esac + + case "$lt_cv_dlopen_self" in + yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; + *) enable_dlopen_self=unknown ;; + esac + + case "$lt_cv_dlopen_self_static" in + yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; + *) enable_dlopen_self_static=unknown ;; + esac +fi + +# Copy echo and quote the copy, instead of the original, because it is +# used later. +ltecho="$echo" +if test "X$ltecho" = "X$CONFIG_SHELL $0 --fallback-echo"; then + ltecho="$CONFIG_SHELL \$0 --fallback-echo" +fi +LTSHELL="$SHELL" + +LTCONFIG_VERSION="$VERSION" + +# Only quote variables if we're using ltmain.sh. +case "$ltmain" in +*.sh) + # Now quote all the things that may contain metacharacters. + for var in ltecho old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS \ + AR CC LD LN_S NM LTSHELL LTCONFIG_VERSION \ + reload_flag reload_cmds wl \ + pic_flag link_static_flag no_builtin_flag export_dynamic_flag_spec \ + thread_safe_flag_spec whole_archive_flag_spec libname_spec \ + library_names_spec soname_spec \ + RANLIB old_archive_cmds old_archive_from_new_cmds old_postinstall_cmds \ + old_postuninstall_cmds archive_cmds archive_expsym_cmds postinstall_cmds postuninstall_cmds \ + file_magic_cmd export_symbols_cmds deplibs_check_method allow_undefined_flag no_undefined_flag \ + finish_cmds finish_eval global_symbol_pipe global_symbol_to_cdecl \ + hardcode_libdir_flag_spec hardcode_libdir_separator \ + sys_lib_search_path_spec sys_lib_dlsearch_path_spec \ + compiler_c_o compiler_o_lo need_locks exclude_expsyms include_expsyms; do + + case "$var" in + reload_cmds | old_archive_cmds | old_archive_from_new_cmds | \ + old_postinstall_cmds | old_postuninstall_cmds | \ + export_symbols_cmds | archive_cmds | archive_expsym_cmds | \ + postinstall_cmds | postuninstall_cmds | \ + finish_cmds | sys_lib_search_path_spec | sys_lib_dlsearch_path_spec) + # Double-quote double-evaled strings. + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$double_quote_subst\" -e \"\$sed_quote_subst\" -e \"\$delay_variable_subst\"\`\\\"" + ;; + *) + eval "$var=\\\"\`\$echo \"X\$$var\" | \$Xsed -e \"\$sed_quote_subst\"\`\\\"" + ;; + esac + done + + case "$ltecho" in + *'\$0 --fallback-echo"') + ltecho=`$echo "X$ltecho" | $Xsed -e 's/\\\\\\\$0 --fallback-echo"$/$0 --fallback-echo"/'` + ;; + esac + + trap "$rm \"$ofile\"; exit 1" 1 2 15 + echo "creating $ofile" + $rm "$ofile" + cat < "$ofile" +#! $SHELL + +# `$echo "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Sed that helps us avoid accidentally triggering echo(1) options like -n. +Xsed="sed -e s/^X//" + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test "\${CDPATH+set}" = set; then CDPATH=; export CDPATH; fi + +### BEGIN LIBTOOL CONFIG +EOF + cfgfile="$ofile" + ;; + +*) + # Double-quote the variables that need it (for aesthetics). + for var in old_CC old_CFLAGS old_CPPFLAGS \ + old_LD old_LDFLAGS old_LIBS \ + old_NM old_RANLIB old_LN_S old_DLLTOOL old_OBJDUMP old_AS; do + eval "$var=\\\"\$var\\\"" + done + + # Just create a config file. + cfgfile="$ofile.cfg" + trap "$rm \"$cfgfile\"; exit 1" 1 2 15 + echo "creating $cfgfile" + $rm "$cfgfile" + cat < "$cfgfile" +# `$echo "$cfgfile" | sed 's%^.*/%%'` - Libtool configuration file. +# Generated automatically by $PROGRAM (GNU $PACKAGE $VERSION$TIMESTAMP) +EOF + ;; +esac + +cat <> "$cfgfile" +# Libtool was configured as follows, on host `(hostname || uname -n) 2>/dev/null | sed 1q`: +# +# CC=$old_CC CFLAGS=$old_CFLAGS CPPFLAGS=$old_CPPFLAGS \\ +# LD=$old_LD LDFLAGS=$old_LDFLAGS LIBS=$old_LIBS \\ +# NM=$old_NM RANLIB=$old_RANLIB LN_S=$old_LN_S \\ +# DLLTOOL=$old_DLLTOOL OBJDUMP=$old_OBJDUMP AS=$old_AS \\ +# $0$ltconfig_args +# +# Compiler and other test output produced by $progname, useful for +# debugging $progname, is in ./config.log if it exists. + +# The version of $progname that generated this script. +LTCONFIG_VERSION=$LTCONFIG_VERSION + +# Shell to use when invoking shell scripts. +SHELL=$LTSHELL + +# Whether or not to build shared libraries. +build_libtool_libs=$enable_shared + +# Whether or not to build static libraries. +build_old_libs=$enable_static + +# Whether or not to optimize for fast installation. +fast_install=$enable_fast_install + +# The host system. +host_alias=$host_alias +host=$host + +# An echo program that does not interpret backslashes. +echo=$ltecho + +# The archiver. +AR=$AR + +# The default C compiler. +CC=$CC + +# The linker used to build libraries. +LD=$LD + +# Whether we need hard or soft links. +LN_S=$LN_S + +# A BSD-compatible nm program. +NM=$NM + +# Used on cygwin: DLL creation program. +DLLTOOL="$DLLTOOL" + +# Used on cygwin: object dumper. +OBJDUMP="$OBJDUMP" + +# Used on cygwin: assembler. +AS="$AS" + +# The name of the directory that contains temporary libtool files. +objdir=$objdir + +# How to create reloadable object files. +reload_flag=$reload_flag +reload_cmds=$reload_cmds + +# How to pass a linker flag through the compiler. +wl=$wl + +# Object file suffix (normally "o"). +objext="$objext" + +# Old archive suffix (normally "a"). +libext="$libext" + +# Executable file suffix (normally ""). +exeext="$exeext" + +# Additional compiler flags for building library objects. +pic_flag=$pic_flag + +# Does compiler simultaneously support -c and -o options? +compiler_c_o=$compiler_c_o + +# Can we write directly to a .lo ? +compiler_o_lo=$compiler_o_lo + +# Must we lock files when doing compilation ? +need_locks=$need_locks + +# Do we need the lib prefix for modules? +need_lib_prefix=$need_lib_prefix + +# Do we need a version for libraries? +need_version=$need_version + +# Whether dlopen is supported. +dlopen=$enable_dlopen + +# Whether dlopen of programs is supported. +dlopen_self=$enable_dlopen_self + +# Whether dlopen of statically linked programs is supported. +dlopen_self_static=$enable_dlopen_self_static + +# Compiler flag to prevent dynamic linking. +link_static_flag=$link_static_flag + +# Compiler flag to turn off builtin functions. +no_builtin_flag=$no_builtin_flag + +# Compiler flag to allow reflexive dlopens. +export_dynamic_flag_spec=$export_dynamic_flag_spec + +# Compiler flag to generate shared objects directly from archives. +whole_archive_flag_spec=$whole_archive_flag_spec + +# Compiler flag to generate thread-safe objects. +thread_safe_flag_spec=$thread_safe_flag_spec + +# Library versioning type. +version_type=$version_type + +# Format of library name prefix. +libname_spec=$libname_spec + +# List of archive names. First name is the real one, the rest are links. +# The last name is the one that the linker finds with -lNAME. +library_names_spec=$library_names_spec + +# The coded name of the library, if different from the real name. +soname_spec=$soname_spec + +# Commands used to build and install an old-style archive. +RANLIB=$RANLIB +old_archive_cmds=$old_archive_cmds +old_postinstall_cmds=$old_postinstall_cmds +old_postuninstall_cmds=$old_postuninstall_cmds + +# Create an old-style archive from a shared archive. +old_archive_from_new_cmds=$old_archive_from_new_cmds + +# Commands used to build and install a shared archive. +archive_cmds=$archive_cmds +archive_expsym_cmds=$archive_expsym_cmds +postinstall_cmds=$postinstall_cmds +postuninstall_cmds=$postuninstall_cmds + +# Method to check whether dependent libraries are shared objects. +deplibs_check_method=$deplibs_check_method + +# Command to use when deplibs_check_method == file_magic. +file_magic_cmd=$file_magic_cmd + +# Flag that allows shared libraries with undefined symbols to be built. +allow_undefined_flag=$allow_undefined_flag + +# Flag that forces no undefined symbols. +no_undefined_flag=$no_undefined_flag + +# Commands used to finish a libtool library installation in a directory. +finish_cmds=$finish_cmds + +# Same as above, but a single script fragment to be evaled but not shown. +finish_eval=$finish_eval + +# Take the output of nm and produce a listing of raw symbols and C names. +global_symbol_pipe=$global_symbol_pipe + +# Transform the output of nm in a proper C declaration +global_symbol_to_cdecl=$global_symbol_to_cdecl + +# This is the shared library runtime path variable. +runpath_var=$runpath_var + +# This is the shared library path variable. +shlibpath_var=$shlibpath_var + +# Is shlibpath searched before the hard-coded library search path? +shlibpath_overrides_runpath=$shlibpath_overrides_runpath + +# How to hardcode a shared library path into an executable. +hardcode_action=$hardcode_action + +# Flag to hardcode \$libdir into a binary during linking. +# This must work even if \$libdir does not exist. +hardcode_libdir_flag_spec=$hardcode_libdir_flag_spec + +# Whether we need a single -rpath flag with a separated argument. +hardcode_libdir_separator=$hardcode_libdir_separator + +# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the +# resulting binary. +hardcode_direct=$hardcode_direct + +# Set to yes if using the -LDIR flag during linking hardcodes DIR into the +# resulting binary. +hardcode_minus_L=$hardcode_minus_L + +# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into +# the resulting binary. +hardcode_shlibpath_var=$hardcode_shlibpath_var + +# Compile-time system search path for libraries +sys_lib_search_path_spec=$sys_lib_search_path_spec + +# Run-time system search path for libraries +sys_lib_dlsearch_path_spec=$sys_lib_dlsearch_path_spec + +# Fix the shell variable \$srcfile for the compiler. +fix_srcfile_path="$fix_srcfile_path" + +# Set to yes if exported symbols are required. +always_export_symbols=$always_export_symbols + +# The commands to list exported symbols. +export_symbols_cmds=$export_symbols_cmds + +# Symbols that should not be listed in the preloaded symbols. +exclude_expsyms=$exclude_expsyms + +# Symbols that must always be exported. +include_expsyms=$include_expsyms + +EOF + +case "$ltmain" in +*.sh) + echo '### END LIBTOOL CONFIG' >> "$ofile" + echo >> "$ofile" + case "$host_os" in + aix3*) + cat <<\EOF >> "$ofile" + +# AIX sometimes has problems with the GCC collect2 program. For some +# reason, if we set the COLLECT_NAMES environment variable, the problems +# vanish in a puff of smoke. +if test "${COLLECT_NAMES+set}" != set; then + COLLECT_NAMES= + export COLLECT_NAMES +fi +EOF + ;; + esac + + # Append the ltmain.sh script. + sed '$q' "$ltmain" >> "$ofile" || (rm -f "$ofile"; exit 1) + + chmod +x "$ofile" + ;; + +*) + # Compile the libtool program. + echo "FIXME: would compile $ltmain" + ;; +esac + +test -n "$cache_file" || exit 0 + +# AC_CACHE_SAVE +trap '' 1 2 15 +cat > confcache <<\EOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs. It is not useful on other systems. +# If it contains results you don't want to keep, you may remove or edit it. +# +# By default, configure uses ./config.cache as the cache file, +# creating it if it does not exist already. You can give configure +# the --cache-file=FILE option to use a different cache file; that is +# what configure does when it calls configure scripts in +# subdirectories, so they share the cache. +# Giving --cache-file=/dev/null disables caching, for debugging configure. +# config.status only pays attention to the cache file if you give it the +# --recheck option to rerun configure. +# +EOF +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, don't put newlines in cache variables' values. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +(set) 2>&1 | + case `(ac_space=' '; set | grep ac_space) 2>&1` in + *ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote substitution + # turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + -e "s/'/'\\\\''/g" \ + -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p" + ;; + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p' + ;; + esac >> confcache +if cmp -s $cache_file confcache; then + : +else + if test -w $cache_file; then + echo "updating cache $cache_file" + cat confcache > $cache_file + else + echo "not updating unwritable cache $cache_file" + fi +fi +rm -f confcache + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/ltmain.sh b/ltmain.sh new file mode 100644 index 000000000..ae10cad02 --- /dev/null +++ b/ltmain.sh @@ -0,0 +1,3975 @@ +# ltmain.sh - Provide generalized library-building support services. +# NOTE: Changing this file will not affect anything until you rerun ltconfig. +# +# Copyright (C) 1996-1999 Free Software Foundation, Inc. +# Originally by Gordon Matzigkeit , 1996 +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Check that we have a working $echo. +if test "X$1" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift +elif test "X$1" = X--fallback-echo; then + # Avoid inline document here, it may be left over + : +elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then + # Yippee, $echo works! + : +else + # Restart under the correct shell, and then maybe $echo will work. + exec $SHELL "$0" --no-reexec ${1+"$@"} +fi + +if test "X$1" = X--fallback-echo; then + # used as fallback echo + shift + cat <&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then + echo "$modename: not configured to build any kind of library" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 +fi + +# Global variables. +mode=$default_mode +nonopt= +prev= +prevopt= +run= +show="$echo" +show_help= +execute_dlfiles= +lo2o="s/\\.lo\$/.${objext}/" +o2lo="s/\\.${objext}\$/.lo/" + +# Parse our command line options once, thoroughly. +while test $# -gt 0 +do + arg="$1" + shift + + case "$arg" in + -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;; + *) optarg= ;; + esac + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + execute_dlfiles) + eval "$prev=\"\$$prev \$arg\"" + ;; + *) + eval "$prev=\$arg" + ;; + esac + + prev= + prevopt= + continue + fi + + # Have we seen a non-optional argument yet? + case "$arg" in + --help) + show_help=yes + ;; + + --version) + echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP" + exit 0 + ;; + + --config) + sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0 + exit 0 + ;; + + --debug) + echo "$progname: enabling shell trace mode" + set -x + ;; + + --dry-run | -n) + run=: + ;; + + --features) + echo "host: $host" + if test "$build_libtool_libs" = yes; then + echo "enable shared libraries" + else + echo "disable shared libraries" + fi + if test "$build_old_libs" = yes; then + echo "enable static libraries" + else + echo "disable static libraries" + fi + exit 0 + ;; + + --finish) mode="finish" ;; + + --mode) prevopt="--mode" prev=mode ;; + --mode=*) mode="$optarg" ;; + + --quiet | --silent) + show=: + ;; + + -dlopen) + prevopt="-dlopen" + prev=execute_dlfiles + ;; + + -*) + $echo "$modename: unrecognized option \`$arg'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *) + nonopt="$arg" + break + ;; + esac +done + +if test -n "$prevopt"; then + $echo "$modename: option \`$prevopt' requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 +fi + +if test -z "$show_help"; then + + # Infer the operation mode. + if test -z "$mode"; then + case "$nonopt" in + *cc | *++ | gcc* | *-gcc*) + mode=link + for arg + do + case "$arg" in + -c) + mode=compile + break + ;; + esac + done + ;; + *db | *dbx | *strace | *truss) + mode=execute + ;; + *install*|cp|mv) + mode=install + ;; + *rm) + mode=uninstall + ;; + *) + # If we have no mode, but dlfiles were specified, then do execute mode. + test -n "$execute_dlfiles" && mode=execute + + # Just use the default operation mode. + if test -z "$mode"; then + if test -n "$nonopt"; then + $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2 + else + $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2 + fi + fi + ;; + esac + fi + + # Only execute mode is allowed to have -dlopen flags. + if test -n "$execute_dlfiles" && test "$mode" != execute; then + $echo "$modename: unrecognized option \`-dlopen'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Change the help message to a mode-specific one. + generic_help="$help" + help="Try \`$modename --help --mode=$mode' for more information." + + # These modes are in order of execution frequency so that they run quickly. + case "$mode" in + # libtool compile mode + compile) + modename="$modename: compile" + # Get the compilation command and the source file. + base_compile= + lastarg= + srcfile="$nonopt" + suppress_output= + + user_target=no + for arg + do + # Accept any command-line options. + case "$arg" in + -o) + if test "$user_target" != "no"; then + $echo "$modename: you cannot specify \`-o' more than once" 1>&2 + exit 1 + fi + user_target=next + ;; + + -static) + build_old_libs=yes + continue + ;; + esac + + case "$user_target" in + next) + # The next one is the -o target name + user_target=yes + continue + ;; + yes) + # We got the output file + user_target=set + libobj="$arg" + continue + ;; + esac + + # Accept the current argument as the source file. + lastarg="$srcfile" + srcfile="$arg" + + # Aesthetically quote the previous argument. + + # Backslashify any backslashes, double quotes, and dollar signs. + # These are the only characters that are still specially + # interpreted inside of double-quoted scrings. + lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"` + + # Double-quote args containing other shell metacharacters. + # Many Bourne shells cannot handle close brackets correctly in scan + # sets, so we specify it separately. + case "$lastarg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + lastarg="\"$lastarg\"" + ;; + esac + + # Add the previous argument to base_compile. + if test -z "$base_compile"; then + base_compile="$lastarg" + else + base_compile="$base_compile $lastarg" + fi + done + + case "$user_target" in + set) + ;; + no) + # Get the name of the library object. + libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'` + ;; + *) + $echo "$modename: you must specify a target with \`-o'" 1>&2 + exit 1 + ;; + esac + + # Recognize several different file suffixes. + # If the user specifies -o file.o, it is replaced with file.lo + xform='[cCFSfmso]' + case "$libobj" in + *.ada) xform=ada ;; + *.adb) xform=adb ;; + *.ads) xform=ads ;; + *.asm) xform=asm ;; + *.c++) xform=c++ ;; + *.cc) xform=cc ;; + *.cpp) xform=cpp ;; + *.cxx) xform=cxx ;; + *.f90) xform=f90 ;; + *.for) xform=for ;; + esac + + libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"` + + case "$libobj" in + *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;; + *) + $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2 + exit 1 + ;; + esac + + if test -z "$base_compile"; then + $echo "$modename: you must specify a compilation command" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Delete any leftover library objects. + if test "$build_old_libs" = yes; then + removelist="$obj $libobj" + else + removelist="$libobj" + fi + + $run $rm $removelist + trap "$run $rm $removelist; exit 1" 1 2 15 + + # Calculate the filename of the output object if compiler does + # not support -o with -c + if test "$compiler_c_o" = no; then + output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext} + lockfile="$output_obj.lock" + removelist="$removelist $output_obj $lockfile" + trap "$run $rm $removelist; exit 1" 1 2 15 + else + need_locks=no + lockfile= + fi + + # Lock this critical section if it is needed + # We use this script file to make the link, it avoids creating a new file + if test "$need_locks" = yes; then + until ln "$0" "$lockfile" 2>/dev/null; do + $show "Waiting for $lockfile to be removed" + sleep 2 + done + elif test "$need_locks" = warn; then + if test -f "$lockfile"; then + echo "\ +*** ERROR, $lockfile exists and contains: +`cat $lockfile 2>/dev/null` + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + echo $srcfile > "$lockfile" + fi + + if test -n "$fix_srcfile_path"; then + eval srcfile=\"$fix_srcfile_path\" + fi + + # Only build a PIC object if we are building libtool libraries. + if test "$build_libtool_libs" = yes; then + # Without this assignment, base_compile gets emptied. + fbsd_hideous_sh_bug=$base_compile + + # All platforms use -DPIC, to notify preprocessed assembler code. + command="$base_compile $pic_flag -DPIC $srcfile" + if test "$build_old_libs" = yes; then + lo_libobj="$libobj" + dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$libobj"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'` + + if test -d "$dir"; then + $show "$rm $libobj" + $run $rm $libobj + else + $show "$mkdir $dir" + $run $mkdir $dir + status=$? + if test $status -ne 0 && test ! -d $dir; then + exit $status + fi + fi + fi + if test "$compiler_o_lo" = yes; then + output_obj="$libobj" + command="$command -o $output_obj" + elif test "$compiler_c_o" = yes; then + output_obj="$obj" + command="$command -o $output_obj" + fi + + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + test -n "$output_obj" && $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed, then go on to compile the next one + if test x"$output_obj" != x"$libobj"; then + $show "$mv $output_obj $libobj" + if $run $mv $output_obj $libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # If we have no pic_flag, then copy the object into place and finish. + if test -z "$pic_flag" && test "$build_old_libs" = yes; then + # Rename the .lo from within objdir to obj + if test -f $obj; then + $show $rm $obj + $run $rm $obj + fi + + $show "$mv $libobj $obj" + if $run $mv $libobj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + + # Now arrange that obj and lo_libobj become the same file + $show "$LN_S $obj $lo_libobj" + if $run $LN_S $obj $lo_libobj; then + exit 0 + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Allow error messages only from the first compilation. + suppress_output=' >/dev/null 2>&1' + fi + + # Only build a position-dependent object if we build old libraries. + if test "$build_old_libs" = yes; then + command="$base_compile $srcfile" + if test "$compiler_c_o" = yes; then + command="$command -o $obj" + output_obj="$obj" + fi + + # Suppress compiler output if we already did a PIC compilation. + command="$command$suppress_output" + $run $rm "$output_obj" + $show "$command" + if $run eval "$command"; then : + else + $run $rm $removelist + exit 1 + fi + + if test "$need_locks" = warn && + test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then + echo "\ +*** ERROR, $lockfile contains: +`cat $lockfile 2>/dev/null` + +but it should contain: +$srcfile + +This indicates that another process is trying to use the same +temporary object file, and libtool could not work around it because +your compiler does not support \`-c' and \`-o' together. If you +repeat this compilation, it may succeed, by chance, but you had better +avoid parallel builds (make -j) in this platform, or get a better +compiler." + + $run $rm $removelist + exit 1 + fi + + # Just move the object if needed + if test x"$output_obj" != x"$obj"; then + $show "$mv $output_obj $obj" + if $run $mv $output_obj $obj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + + # Create an invalid libtool object if no PIC, so that we do not + # accidentally link it into a program. + if test "$build_libtool_libs" != yes; then + $show "echo timestamp > $libobj" + $run eval "echo timestamp > \$libobj" || exit $? + else + # Move the .lo from within objdir + $show "$mv $libobj $lo_libobj" + if $run $mv $libobj $lo_libobj; then : + else + error=$? + $run $rm $removelist + exit $error + fi + fi + fi + + # Unlock the critical section if it was locked + if test "$need_locks" != no; then + $rm "$lockfile" + fi + + exit 0 + ;; + + # libtool link mode + link) + modename="$modename: link" + C_compiler="$CC" # save it, to compile generated C sources + CC="$nonopt" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + # It is impossible to link a dll without this setting, and + # we shouldn't force the makefile maintainer to figure out + # which system we are compiling for in order to pass an extra + # flag for every libtool invokation. + # allow_undefined=no + + # FIXME: Unfortunately, there are problems with the above when trying + # to make a dll which has undefined symbols, in which case not + # even a static library is built. For now, we need to specify + # -no-undefined on the libtool link line when we can be certain + # that all symbols are satisfied, otherwise we get a static library. + allow_undefined=yes + + # This is a source program that is used to create dlls on Windows + # Don't remove nor modify the starting and closing comments +# /* ltdll.c starts here */ +# #define WIN32_LEAN_AND_MEAN +# #include +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #ifndef __CYGWIN__ +# # ifdef __CYGWIN32__ +# # define __CYGWIN__ __CYGWIN32__ +# # endif +# #endif +# +# #ifdef __cplusplus +# extern "C" { +# #endif +# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved); +# #ifdef __cplusplus +# } +# #endif +# +# #ifdef __CYGWIN__ +# #include +# DECLARE_CYGWIN_DLL( DllMain ); +# #endif +# HINSTANCE __hDllInstance_base; +# +# BOOL APIENTRY +# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved) +# { +# __hDllInstance_base = hInst; +# return TRUE; +# } +# /* ltdll.c ends here */ + # This is a source program that is used to create import libraries + # on Windows for dlls which lack them. Don't remove nor modify the + # starting and closing comments +# /* impgen.c starts here */ +# /* Copyright (C) 1999 Free Software Foundation, Inc. +# +# This file is part of GNU libtool. +# +# 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# */ +# +# #include /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* for strdup() */ +# +# static unsigned int +# pe_get16 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[2]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 2); +# return b[0] + (b[1]<<8); +# } +# +# static unsigned int +# pe_get32 (fd, offset) +# int fd; +# int offset; +# { +# unsigned char b[4]; +# lseek (fd, offset, SEEK_SET); +# read (fd, b, 4); +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# static unsigned int +# pe_as32 (ptr) +# void *ptr; +# { +# unsigned char *b = ptr; +# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24); +# } +# +# int +# main (argc, argv) +# int argc; +# char *argv[]; +# { +# int dll; +# unsigned long pe_header_offset, opthdr_ofs, num_entries, i; +# unsigned long export_rva, export_size, nsections, secptr, expptr; +# unsigned long name_rvas, nexp; +# unsigned char *expdata, *erva; +# char *filename, *dll_name; +# +# filename = argv[1]; +# +# dll = open(filename, O_RDONLY|O_BINARY); +# if (!dll) +# return 1; +# +# dll_name = filename; +# +# for (i=0; filename[i]; i++) +# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':') +# dll_name = filename + i +1; +# +# pe_header_offset = pe_get32 (dll, 0x3c); +# opthdr_ofs = pe_header_offset + 4 + 20; +# num_entries = pe_get32 (dll, opthdr_ofs + 92); +# +# if (num_entries < 1) /* no exports */ +# return 1; +# +# export_rva = pe_get32 (dll, opthdr_ofs + 96); +# export_size = pe_get32 (dll, opthdr_ofs + 100); +# nsections = pe_get16 (dll, pe_header_offset + 4 +2); +# secptr = (pe_header_offset + 4 + 20 + +# pe_get16 (dll, pe_header_offset + 4 + 16)); +# +# expptr = 0; +# for (i = 0; i < nsections; i++) +# { +# char sname[8]; +# unsigned long secptr1 = secptr + 40 * i; +# unsigned long vaddr = pe_get32 (dll, secptr1 + 12); +# unsigned long vsize = pe_get32 (dll, secptr1 + 16); +# unsigned long fptr = pe_get32 (dll, secptr1 + 20); +# lseek(dll, secptr1, SEEK_SET); +# read(dll, sname, 8); +# if (vaddr <= export_rva && vaddr+vsize > export_rva) +# { +# expptr = fptr + (export_rva - vaddr); +# if (export_rva + export_size > vaddr + vsize) +# export_size = vsize - (export_rva - vaddr); +# break; +# } +# } +# +# expdata = (unsigned char*)malloc(export_size); +# lseek (dll, expptr, SEEK_SET); +# read (dll, expdata, export_size); +# erva = expdata - export_rva; +# +# nexp = pe_as32 (expdata+24); +# name_rvas = pe_as32 (expdata+32); +# +# printf ("EXPORTS\n"); +# for (i = 0; i&2 + fi + if test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + else + if test -z "$pic_flag" && test -n "$link_static_flag"; then + dlopen_self=$dlopen_self_static + fi + fi + build_libtool_libs=no + build_old_libs=yes + prefer_static_libs=yes + break + ;; + esac + done + + # See if our shared archives depend on static archives. + test -n "$old_archive_from_new_cmds" && build_old_libs=yes + + # Go through the arguments, transforming them on the way. + while test $# -gt 0; do + arg="$1" + shift + + # If the previous option needs an argument, assign it. + if test -n "$prev"; then + case "$prev" in + output) + compile_command="$compile_command @OUTPUT@" + finalize_command="$finalize_command @OUTPUT@" + ;; + esac + + case "$prev" in + dlfiles|dlprefiles) + if test "$preload" = no; then + # Add the symbol object into the linking commands. + compile_command="$compile_command @SYMFILE@" + finalize_command="$finalize_command @SYMFILE@" + preload=yes + fi + case "$arg" in + *.la | *.lo) ;; # We handle these cases below. + force) + if test "$dlself" = no; then + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + self) + if test "$prev" = dlprefiles; then + dlself=yes + elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then + dlself=yes + else + dlself=needless + export_dynamic=yes + fi + prev= + continue + ;; + *) + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + else + dlprefiles="$dlprefiles $arg" + fi + prev= + ;; + esac + ;; + expsyms) + export_symbols="$arg" + if test ! -f "$arg"; then + $echo "$modename: symbol file \`$arg' does not exist" + exit 1 + fi + prev= + continue + ;; + expsyms_regex) + export_symbols_regex="$arg" + prev= + continue + ;; + release) + release="-$arg" + prev= + continue + ;; + rpath | xrpath) + # We need an absolute path. + case "$arg" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + if test "$prev" = rpath; then + case "$rpath " in + *" $arg "*) ;; + *) rpath="$rpath $arg" ;; + esac + else + case "$xrpath " in + *" $arg "*) ;; + *) xrpath="$xrpath $arg" ;; + esac + fi + prev= + continue + ;; + *) + eval "$prev=\"\$arg\"" + prev= + continue + ;; + esac + fi + + prevarg="$arg" + + case "$arg" in + -all-static) + if test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -allow-undefined) + # FIXME: remove this flag sometime in the future. + $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2 + continue + ;; + + -avoid-version) + avoid_version=yes + continue + ;; + + -dlopen) + prev=dlfiles + continue + ;; + + -dlpreopen) + prev=dlprefiles + continue + ;; + + -export-dynamic) + export_dynamic=yes + continue + ;; + + -export-symbols | -export-symbols-regex) + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: not more than one -exported-symbols argument allowed" + exit 1 + fi + if test "X$arg" = "X-export-symbols"; then + prev=expsyms + else + prev=expsyms_regex + fi + continue + ;; + + -L*) + dir=`$echo "X$arg" | $Xsed -e 's/^-L//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + dir="$absdir" + ;; + esac + case " $deplibs " in + *" $arg "*) ;; + *) deplibs="$deplibs $arg";; + esac + case " $lib_search_path " in + *" $dir "*) ;; + *) lib_search_path="$lib_search_path $dir";; + esac + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + case ":$dllsearchpath:" in + ::) dllsearchpath="$dllsearchdir";; + *":$dllsearchdir:"*) ;; + *) dllsearchpath="$dllsearchpath:$dllsearchdir";; + esac + ;; + esac + ;; + + -l*) + if test "$arg" = "-lc"; then + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # These systems don't actually have c library (as such) + continue + ;; + esac + elif test "$arg" = "-lm"; then + case "$host" in + *-*-cygwin* | *-*-beos*) + # These systems don't actually have math library (as such) + continue + ;; + esac + fi + deplibs="$deplibs $arg" + ;; + + -module) + module=yes + continue + ;; + + -no-undefined) + allow_undefined=no + continue + ;; + + -o) prev=output ;; + + -release) + prev=release + continue + ;; + + -rpath) + prev=rpath + continue + ;; + + -R) + prev=xrpath + continue + ;; + + -R*) + dir=`$echo "X$arg" | $Xsed -e 's/^-R//'` + # We need an absolute path. + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + $echo "$modename: only absolute run-paths are allowed" 1>&2 + exit 1 + ;; + esac + case "$xrpath " in + *" $dir "*) ;; + *) xrpath="$xrpath $dir" ;; + esac + continue + ;; + + -static) + # If we have no pic_flag, then this is the same as -all-static. + if test -z "$pic_flag" && test -n "$link_static_flag"; then + compile_command="$compile_command $link_static_flag" + finalize_command="$finalize_command $link_static_flag" + fi + continue + ;; + + -thread-safe) + thread_safe=yes + continue + ;; + + -version-info) + prev=vinfo + continue + ;; + + # Some other compiler flag. + -* | +*) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + + *.o | *.obj | *.a | *.lib) + # A standard object. + objs="$objs $arg" + ;; + + *.lo) + # A library object. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then + prev= + continue + else + # If libtool objects are unsupported, then we need to preload. + prev=dlprefiles + fi + fi + + if test "$prev" = dlprefiles; then + # Preload the old-style object. + dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"` + prev= + fi + libobjs="$libobjs $arg" + ;; + + *.la) + # A libtool-controlled library. + + dlname= + libdir= + library_names= + old_library= + + # Check to see that this really is a libtool archive. + if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2 + exit 1 + fi + + # If the library was installed with an old release of libtool, + # it will not redefine variable installed. + installed=yes + + # Read the .la file + # If there is no directory component, then add one. + case "$arg" in + */* | *\\*) . $arg ;; + *) . ./$arg ;; + esac + + # Get the name of the library we link against. + linklib= + for l in $old_library $library_names; do + linklib="$l" + done + + if test -z "$linklib"; then + $echo "$modename: cannot find name of link library for \`$arg'" 1>&2 + exit 1 + fi + + # Find the relevant object directory and library name. + name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'` + + if test "X$installed" = Xyes; then + dir="$libdir" + else + dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'` + if test "X$dir" = "X$arg"; then + dir="$objdir" + else + dir="$dir/$objdir" + fi + fi + + if test -n "$dependency_libs"; then + # Extract -R and -L from dependency_libs + temp_deplibs= + for deplib in $dependency_libs; do + case "$deplib" in + -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'` + case " $rpath $xrpath " in + *" $temp_xrpath "*) ;; + *) xrpath="$xrpath $temp_xrpath";; + esac;; + -L*) case "$compile_command $temp_deplibs " in + *" $deplib "*) ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'` + case " $lib_search_path " in + *" $temp_dir "*) ;; + *) lib_search_path="$lib_search_path $temp_dir";; + esac + ;; + *) temp_deplibs="$temp_deplibs $deplib";; + esac + done + dependency_libs="$temp_deplibs" + fi + + if test -z "$libdir"; then + # It is a libtool convenience library, so add in its objects. + convenience="$convenience $dir/$old_library" + old_convenience="$old_convenience $dir/$old_library" + deplibs="$deplibs$dependency_libs" + compile_command="$compile_command $dir/$old_library$dependency_libs" + finalize_command="$finalize_command $dir/$old_library$dependency_libs" + continue + fi + + # This library was specified with -dlopen. + if test "$prev" = dlfiles; then + dlfiles="$dlfiles $arg" + if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then + # If there is no dlname, no dlopen support or we're linking statically, + # we need to preload. + prev=dlprefiles + else + # We should not create a dependency on this library, but we + # may need any libraries it requires. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + prev= + continue + fi + fi + + # The library was specified with -dlpreopen. + if test "$prev" = dlprefiles; then + # Prefer using a static library (so that no silly _DYNAMIC symbols + # are required to link). + if test -n "$old_library"; then + dlprefiles="$dlprefiles $dir/$old_library" + else + dlprefiles="$dlprefiles $dir/$linklib" + fi + prev= + fi + + if test -n "$library_names" && + { test "$prefer_static_libs" = no || test -z "$old_library"; }; then + link_against_libtool_libs="$link_against_libtool_libs $arg" + if test -n "$shlibpath_var"; then + # Make sure the rpath contains only unique directories. + case "$temp_rpath " in + *" $dir "*) ;; + *) temp_rpath="$temp_rpath $dir" ;; + esac + fi + + # We need an absolute path. + case "$dir" in + [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;; + *) + absdir=`cd "$dir" && pwd` + if test -z "$absdir"; then + $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2 + $echo "$modename: passing it literally to the linker, although it might fail" 1>&2 + absdir="$dir" + fi + ;; + esac + + # This is the magic to use -rpath. + # Skip directories that are in the system default run-time + # search path, unless they have been requested with -R. + case " $sys_lib_dlsearch_path " in + *" $absdir "*) ;; + *) + case "$compile_rpath " in + *" $absdir "*) ;; + *) compile_rpath="$compile_rpath $absdir" + esac + ;; + esac + + case " $sys_lib_dlsearch_path " in + *" $libdir "*) ;; + *) + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" + esac + ;; + esac + + lib_linked=yes + case "$hardcode_action" in + immediate | unsupported) + if test "$hardcode_direct" = no; then + compile_command="$compile_command $dir/$linklib" + deplibs="$deplibs $dir/$linklib" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2*) + dllsearchdir=`cd "$dir" && pwd || echo "$dir"` + if test -n "$dllsearchpath"; then + dllsearchpath="$dllsearchpath:$dllsearchdir" + else + dllsearchpath="$dllsearchdir" + fi + ;; + esac + elif test "$hardcode_minus_L" = no; then + case "$host" in + *-*-sunos*) + compile_shlibpath="$compile_shlibpath$dir:" + ;; + esac + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$dir -l$name" + elif test "$hardcode_shlibpath_var" = no; then + case ":$compile_shlibpath:" in + *":$dir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$dir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + relink) + if test "$hardcode_direct" = yes; then + compile_command="$compile_command $absdir/$linklib" + deplibs="$deplibs $absdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$compile_command " in + *" -L$absdir "*) ;; + *) compile_command="$compile_command -L$absdir";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -L$absdir -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$compile_shlibpath:" in + *":$absdir:"*) ;; + *) compile_shlibpath="$compile_shlibpath$absdir:";; + esac + compile_command="$compile_command -l$name" + deplibs="$deplibs -l$name" + else + lib_linked=no + fi + ;; + + *) + lib_linked=no + ;; + esac + + if test "$lib_linked" != yes; then + $echo "$modename: configuration error: unsupported hardcode properties" + exit 1 + fi + + # Finalize command for both is simple: just hardcode it. + if test "$hardcode_direct" = yes; then + finalize_command="$finalize_command $libdir/$linklib" + elif test "$hardcode_minus_L" = yes; then + case "$finalize_command " in + *" -L$libdir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + elif test "$hardcode_shlibpath_var" = yes; then + case ":$finalize_shlibpath:" in + *":$libdir:"*) ;; + *) finalize_shlibpath="$finalize_shlibpath$libdir:";; + esac + finalize_command="$finalize_command -l$name" + else + # We cannot seem to hardcode it, guess we'll fake it. + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$libdir";; + esac + finalize_command="$finalize_command -l$name" + fi + else + # Transform directly to old archives if we don't build new libraries. + if test -n "$pic_flag" && test -z "$old_library"; then + $echo "$modename: cannot find static library for \`$arg'" 1>&2 + exit 1 + fi + + # Here we assume that one of hardcode_direct or hardcode_minus_L + # is not unsupported. This is valid on all known static and + # shared platforms. + if test "$hardcode_direct" != unsupported; then + test -n "$old_library" && linklib="$old_library" + compile_command="$compile_command $dir/$linklib" + finalize_command="$finalize_command $dir/$linklib" + else + case "$compile_command " in + *" -L$dir "*) ;; + *) compile_command="$compile_command -L$dir";; + esac + compile_command="$compile_command -l$name" + case "$finalize_command " in + *" -L$dir "*) ;; + *) finalize_command="$finalize_command -L$dir";; + esac + finalize_command="$finalize_command -l$name" + fi + fi + + # Add in any libraries that this one depends upon. + compile_command="$compile_command$dependency_libs" + finalize_command="$finalize_command$dependency_libs" + continue + ;; + + # Some other compiler argument. + *) + # Unknown arguments in both finalize_command and compile_command need + # to be aesthetically quoted because they are evaled later. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + ;; + esac + + # Now actually substitute the argument into the commands. + if test -n "$arg"; then + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + done + + if test -n "$prev"; then + $echo "$modename: the \`$prevarg' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then + eval arg=\"$export_dynamic_flag_spec\" + compile_command="$compile_command $arg" + finalize_command="$finalize_command $arg" + fi + + oldlibs= + # calculate the name of the file, without its directory + outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'` + libobjs_save="$libobjs" + + case "$output" in + "") + $echo "$modename: you must specify an output file" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + + *.a | *.lib) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into archives" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for archives" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for archives" 1>&2 + fi + + if test -n "$export_symbols" || test -n "$export_symbols_regex"; then + $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2 + fi + + # Now set the variables for building old libraries. + build_libtool_libs=no + oldlibs="$output" + ;; + + *.la) + # Make sure we only generate libraries of the form `libNAME.la'. + case "$outputname" in + lib*) + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'` + eval libname=\"$libname_spec\" + ;; + *) + if test "$module" = no; then + $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + if test "$need_lib_prefix" != no; then + # Add the "lib" prefix for modules if required + name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + eval libname=\"$libname_spec\" + else + libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'` + fi + ;; + esac + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + if test -n "$objs"; then + $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1 + exit 1 + fi + + # How the heck are we supposed to write a wrapper for a shared library? + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2 + exit 1 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2 + fi + + set dummy $rpath + if test $# -gt 2; then + $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2 + fi + install_libdir="$2" + + oldlibs= + if test -z "$rpath"; then + if test "$build_libtool_libs" = yes; then + # Building a libtool convenience library. + libext=al + oldlibs="$output_objdir/$libname.$libext $oldlibs" + build_libtool_libs=convenience + build_old_libs=yes + fi + dependency_libs="$deplibs" + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2 + fi + else + + # Parse the version information argument. + IFS="${IFS= }"; save_ifs="$IFS"; IFS=':' + set dummy $vinfo 0 0 0 + IFS="$save_ifs" + + if test -n "$8"; then + $echo "$modename: too many parameters to \`-version-info'" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + current="$2" + revision="$3" + age="$4" + + # Check that each of the things are valid numbers. + case "$current" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$revision" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + case "$age" in + 0 | [1-9] | [1-9][0-9]*) ;; + *) + $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + ;; + esac + + if test $age -gt $current; then + $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2 + $echo "$modename: \`$vinfo' is not valid version information" 1>&2 + exit 1 + fi + + # Calculate the version variables. + major= + versuffix= + verstring= + case "$version_type" in + none) ;; + + irix) + major=`expr $current - $age + 1` + versuffix="$major.$revision" + verstring="sgi$major.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$revision + while test $loop != 0; do + iface=`expr $revision - $loop` + loop=`expr $loop - 1` + verstring="sgi$major.$iface:$verstring" + done + ;; + + linux) + major=.`expr $current - $age` + versuffix="$major.$age.$revision" + ;; + + osf) + major=`expr $current - $age` + versuffix=".$current.$age.$revision" + verstring="$current.$age.$revision" + + # Add in all the interfaces that we are compatible with. + loop=$age + while test $loop != 0; do + iface=`expr $current - $loop` + loop=`expr $loop - 1` + verstring="$verstring:${iface}.0" + done + + # Make executables depend on our current version. + verstring="$verstring:${current}.0" + ;; + + sunos) + major=".$current" + versuffix=".$current.$revision" + ;; + + freebsd-aout) + major=".$current" + versuffix=".$current.$revision"; + ;; + + freebsd-elf) + major=".$current" + versuffix=".$current"; + ;; + + windows) + # Like Linux, but with '-' rather than '.', since we only + # want one extension on Windows 95. + major=`expr $current - $age` + versuffix="-$major-$age-$revision" + ;; + + *) + $echo "$modename: unknown library version type \`$version_type'" 1>&2 + echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2 + exit 1 + ;; + esac + + # Clear the version info if we defaulted, and they specified a release. + if test -z "$vinfo" && test -n "$release"; then + major= + verstring="0.0" + if test "$need_version" = no; then + versuffix= + else + versuffix=".0.0" + fi + fi + + # Remove version info from name if versioning should be avoided + if test "$avoid_version" = yes && test "$need_version" = no; then + major= + versuffix= + verstring="" + fi + + # Check to see if the archive will have undefined symbols. + if test "$allow_undefined" = yes; then + if test "$allow_undefined_flag" = unsupported; then + $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2 + build_libtool_libs=no + build_old_libs=yes + fi + else + # Don't allow undefined symbols. + allow_undefined_flag="$no_undefined_flag" + fi + + dependency_libs="$deplibs" + case "$host" in + *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*) + # these systems don't actually have a c library (as such)! + ;; + *) + # Add libc to deplibs on all other systems. + deplibs="$deplibs -lc" + ;; + esac + fi + + # Create the output directory, or remove our outputs if we need to. + if test -d $output_objdir; then + $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*" + $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.* + else + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + # Now set the variables for building old libraries. + if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then + oldlibs="$oldlibs $output_objdir/$libname.$libext" + + # Transform .lo files to .o files. + oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP` + fi + + if test "$build_libtool_libs" = yes; then + # Transform deplibs into only deplibs that can be linked in shared. + name_save=$name + libname_save=$libname + release_save=$release + versuffix_save=$versuffix + major_save=$major + # I'm not sure if I'm treating the release correctly. I think + # release should show up in the -l (ie -lgmp5) so we don't want to + # add it in twice. Is that correct? + release="" + versuffix="" + major="" + newdeplibs= + droppeddeps=no + case "$deplibs_check_method" in + pass_all) + # Don't check for shared/static. Everything works. + # This might be a little naive. We might want to check + # whether the library exists or not. But this is on + # osf3 & osf4 and I'm not really sure... Just + # implementing what was already the behaviour. + newdeplibs=$deplibs + ;; + test_compile) + # This code stresses the "libraries are programs" paradigm to its + # limits. Maybe even breaks it. We compile a program, linking it + # against the deplibs as a proxy for the library. Then we can check + # whether they linked in statically or dynamically with ldd. + $rm conftest.c + cat > conftest.c </dev/null` + for potent_lib in $potential_libs; do + # Follow soft links. + if ls -lLd "$potent_lib" 2>/dev/null \ + | grep " -> " >/dev/null; then + continue + fi + # The statement above tries to avoid entering an + # endless loop below, in case of cyclic links. + # We might still enter an endless loop, since a link + # loop can be closed while we follow links, + # but so what? + potlib="$potent_lib" + while test -h "$potlib" 2>/dev/null; do + potliblink=`ls -ld $potlib | sed 's/.* -> //'` + case "$potliblink" in + [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";; + *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";; + esac + done + if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \ + | sed 10q \ + | egrep "$file_magic_regex" > /dev/null; then + newdeplibs="$newdeplibs $a_deplib" + a_deplib="" + break 2 + fi + done + done + if test -n "$a_deplib" ; then + droppeddeps=yes + echo + echo "*** Warning: This library needs some functionality provided by $a_deplib." + echo "*** I have the capability to make that library automatically link in when" + echo "*** you link to this library. But I can only do this if you have a" + echo "*** shared version of the library, which you do not appear to have." + fi + else + # Add a -L argument. + newdeplibs="$newdeplibs $a_deplib" + fi + done # Gone through all deplibs. + ;; + none | unknown | *) + newdeplibs="" + if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \ + -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' | + grep . >/dev/null; then + echo + if test "X$deplibs_check_method" = "Xnone"; then + echo "*** Warning: inter-library dependencies are not supported in this platform." + else + echo "*** Warning: inter-library dependencies are not known to be supported." + fi + echo "*** All declared inter-library dependencies are being dropped." + droppeddeps=yes + fi + ;; + esac + versuffix=$versuffix_save + major=$major_save + release=$release_save + libname=$libname_save + name=$name_save + + if test "$droppeddeps" = yes; then + if test "$module" = yes; then + echo + echo "*** Warning: libtool could not satisfy all declared inter-library" + echo "*** dependencies of module $libname. Therefore, libtool will create" + echo "*** a static module, that should work as long as the dlopening" + echo "*** application is linked with the -dlopen flag." + if test -z "$global_symbol_pipe"; then + echo + echo "*** However, this would only work if libtool was able to extract symbol" + echo "*** lists from a program, using \`nm' or equivalent, but libtool could" + echo "*** not find such a program. So, this module is probably useless." + echo "*** \`nm' from GNU binutils and a full rebuild may help." + fi + if test "$build_old_libs" = no; then + oldlibs="$output_objdir/$libname.$libext" + build_libtool_libs=module + build_old_libs=yes + else + build_libtool_libs=no + fi + else + echo "*** The inter-library dependencies that have been dropped here will be" + echo "*** automatically added whenever a program is linked with this library" + echo "*** or is declared to -dlopen it." + fi + fi + # Done checking deplibs! + deplibs=$newdeplibs + fi + + # All the library-specific variables (install_libdir is set above). + library_names= + old_library= + dlname= + + # Test again, we may have decided not to build it any more + if test "$build_libtool_libs" = yes; then + # Get the real and link names of the library. + eval library_names=\"$library_names_spec\" + set dummy $library_names + realname="$2" + shift; shift + + if test -n "$soname_spec"; then + eval soname=\"$soname_spec\" + else + soname="$realname" + fi + + lib="$output_objdir/$realname" + for link + do + linknames="$linknames $link" + done + + # Ensure that we have .o objects for linkers which dislike .lo + # (e.g. aix) incase we are running --disable-static + for obj in $libobjs; do + oldobj=`$echo "X$obj" | $Xsed -e "$lo2o"` + if test ! -f $oldobj; then + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + # Use standard objects if they are pic + test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then + $show "generating symbol list for \`$libname.la'" + export_symbols="$output_objdir/$libname.exp" + $run $rm $export_symbols + eval cmds=\"$export_symbols_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + if test -n "$export_symbols_regex"; then + $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\"" + $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"' + $show "$mv \"${export_symbols}T\" \"$export_symbols\"" + $run eval '$mv "${export_symbols}T" "$export_symbols"' + fi + fi + fi + + if test -n "$export_symbols" && test -n "$include_expsyms"; then + $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"' + fi + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval libobjs=\"\$libobjs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then + eval flag=\"$thread_safe_flag_spec\" + linkopts="$linkopts $flag" + fi + + # Do each of the archive commands. + if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then + eval cmds=\"$archive_expsym_cmds\" + else + eval cmds=\"$archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Create links to the real library. + for linkname in $linknames; do + if test "$realname" != "$linkname"; then + $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $? + fi + done + + # If -module or -export-dynamic was specified, set the dlname. + if test "$module" = yes || test "$export_dynamic" = yes; then + # On all known operating systems, these are identical. + dlname="$soname" + fi + fi + ;; + + *.lo | *.o | *.obj) + if test -n "$link_against_libtool_libs"; then + $echo "$modename: error: cannot link libtool libraries into objects" 1>&2 + exit 1 + fi + + if test -n "$deplibs"; then + $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2 + fi + + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2 + fi + + if test -n "$rpath"; then + $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2 + fi + + if test -n "$xrpath"; then + $echo "$modename: warning: \`-R' is ignored for objects" 1>&2 + fi + + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for objects" 1>&2 + fi + + case "$output" in + *.lo) + if test -n "$objs"; then + $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2 + exit 1 + fi + libobj="$output" + obj=`$echo "X$output" | $Xsed -e "$lo2o"` + ;; + *) + libobj= + obj="$output" + ;; + esac + + # Delete the old objects. + $run $rm $obj $libobj + + # Objects from convenience libraries. This assumes + # single-version convenience libraries. Whenever we create + # different ones for PIC/non-PIC, this we'll have to duplicate + # the extraction. + reload_conv_objs= + gentop= + # reload_cmds runs $LD directly, so let us get rid of + # -Wl from whole_archive_flag_spec + wl= + + if test -n "$convenience"; then + if test -n "$whole_archive_flag_spec"; then + eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\" + else + gentop="$output_objdir/${obj}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + for xlib in $convenience; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP` + done + fi + fi + + # Create the old-style object. + reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs" + + output="$obj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + + # Exit if we aren't doing a library object file. + if test -z "$libobj"; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + fi + + if test "$build_libtool_libs" != yes; then + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + # Create an invalid libtool object if no PIC, so that we don't + # accidentally link it into a program. + $show "echo timestamp > $libobj" + $run eval "echo timestamp > $libobj" || exit $? + exit 0 + fi + + if test -n "$pic_flag"; then + # Only do commands if we really have different PIC objects. + reload_objs="$libobjs $reload_conv_objs" + output="$libobj" + eval cmds=\"$reload_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + else + # Just create a symlink. + $show $rm $libobj + $run $rm $libobj + $show "$LN_S $obj $libobj" + $run $LN_S $obj $libobj || exit $? + fi + + if test -n "$gentop"; then + $show "${rm}r $gentop" + $run ${rm}r $gentop + fi + + exit 0 + ;; + + # Anything else should be a program. + *) + if test -n "$vinfo"; then + $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2 + fi + + if test -n "$release"; then + $echo "$modename: warning: \`-release' is ignored for programs" 1>&2 + fi + + if test "$preload" = yes; then + if test "$dlopen" = unknown && test "$dlopen_self" = unknown && + test "$dlopen_self_static" = unknown; then + $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support." + fi + fi + + if test -n "$rpath$xrpath"; then + # If the user specified any rpath flags, then add them. + for libdir in $rpath $xrpath; do + # This is the magic to use -rpath. + case "$compile_rpath " in + *" $libdir "*) ;; + *) compile_rpath="$compile_rpath $libdir" ;; + esac + case "$finalize_rpath " in + *" $libdir "*) ;; + *) finalize_rpath="$finalize_rpath $libdir" ;; + esac + done + fi + + # Now hardcode the library paths + rpath= + hardcode_libdirs= + for libdir in $compile_rpath $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$perm_rpath " in + *" $libdir "*) ;; + *) perm_rpath="$perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + compile_rpath="$rpath" + + rpath= + hardcode_libdirs= + for libdir in $finalize_rpath; do + if test -n "$hardcode_libdir_flag_spec"; then + if test -n "$hardcode_libdir_separator"; then + if test -z "$hardcode_libdirs"; then + hardcode_libdirs="$libdir" + else + # Just accumulate the unique libdirs. + case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in + *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*) + ;; + *) + hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir" + ;; + esac + fi + else + eval flag=\"$hardcode_libdir_flag_spec\" + rpath="$rpath $flag" + fi + elif test -n "$runpath_var"; then + case "$finalize_perm_rpath " in + *" $libdir "*) ;; + *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;; + esac + fi + done + # Substitute the hardcoded libdirs into the rpath. + if test -n "$hardcode_libdir_separator" && + test -n "$hardcode_libdirs"; then + libdir="$hardcode_libdirs" + eval rpath=\" $hardcode_libdir_flag_spec\" + fi + finalize_rpath="$rpath" + + output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'` + if test "X$output_objdir" = "X$output"; then + output_objdir="$objdir" + else + output_objdir="$output_objdir/$objdir" + fi + + # Create the binary in the object directory, then wrap it. + if test ! -d $output_objdir; then + $show "$mkdir $output_objdir" + $run $mkdir $output_objdir + status=$? + if test $status -ne 0 && test ! -d $output_objdir; then + exit $status + fi + fi + + if test -n "$libobjs" && test "$build_old_libs" = yes; then + # Transform all the library objects into standard objects. + compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + fi + + dlsyms= + if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then + if test -n "$NM" && test -n "$global_symbol_pipe"; then + dlsyms="${outputname}S.c" + else + $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2 + fi + fi + + if test -n "$dlsyms"; then + case "$dlsyms" in + "") ;; + *.c) + # Discover the nlist of each of the dlfiles. + nlist="$output_objdir/${outputname}.nm" + + $show "$rm $nlist ${nlist}S ${nlist}T" + $run $rm "$nlist" "${nlist}S" "${nlist}T" + + # Parse the name list into a source file. + $show "creating $output_objdir/$dlsyms" + + test -z "$run" && $echo > "$output_objdir/$dlsyms" "\ +/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */ +/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */ + +#ifdef __cplusplus +extern \"C\" { +#endif + +/* Prevent the only kind of declaration conflicts we can make. */ +#define lt_preloaded_symbols some_other_symbol + +/* External symbol declarations for the compiler. */\ +" + + if test "$dlself" = yes; then + $show "generating symbol list for \`$output'" + + test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist" + + # Add our own program objects to the symbol list. + progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP` + for arg in $progfiles; do + $show "extracting global C symbols from \`$arg'" + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -n "$exclude_expsyms"; then + $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + if test -n "$export_symbols_regex"; then + $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T' + $run eval '$mv "$nlist"T "$nlist"' + fi + + # Prepare the list of exported symbols + if test -z "$export_symbols"; then + export_symbols="$output_objdir/$output.exp" + $run $rm $export_symbols + $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' + else + $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"' + $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T' + $run eval 'mv "$nlist"T "$nlist"' + fi + fi + + for arg in $dlprefiles; do + $show "extracting global C symbols from \`$arg'" + name=`echo "$arg" | sed -e 's%^.*/%%'` + $run eval 'echo ": $name " >> "$nlist"' + $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'" + done + + if test -z "$run"; then + # Make sure we have at least an empty file. + test -f "$nlist" || : > "$nlist" + + if test -n "$exclude_expsyms"; then + egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T + $mv "$nlist"T "$nlist" + fi + + # Try sorting and uniquifying the output. + if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then + : + else + grep -v "^: " < "$nlist" > "$nlist"S + fi + + if test -f "$nlist"S; then + eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"' + else + echo '/* NONE */' >> "$output_objdir/$dlsyms" + fi + + $echo >> "$output_objdir/$dlsyms" "\ + +#undef lt_preloaded_symbols + +#if defined (__STDC__) && __STDC__ +# define lt_ptr_t void * +#else +# define lt_ptr_t char * +# define const +#endif + +/* The mapping between symbol names and symbols. */ +const struct { + const char *name; + lt_ptr_t address; +} +lt_preloaded_symbols[] = +{\ +" + + sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \ + -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \ + < "$nlist" >> "$output_objdir/$dlsyms" + + $echo >> "$output_objdir/$dlsyms" "\ + {0, (lt_ptr_t) 0} +}; + +/* This works around a problem in FreeBSD linker */ +#ifdef FREEBSD_WORKAROUND +static const void *lt_preloaded_setup() { + return lt_preloaded_symbols; +} +#endif + +#ifdef __cplusplus +} +#endif\ +" + fi + + pic_flag_for_symtable= + case "$host" in + # compiling the symbol table file with pic_flag works around + # a FreeBSD bug that causes programs to crash when -lm is + # linked before any other PIC object. But we must not use + # pic_flag when linking with -static. The problem exists in + # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1. + *-*-freebsd2*|*-*-freebsd3.0*) + case "$compile_command " in + *" -static "*) ;; + *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";; + esac + esac + + # Now compile the dynamic symbol file. + $show "(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")" + $run eval '(cd $output_objdir && $C_compiler -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $? + + # Clean up the generated files. + $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T" + $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T" + + # Transform the symbol file into the correct name. + compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"` + ;; + *) + $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2 + exit 1 + ;; + esac + else + # We keep going just in case the user didn't refer to + # lt_preloaded_symbols. The linker will fail if global_symbol_pipe + # really was required. + + # Nullify the symbol file. + compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"` + finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"` + fi + + if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then + # Replace the output file specification. + compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'` + link_command="$compile_command$compile_rpath" + + # We have no uninstalled library dependencies, so finalize right now. + $show "$link_command" + $run eval "$link_command" + status=$? + + # Delete the generated files. + if test -n "$dlsyms"; then + $show "$rm $output_objdir/${outputname}S.${objext}" + $run $rm "$output_objdir/${outputname}S.${objext}" + fi + + exit $status + fi + + if test -n "$shlibpath_var"; then + # We should set the shlibpath_var + rpath= + for dir in $temp_rpath; do + case "$dir" in + [\\/]* | [A-Za-z]:[\\/]*) + # Absolute path. + rpath="$rpath$dir:" + ;; + *) + # Relative path: add a thisdir entry. + rpath="$rpath\$thisdir/$dir:" + ;; + esac + done + temp_rpath="$rpath" + fi + + if test -n "$compile_shlibpath$finalize_shlibpath"; then + compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command" + fi + if test -n "$finalize_shlibpath"; then + finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command" + fi + + compile_var= + finalize_var= + if test -n "$runpath_var"; then + if test -n "$perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $perm_rpath; do + rpath="$rpath$dir:" + done + compile_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + if test -n "$finalize_perm_rpath"; then + # We should set the runpath_var. + rpath= + for dir in $finalize_perm_rpath; do + rpath="$rpath$dir:" + done + finalize_var="$runpath_var=\"$rpath\$$runpath_var\" " + fi + fi + + if test "$hardcode_action" = relink; then + # Fast installation is not supported + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + + $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2 + $echo "$modename: \`$output' will be relinked during installation" 1>&2 + else + if test "$fast_install" != no; then + link_command="$finalize_var$compile_command$finalize_rpath" + if test "$fast_install" = yes; then + relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'` + else + # fast_install is set to needless + relink_command= + fi + else + link_command="$compile_var$compile_command$compile_rpath" + relink_command="$finalize_var$finalize_command$finalize_rpath" + fi + fi + + # Replace the output file specification. + link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'` + + # Delete the old output files. + $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname + + $show "$link_command" + $run eval "$link_command" || exit $? + + # Now create the wrapper script. + $show "creating $output" + + # Quote the relink command for shipping. + if test -n "$relink_command"; then + relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"` + fi + + # Quote $echo for shipping. + if test "X$echo" = "X$SHELL $0 --fallback-echo"; then + case "$0" in + [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";; + *) qecho="$SHELL `pwd`/$0 --fallback-echo";; + esac + qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"` + else + qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"` + fi + + # Only actually do things if our run command is non-null. + if test -z "$run"; then + # win32 will think the script is a binary if it has + # a .exe suffix, so we strip it off here. + case $output in + *.exe) output=`echo $output|sed 's,.exe$,,'` ;; + esac + $rm $output + trap "$rm $output; exit 1" 1 2 15 + + $echo > $output "\ +#! $SHELL + +# $output - temporary wrapper script for $objdir/$outputname +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# The $output program cannot be directly executed until all the libtool +# libraries that it depends on are installed. +# +# This wrapper script should never be moved out of the build directory. +# If it is, it will not operate correctly. + +# Sed substitution that helps us do robust quoting. It backslashifies +# metacharacters that are still active within double-quoted strings. +Xsed='sed -e 1s/^X//' +sed_quote_subst='$sed_quote_subst' + +# The HP-UX ksh and POSIX shell print the target directory to stdout +# if CDPATH is set. +if test \"\${CDPATH+set}\" = set; then CDPATH=; export CDPATH; fi + +relink_command=\"$relink_command\" + +# This environment variable determines our operation mode. +if test \"\$libtool_install_magic\" = \"$magic\"; then + # install mode needs the following variable: + link_against_libtool_libs='$link_against_libtool_libs' +else + # When we are sourced in execute mode, \$file and \$echo are already set. + if test \"\$libtool_execute_magic\" != \"$magic\"; then + echo=\"$qecho\" + file=\"\$0\" + # Make sure echo works. + if test \"X\$1\" = X--no-reexec; then + # Discard the --no-reexec flag, and continue. + shift + elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then + # Yippee, \$echo works! + : + else + # Restart under the correct shell, and then maybe \$echo will work. + exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"} + fi + fi\ +" + $echo >> $output "\ + + # Find the directory that this script lives in. + thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\` + test \"x\$thisdir\" = \"x\$file\" && thisdir=. + + # Follow symbolic links until we get to the real thisdir. + file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\` + while test -n \"\$file\"; do + destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\` + + # If there was a directory component, then change thisdir. + if test \"x\$destdir\" != \"x\$file\"; then + case \"\$destdir\" in + [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;; + *) thisdir=\"\$thisdir/\$destdir\" ;; + esac + fi + + file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\` + file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\` + done + + # Try to get the absolute directory name. + absdir=\`cd \"\$thisdir\" && pwd\` + test -n \"\$absdir\" && thisdir=\"\$absdir\" +" + + if test "$fast_install" = yes; then + echo >> $output "\ + program=lt-'$outputname' + progdir=\"\$thisdir/$objdir\" + + if test ! -f \"\$progdir/\$program\" || \\ + { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\ + test \"X\$file\" != \"X\$progdir/\$program\"; }; then + + file=\"\$\$-\$program\" + + if test ! -d \"\$progdir\"; then + $mkdir \"\$progdir\" + else + $rm \"\$progdir/\$file\" + fi" + + echo >> $output "\ + + # relink executable if necessary + if test -n \"\$relink_command\"; then + if (cd \"\$thisdir\" && eval \$relink_command); then : + else + $rm \"\$progdir/\$file\" + exit 1 + fi + fi + + $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null || + { $rm \"\$progdir/\$program\"; + $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; } + $rm \"\$progdir/\$file\" + fi" + else + echo >> $output "\ + program='$outputname$exeext' + progdir=\"\$thisdir/$objdir\" +" + fi + + echo >> $output "\ + + if test -f \"\$progdir/\$program\"; then" + + # Export our shlibpath_var if we have one. + if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then + $echo >> $output "\ + # Add our own library path to $shlibpath_var + $shlibpath_var=\"$temp_rpath\$$shlibpath_var\" + + # Some systems cannot cope with colon-terminated $shlibpath_var + # The second colon is a workaround for a bug in BeOS R4 sed + $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\` + + export $shlibpath_var +" + fi + + # fixup the dll searchpath if we need to. + if test -n "$dllsearchpath"; then + $echo >> $output "\ + # Add the dll search path components to the executable PATH + PATH=$dllsearchpath:\$PATH +" + fi + + $echo >> $output "\ + if test \"\$libtool_execute_magic\" != \"$magic\"; then + # Run the actual program with our arguments. +" + case $host in + *-*-cygwin* | *-*-mingw | *-*-os2*) + # win32 systems need to use the prog path for dll + # lookup to work + $echo >> $output "\ + exec \$progdir\\\\\$program \${1+\"\$@\"} +" + ;; + *) + $echo >> $output "\ + # Export the path to the program. + PATH=\"\$progdir:\$PATH\" + export PATH + + exec \$program \${1+\"\$@\"} +" + ;; + esac + $echo >> $output "\ + \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\" + exit 1 + fi + else + # The program doesn't exist. + \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2 + \$echo \"This script is just a wrapper for \$program.\" 1>&2 + echo \"See the $PACKAGE documentation for more information.\" 1>&2 + exit 1 + fi +fi\ +" + chmod +x $output + fi + exit 0 + ;; + esac + + # See if we need to build an old-fashioned archive. + for oldlib in $oldlibs; do + + if test "$build_libtool_libs" = convenience; then + oldobjs="$libobjs_save" + addlibs="$convenience" + build_libtool_libs=no + else + if test "$build_libtool_libs" = module; then + oldobjs="$libobjs_save" + build_libtool_libs=no + else + oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP` + fi + addlibs="$old_convenience" + fi + + if test -n "$addlibs"; then + gentop="$output_objdir/${outputname}x" + $show "${rm}r $gentop" + $run ${rm}r "$gentop" + $show "mkdir $gentop" + $run mkdir "$gentop" + status=$? + if test $status -ne 0 && test ! -d "$gentop"; then + exit $status + fi + generated="$generated $gentop" + + # Add in members from convenience archives. + for xlib in $addlibs; do + # Extract the objects. + case "$xlib" in + [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;; + *) xabs=`pwd`"/$xlib" ;; + esac + xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'` + xdir="$gentop/$xlib" + + $show "${rm}r $xdir" + $run ${rm}r "$xdir" + $show "mkdir $xdir" + $run mkdir "$xdir" + status=$? + if test $status -ne 0 && test ! -d "$xdir"; then + exit $status + fi + $show "(cd $xdir && $AR x $xabs)" + $run eval "(cd \$xdir && $AR x \$xabs)" || exit $? + + oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP` + done + fi + + # Do each command in the archive commands. + if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then + eval cmds=\"$old_archive_from_new_cmds\" + else + # Ensure that we have .o objects in place incase we decided + # not to build a shared library, and have fallen back to building + # static libs even though --disable-static was passed! + for oldobj in $oldobjs; do + if test ! -f $oldobj; then + obj=`$echo "X$oldobj" | $Xsed -e "$o2lo"` + $show "${LN_S} $obj $oldobj" + $run ${LN_S} $obj $oldobj || exit $? + fi + done + + eval cmds=\"$old_archive_cmds\" + fi + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$generated"; then + $show "${rm}r$generated" + $run ${rm}r$generated + fi + + # Now create the libtool archive. + case "$output" in + *.la) + old_library= + test "$build_old_libs" = yes && old_library="$libname.$libext" + $show "creating $output" + + if test -n "$xrpath"; then + temp_xrpath= + for libdir in $xrpath; do + temp_xrpath="$temp_xrpath -R$libdir" + done + dependency_libs="$temp_xrpath $dependency_libs" + fi + + # Only create the output if not a dry run. + if test -z "$run"; then + for installed in no yes; do + if test "$installed" = yes; then + if test -z "$install_libdir"; then + break + fi + output="$output_objdir/$outputname"i + fi + $rm $output + $echo > $output "\ +# $outputname - a libtool library file +# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP +# +# Please DO NOT delete this file! +# It is necessary for linking the library. + +# The name that we can dlopen(3). +dlname='$dlname' + +# Names of this library. +library_names='$library_names' + +# The name of the static archive. +old_library='$old_library' + +# Libraries that this one depends upon. +dependency_libs='$dependency_libs' + +# Version information for $libname. +current=$current +age=$age +revision=$revision + +# Is this an already installed library? +installed=$installed + +# Directory that this library needs to be installed in: +libdir='$install_libdir'\ +" + done + fi + + # Do a symbolic link so that the libtool archive can be found in + # LD_LIBRARY_PATH before the program is installed. + $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" + $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $? + ;; + esac + exit 0 + ;; + + # libtool install mode + install) + modename="$modename: install" + + # There may be an optional sh(1) argument at the beginning of + # install_prog (especially on Windows NT). + if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then + # Aesthetically quote it. + arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$arg " + arg="$1" + shift + else + install_prog= + arg="$nonopt" + fi + + # The real first argument should be the name of the installation program. + # Aesthetically quote it. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog$arg" + + # We need to accept at least all the BSD install flags. + dest= + files= + opts= + prev= + install_type= + isdir=no + stripme= + for arg + do + if test -n "$dest"; then + files="$files $dest" + dest="$arg" + continue + fi + + case "$arg" in + -d) isdir=yes ;; + -f) prev="-f" ;; + -g) prev="-g" ;; + -m) prev="-m" ;; + -o) prev="-o" ;; + -s) + stripme=" -s" + continue + ;; + -*) ;; + + *) + # If the previous option needed an argument, then skip it. + if test -n "$prev"; then + prev= + else + dest="$arg" + continue + fi + ;; + esac + + # Aesthetically quote the argument. + arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"` + case "$arg" in + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*) + arg="\"$arg\"" + ;; + esac + install_prog="$install_prog $arg" + done + + if test -z "$install_prog"; then + $echo "$modename: you must specify an install program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -n "$prev"; then + $echo "$modename: the \`$prev' option requires an argument" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + if test -z "$files"; then + if test -z "$dest"; then + $echo "$modename: no file or destination specified" 1>&2 + else + $echo "$modename: you must specify a destination" 1>&2 + fi + $echo "$help" 1>&2 + exit 1 + fi + + # Strip any trailing slash from the destination. + dest=`$echo "X$dest" | $Xsed -e 's%/$%%'` + + # Check to see that the destination is a directory. + test -d "$dest" && isdir=yes + if test "$isdir" = yes; then + destdir="$dest" + destname= + else + destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'` + test "X$destdir" = "X$dest" && destdir=. + destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'` + + # Not a directory, so check to see that there is only one file specified. + set dummy $files + if test $# -gt 2; then + $echo "$modename: \`$dest' is not a directory" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + fi + case "$destdir" in + [\\/]* | [A-Za-z]:[\\/]*) ;; + *) + for file in $files; do + case "$file" in + *.lo) ;; + *) + $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + done + ;; + esac + + # This variable tells wrapper scripts just to set variables rather + # than running their programs. + libtool_install_magic="$magic" + + staticlibs= + future_libdirs= + current_libdirs= + for file in $files; do + + # Do each installation. + case "$file" in + *.a | *.lib) + # Do the static libraries later. + staticlibs="$staticlibs $file" + ;; + + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$file' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + library_names= + old_library= + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Add the libdir to current_libdirs if it is the destination. + if test "X$destdir" = "X$libdir"; then + case "$current_libdirs " in + *" $libdir "*) ;; + *) current_libdirs="$current_libdirs $libdir" ;; + esac + else + # Note the libdir as a future libdir. + case "$future_libdirs " in + *" $libdir "*) ;; + *) future_libdirs="$future_libdirs $libdir" ;; + esac + fi + + dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/" + test "X$dir" = "X$file/" && dir= + dir="$dir$objdir" + + # See the names of the shared library. + set dummy $library_names + if test -n "$2"; then + realname="$2" + shift + shift + + # Install the shared library and build the symlinks. + $show "$install_prog $dir/$realname $destdir/$realname" + $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $? + + if test $# -gt 0; then + # Delete the old symlinks, and create new ones. + for linkname + do + if test "$linkname" != "$realname"; then + $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)" + fi + done + fi + + # Do each command in the postinstall commands. + lib="$destdir/$realname" + eval cmds=\"$postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + fi + + # Install the pseudo-library for information purposes. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + instname="$dir/$name"i + $show "$install_prog $instname $destdir/$name" + $run eval "$install_prog $instname $destdir/$name" || exit $? + + # Maybe install the static library, too. + test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library" + ;; + + *.lo) + # Install (i.e. copy) a libtool object. + + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Deduce the name of the destination old-style object file. + case "$destfile" in + *.lo) + staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"` + ;; + *.o | *.obj) + staticdest="$destfile" + destfile= + ;; + *) + $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; + esac + + # Install the libtool object if requested. + if test -n "$destfile"; then + $show "$install_prog $file $destfile" + $run eval "$install_prog $file $destfile" || exit $? + fi + + # Install the old object if enabled. + if test "$build_old_libs" = yes; then + # Deduce the name of the old-style object file. + staticobj=`$echo "X$file" | $Xsed -e "$lo2o"` + + $show "$install_prog $staticobj $staticdest" + $run eval "$install_prog \$staticobj \$staticdest" || exit $? + fi + exit 0 + ;; + + *) + # Figure out destination file name, if it wasn't already specified. + if test -n "$destname"; then + destfile="$destdir/$destname" + else + destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + destfile="$destdir/$destfile" + fi + + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + link_against_libtool_libs= + relink_command= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Check the variables that should have been set. + if test -z "$link_against_libtool_libs"; then + $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2 + exit 1 + fi + + finalize=yes + for lib in $link_against_libtool_libs; do + # Check to see that each library is installed. + libdir= + if test -f "$lib"; then + # If there is no directory component, then add one. + case "$lib" in + */* | *\\*) . $lib ;; + *) . ./$lib ;; + esac + fi + libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`" + if test -n "$libdir" && test ! -f "$libfile"; then + $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2 + finalize=no + fi + done + + outputname= + if test "$fast_install" = no && test -n "$relink_command"; then + if test "$finalize" = yes && test -z "$run"; then + tmpdir="/tmp" + test -n "$TMPDIR" && tmpdir="$TMPDIR" + tmpdir="$tmpdir/libtool-$$" + if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then : + else + $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2 + continue + fi + outputname="$tmpdir/$file" + # Replace the output file specification. + relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'` + + $show "$relink_command" + if $run eval "$relink_command"; then : + else + $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2 + ${rm}r "$tmpdir" + continue + fi + file="$outputname" + else + $echo "$modename: warning: cannot relink \`$file'" 1>&2 + fi + else + # Install the binary that we compiled earlier. + file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"` + fi + fi + + $show "$install_prog$stripme $file $destfile" + $run eval "$install_prog\$stripme \$file \$destfile" || exit $? + test -n "$outputname" && ${rm}r "$tmpdir" + ;; + esac + done + + for file in $staticlibs; do + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + # Set up the ranlib parameters. + oldlib="$destdir/$name" + + $show "$install_prog $file $oldlib" + $run eval "$install_prog \$file \$oldlib" || exit $? + + # Do each command in the postinstall commands. + eval cmds=\"$old_postinstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || exit $? + done + IFS="$save_ifs" + done + + if test -n "$future_libdirs"; then + $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2 + fi + + if test -n "$current_libdirs"; then + # Maybe just do a dry run. + test -n "$run" && current_libdirs=" -n$current_libdirs" + exec $SHELL $0 --finish$current_libdirs + exit 1 + fi + + exit 0 + ;; + + # libtool finish mode + finish) + modename="$modename: finish" + libdirs="$nonopt" + admincmds= + + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + for dir + do + libdirs="$libdirs $dir" + done + + for libdir in $libdirs; do + if test -n "$finish_cmds"; then + # Do each command in the finish commands. + eval cmds=\"$finish_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" || admincmds="$admincmds + $cmd" + done + IFS="$save_ifs" + fi + if test -n "$finish_eval"; then + # Do the single finish_eval. + eval cmds=\"$finish_eval\" + $run eval "$cmds" || admincmds="$admincmds + $cmds" + fi + done + fi + + # Exit here if they wanted silent mode. + test "$show" = : && exit 0 + + echo "----------------------------------------------------------------------" + echo "Libraries have been installed in:" + for libdir in $libdirs; do + echo " $libdir" + done + echo + echo "If you ever happen to want to link against installed libraries" + echo "in a given directory, LIBDIR, you must either use libtool, and" + echo "specify the full pathname of the library, or use \`-LLIBDIR'" + echo "flag during linking and do at least one of the following:" + if test -n "$shlibpath_var"; then + echo " - add LIBDIR to the \`$shlibpath_var' environment variable" + echo " during execution" + fi + if test -n "$runpath_var"; then + echo " - add LIBDIR to the \`$runpath_var' environment variable" + echo " during linking" + fi + if test -n "$hardcode_libdir_flag_spec"; then + libdir=LIBDIR + eval flag=\"$hardcode_libdir_flag_spec\" + + echo " - use the \`$flag' linker flag" + fi + if test -n "$admincmds"; then + echo " - have your system administrator run these commands:$admincmds" + fi + if test -f /etc/ld.so.conf; then + echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'" + fi + echo + echo "See any operating system documentation about shared libraries for" + echo "more information, such as the ld(1) and ld.so(8) manual pages." + echo "----------------------------------------------------------------------" + exit 0 + ;; + + # libtool execute mode + execute) + modename="$modename: execute" + + # The first argument is the command name. + cmd="$nonopt" + if test -z "$cmd"; then + $echo "$modename: you must specify a COMMAND" 1>&2 + $echo "$help" + exit 1 + fi + + # Handle -dlopen flags immediately. + for file in $execute_dlfiles; do + if test ! -f "$file"; then + $echo "$modename: \`$file' is not a file" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + dir= + case "$file" in + *.la) + # Check to see that this really is a libtool archive. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then : + else + $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + # Read the libtool library. + dlname= + library_names= + + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Skip this library if it cannot be dlopened. + if test -z "$dlname"; then + # Warn if it was a shared library. + test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'" + continue + fi + + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + + if test -f "$dir/$objdir/$dlname"; then + dir="$dir/$objdir" + else + $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2 + exit 1 + fi + ;; + + *.lo) + # Just add the directory containing the .lo file. + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + ;; + + *) + $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2 + continue + ;; + esac + + # Get the absolute pathname. + absdir=`cd "$dir" && pwd` + test -n "$absdir" && dir="$absdir" + + # Now add the directory to shlibpath_var. + if eval "test -z \"\$$shlibpath_var\""; then + eval "$shlibpath_var=\"\$dir\"" + else + eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\"" + fi + done + + # This variable tells wrapper scripts just to set shlibpath_var + # rather than running their programs. + libtool_execute_magic="$magic" + + # Check if any of the arguments is a wrapper script. + args= + for file + do + case "$file" in + -*) ;; + *) + # Do a test to see if this is really a libtool program. + if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + # If there is no directory component, then add one. + case "$file" in + */* | *\\*) . $file ;; + *) . ./$file ;; + esac + + # Transform arg to wrapped name. + file="$progdir/$program" + fi + ;; + esac + # Quote arguments (to preserve shell metacharacters). + file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"` + args="$args \"$file\"" + done + + if test -z "$run"; then + # Export the shlibpath_var. + eval "export $shlibpath_var" + + # Restore saved enviroment variables + if test "${save_LC_ALL+set}" = set; then + LC_ALL="$save_LC_ALL"; export LC_ALL + fi + if test "${save_LANG+set}" = set; then + LANG="$save_LANG"; export LANG + fi + + # Now actually exec the command. + eval "exec \$cmd$args" + + $echo "$modename: cannot exec \$cmd$args" + exit 1 + else + # Display what would be done. + eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\"" + $echo "export $shlibpath_var" + $echo "$cmd$args" + exit 0 + fi + ;; + + # libtool uninstall mode + uninstall) + modename="$modename: uninstall" + rm="$nonopt" + files= + + for arg + do + case "$arg" in + -*) rm="$rm $arg" ;; + *) files="$files $arg" ;; + esac + done + + if test -z "$rm"; then + $echo "$modename: you must specify an RM program" 1>&2 + $echo "$help" 1>&2 + exit 1 + fi + + for file in $files; do + dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'` + test "X$dir" = "X$file" && dir=. + name=`$echo "X$file" | $Xsed -e 's%^.*/%%'` + + rmfiles="$file" + + case "$name" in + *.la) + # Possibly a libtool archive, so verify it. + if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then + . $dir/$name + + # Delete the libtool libraries and symlinks. + for n in $library_names; do + rmfiles="$rmfiles $dir/$n" + done + test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library" + + $show "$rm $rmfiles" + $run $rm $rmfiles + + if test -n "$library_names"; then + # Do each command in the postuninstall commands. + eval cmds=\"$postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + if test -n "$old_library"; then + # Do each command in the old_postuninstall commands. + eval cmds=\"$old_postuninstall_cmds\" + IFS="${IFS= }"; save_ifs="$IFS"; IFS='~' + for cmd in $cmds; do + IFS="$save_ifs" + $show "$cmd" + $run eval "$cmd" + done + IFS="$save_ifs" + fi + + # FIXME: should reinstall the best remaining shared library. + fi + ;; + + *.lo) + if test "$build_old_libs" = yes; then + oldobj=`$echo "X$name" | $Xsed -e "$lo2o"` + rmfiles="$rmfiles $dir/$oldobj" + fi + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + + *) + $show "$rm $rmfiles" + $run $rm $rmfiles + ;; + esac + done + exit 0 + ;; + + "") + $echo "$modename: you must specify a MODE" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 + ;; + esac + + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$generic_help" 1>&2 + exit 1 +fi # test -z "$show_help" + +# We need to display help for each of the modes. +case "$mode" in +"") $echo \ +"Usage: $modename [OPTION]... [MODE-ARG]... + +Provide generalized library-building support services. + + --config show all configuration variables + --debug enable verbose shell tracing +-n, --dry-run display commands without modifying any files + --features display basic configuration information and exit + --finish same as \`--mode=finish' + --help display this help message and exit + --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS] + --quiet same as \`--silent' + --silent don't print informational messages + --version print version information + +MODE must be one of the following: + + compile compile a source file into a libtool object + execute automatically set library path, then run a program + finish complete the installation of libtool libraries + install install libraries or executables + link create a library or an executable + uninstall remove libraries from an installed directory + +MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for +a more detailed description of MODE." + exit 0 + ;; + +compile) + $echo \ +"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE + +Compile a source file into a libtool library object. + +This mode accepts the following additional options: + + -o OUTPUT-FILE set the output file name to OUTPUT-FILE + -static always build a \`.o' file suitable for static linking + +COMPILE-COMMAND is a command to be used in creating a \`standard' object file +from the given SOURCEFILE. + +The output file name is determined by removing the directory component from +SOURCEFILE, then substituting the C source code suffix \`.c' with the +library object suffix, \`.lo'." + ;; + +execute) + $echo \ +"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]... + +Automatically set library path, then run a program. + +This mode accepts the following additional options: + + -dlopen FILE add the directory containing FILE to the library path + +This mode sets the library path environment variable according to \`-dlopen' +flags. + +If any of the ARGS are libtool executable wrappers, then they are translated +into their corresponding uninstalled binary, and any of their required library +directories are added to the library path. + +Then, COMMAND is executed, with ARGS as arguments." + ;; + +finish) + $echo \ +"Usage: $modename [OPTION]... --mode=finish [LIBDIR]... + +Complete the installation of libtool libraries. + +Each LIBDIR is a directory that contains libtool libraries. + +The commands that this mode executes may require superuser privileges. Use +the \`--dry-run' option if you just want to see what would be executed." + ;; + +install) + $echo \ +"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND... + +Install executables or libraries. + +INSTALL-COMMAND is the installation command. The first component should be +either the \`install' or \`cp' program. + +The rest of the components are interpreted as arguments to that command (only +BSD-compatible install options are recognized)." + ;; + +link) + $echo \ +"Usage: $modename [OPTION]... --mode=link LINK-COMMAND... + +Link object files or libraries together to form another library, or to +create an executable program. + +LINK-COMMAND is a command using the C compiler that you would use to create +a program from several object files. + +The following components of LINK-COMMAND are treated specially: + + -all-static do not do any dynamic linking at all + -avoid-version do not add a version suffix if possible + -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime + -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols + -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3) + -export-symbols SYMFILE + try to export only the symbols listed in SYMFILE + -export-symbols-regex REGEX + try to export only the symbols matching REGEX + -LLIBDIR search LIBDIR for required installed libraries + -lNAME OUTPUT-FILE requires the installed library libNAME + -module build a library that can dlopened + -no-undefined declare that a library does not refer to external symbols + -o OUTPUT-FILE create OUTPUT-FILE from the specified objects + -release RELEASE specify package release information + -rpath LIBDIR the created library will eventually be installed in LIBDIR + -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries + -static do not do any dynamic linking of libtool libraries + -version-info CURRENT[:REVISION[:AGE]] + specify library version info [each variable defaults to 0] + +All other options (arguments beginning with \`-') are ignored. + +Every other argument is treated as a filename. Files ending in \`.la' are +treated as uninstalled libtool libraries, other files are standard or library +object files. + +If the OUTPUT-FILE ends in \`.la', then a libtool library is created, +only library objects (\`.lo' files) may be specified, and \`-rpath' is +required, except when creating a convenience library. + +If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created +using \`ar' and \`ranlib', or on Windows using \`lib'. + +If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file +is created, otherwise an executable program is created." + ;; + +uninstall) + $echo \ +"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE... + +Remove libraries from an installation directory. + +RM is the name of the program to use to delete files associated with each FILE +(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed +to RM. + +If FILE is a libtool library, all the files associated with it are deleted. +Otherwise, only FILE itself is deleted using RM." + ;; + +*) + $echo "$modename: invalid operation mode \`$mode'" 1>&2 + $echo "$help" 1>&2 + exit 1 + ;; +esac + +echo +$echo "Try \`$modename --help' for more information about other modes." + +exit 0 + +# Local Variables: +# mode:shell-script +# sh-indentation:2 +# End: diff --git a/missing b/missing new file mode 100755 index 000000000..cbe2b0ef0 --- /dev/null +++ b/missing @@ -0,0 +1,188 @@ +#! /bin/sh +# Common stub for a few missing GNU programs while installing. +# Copyright (C) 1996, 1997 Free Software Foundation, Inc. +# Franc,ois Pinard , 1996. + +# 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, 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., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. + +if test $# -eq 0; then + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 +fi + +case "$1" in + + -h|--h|--he|--hel|--help) + echo "\ +$0 [OPTION]... PROGRAM [ARGUMENT]... + +Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an +error status if there is no known handling for PROGRAM. + +Options: + -h, --help display this help and exit + -v, --version output version information and exit + +Supported PROGRAM values: + aclocal touch file \`aclocal.m4' + autoconf touch file \`configure' + autoheader touch file \`config.h.in' + automake touch all \`Makefile.in' files + bison create \`y.tab.[ch]', if possible, from existing .[ch] + flex create \`lex.yy.c', if possible, from existing .c + lex create \`lex.yy.c', if possible, from existing .c + makeinfo touch the output file + yacc create \`y.tab.[ch]', if possible, from existing .[ch]" + ;; + + -v|--v|--ve|--ver|--vers|--versi|--versio|--version) + echo "missing - GNU libit 0.0" + ;; + + -*) + echo 1>&2 "$0: Unknown \`$1' option" + echo 1>&2 "Try \`$0 --help' for more information" + exit 1 + ;; + + aclocal) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acinclude.m4' or \`configure.in'. You might want + to install the \`Automake' and \`Perl' packages. Grab them from + any GNU archive site." + touch aclocal.m4 + ;; + + autoconf) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`configure.in'. You might want to install the + \`Autoconf' and \`GNU m4' packages. Grab them from any GNU + archive site." + touch configure + ;; + + autoheader) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`acconfig.h' or \`configure.in'. You might want + to install the \`Autoconf' and \`GNU m4' packages. Grab them + from any GNU archive site." + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER([^):]*:\([^)]*\)).*/\1/p' configure.in` + if test -z "$files"; then + files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^):]*\)).*/\1/p' configure.in` + test -z "$files" || files="$files.in" + else + files=`echo "$files" | sed -e 's/:/ /g'` + fi + test -z "$files" && files="config.h.in" + touch $files + ;; + + automake) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified \`Makefile.am', \`acinclude.m4' or \`configure.in'. + You might want to install the \`Automake' and \`Perl' packages. + Grab them from any GNU archive site." + find . -type f -name Makefile.am -print \ + | sed 's/^\(.*\).am$/touch \1.in/' \ + | sh + ;; + + bison|yacc) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.y' file. You may need the \`Bison' package + in order for those modifications to take effect. You can get + \`Bison' from any GNU archive site." + rm -f y.tab.c y.tab.h + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.y) + SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.c + fi + SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" y.tab.h + fi + ;; + esac + fi + if [ ! -f y.tab.h ]; then + echo >y.tab.h + fi + if [ ! -f y.tab.c ]; then + echo 'main() { return 0; }' >y.tab.c + fi + ;; + + lex|flex) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.l' file. You may need the \`Flex' package + in order for those modifications to take effect. You can get + \`Flex' from any GNU archive site." + rm -f lex.yy.c + if [ $# -ne 1 ]; then + eval LASTARG="\${$#}" + case "$LASTARG" in + *.l) + SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` + if [ -f "$SRCFILE" ]; then + cp "$SRCFILE" lex.yy.c + fi + ;; + esac + fi + if [ ! -f lex.yy.c ]; then + echo 'main() { return 0; }' >lex.yy.c + fi + ;; + + makeinfo) + echo 1>&2 "\ +WARNING: \`$1' is missing on your system. You should only need it if + you modified a \`.texi' or \`.texinfo' file, or any other file + indirectly affecting the aspect of the manual. The spurious + call might also be the consequence of using a buggy \`make' (AIX, + DU, IRIX). You might want to install the \`Texinfo' package or + the \`GNU make' package. Grab either from any GNU archive site." + file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'` + if test -z "$file"; then + file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` + file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file` + fi + touch $file + ;; + + *) + echo 1>&2 "\ +WARNING: \`$1' is needed, and you do not seem to have it handy on your + system. You might have modified some files without having the + proper tools for further handling them. Check the \`README' file, + it often tells you about the needed prerequirements for installing + this package. You may also peek at any GNU archive site, in case + some other package would contain this missing \`$1' program." + exit 1 + ;; +esac + +exit 0 diff --git a/mkinstalldirs b/mkinstalldirs new file mode 100755 index 000000000..5d6b78611 --- /dev/null +++ b/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2001-10-12 23:28:53 brianb Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/samples/debug.c b/samples/debug.c new file mode 100644 index 000000000..630e019bf --- /dev/null +++ b/samples/debug.c @@ -0,0 +1,62 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static char software_version[] = "$Id: debug.c,v 1.1 2001-10-12 23:28:53 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +extern errno; + +get_incoming (int fd) +{ + +FILE *out; +int len, i, offs=0; +unsigned char buf[BUFSIZ]; + + + + out = fopen("client.out","w"); + + while ((len = read(fd, buf, BUFSIZ)) > 0) { + fprintf (out,"len is %d\n",len); + for (i=0;i=' ' && buf[i]<'z') + fprintf(out," %c",buf[i]); + fprintf(out,"\n"); + } + fflush(out); + } + close(fd); + fclose(out); +} diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 000000000..13e35a087 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,5 @@ +if ODBC +SUBDIRS = tds ctlib dblib odbc server +else +SUBDIRS = tds ctlib dblib server +endif diff --git a/src/Makefile.in b/src/Makefile.in new file mode 100644 index 000000000..f775ac771 --- /dev/null +++ b/src/Makefile.in @@ -0,0 +1,288 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = .. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ +@ODBC_TRUE@SUBDIRS = tds ctlib dblib odbc server +@ODBC_FALSE@SUBDIRS = tds ctlib dblib server +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +DIST_SUBDIRS = tds ctlib dblib odbc server tds ctlib dblib server +all: all-redirect +.SUFFIXES: +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(DIST_SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: +uninstall: uninstall-recursive +all-am: Makefile +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-tags clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-tags distclean-generic clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: install-data-recursive uninstall-data-recursive \ +install-exec-recursive uninstall-exec-recursive installdirs-recursive \ +uninstalldirs-recursive all-recursive check-recursive \ +installcheck-recursive info-recursive dvi-recursive \ +mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/ctlib/Makefile.am b/src/ctlib/Makefile.am new file mode 100644 index 000000000..e05c23c66 --- /dev/null +++ b/src/ctlib/Makefile.am @@ -0,0 +1,9 @@ +SUBDIRS = unittests + +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libct.la +libct_la_SOURCES= ct.c cs.c blk.c ctutil.c +libct_la_LIBADD = $(patsubst %, $(TDSDIR)/%, \ + $(patsubst %.c, %.lo, $(TDSSOURCES))) +INCLUDES = -I$(top_srcdir)/include diff --git a/src/ctlib/Makefile.in b/src/ctlib/Makefile.in new file mode 100644 index 000000000..475295a86 --- /dev/null +++ b/src/ctlib/Makefile.in @@ -0,0 +1,406 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +SUBDIRS = unittests + +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libct.la +libct_la_SOURCES = ct.c cs.c blk.c ctutil.c +libct_la_LIBADD = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, %.lo, $(TDSSOURCES))) + +INCLUDES = -I$(top_srcdir)/include +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libct_la_LDFLAGS = +libct_la_DEPENDENCIES = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, \ +%.lo, $(TDSSOURCES))) +libct_la_OBJECTS = ct.lo cs.lo blk.lo ctutil.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libct_la_SOURCES) +OBJECTS = $(libct_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/ctlib/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libct.la: $(libct_la_OBJECTS) $(libct_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libct_la_LDFLAGS) $(libct_la_OBJECTS) $(libct_la_LIBADD) $(LIBS) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/ctlib + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +blk.lo blk.o : blk.c ../../include/bkpublic.h ../../include/cspublic.h \ + ../../include/tds.h ../../include/tds_configs.h \ + ../../include/tdsver.h +cs.lo cs.o : cs.c ../../include/cspublic.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h +ct.lo ct.o : ct.c ../../include/ctpublic.h ../../include/cspublic.h \ + ../../include/tds.h ../../include/tds_configs.h \ + ../../include/tdsver.h ../../include/ctlib.h +ctutil.lo ctutil.o : ctutil.c ../../include/ctlib.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/cspublic.h + +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-recursive +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c new file mode 100644 index 000000000..4b404ab18 --- /dev/null +++ b/src/ctlib/blk.c @@ -0,0 +1,53 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +static char software_version[] = "$Id: blk.c,v 1.1 2001-10-12 23:29:05 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +CS_RETCODE blk_init(CS_BLKDESC *blkdesc, CS_INT direction, CS_CHAR *tablename, CS_INT tnamelen) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_alloc(CS_CONNECTION *conn, CS_INT version, CS_BLKDESC **blkptr) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_props(CS_BLKDESC *blkdesc, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_done(CS_BLKDESC *blkdesc, CS_INT type, CS_INT *outrow) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_bind(CS_BLKDESC *blkdesc, CS_INT colnum, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT *datalen, CS_SMALLINT *indicator) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_rowxfer(CS_BLKDESC *blkdesc) +{ + return CS_SUCCEED; +} +CS_RETCODE blk_drop(CS_BLKDESC *blkdesc) +{ + return CS_SUCCEED; +} diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c new file mode 100644 index 000000000..34753a3ad --- /dev/null +++ b/src/ctlib/cs.c @@ -0,0 +1,105 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +static char software_version[] = "$Id: cs.c,v 1.1 2001-10-12 23:29:05 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +CS_RETCODE cs_ctx_alloc(CS_INT version, CS_CONTEXT **ctx) +{ + *ctx = (CS_CONTEXT *) malloc(sizeof(CS_CONTEXT)); + return CS_SUCCEED; +} +CS_RETCODE cs_ctx_drop(CS_CONTEXT *ctx) +{ + if (ctx) free(ctx); + return CS_SUCCEED; +} +CS_RETCODE cs_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + return CS_SUCCEED; +} +CS_RETCODE cs_convert(CS_CONTEXT *ctx, CS_DATAFMT *srcfmt, CS_VOID *srcdata, CS_DATAFMT *destfmt, CS_VOID *destdata, CS_INT *resultlen) +{ +int src_type, dest_type; + + src_type = _ct_get_server_type(srcfmt->datatype); + dest_type = _ct_get_server_type(destfmt->datatype); + + tds_convert(src_type, srcdata, srcfmt ? srcfmt->maxlength : 0, + dest_type, destdata, destfmt ? destfmt->maxlength : 0); + return CS_SUCCEED; +} +CS_RETCODE cs_dt_crack(CS_CONTEXT *ctx, CS_INT datetype, CS_VOID *dateval, CS_DATEREC *daterec) +{ +CS_DATETIME *dt; +CS_DATETIME4 *dt4; +time_t tmp_secs_from_epoch; +struct tm *t; + + if (datetype == CS_DATETIME_TYPE) { + dt = (TDS_DATETIME *)dateval; + tmp_secs_from_epoch = ((dt->dtdays - 25567) * (24*60*60)) + + (dt->dttime / 300); + } else if (datetype == CS_DATETIME4_TYPE) { + dt4 = (TDS_DATETIME4 *)dateval; + tmp_secs_from_epoch = ((dt4->days - 25567) * (24*60*60)) + + (dt4->minutes * 60); + } else { + return CS_FAIL; + } + t = (struct tm *) gmtime(&tmp_secs_from_epoch); + daterec->dateyear = t->tm_year + 1900; + daterec->datemonth = t->tm_mon; + daterec->datedmonth = t->tm_mday; + daterec->datedyear = t->tm_yday; + daterec->datedweek = t->tm_wday; + daterec->datehour = t->tm_hour; + daterec->dateminute = t->tm_min; + daterec->datesecond = t->tm_sec; + daterec->datetzone = 0; /* ??? */ + + return CS_SUCCEED; +} +CS_RETCODE cs_loc_alloc(CS_CONTEXT *ctx, CS_LOCALE **locptr) +{ + return CS_SUCCEED; +} +CS_RETCODE cs_loc_drop(CS_CONTEXT *ctx, CS_LOCALE *locale) +{ + return CS_SUCCEED; +} +CS_RETCODE cs_locale(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + return CS_SUCCEED; +} +CS_RETCODE cs_dt_info(CS_CONTEXT *ctx, CS_INT action, CS_LOCALE *locale, CS_INT type, CS_INT item, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + if (action==CS_SET) { + switch(type) { + case CS_DT_CONVFMT: + break; + } + } + return CS_SUCCEED; +} diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c new file mode 100644 index 000000000..2041f5bf2 --- /dev/null +++ b/src/ctlib/ct.c @@ -0,0 +1,1279 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +static char software_version[] = "$Id: ct.c,v 1.1 2001-10-12 23:29:05 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +/* these function pointers are called by the tds layer to propagate message +** back up to the CLI */ +extern int (*g_tds_msg_handler)(); +extern int (*g_tds_err_handler)(); + +static void _ct_bind_data(CS_COMMAND *cmd); + + +CS_RETCODE ct_exit(CS_CONTEXT *ctx, CS_INT unused) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_exit()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_init(CS_CONTEXT *ctx, CS_INT version) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_init()\n"); + /* set the functions in the TDS layer to point to the correct info/err + * message handler functions */ + g_tds_msg_handler = ctlib_handle_info_message; + g_tds_err_handler = ctlib_handle_err_message; + return CS_SUCCEED; +} +CS_RETCODE ct_con_alloc(CS_CONTEXT *ctx, CS_CONNECTION **con) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_alloc()\n"); + *con = (CS_CONNECTION *) malloc(sizeof(CS_CONNECTION)); + memset(*con,'\0',sizeof(CS_CONNECTION)); + (*con)->tds_login = (void *) tds_alloc_login(); + + /* so we know who we belong to */ + (*con)->ctx = ctx; + + /* set default values */ + tds_set_library((*con)->tds_login, "CT-Library"); + /* tds_set_charset((*con)->tds_login, "iso_1"); */ + /* tds_set_packet((*con)->tds_login, TDS_DEF_BLKSZ); */ + return CS_SUCCEED; +} +CS_RETCODE ct_callback(CS_CONTEXT *ctx, CS_CONNECTION *con, CS_INT action, CS_INT type, CS_VOID *func) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_callback() action = %s\n", + CS_GET ? "CS_GET" : "CS_SET"); + /* one of these has to be defined */ + if (!ctx && !con) + return CS_FAIL; + + if (action==CS_GET) { + switch(type) { + case CS_CLIENTMSG_CB: + func = (CS_VOID *) con ? con->_clientmsg_cb : ctx->_clientmsg_cb; + return CS_SUCCEED; + case CS_SERVERMSG_CB: + func = (CS_VOID *) con ? con->_servermsg_cb : ctx->_servermsg_cb; + return CS_SUCCEED; + default: + fprintf(stderr,"Unknown callback %d\n",type); + func = (CS_VOID *) NULL; + return CS_SUCCEED; + } + } + /* CS_SET */ + switch(type) { + case CS_CLIENTMSG_CB: + if (con) + con->_clientmsg_cb = func; + else + ctx->_clientmsg_cb = func; + break; + case CS_SERVERMSG_CB: + if (con) + con->_servermsg_cb = func; + else + ctx->_servermsg_cb = func; + break; + } + return CS_SUCCEED; +} + +CS_RETCODE ct_con_props(CS_CONNECTION *con, CS_INT action, CS_INT property, +CS_VOID *buffer, CS_INT buflen, CS_INT *out_len) +{ +CS_INT intval = 0, maxcp; +TDSSOCKET *tds; +TDSLOGIN *tds_login; +char *set_buffer = NULL; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_props() action = %d property = %d\n", + action, property); + + tds = con->tds_socket; + tds_login = con->tds_login; + + if (action==CS_SET) { + if (property == CS_USERNAME || property == CS_PASSWORD + || property == CS_APPNAME || property == CS_HOSTNAME) { + if (buflen == CS_NULLTERM) { + maxcp = strlen(buffer); + set_buffer = (char *)malloc(maxcp + 1); + strcpy(set_buffer, buffer); + } else if (buflen == CS_UNUSED) { + return CS_SUCCEED; + } else { + set_buffer = (char *)malloc(buflen + 1); + strncpy(set_buffer, buffer, buflen); + set_buffer[buflen] = '\0'; + } + } + + /* XXX "login" properties shouldn't be set after + * login. I don't know if it should fail silently + * or return an error. + */ + switch (property) { + case CS_USERNAME: + tds_set_user(tds_login, set_buffer); + break; + case CS_PASSWORD: + tds_set_passwd(tds_login, set_buffer); + break; + case CS_APPNAME: + tds_set_app(tds_login, set_buffer); + break; + case CS_HOSTNAME: + tds_set_app(tds_login, set_buffer); + break; + case CS_LOC_PROP: + con->locale = (CS_LOCALE *)buffer; + break; + case CS_USERDATA: + if (con->userdata) { + free(con->userdata); + } + con->userdata = (void *)malloc(buflen+1); + con->userdata_len = buflen; + memcpy(con->userdata, buffer, buflen); + break; + case CS_BULK_LOGIN: + memcpy(&intval, buffer, sizeof(intval)); + if (intval) + tds_set_bulk(tds_login,1); + else + tds_set_bulk(tds_login,0); + break; + case CS_PACKETSIZE: + memcpy(&intval, buffer, sizeof(intval)); + tds_set_packet(tds_login, (short)intval); + break; + case CS_TDS_VERSION: + /* FIX ME + * (a) We don't support all versions in tds/login.c - + * I tried to pick reasonable versions. + * (b) Might need support outside of tds/login.c + * (c) It's a "negotiated" property so probably + * needs tds_process_env_chg() support + * (d) Minor - we don't check against context + * which should limit the acceptable values + */ + if (*(int *)buffer == CS_TDS_40) { + tds_set_version(tds_login, 4, 2); + } else if (*(int *)buffer == CS_TDS_42) { + tds_set_version(tds_login, 4, 2); + } else if (*(int *)buffer == CS_TDS_46) { + tds_set_version(tds_login, 4, 6); + } else if (*(int *)buffer == CS_TDS_495) { + tds_set_version(tds_login, 4, 6); + } else if (*(int *)buffer == CS_TDS_50) { + tds_set_version(tds_login, 5, 0); + } else if (*(int *)buffer == CS_TDS_70) { + tds_set_version(tds_login, 7, 0); + } else { + return CS_FAIL; + } + break; + default: + tdsdump_log(TDS_DBG_ERROR, "%L Unknown property %d\n",property); + break; + } + if (set_buffer) free(set_buffer); + } else if (action==CS_GET) { + switch (property) { + case CS_USERNAME: + maxcp = strlen(tds_login->user_name); + if (out_len) *out_len=maxcp; + if (maxcp>=buflen) maxcp = buflen-1; + strncpy(buffer,tds_login->user_name,maxcp); + ((char *)buffer)[maxcp]='\0'; + break; + case CS_PASSWORD: + maxcp = strlen(tds_login->password); + if (out_len) *out_len=maxcp; + if (maxcp>=buflen) maxcp = buflen-1; + strncpy(buffer,tds_login->password,maxcp); + ((char *)buffer)[maxcp]='\0'; + break; + case CS_APPNAME: + maxcp = strlen(tds_login->app_name); + if (out_len) *out_len=maxcp; + if (maxcp>=buflen) maxcp = buflen-1; + strncpy(buffer,tds_login->app_name,maxcp); + ((char *)buffer)[maxcp]='\0'; + break; + case CS_HOSTNAME: + maxcp = strlen(tds_login->host_name); + if (out_len) *out_len=maxcp; + if (maxcp>=buflen) maxcp = buflen-1; + strncpy(buffer,tds_login->host_name,maxcp); + ((char *)buffer)[maxcp]='\0'; + break; + case CS_LOC_PROP: + buffer = (CS_VOID *)con->locale; + break; + case CS_USERDATA: + maxcp = con->userdata_len; + if (out_len) *out_len=maxcp; + if (maxcp>buflen) maxcp = buflen; + memcpy(buffer, con->userdata, maxcp); + break; + case CS_CON_STATUS: + if (tds && tds->s) + intval |= CS_CONSTAT_CONNECTED; + else + intval &= ~CS_CONSTAT_CONNECTED; + if (tds && tds->state==TDS_DEAD) + intval |= CS_CONSTAT_DEAD; + else + intval &= ~CS_CONSTAT_DEAD; + memcpy(buffer, &intval, sizeof(intval)); + break; + case CS_BULK_LOGIN: + if (tds_login->bulk_copy) + intval=CS_FALSE; + else + intval=CS_TRUE; + memcpy(buffer, &intval, sizeof(intval)); + break; + case CS_PACKETSIZE: + if (tds && tds->env) + intval = tds->env->block_size; + else + intval = tds_login->block_size; + memcpy(buffer, &intval, sizeof(intval)); + if (out_len) *out_len=sizeof(intval); + break; + default: + tdsdump_log(TDS_DBG_ERROR, "%L Unknown property %d\n",property); + break; + } + } + return CS_SUCCEED; +} + +CS_RETCODE ct_connect(CS_CONNECTION *con, CS_CHAR *servername, CS_INT snamelen) +{ +char *server; +int needfree=0; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_connect() servername = %s\n", servername); + + if (snamelen==0 || snamelen==CS_UNUSED) { + server=NULL; + } else if (snamelen==CS_NULLTERM) { + server=(char *)servername; + } else { + server = (char *) malloc(snamelen+1); + needfree++; + strncpy(server,servername,snamelen); + server[snamelen]='\0'; + } + tds_set_server(con->tds_login,server); + if (!(con->tds_socket = (void *) tds_connect(con->tds_login))) { + if (needfree) free(server); + tdsdump_log(TDS_DBG_FUNC, "%L leaving ct_connect() returning %d\n", CS_FAIL); + return CS_FAIL; + } + + tds_set_parent( con->tds_socket, con); + + if (needfree) free(server); + + tdsdump_log(TDS_DBG_FUNC, "%L leaving ct_connect() returning %d\n", CS_SUCCEED); + return CS_SUCCEED; +} +CS_RETCODE ct_cmd_alloc(CS_CONNECTION *con, CS_COMMAND **cmd) +{ + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_alloc()\n"); + + *cmd = (CS_COMMAND *) malloc(sizeof(CS_COMMAND)); + memset(*cmd,'\0',sizeof(CS_COMMAND)); + + /* so we know who we belong to */ + (*cmd)->con = con; + + return CS_SUCCEED; +} +CS_RETCODE ct_command(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT option) +{ +int query_len; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_command()\n"); + /* FIX ME -- will only work for type CS_LANG_CMD */ + if (buflen==CS_NULLTERM) { + query_len = strlen(buffer); + } else { + query_len = buflen; + } + if (cmd->query) free(cmd->query); + cmd->query = (char *) malloc(query_len + 1); + strncpy(cmd->query,(char *)buffer,query_len); + cmd->query[query_len]='\0'; + + return CS_SUCCEED; +} +CS_RETCODE ct_send_dyn(CS_COMMAND *cmd) +{ + if (cmd->dynamic_cmd==CS_PREPARE) { + cmd->dynamic_cmd=0; + if (tds_submit_prepare(cmd->con->tds_socket, cmd->query, cmd->dyn_id)==TDS_FAIL) + return CS_FAIL; + else + return CS_SUCCEED; + } +} +CS_RETCODE ct_send(CS_COMMAND *cmd) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_send()\n"); + if (cmd->dynamic_cmd) + return ct_send_dyn(cmd); + + if (tds_submit_query(cmd->con->tds_socket, cmd->query)==TDS_FAIL) + return CS_FAIL; + else + return CS_SUCCEED; +} +CS_RETCODE ct_results_dyn(CS_COMMAND *cmd, CS_INT *result_type) +{ +TDSRESULTINFO *resinfo; +TDSSOCKET *tds; +TDSDYNAMIC *dyn; + + tds = cmd->con->tds_socket; + + if (cmd->dynamic_cmd==CS_DESCRIBE_INPUT) { + dyn = tds->dyns[tds->cur_dyn_elem]; + if (dyn->dyn_state) { + dyn->dyn_state = 0; + return CS_END_RESULTS; + } else { + dyn->dyn_state++; + *result_type = CS_DESCRIBE_RESULT; + return CS_SUCCEED; + } + } + +} +CS_RETCODE ct_results(CS_COMMAND *cmd, CS_INT *result_type) +{ +TDSRESULTINFO *resinfo; +TDSSOCKET *tds; +int ret; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_results()\n"); + + if (cmd->dynamic_cmd) { + return ct_results_dyn(cmd, result_type); + } + + if (cmd->cmd_done) { + cmd->cmd_done = 0; + *result_type = CS_CMD_DONE; + return CS_SUCCEED; + } + + tds = cmd->con->tds_socket; + + switch (ret = tds_process_result_tokens(tds)) { + case TDS_SUCCEED: + resinfo = tds->res_info; + if (resinfo->rows_exist) { + *result_type = CS_ROW_RESULT; + cmd->cmd_done = 1; + } else { + *result_type = CS_CMD_SUCCEED; + } + return CS_SUCCEED; + case TDS_NO_MORE_RESULTS: + if (tds->res_info && !tds->res_info->rows_exist) { + if (cmd->empty_res_hack) { + cmd->empty_res_hack=0; + *result_type = CS_CMD_DONE; + return CS_END_RESULTS; + } else { + cmd->empty_res_hack=1; + *result_type = CS_ROW_RESULT; + return CS_SUCCEED; + } + } else { + *result_type = CS_CMD_DONE; + return CS_END_RESULTS; + } + case TDS_FAIL: + if (tds->state == TDS_DEAD) { + return CS_FAIL; + } else { + *result_type = CS_CMD_FAIL; + return CS_SUCCEED; + } + default: + return CS_FAIL; + } + return CS_FAIL; +} +CS_RETCODE ct_bind(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT *copied, CS_SMALLINT *indicator) +{ +TDSCOLINFO * colinfo; +CT_COLINFO *ctcolinfo; /* additional information about columns used by ctlib */ +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_bind()\n"); + + tds = (TDSSOCKET *) cmd->con->tds_socket; + resinfo = tds->res_info; + colinfo = resinfo->columns[item-1]; + colinfo->varaddr = (char *)buffer; + colinfo->column_bindtype = datafmt->datatype; + colinfo->column_bindfmt = datafmt->format; + tdsdump_log(TDS_DBG_INFO1, "%L inside ct_bind() item = %d datafmt->datatype = %d\n", item, datafmt->datatype); + colinfo->column_bindlen = datafmt->maxlength; + if (indicator) { + colinfo->column_nullbind = (TDS_CHAR *) indicator; + } + if (copied) { + colinfo->column_lenbind = (TDS_CHAR *) copied; + } + return CS_SUCCEED; +} + +CS_RETCODE ct_fetch(CS_COMMAND *cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT *rows_read) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_fetch()\n"); + + switch (tds_process_row_tokens(cmd->con->tds_socket)) { + case TDS_SUCCEED: + if (rows_read) *rows_read = 1; + _ct_bind_data(cmd); + return TDS_SUCCEED; + case TDS_NO_MORE_ROWS: + if (rows_read) *rows_read = 0; + return CS_END_DATA; + default: + if (rows_read) *rows_read = 0; + return CS_FAIL; + } + return CS_SUCCEED; +} + +static void _ct_bind_data(CS_COMMAND *cmd) +{ +int i; +TDSCOLINFO *curcol; +TDSRESULTINFO *resinfo = cmd->con->tds_socket->res_info; +unsigned char *src; +unsigned char *dest; +TDS_INT srctype, srclen, desttype, destlen, len; + + tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_bind_data()\n"); + + for (i=0; inum_cols; i++) { + curcol = resinfo->columns[i]; + + if (curcol->column_nullbind) { + if (tds_get_null(resinfo->current_row,i)) { + *((CS_SMALLINT *)curcol->column_nullbind) = -1; + } else { + *((CS_SMALLINT *)curcol->column_nullbind) = 0; + } + } + /* printf("%d %s\n",i,resinfo->columns[i]->column_value); */ + + srctype = curcol->column_type; + desttype = _ct_get_server_type(curcol->column_bindtype); + dest = curcol->varaddr; + tdsdump_log(TDS_DBG_INFO1, "%L inside _ct_bind_data() converting column %d from type %d to type %d\n", + i, srctype, desttype); + + if (dest && !tds_get_null(resinfo->current_row,i)) { + srctype = tds_get_conversion_type(srctype, curcol->column_size); + destlen = curcol->column_bindlen; + if (is_blob_type(srctype)) { + src = curcol->column_textvalue; + srclen = curcol->column_textsize; + } else { + src = &(resinfo->current_row[curcol->column_offset]); + srclen = curcol->column_size; + } + tdsdump_log(TDS_DBG_INFO1, "%L inside _ct_bind_data() setting source length for %d = %d\n", i, srclen); + len = tds_convert(srctype, src, srclen, desttype, dest, destlen); + tdsdump_log(TDS_DBG_INFO2, "%L inside _ct_bind_data() conversion done len = %d bindfmt = %d\n", len, curcol->column_bindfmt); + + /* XXX need utf16 support (NCHAR,NVARCHAR,NTEXT) */ + switch (curcol->column_bindfmt) { + case CS_FMT_NULLTERM: + if (desttype==SYBCHAR || desttype==SYBVARCHAR + || desttype==SYBTEXT) { + if (destlen > len) dest[len] = '\0'; + else dest[len-1] = '\0'; + len++; /* CS_FMT_NULLTERM includes the null in the size */ + } + break; + case CS_FMT_UNUSED: + break; + case CS_FMT_PADBLANK: + if (desttype==SYBCHAR || desttype==SYBVARCHAR + || desttype==SYBTEXT) { + if (destlen > len) { + memset(dest+len, (int)' ', destlen - len); + } + } + break; + case CS_FMT_PADNULL: + if (desttype==SYBCHAR || desttype==SYBVARCHAR + || desttype==SYBBINARY || desttype==SYBVARBINARY + || desttype==SYBTEXT || desttype==SYBIMAGE) { + if (destlen > len) { + memset(dest+len, 0, destlen - len); + } + } + break; + default: + break; + } + if (curcol->column_lenbind) { + tdsdump_log(TDS_DBG_INFO1, "%L inside _ct_bind_data() length binding len = %d\n", len); + *((CS_INT *)curcol->column_lenbind) = len; + } + } + } +} + +CS_RETCODE ct_cmd_drop(CS_COMMAND *cmd) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_drop()\n"); + if (cmd) { + if (cmd->query) free(cmd->query); + free(cmd); + } + return CS_SUCCEED; +} +CS_RETCODE ct_close(CS_CONNECTION *con, CS_INT option) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_close()\n"); + tds_free_socket(con->tds_socket); + return CS_SUCCEED; +} + + +CS_RETCODE ct_con_drop(CS_CONNECTION *con) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_drop()\n"); + if (con) { + if (con->userdata) free(con->userdata); + if (con->tds_login) tds_free_login(con->tds_login); + free(con); + } + return CS_SUCCEED; +} + + +int _ct_get_client_type(int datatype, int size) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_get_client_type()\n"); + switch (datatype) { + case SYBBIT: + case SYBBITN: + return CS_BIT_TYPE; + break; + case SYBCHAR: + case SYBVARCHAR: + return CS_CHAR_TYPE; + break; + case SYBINT4: + return CS_INT_TYPE; + break; + case SYBINT2: + return CS_SMALLINT_TYPE; + break; + case SYBINT1: + return CS_TINYINT_TYPE; + break; + case SYBINTN: + if (size==4) { + return CS_INT_TYPE; + } else if (size==2) { + return CS_SMALLINT_TYPE; + } else if (size==1) { + return CS_TINYINT_TYPE; + } else { + fprintf(stderr,"Unknown size %d for SYBINTN\n", size); + } + break; + case SYBREAL: + return CS_REAL_TYPE; + break; + case SYBFLT8: + return CS_FLOAT_TYPE; + break; + case SYBFLTN: + if (size==4) { + return CS_REAL_TYPE; + } else if (size==8) { + return CS_FLOAT_TYPE; + } else { + fprintf(stderr,"Error! unknown float size of %d\n",size); + } + case SYBMONEY: + return CS_MONEY_TYPE; + break; + case SYBMONEY4: + return CS_MONEY4_TYPE; + break; + case SYBMONEYN: + if (size==4) { + return CS_MONEY4_TYPE; + } else if (size==8) { + return CS_MONEY_TYPE; + } else { + fprintf(stderr,"Error! unknown money size of %d\n",size); + } + case SYBDATETIME: + return CS_DATETIME_TYPE; + break; + case SYBDATETIME4: + return CS_DATETIME4_TYPE; + break; + case SYBDATETIMN: + if (size==4) { + return CS_DATETIME4_TYPE; + } else if (size==8) { + return CS_DATETIME_TYPE; + } else { + fprintf(stderr,"Error! unknown date size of %d\n",size); + return CS_FAIL; + } + break; + case SYBNUMERIC: + return CS_NUMERIC_TYPE; + break; + case SYBDECIMAL: + return CS_DECIMAL_TYPE; + break; + case SYBBINARY: + return CS_BINARY_TYPE; + break; + case SYBIMAGE: + return CS_IMAGE_TYPE; + break; + case SYBVARBINARY: + return CS_VARBINARY_TYPE; + break; + case SYBTEXT: + return CS_TEXT_TYPE; + break; + } +} +int _ct_get_server_type(int datatype) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_get_server_type()\n"); + switch (datatype) { + case CS_IMAGE_TYPE: + return SYBIMAGE; + break; + case CS_BINARY_TYPE: + return SYBBINARY; + break; + case CS_BIT_TYPE: + return SYBBIT; + break; + case CS_CHAR_TYPE: + return SYBCHAR; + break; + case CS_INT_TYPE: + return SYBINT4; + break; + case CS_SMALLINT_TYPE: + return SYBINT2; + break; + case CS_TINYINT_TYPE: + return SYBINT1; + break; + case CS_REAL_TYPE: + return SYBREAL; + break; + case CS_FLOAT_TYPE: + return SYBFLT8; + break; + case CS_MONEY_TYPE: + return SYBMONEY; + break; + case CS_MONEY4_TYPE: + return SYBMONEY4; + break; + case CS_DATETIME_TYPE: + return SYBDATETIME; + break; + case CS_DATETIME4_TYPE: + return SYBDATETIME4; + break; + case CS_NUMERIC_TYPE: + return SYBNUMERIC; + break; + case CS_DECIMAL_TYPE: + return SYBDECIMAL; + break; + case CS_VARBINARY_TYPE: + return SYBVARBINARY; + break; + case CS_TEXT_TYPE: + return SYBTEXT; + break; + default: + return -1; + break; + } +} + +CS_RETCODE ct_cancel(CS_CONNECTION *conn, CS_COMMAND *cmd, CS_INT type) +{ + CS_RETCODE ret; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cancel()\n"); + if (type == CS_CANCEL_CURRENT) { + if (conn || !cmd) return CS_FAIL; + while (1) { + ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, NULL); + if ((ret != CS_SUCCEED) && (ret != CS_ROW_FAIL)) { + break; + } + } + if (cmd->con->tds_socket) { + tds_free_results(cmd->con->tds_socket->res_info); + } + return ret; + } + + if ((conn && cmd) || (!conn && !cmd)) { + return CS_FAIL; + } + if (cmd) conn = cmd->con; + tds_send_cancel(conn->tds_socket); + tds_process_cancel(conn->tds_socket); + return CS_SUCCEED; +} + +CS_RETCODE ct_describe(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt) +{ +TDSSOCKET *tds; +TDSRESULTINFO *resinfo; +TDSCOLINFO *curcol; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_describe()\n"); + tds = cmd->con->tds_socket; + + if (cmd->dynamic_cmd) { + resinfo = tds->dyns[tds->cur_dyn_elem]->res_info; + } else { + resinfo = cmd->con->tds_socket->res_info; + } + + if (item<1 || item>resinfo->num_cols) return CS_FAIL; + curcol=resinfo->columns[item-1]; + strncpy(datafmt->name, curcol->column_name, CS_MAX_NAME); + datafmt->namelen = strlen(curcol->column_name); + /* need to turn the SYBxxx into a CS_xxx_TYPE */ + datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_size); + tdsdump_log(TDS_DBG_INFO1, "%L inside ct_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype, curcol->column_type); + datafmt->maxlength = curcol->column_size; + datafmt->usertype = curcol->column_usertype; + datafmt->precision = curcol->column_prec; + datafmt->scale = curcol->column_scale; + /* FIX ME -- TDS 5.0 has status information in the results + ** however, this will work for 4.2 as well */ + if (is_nullable_type(curcol->column_type)) + datafmt->status |= CS_CANBENULL; + datafmt->count = 1; + datafmt->locale = NULL; + + return CS_SUCCEED; +} +CS_RETCODE ct_res_info_dyn(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len) +{ +TDSSOCKET *tds = cmd->con->tds_socket; +TDSDYNAMIC *dyn; +CS_INT int_val; + + switch(type) { + case CS_NUMDATA: + dyn = tds->dyns[tds->cur_dyn_elem]; + int_val = dyn->res_info->num_cols; + memcpy(buffer, &int_val, sizeof(CS_INT)); + break; + default: + fprintf(stderr,"Unknown type in ct_res_info_dyn: %d\n",type); + return CS_FAIL; + } + return CS_SUCCEED; +} +CS_RETCODE ct_res_info(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len) +{ +TDSSOCKET *tds = cmd->con->tds_socket; +TDSRESULTINFO *resinfo = tds->res_info; +CS_INT int_val; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_res_info()\n"); + if (cmd->dynamic_cmd) { + return ct_res_info_dyn(cmd, type, buffer, buflen, out_len); + } + switch(type) { + case CS_NUMDATA: + int_val = resinfo->num_cols; + memcpy(buffer, &int_val, sizeof(CS_INT)); + break; + case CS_ROW_COUNT: + /* resinfo check by kostya@warmcat.excom.spb.su */ + if (resinfo) { + int_val = resinfo->row_count; + } else { + int_val = tds->rows_affected; + } + memcpy(buffer, &int_val, sizeof(CS_INT)); + break; + default: + fprintf(stderr,"Unknown type in ct_res_info: %d\n",type); + return CS_FAIL; + break; + } + return CS_SUCCEED; +} +CS_RETCODE ct_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_config()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_cmd_props(CS_COMMAND *cmd, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_props()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_compute_info(CS_COMMAND *cmd, CS_INT type, CS_INT colnum, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_compute_info()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_get_data(CS_COMMAND *cmd, CS_INT item, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_get_data()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_capability(CS_CONNECTION *con, CS_INT action, CS_INT type, CS_INT capability, CS_VOID *value) +{ +TDSLOGIN *login; +unsigned char *mask; + + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_capability()\n"); + login = (TDSLOGIN *) con->tds_login; + mask = login->capabilities; + + if (action==CS_SET && type==CS_CAP_RESPONSE) { + if (*((CS_BOOL *)value)==CS_TRUE) { + switch(capability) { + case CS_DATA_NOBOUNDARY: + mask[13]|=0x01;break; + case CS_DATA_NOTDSDEBUG: + mask[13]|=0x02;break; + case CS_RES_NOSTRIPBLANKS: + mask[13]|=0x04;break; + case CS_DATA_NOINT8: + mask[13]|=0x08;break; + case CS_DATA_NOINTN: + mask[14]|=0x01;break; + case CS_DATA_NODATETIMEN: + mask[14]|=0x02;break; + case CS_DATA_NOMONEYN: + mask[14]|=0x04;break; + case CS_CON_NOOOB: + mask[14]|=0x08;break; + case CS_CON_NOINBAND: + mask[14]|=0x10;break; + case CS_PROTO_NOTEXT: + mask[14]|=0x20;break; + case CS_PROTO_NOBULK: + mask[14]|=0x40;break; + case CS_DATA_NOSENSITIVITY: + mask[14]|=0x80;break; + case CS_DATA_NOFLT4: + mask[15]|=0x01;break; + case CS_DATA_NOFLT8: + mask[15]|=0x02;break; + case CS_DATA_NONUM: + mask[15]|=0x04;break; + case CS_DATA_NOTEXT: + mask[15]|=0x08;break; + case CS_DATA_NOIMAGE: + mask[15]|=0x10;break; + case CS_DATA_NODEC: + mask[15]|=0x20;break; + case CS_DATA_NOLCHAR: + mask[15]|=0x40;break; + case CS_DATA_NOLBIN: + mask[15]|=0x80;break; + case CS_DATA_NOCHAR: + mask[16]|=0x01;break; + case CS_DATA_NOVCHAR: + mask[16]|=0x02;break; + case CS_DATA_NOBIN: + mask[16]|=0x04;break; + case CS_DATA_NOVBIN: + mask[16]|=0x08;break; + case CS_DATA_NOMNY8: + mask[16]|=0x10;break; + case CS_DATA_NOMNY4: + mask[16]|=0x20;break; + case CS_DATA_NODATE8: + mask[16]|=0x40;break; + case CS_DATA_NODATE4: + mask[16]|=0x80;break; + case CS_RES_NOMSG: + mask[17]|=0x02;break; + case CS_RES_NOEED: + mask[17]|=0x04;break; + case CS_RES_NOPARAM: + mask[17]|=0x08;break; + case CS_DATA_NOINT1: + mask[17]|=0x10;break; + case CS_DATA_NOINT2: + mask[17]|=0x20;break; + case CS_DATA_NOINT4: + mask[17]|=0x40;break; + case CS_DATA_NOBIT: + mask[17]|=0x80;break; + } + } else { + switch(capability) { + case CS_DATA_NOBOUNDARY: + mask[13]&=(!0x01);break; + case CS_DATA_NOTDSDEBUG: + mask[13]&=(!0x02);break; + case CS_RES_NOSTRIPBLANKS: + mask[13]&=(!0x04);break; + case CS_DATA_NOINT8: + mask[13]&=(!0x08);break; + case CS_DATA_NOINTN: + mask[14]&=(!0x01);break; + case CS_DATA_NODATETIMEN: + mask[14]&=(!0x02);break; + case CS_DATA_NOMONEYN: + mask[14]&=(!0x04);break; + case CS_CON_NOOOB: + mask[14]&=(!0x08);break; + case CS_CON_NOINBAND: + mask[14]&=(!0x10);break; + case CS_PROTO_NOTEXT: + mask[14]&=(!0x20);break; + case CS_PROTO_NOBULK: + mask[14]&=(!0x40);break; + case CS_DATA_NOSENSITIVITY: + mask[14]&=(!0x80);break; + case CS_DATA_NOFLT4: + mask[15]&=(!0x01);break; + case CS_DATA_NOFLT8: + mask[15]&=(!0x02);break; + case CS_DATA_NONUM: + mask[15]&=(!0x04);break; + case CS_DATA_NOTEXT: + mask[15]&=(!0x08);break; + case CS_DATA_NOIMAGE: + mask[15]&=(!0x10);break; + case CS_DATA_NODEC: + mask[15]&=(!0x20);break; + case CS_DATA_NOLCHAR: + mask[15]&=(!0x40);break; + case CS_DATA_NOLBIN: + mask[15]&=(!0x80);break; + case CS_DATA_NOCHAR: + mask[16]&=(!0x01);break; + case CS_DATA_NOVCHAR: + mask[16]&=(!0x02);break; + case CS_DATA_NOBIN: + mask[16]&=(!0x04);break; + case CS_DATA_NOVBIN: + mask[16]&=(!0x08);break; + case CS_DATA_NOMNY8: + mask[16]&=(!0x10);break; + case CS_DATA_NOMNY4: + mask[16]&=(!0x20);break; + case CS_DATA_NODATE8: + mask[16]&=(!0x40);break; + case CS_DATA_NODATE4: + mask[16]&=(!0x80);break; + case CS_RES_NOMSG: + mask[17]&=(!0x02);break; + case CS_RES_NOEED: + mask[17]&=(!0x04);break; + case CS_RES_NOPARAM: + mask[17]&=(!0x08);break; + case CS_DATA_NOINT1: + mask[17]&=(!0x10);break; + case CS_DATA_NOINT2: + mask[17]&=(!0x20);break; + case CS_DATA_NOINT4: + mask[17]&=(!0x40);break; + case CS_DATA_NOBIT: + mask[17]&=(!0x80);break; + } + } + } else if (action==CS_GET && type==CS_CAP_RESPONSE) { + switch (capability) { + case CS_DATA_NOBOUNDARY: + *((CS_BOOL *)value)=mask[13]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOTDSDEBUG: + *((CS_BOOL *)value)=mask[13]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_RES_NOSTRIPBLANKS: + *((CS_BOOL *)value)=mask[13]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOINT8: + *((CS_BOOL *)value)=mask[13]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOINTN: + *((CS_BOOL *)value)=mask[14]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NODATETIMEN: + *((CS_BOOL *)value)=mask[14]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOMONEYN: + *((CS_BOOL *)value)=mask[14]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_CON_NOOOB: + *((CS_BOOL *)value)=mask[14]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_CON_NOINBAND: + *((CS_BOOL *)value)=mask[14]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_PROTO_NOTEXT: + *((CS_BOOL *)value)=mask[14]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_PROTO_NOBULK: + *((CS_BOOL *)value)=mask[14]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOSENSITIVITY: + *((CS_BOOL *)value)=mask[14]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOFLT4: + *((CS_BOOL *)value)=mask[15]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOFLT8: + *((CS_BOOL *)value)=mask[15]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NONUM: + *((CS_BOOL *)value)=mask[15]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOTEXT: + *((CS_BOOL *)value)=mask[15]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOIMAGE: + *((CS_BOOL *)value)=mask[15]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NODEC: + *((CS_BOOL *)value)=mask[15]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOLCHAR: + *((CS_BOOL *)value)=mask[15]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOLBIN: + *((CS_BOOL *)value)=mask[15]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOCHAR: + *((CS_BOOL *)value)=mask[16]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOVCHAR: + *((CS_BOOL *)value)=mask[16]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOBIN: + *((CS_BOOL *)value)=mask[16]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOVBIN: + *((CS_BOOL *)value)=mask[16]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOMNY8: + *((CS_BOOL *)value)=mask[16]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOMNY4: + *((CS_BOOL *)value)=mask[16]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NODATE8: + *((CS_BOOL *)value)=mask[16]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NODATE4: + *((CS_BOOL *)value)=mask[16]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_RES_NOMSG: + *((CS_BOOL *)value)=mask[17]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_RES_NOEED: + *((CS_BOOL *)value)=mask[17]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_RES_NOPARAM: + *((CS_BOOL *)value)=mask[17]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOINT1: + *((CS_BOOL *)value)=mask[17]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOINT2: + *((CS_BOOL *)value)=mask[17]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOINT4: + *((CS_BOOL *)value)=mask[17]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NOBIT: + *((CS_BOOL *)value)=mask[17]&0x80 ? CS_TRUE : CS_FALSE;break; + } + } else if (action==CS_GET && type==CS_CAP_REQUEST) { + switch (capability) { + case CS_PROTO_DYNPROC: + *((CS_BOOL *)value)=mask[2]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_FLTN: + *((CS_BOOL *)value)=mask[2]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_BITN: + *((CS_BOOL *)value)=mask[2]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_INT8: + *((CS_BOOL *)value)=mask[2]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_VOID: + *((CS_BOOL *)value)=mask[2]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_CON_INBAND: + *((CS_BOOL *)value)=mask[3]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_CON_LOGICAL: + *((CS_BOOL *)value)=mask[3]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_PROTO_TEXT: + *((CS_BOOL *)value)=mask[3]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_PROTO_BULK: + *((CS_BOOL *)value)=mask[3]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_URGNOTIF: + *((CS_BOOL *)value)=mask[3]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_SENSITIVITY: + *((CS_BOOL *)value)=mask[3]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_BOUNDARY: + *((CS_BOOL *)value)=mask[3]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_PROTO_DYNAMIC: + *((CS_BOOL *)value)=mask[3]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_MONEYN: + *((CS_BOOL *)value)=mask[4]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_PREV: + *((CS_BOOL *)value)=mask[4]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_FIRST: + *((CS_BOOL *)value)=mask[4]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_LAST: + *((CS_BOOL *)value)=mask[4]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_ABS: + *((CS_BOOL *)value)=mask[4]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_REL: + *((CS_BOOL *)value)=mask[4]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_CSR_MULTI: + *((CS_BOOL *)value)=mask[4]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_CON_OOB: + *((CS_BOOL *)value)=mask[4]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_NUM: + *((CS_BOOL *)value)=mask[5]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_TEXT: + *((CS_BOOL *)value)=mask[5]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_IMAGE: + *((CS_BOOL *)value)=mask[5]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_DEC: + *((CS_BOOL *)value)=mask[5]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_LCHAR: + *((CS_BOOL *)value)=mask[5]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_LBIN: + *((CS_BOOL *)value)=mask[5]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_INTN: + *((CS_BOOL *)value)=mask[5]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_DATETIMEN: + *((CS_BOOL *)value)=mask[5]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_BIN: + *((CS_BOOL *)value)=mask[6]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_VBIN: + *((CS_BOOL *)value)=mask[6]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_MNY8: + *((CS_BOOL *)value)=mask[6]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_MNY4: + *((CS_BOOL *)value)=mask[6]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_DATE8: + *((CS_BOOL *)value)=mask[6]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_DATE4: + *((CS_BOOL *)value)=mask[6]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_FLT4: + *((CS_BOOL *)value)=mask[6]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_FLT8: + *((CS_BOOL *)value)=mask[6]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_MSG: + *((CS_BOOL *)value)=mask[7]&0x01 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_PARAM: + *((CS_BOOL *)value)=mask[7]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_INT1: + *((CS_BOOL *)value)=mask[7]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_INT2: + *((CS_BOOL *)value)=mask[7]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_INT4: + *((CS_BOOL *)value)=mask[7]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_BIT: + *((CS_BOOL *)value)=mask[7]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_CHAR: + *((CS_BOOL *)value)=mask[7]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_DATA_VCHAR: + *((CS_BOOL *)value)=mask[7]&0x80 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_LANG: + *((CS_BOOL *)value)=mask[8]&0x02 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_RPC: + *((CS_BOOL *)value)=mask[8]&0x04 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_NOTIF: + *((CS_BOOL *)value)=mask[8]&0x08 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_MSTMT: + *((CS_BOOL *)value)=mask[8]&0x10 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_BCP: + *((CS_BOOL *)value)=mask[8]&0x20 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_CURSOR: + *((CS_BOOL *)value)=mask[8]&0x40 ? CS_TRUE : CS_FALSE;break; + case CS_REQ_DYN: + *((CS_BOOL *)value)=CS_FALSE; /* mask[8]&0x80 ? CS_TRUE : CS_FALSE;*/ break; + } + } else { + /* bad values */ + return CS_FAIL; + } + return CS_SUCCEED; +} +CS_RETCODE ct_dynamic(CS_COMMAND *cmd, CS_INT type, CS_CHAR *id, CS_INT idlen, CS_CHAR *buffer, CS_INT buflen) +{ +static int stmt_no=1; +int query_len, id_len; + + cmd->dynamic_cmd=type; + switch(type) { + case CS_PREPARE: + /* store away the id */ + if (idlen==CS_NULLTERM) { + id_len = strlen(id); + } else { + id_len = idlen; + } + if (cmd->dyn_id) free(cmd->dyn_id); + cmd->dyn_id = (char *) malloc(id_len + 1); + strncpy(cmd->dyn_id,(char *)id,id_len); + cmd->dyn_id[id_len]='\0'; + + /* now the query */ + if (buflen==CS_NULLTERM) { + query_len = strlen(buffer); + } else { + query_len = buflen; + } + if (cmd->query) free(cmd->query); + cmd->query = (char *) malloc(query_len + 1); + strncpy(cmd->query,(char *)buffer,query_len); + cmd->query[query_len]='\0'; + + break; + case CS_DEALLOC: + break; + case CS_DESCRIBE_INPUT: + break; + case CS_EXECUTE: + break; + } + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_dynamic()\n"); + return CS_SUCCEED; +} +CS_RETCODE ct_param(CS_COMMAND *cmd, CS_DATAFMT *datafmt, CS_VOID *data, CS_INT datalen, CS_SMALLINT indicator) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_param()\n"); +} +CS_RETCODE ct_options(CS_CONNECTION *con, CS_INT action, CS_INT option, CS_VOID *param, CS_INT paramlen, CS_INT *outlen) +{ + tdsdump_log(TDS_DBG_FUNC, "%L inside ct_options()\n"); + return CS_SUCCEED; +} diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c new file mode 100644 index 000000000..1587fd823 --- /dev/null +++ b/src/ctlib/ctutil.c @@ -0,0 +1,78 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "ctlib.h" +#include "cspublic.h" +#include "tds.h" +/* #include "fortify.h" */ + + +static char software_version[] = "$Id: ctutil.c,v 1.1 2001-10-12 23:29:05 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +/* all this was copied directly from the dblib functions */ +int ctlib_handle_info_message(void *aStruct) +{ +CS_CONNECTION *con = (CS_CONNECTION *)aStruct; +TDSSOCKET* tds = con->tds_socket; +CS_CLIENTMSG errmsg; + + return ctlib_handle_err_message(aStruct); +/* + memset(&errmsg,'\0',sizeof(errmsg)); + errmsg.msgnumber=tds->msg_info->msg_number; + strcpy(errmsg.msgstring,tds->msg_info->message); + errmsg.msgstringlen=strlen(tds->msg_info->message); + errmsg.osnumber=0; + errmsg.osstring[0]='\0'; + errmsg.osstringlen=0; + if (con->_clientmsg_cb) + con->_clientmsg_cb(con->ctx,con,&errmsg); + else if (con->ctx->_clientmsg_cb) + con->ctx->_clientmsg_cb(con->ctx,con,&errmsg); +*/ +} + +int ctlib_handle_err_message(void *aStruct) +{ +CS_CONNECTION *con = (CS_CONNECTION *)aStruct; +TDSSOCKET* tds = con->tds_socket; +CS_SERVERMSG errmsg; +TDSMSGINFO *msg = tds->msg_info; + + memset(&errmsg,'\0',sizeof(errmsg)); + errmsg.msgnumber=msg->msg_number; + strcpy(errmsg.text,msg->message); + errmsg.state=msg->msg_state; + errmsg.severity=msg->msg_level; + errmsg.line=msg->line_number; + if (msg->server) { + errmsg.svrnlen = strlen(msg->server); + strncpy(errmsg.svrname, msg->server, CS_MAX_NAME); + } + if (msg->proc_name) { + errmsg.proclen = strlen(msg->proc_name); + strncpy(errmsg.proc, msg->proc_name, CS_MAX_NAME); + } + if (con->_servermsg_cb) + con->_servermsg_cb(con->ctx,con,&errmsg); + else if (con->ctx->_servermsg_cb) + con->ctx->_servermsg_cb(con->ctx,con,&errmsg); +} diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am new file mode 100644 index 000000000..f6ed8f10c --- /dev/null +++ b/src/ctlib/unittests/Makefile.am @@ -0,0 +1,11 @@ +TESTS = t0001 t0002 t0003 t0004 +check_PROGRAMS = t0001 t0002 t0003 t0004 + +t0001_SOURCES = t0001.c common.c +t0002_SOURCES = t0002.c common.c +t0003_SOURCES = t0003.c common.c +t0004_SOURCES = t0004.c common.c + +LIBS = ../libct.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h diff --git a/src/ctlib/unittests/Makefile.in b/src/ctlib/unittests/Makefile.in new file mode 100644 index 000000000..1a150c768 --- /dev/null +++ b/src/ctlib/unittests/Makefile.in @@ -0,0 +1,371 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +TESTS = t0001 t0002 t0003 t0004 +check_PROGRAMS = t0001 t0002 t0003 t0004 + +t0001_SOURCES = t0001.c common.c +t0002_SOURCES = t0002.c common.c +t0003_SOURCES = t0003.c common.c +t0004_SOURCES = t0004.c common.c + +LIBS = ../libct.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +t0001_OBJECTS = t0001.o common.o +t0001_LDADD = $(LDADD) +t0001_DEPENDENCIES = +t0001_LDFLAGS = +t0002_OBJECTS = t0002.o common.o +t0002_LDADD = $(LDADD) +t0002_DEPENDENCIES = +t0002_LDFLAGS = +t0003_OBJECTS = t0003.o common.o +t0003_LDADD = $(LDADD) +t0003_DEPENDENCIES = +t0003_LDFLAGS = +t0004_OBJECTS = t0004.o common.o +t0004_LDADD = $(LDADD) +t0004_DEPENDENCIES = +t0004_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(include_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(t0001_SOURCES) $(t0002_SOURCES) $(t0003_SOURCES) $(t0004_SOURCES) +OBJECTS = $(t0001_OBJECTS) $(t0002_OBJECTS) $(t0003_OBJECTS) $(t0004_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/ctlib/unittests/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-checkPROGRAMS: + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) + +distclean-checkPROGRAMS: + +maintainer-clean-checkPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +t0001: $(t0001_OBJECTS) $(t0001_DEPENDENCIES) + @rm -f t0001 + $(LINK) $(t0001_LDFLAGS) $(t0001_OBJECTS) $(t0001_LDADD) $(LIBS) + +t0002: $(t0002_OBJECTS) $(t0002_DEPENDENCIES) + @rm -f t0002 + $(LINK) $(t0002_LDFLAGS) $(t0002_OBJECTS) $(t0002_LDADD) $(LIBS) + +t0003: $(t0003_OBJECTS) $(t0003_DEPENDENCIES) + @rm -f t0003 + $(LINK) $(t0003_LDFLAGS) $(t0003_OBJECTS) $(t0003_LDADD) $(LIBS) + +t0004: $(t0004_OBJECTS) $(t0004_DEPENDENCIES) + @rm -f t0004 + $(LINK) $(t0004_LDFLAGS) $(t0004_OBJECTS) $(t0004_LDADD) $(LIBS) + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/ctlib/unittests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-checkPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-checkPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-checkPROGRAMS distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-checkPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-checkPROGRAMS distclean-checkPROGRAMS \ +clean-checkPROGRAMS maintainer-clean-checkPROGRAMS mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool uninstall-includeHEADERS \ +install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir check-TESTS info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c new file mode 100644 index 000000000..0c74090d1 --- /dev/null +++ b/src/ctlib/unittests/common.c @@ -0,0 +1,171 @@ +#include +#include +#include + +static char software_version[] = "$Id: common.c,v 1.1 2001-10-12 23:29:06 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +char USER[512]; +char SERVER[512]; +char PASSWORD[512]; +char DATABASE[512]; + +CS_RETCODE read_login_info() +{ + FILE *in; + char line[512]; + char *s1, *s2; + + in = fopen("../../../PWD","r"); + if (!in) { + fprintf(stderr,"Can not open PWD file\n\n"); + return CS_FAIL; + } + + while (fgets(line, 512, in)) { + s1=strtok(line,"="); + s2=strtok(NULL,"\n"); + if (!s1 || !s2) { continue; } + if (!strcmp(s1,"UID")) { strcpy(USER,s2); } + else if (!strcmp(s1,"SRV")) { strcpy(SERVER,s2); } + else if (!strcmp(s1,"PWD")) { strcpy(PASSWORD,s2); } + else if (!strcmp(s1,"DB")) { strcpy(DATABASE,s2); } + } + return CS_SUCCEED; +} + + +CS_RETCODE try_ctlogin( + CS_CONTEXT **ctx, + CS_CONNECTION **conn, + CS_COMMAND **cmd, + int verbose) +{ + CS_RETCODE ret; + char query[30]; + + /* read login information from PWD file */ + ret = read_login_info(); + if (ret != CS_SUCCEED) { + if (verbose) { fprintf(stderr,"read_login_info() failed!\n"); } + return ret; + } + ret = cs_ctx_alloc(CS_VERSION_100, ctx); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"Context Alloc failed!\n"); } + return ret; + } + ret = ct_init(*ctx, CS_VERSION_100); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"Library Init failed!\n"); } + return ret; + } + ret = ct_con_alloc(*ctx, conn); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"Connect Alloc failed!\n"); } + return ret; + } + ret = ct_con_props(*conn, CS_SET, CS_USERNAME, USER, CS_NULLTERM, NULL); + if (ret!=CS_SUCCEED) { + if (verbose) { + fprintf(stderr,"ct_con_props() SET USERNAME failed!\n"); + } + return ret; + } + ret = ct_con_props(*conn, CS_SET, CS_PASSWORD, PASSWORD, CS_NULLTERM, NULL); + if (ret!=CS_SUCCEED) { + if (verbose) { + fprintf(stderr,"ct_con_props() SET PASSWORD failed!\n"); + } + return ret; + } + ret = ct_connect(*conn, SERVER, CS_NULLTERM); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"Connection failed!\n"); } + return ret; + } + ret = ct_cmd_alloc(*conn, cmd); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"Command Alloc failed!\n"); } + return ret; + } + + strcpy(query,"use "); + strncat(query,DATABASE,20); + + ret = run_command(*cmd, query); + if (ret != CS_SUCCEED) return ret; + + return CS_SUCCEED; +} + + +CS_RETCODE try_ctlogout( + CS_CONTEXT *ctx, + CS_CONNECTION *conn, + CS_COMMAND *cmd, + int verbose) +{ + CS_RETCODE ret; + + ret = ct_cancel(conn, NULL, CS_CANCEL_ALL); + if (ret!=CS_SUCCEED) { + if (verbose) { fprintf(stderr,"ct_cancel() failed!\n"); } + return ret; + } + ct_cmd_drop(cmd); + ct_close(conn, CS_UNUSED); + ct_con_drop(conn); + ct_exit(ctx, CS_UNUSED); + cs_ctx_drop(ctx); + + return CS_SUCCEED; +} + +/* Run commands from which we expect no results returned */ +CS_RETCODE run_command(CS_COMMAND *cmd, char *sql) +{ + CS_RETCODE ret, results_ret; + CS_INT result_type; + + if (cmd == NULL) { return CS_FAIL; } + + ret = ct_command(cmd, CS_LANG_CMD, sql, CS_NULLTERM, CS_UNUSED); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_command() failed\n"); + return ret; + } + ret = ct_send(cmd); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_send() failed\n"); + return ret; + } + while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) { + switch ((int)result_type) { + case CS_CMD_SUCCEED: + break; + case CS_CMD_DONE: + break; + case CS_CMD_FAIL: + fprintf(stderr,"ct_results() result_type CS_CMD_FAIL.\n"); + /* return CS_FAIL; */ + break; + default: + fprintf(stderr,"ct_results() unexpected result_type.\n"); + return CS_FAIL; + } + } + switch ((int) results_ret) { + case CS_END_RESULTS: + break; + case CS_FAIL: + fprintf(stderr,"ct_results() failed.\n"); + return CS_FAIL; + break; + default: + fprintf(stderr,"ct_results() unexpected return.\n"); + return CS_FAIL; + } + + return CS_SUCCEED; +} diff --git a/src/ctlib/unittests/common.h b/src/ctlib/unittests/common.h new file mode 100644 index 000000000..80d7dceed --- /dev/null +++ b/src/ctlib/unittests/common.h @@ -0,0 +1,14 @@ + +#ifndef COMMON_h +#define COMMON_h + +static char rcsid_common_h [ ] = + "$Id: common.h,v 1.1 2001-10-12 23:29:07 brianb Exp $"; +static void *no_unused_common_h_warn[]={rcsid_common_h, no_unused_common_h_warn}; + +extern char PASSWORD[512]; +extern char USER[512]; +extern char SERVER[512]; +extern char DATABASE[512]; + +#endif diff --git a/src/ctlib/unittests/t0001.c b/src/ctlib/unittests/t0001.c new file mode 100644 index 000000000..41f3fab21 --- /dev/null +++ b/src/ctlib/unittests/t0001.c @@ -0,0 +1,35 @@ +#include +#include +/* only include this if you need access to PWD information */ +/* #include "common.h" */ + +static char software_version[] = "$Id: t0001.c,v 1.1 2001-10-12 23:29:06 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +int main() +{ + CS_CONTEXT *ctx; + CS_CONNECTION *conn; + CS_COMMAND *cmd; + CS_RETCODE ret; + int verbose = 0; + + fprintf(stdout, "%s: Testing login, logout\n", __FILE__); + if (verbose) { fprintf(stdout, "Trying login\n"); } + ret = try_ctlogin(&ctx, &conn, &cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Login failed\n"); + return 1; + } + + if (verbose) { fprintf(stdout, "Trying logout\n"); } + ret = try_ctlogout(ctx, conn, cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Logout failed\n"); + return 2; + } + + if (verbose) { fprintf(stdout, "Test suceeded\n"); } + return 0; +} diff --git a/src/ctlib/unittests/t0002.c b/src/ctlib/unittests/t0002.c new file mode 100644 index 000000000..27644afa1 --- /dev/null +++ b/src/ctlib/unittests/t0002.c @@ -0,0 +1,124 @@ +#include +#include +#include "common.h" + +static char software_version[] = "$Id: t0002.c,v 1.1 2001-10-12 23:29:07 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +/* + * ct_send SQL |select name = @@servername| + * ct_bind variable + * ct_fetch and print results + */ +int main() +{ + CS_CONTEXT *ctx; + CS_CONNECTION *conn; + CS_COMMAND *cmd; + int verbose = 0; + + CS_RETCODE ret; + CS_RETCODE results_ret; + CS_DATAFMT datafmt; + CS_INT datalength; + CS_SMALLINT ind; + CS_INT count, row_count = 0; + CS_INT result_type; + CS_CHAR name[256]; + + fprintf(stdout, "%s: Testing bind & select\n", __FILE__); + if (verbose) { fprintf(stdout, "Trying login\n"); } + ret = try_ctlogin(&ctx, &conn, &cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Login failed\n"); + return 1; + } + + ret = ct_command(cmd, CS_LANG_CMD, "select name = @@servername", + CS_NULLTERM, CS_UNUSED); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_command() failed\n"); + return 1; + } + ret = ct_send(cmd); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_send() failed\n"); + return 1; + } + while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) { + switch ((int)result_type) { + case CS_CMD_SUCCEED: + break; + case CS_CMD_DONE: + break; + case CS_CMD_FAIL: + fprintf(stderr,"ct_results() result_type CS_CMD_FAIL.\n"); + return 1; + case CS_ROW_RESULT: + datafmt.datatype = CS_CHAR_TYPE; + datafmt.format = CS_FMT_NULLTERM; + datafmt.maxlength = 256; + datafmt.count = 1; + datafmt.locale = NULL; + ret = ct_bind(cmd, 1, &datafmt, name, &datalength, &ind); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_bind() failed\n"); + return 1; + } + + while(((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, + &count)) == CS_SUCCEED) + || (ret == CS_ROW_FAIL)) { + row_count += count; + if (ret == CS_ROW_FAIL) { + fprintf(stderr, "ct_fetch() CS_ROW_FAIL on row %d.\n", + row_count); + return 1; + } + else if (ret == CS_SUCCEED) { + if (verbose) { fprintf(stdout, "server name = %s\n", name); } + } + else { + break; + } + } + switch ((int)ret) { + case CS_END_DATA: + break; + case CS_FAIL: + fprintf(stderr, "ct_fetch() returned CS_FAIL.\n"); + return 1; + default: + fprintf(stderr, "ct_fetch() unexpected return.\n"); + return 1; + } + break; + case CS_COMPUTE_RESULT: + fprintf(stderr,"ct_results() unexpected CS_COMPUTE_RESULT.\n"); + return 1; + default: + fprintf(stderr,"ct_results() unexpected result_type.\n"); + return 1; + } + } + switch ((int) results_ret) { + case CS_END_RESULTS: + break; + case CS_FAIL: + fprintf(stderr,"ct_results() failed.\n"); + return 1; + break; + default: + fprintf(stderr,"ct_results() unexpected return.\n"); + return 1; + } + + if (verbose) { fprintf(stdout, "Trying logout\n"); } + ret = try_ctlogout(ctx, conn, cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Logout failed\n"); + return 1; + } + + return 0; +} diff --git a/src/ctlib/unittests/t0003.c b/src/ctlib/unittests/t0003.c new file mode 100644 index 000000000..c1a0b5621 --- /dev/null +++ b/src/ctlib/unittests/t0003.c @@ -0,0 +1,158 @@ +#include +#include +#include "common.h" + +static char software_version[] = "$Id: t0003.c,v 1.1 2001-10-12 23:29:07 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +/* Testing: Retrieve CS_TEXT_TYPE using ct_bind() */ +int main() +{ + CS_CONTEXT *ctx; + CS_CONNECTION *conn; + CS_COMMAND *cmd; + int i, verbose = 0; + + CS_RETCODE ret; + CS_RETCODE results_ret; + CS_INT result_type; + CS_INT col, num_cols; + + CS_DATAFMT datafmt; + CS_INT datalength; + CS_SMALLINT ind; + CS_INT count, row_count = 0; + + CS_CHAR name[1024]; + char large_sql[1024]; + char len600[601]; + char temp[11]; + for (i = 0; i<60; i++) { + sprintf(temp, "_abcde_%03d", (i+1)*10); + strcat(len600, temp); + } + len600[600] = '\0'; + + fprintf(stdout, "%s: Retrieve CS_TEXT_TYPE using ct_bind()\n", __FILE__); + if (verbose) { fprintf(stdout, "Trying login\n"); } + ret = try_ctlogin(&ctx, &conn, &cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Login failed\n"); + return 1; + } + + ret = run_command(cmd, "DROP TABLE test_table"); + if (ret != CS_SUCCEED) return 1; + ret = run_command(cmd, "CREATE TABLE test_table (id int, name text)"); + if (ret != CS_SUCCEED) return 1; +/* + ret = run_command(cmd, "INSERT test_table (id, name) VALUES (1, 'name1')"); + if (ret != CS_SUCCEED) return 1; +*/ + sprintf(large_sql, "INSERT test_table (id, name) VALUES (2, '%s')", len600); + ret = run_command(cmd, large_sql); + if (ret != CS_SUCCEED) return 1; + + ret = ct_command(cmd, CS_LANG_CMD, + "SELECT name FROM test_table", CS_NULLTERM, CS_UNUSED); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_command() failed\n"); + return 1; + } + ret = ct_send(cmd); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_send() failed\n"); + return 1; + } + while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) { + switch ((int)result_type) { + case CS_CMD_SUCCEED: + break; + case CS_CMD_DONE: + break; + case CS_CMD_FAIL: + fprintf(stderr,"ct_results() result_type CS_CMD_FAIL.\n"); + return 1; + case CS_ROW_RESULT: + ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_res_info() failed"); + return 1; + } + if (num_cols != 1) { + fprintf(stderr, "num_cols %d != 1", num_cols); + return 1; + } + ret = ct_describe(cmd, 1, &datafmt); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_describe() failed"); + return 1; + } + datafmt.format = CS_FMT_NULLTERM; + if (datafmt.maxlength > 1024) { + datafmt.maxlength = 1024; + } + ret = ct_bind(cmd, 1, &datafmt, name, &datalength, &ind); + if (ret != CS_SUCCEED) { + fprintf(stderr, "ct_bind() failed\n"); + return 1; + } + + while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, + &count)) == CS_SUCCEED) + || (ret == CS_ROW_FAIL)) { + row_count += count; + if (ret == CS_ROW_FAIL) { + fprintf(stderr, "ct_fetch() CS_ROW_FAIL on row %d.\n", + row_count); + return 1; + } + else { /* ret == CS_SUCCEED */ + if (verbose) { fprintf(stdout, "name = '%s'\n", name); } + if (strcmp(name, len600)) { + fprintf(stderr, "Bad return:\n'%s'\n! =\n'%s'\n", name, len600); + return 1; + } + } + } + switch ((int)ret) { + case CS_END_DATA: + break; + case CS_FAIL: + fprintf(stderr, "ct_fetch() returned CS_FAIL.\n"); + return 1; + default: + fprintf(stderr, "ct_fetch() unexpected return.\n"); + return 1; + } + break; + case CS_COMPUTE_RESULT: + fprintf(stderr,"ct_results() unexpected CS_COMPUTE_RESULT.\n"); + return 1; + default: + fprintf(stderr,"ct_results() unexpected result_type.\n"); + return 1; + } + } + switch ((int) results_ret) { + case CS_END_RESULTS: + break; + case CS_FAIL: + fprintf(stderr,"ct_results() failed.\n"); + return 1; + break; + default: + fprintf(stderr,"ct_results() unexpected return.\n"); + return 1; + } + + if (verbose) { fprintf(stdout, "Trying logout\n"); } + ret = try_ctlogout(ctx, conn, cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Logout failed\n"); + return 1; + } + + return 0; +} + diff --git a/src/ctlib/unittests/t0004.c b/src/ctlib/unittests/t0004.c new file mode 100644 index 000000000..2fba52f48 --- /dev/null +++ b/src/ctlib/unittests/t0004.c @@ -0,0 +1,120 @@ +#include +#include +#include "common.h" + +static char software_version[] = "$Id: t0004.c,v 1.1 2001-10-12 23:29:07 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +/* protos */ +int do_fetch(CS_COMMAND *cmd); + +/* defines */ +#define NUMROWS 5 + +/* Testing: Test order of ct_results() */ +int main() +{ + CS_CONTEXT *ctx; + CS_CONNECTION *conn; + CS_COMMAND *cmd; + int i, verbose = 0; + + CS_RETCODE ret; + CS_RETCODE results_ret; + CS_INT result_type; + CS_INT col, num_cols; + + CS_DATAFMT datafmt; + CS_INT datalength; + CS_SMALLINT ind; + char query[1024]; + CS_INT results[] = {CS_ROW_RESULT, CS_CMD_DONE, CS_END_RESULTS}; + int result_num = 0; + + fprintf(stdout, "%s: Check ordering of returns from cs_results()\n", __FILE__); + if (verbose) { fprintf(stdout, "Trying login\n"); } + ret = try_ctlogin(&ctx, &conn, &cmd, verbose); + if (ret != CS_SUCCEED) { + fprintf(stderr, "Login failed\n"); + return 1; + } + + ret = run_command(cmd, "DROP TABLE t0004"); + if (ret != CS_SUCCEED) return 1; + ret = run_command(cmd, "CREATE TABLE t0004 (id int)"); + if (ret != CS_SUCCEED) return 1; + for (i=0;i /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +bcp.lo bcp.o : bcp.c ../../include/tdsutil.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/sybfront.h ../../include/sybdb.h \ + ../../include/dblib.h +dblib.lo dblib.o : dblib.c ../../include/tdsutil.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/sybfront.h ../../include/sybdb.h \ + ../../include/dblib.h ../../include/tdsconvert.h +dbutil.lo dbutil.o : dbutil.c ../../include/sybdb.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/dblib.h +rpc.lo rpc.o : rpc.c ../../include/tdsutil.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/sybfront.h ../../include/sybdb.h \ + ../../include/dblib.h +xact.lo xact.o : xact.c ../../include/tdsutil.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/sybfront.h ../../include/sybdb.h \ + ../../include/dblib.h + +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-recursive +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c new file mode 100644 index 000000000..7369d6982 --- /dev/null +++ b/src/dblib/bcp.c @@ -0,0 +1,577 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tdsutil.h" +#include "tds.h" +#include "sybfront.h" +#include "sybdb.h" +#include "dblib.h" +#include + + +static char software_version[] = "$Id: bcp.c,v 1.1 2001-10-12 23:29:10 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +RETCODE BCP_SETL(LOGINREC *login, DBBOOL enable) +{ + tds_set_bulk(login->tds_login, enable); + return SUCCEED; +} +RETCODE bcp_init(DBPROCESS *dbproc, char *tblname, char *hfile, char *errfile, int direction) +{ + dbproc->bcp_hostfile = (char *) malloc(strlen(hfile)+1); + strcpy(dbproc->bcp_hostfile, hfile); + dbproc->bcp_errorfile = (char *) malloc(strlen(errfile)+1); + strcpy(dbproc->bcp_errorfile, errfile); + dbproc->bcp_tablename = (char *) malloc(strlen(tblname)+1); + strcpy(dbproc->bcp_tablename, tblname); + dbproc->bcp_direction = direction; + return SUCCEED; +} +RETCODE bcp_collen(DBPROCESS *dbproc, DBINT varlen, int table_column) +{ + return SUCCEED; +} +RETCODE bcp_columns(DBPROCESS *dbproc, int host_colcount) +{ +int i; + if (dbproc->bcp_columns) { + for (i=0;ibcp_colcount;i++) { + if (dbproc->bcp_columns[i]->terminator) + free(dbproc->bcp_columns[i]->terminator); + free(dbproc->bcp_columns[i]); + } + free(dbproc->bcp_columns); + } + dbproc->bcp_colcount = host_colcount; + dbproc->bcp_columns = (BCP_COLINFO **) malloc(host_colcount * sizeof(BCP_COLINFO *)); + for (i=0;ibcp_colcount;i++) { + dbproc->bcp_columns[i] = (BCP_COLINFO *) malloc(sizeof(BCP_COLINFO)); + memset(dbproc->bcp_columns[i], '\0', sizeof(BCP_COLINFO)); + } + + return SUCCEED; +} +RETCODE bcp_colfmt(DBPROCESS *dbproc, int host_colnum, int host_type, int host_prefixlen, DBINT host_collen, BYTE *host_term,int host_termlen, int table_colnum) +{ +BCP_COLINFO *bcpcol; + + if (host_colnum < 1 || host_colnum > dbproc->bcp_colcount) + return FAIL; + + bcpcol = dbproc->bcp_columns[host_colnum - 1]; + bcpcol->datatype = host_type; + bcpcol->prefix_len = host_prefixlen; + bcpcol->column_len = host_collen; + bcpcol->terminator = (BYTE *) malloc(host_termlen+1); + memcpy(bcpcol->terminator, host_term, host_termlen); + bcpcol->term_len = host_termlen; + bcpcol->column = table_colnum; + + return SUCCEED; +} +RETCODE bcp_colfmt_ps(DBPROCESS *dbproc, int host_colnum, int host_type, int host_prefixlen, DBINT host_collen, BYTE *host_term,int host_termlen, int table_colnum, DBTYPEINFO *typeinfo) +{ + return SUCCEED; +} +RETCODE bcp_control(DBPROCESS *dbproc, int field, DBINT value) +{ + return SUCCEED; +} +RETCODE bcp_colptr(DBPROCESS *dbproc, BYTE *colptr, int table_column) +{ + return SUCCEED; +} +DBBOOL bcp_getl(LOGINREC *login) +{ + return SUCCEED; +} +static RETCODE _bcp_exec_out(DBPROCESS *dbproc, DBINT *rows_copied) +{ +char query[256]; +int ret; +int i; +TDSSOCKET *tds = dbproc->tds_socket; +TDSRESULTINFO *resinfo; +BCP_COLINFO *bcpcol; +TDSCOLINFO *curcol; +BYTE *src; +int srctype; +BYTE dest[256]; +long len; +FILE *hostfile; +TDS_TINYINT ti; +TDS_SMALLINT si; +TDS_INT li; + + + if (! (hostfile = fopen(dbproc->bcp_hostfile, "w"))) { + return FAIL; + } + + sprintf(query,"select * from %s", dbproc->bcp_tablename); + tds_submit_query(tds,query); + + if (tds_process_result_tokens(tds) == TDS_FAIL) { + fclose(hostfile); + return FAIL; + } + if (!tds->res_info) { + fclose(hostfile); + return FAIL; + } + + resinfo=tds->res_info; + + while (tds_process_row_tokens(tds)==TDS_SUCCEED) { + for (i=0;ibcp_colcount;i++) { + bcpcol=dbproc->bcp_columns[i]; + curcol=resinfo->columns[bcpcol->column - 1]; + if (is_blob_type(curcol->column_type)) { + /* FIX ME -- no converts supported */ + src = curcol->column_textvalue; + len = curcol->column_textsize; + } else { + src = &resinfo->current_row[curcol->column_offset]; + + srctype = tds_get_conversion_type(curcol->column_type, curcol->column_size); + len = tds_convert(srctype, + src, curcol->column_size, + bcpcol->datatype, dest, 255); + } + + /* FIX ME -- does not handle prefix_len == -1 */ + /* The prefix */ + switch (bcpcol->prefix_len) { + case 1: + ti = len; + fwrite(&ti,sizeof(ti),1,hostfile); + break; + case 2: + si = len; + fwrite(&si,sizeof(si),1,hostfile); + break; + case 4: + li = len; + fwrite(&li,sizeof(li),1,hostfile); + break; + } + + /* The data */ + if (is_blob_type(curcol->column_type)) { + fwrite(src,len,1,hostfile); + } else { + if (bcpcol->column_len != -1) { + len = len > bcpcol->column_len ? + bcpcol->column_len : len; + } + fwrite(dest,len,1,hostfile); + } + + /* The terminator */ + if (bcpcol->terminator && bcpcol->term_len > 0) { + fwrite(bcpcol->terminator, + bcpcol->term_len, 1, hostfile); + } + } + } + fclose(hostfile); + *rows_copied = resinfo->row_count; + return SUCCEED; +} + +/* +** _bcp_start_copy() sends the 'bulk insert' command, processes the result +** set, and stores results to the BCP_COLINFO structure +*/ +static RETCODE _bcp_start_copy(DBPROCESS *dbproc) +{ +TDSSOCKET *tds = dbproc->tds_socket; +TDSRESULTINFO *resinfo; +BCP_COLINFO *bcpcol; +TDSCOLINFO *curcol; +int colid; +int i; +char query[256]; +int marker; + +if (IS_TDS42(tds)) { + sprintf(query,"select * from %s where 0=1",dbproc->bcp_tablename); + tds_submit_query(tds,query); + + if (tds_process_result_tokens(tds) == TDS_FAIL) { + return FAIL; + } + if (!tds->res_info) { + return FAIL; + } + resinfo = tds->res_info; + + for (i=0;inum_cols;i++) { + /* FIX ME -- assumes file and table in same order */ + curcol = resinfo->columns[i]; + bcpcol=dbproc->bcp_columns[i]; + + bcpcol->db_type = curcol->column_type; + bcpcol->db_length = curcol->column_size; + } +} + sprintf(query,"insert bulk %s",dbproc->bcp_tablename); + tds_submit_query(tds,query); + +if (IS_TDS50(tds)) { + + if (tds_process_result_tokens(tds) == TDS_FAIL) { + return FAIL; + } + if (!tds->res_info) { + return FAIL; + } + + resinfo = tds->res_info; + while (tds_process_row_tokens(tds) == SUCCEED) { + curcol = resinfo->columns[4]; + colid = resinfo->current_row[curcol->column_offset]; + bcpcol = NULL; + for (i=0;ibcp_colcount;i++) { + if (dbproc->bcp_columns[i]->column == colid) + bcpcol=dbproc->bcp_columns[i]; + } + if (!bcpcol) { + fprintf(stderr,"Error: bcp_colfmt not called for database column %d\n",colid); + } else { + /* db_type */ + curcol = resinfo->columns[5]; + bcpcol->db_type = resinfo->current_row[curcol->column_offset]; + /* db_length */ + curcol = resinfo->columns[6]; + memcpy(&bcpcol->db_length, + &resinfo->current_row[curcol->column_offset],4); + /* db_offset */ + curcol = resinfo->columns[8]; + memcpy(&bcpcol->db_offset, + &resinfo->current_row[curcol->column_offset],2); + } + } +} else { + marker = tds_get_byte(tds); + tds_process_default_tokens(tds,marker); + if (!is_end_token(marker)) { + return FAIL; + } +} + return SUCCEED; + +} + +RETCODE _bcp_read_hostfile(DBPROCESS *dbproc, FILE *hostfile) +{ +TDSSOCKET *tds = dbproc->tds_socket; +TDSRESULTINFO *resinfo; +BCP_COLINFO *bcpcol; +TDSCOLINFO *curcol; +int i; +TDS_TINYINT ti; +TDS_SMALLINT si; +TDS_INT li; +int collen; +int bytes_read; + + for (i=0;ibcp_colcount;i++) { + bcpcol = dbproc->bcp_columns[i]; + collen = 0; + /* FIX ME -- handle the prefix_len == -1 case */ + /* Prefix */ + if (bcpcol->prefix_len) { + switch(bcpcol->prefix_len) { + case 1: + fread(&ti, 1, 1, hostfile); + collen = ti; + break; + case 2: + fread(&si, 1, 1, hostfile); + collen = si; + break; + case 4: + fread(&li, 1, 1, hostfile); + collen = li; + break; + } + } + /* FIX ME -- handle null case */ + /* Column Length */ + if (bcpcol->column_len>0) + collen = bcpcol->column_len; + + /* Fixed Length data */ + if (!collen && is_fixed_type(bcpcol->datatype)) { + collen = get_size_by_type(bcpcol->datatype); + } + + if (bcpcol->data) { + free(bcpcol->data); + } + bcpcol->data_size = collen; + bcpcol->data = (BYTE *) malloc(collen + 1); + if (collen) { + bytes_read = fread(bcpcol->data,collen,1,hostfile); + if (!bytes_read) + return FAIL; + } else { + bcpcol->data[0]='\0'; /* debugging */ + } + } + return SUCCEED; +} + +/* +** Add fixed size columns to the row +*/ +static int _bcp_add_fixed_columns(DBPROCESS *dbproc, BYTE *rowbuffer, int start) +{ +int row_pos = start; +BCP_COLINFO *bcpcol; +int i; +int cpbytes; + + for(i=0;ibcp_colcount;i++) { + /* FIX ME -- assumes number and order of columns + ** in file matches that of the database */ + bcpcol = dbproc->bcp_columns[i]; + if (!is_nullable_type(bcpcol->db_type)) { + /* compute the length to copy to the row + ** buffer */ + cpbytes = bcpcol->data_size > bcpcol->db_length + ? bcpcol->db_length : bcpcol->data_size; + memcpy(&rowbuffer[row_pos],bcpcol->data,cpbytes); + + if (row_pos != bcpcol->db_offset) { + fprintf(stderr,"Error: computed offset does not match one returned from database engine\n"); + } + row_pos += bcpcol->db_length; + } + } + return row_pos; +} + +/* +** Add variable size columns to the row +*/ +static int _bcp_add_variable_columns(DBPROCESS *dbproc, BYTE *rowbuffer, int start) +{ +int row_pos = start; +BCP_COLINFO *bcpcol; +int i; +int cpbytes; +int eod_ptr; +BYTE offset_table[256]; +int offset_pos = 0; +BYTE adjust_table[256]; +int adjust_pos = 0; +int num_cols = 0; + + for(i=0;ibcp_colcount;i++) { + /* FIX ME -- see fixed columns */ + bcpcol = dbproc->bcp_columns[i]; + if (is_nullable_type(bcpcol->db_type)) { + if (is_blob_type(bcpcol->db_type)) { + /* no need to copy they are all zero bytes */ + cpbytes = 16; + /* save for data write */ + bcpcol->txptr_offset = row_pos; + } else { + /* compute the length to copy to the row + ** buffer */ + cpbytes = bcpcol->data_size > bcpcol->db_length + ? bcpcol->db_length : bcpcol->data_size; + memcpy(&rowbuffer[row_pos],bcpcol->data,cpbytes); + } + + /* update offset and adjust tables (if necessary) */ + offset_table[offset_pos++] = row_pos % 256; + if (row_pos > 255 && + (adjust_pos==0 || + row_pos/256 != adjust_table[adjust_pos])) { + adjust_table[adjust_pos++]=row_pos / 256; + } + + num_cols++; + row_pos += cpbytes; + } + } + eod_ptr = row_pos; + + /* write the marker */ + rowbuffer[row_pos++]=num_cols + 1; + + /* write the adjust table (right to left) */ + for (i=adjust_pos-1;i>=0;i--) { + fprintf(stderr,"adjust %d\n",adjust_table[i]); + rowbuffer[row_pos++]=adjust_table[i]; + } + + /* the EOD (end of data) pointer */ + rowbuffer[row_pos++]=eod_ptr; + + /* write the offset table (right to left) */ + for (i=offset_pos-1;i>=0;i--) { + fprintf(stderr,"offset %d\n",offset_table[i]); + rowbuffer[row_pos++]=offset_table[i]; + } + + return row_pos; +} +static RETCODE _bcp_exec_in(DBPROCESS *dbproc, DBINT *rows_copied) +{ +FILE *hostfile; +TDSSOCKET *tds = dbproc->tds_socket; +TDSRESULTINFO *resinfo; +BCP_COLINFO *bcpcol; +TDSCOLINFO *curcol; +int i; +int collen; +/* FIX ME -- calculate dynamically */ +unsigned char rowbuffer[32768]; +int row_pos; +/* end of data pointer...the last byte of var data before the adjust table */ +int var_cols; +int row_sz_pos; +TDS_SMALLINT row_size; +unsigned char magic1[] = {0x07,0x00,0x08,0x00,0x00,0x00,0x00,0x00}; +int marker; +int blob_cols = 0; + + if (! (hostfile = fopen(dbproc->bcp_hostfile, "r"))) { + return FAIL; + } + + if (_bcp_start_copy(dbproc)==FAIL) { + fclose(hostfile); + return FAIL; + } + resinfo = tds->res_info; + + for(i=0;ibcp_colcount;i++) { + bcpcol = dbproc->bcp_columns[i]; + if (is_nullable_type(bcpcol->db_type)) + var_cols++; + } + /* set packet type to send bulk data */ + tds->out_flag = 0x07; + while (_bcp_read_hostfile(dbproc,hostfile)==SUCCEED) { + /* zero the rowbuffer */ + memset(rowbuffer,'\0',32768); + + /* offset 0 = number of var columns */ + /* offset 1 = row number. zeroed (datasever assigns) */ + row_pos = 2; + rowbuffer[0] = var_cols; + + row_pos = _bcp_add_fixed_columns(dbproc, rowbuffer, row_pos); +if (IS_TDS42(tds)) { + row_pos += 2; /* Microsoft mystery bytes */ +} + if (var_cols) { + row_sz_pos = row_pos; + row_pos += 2; /* row length */ + row_pos = _bcp_add_variable_columns(dbproc, rowbuffer, row_pos); + row_size = row_pos; + } + memcpy(&rowbuffer[row_sz_pos],&row_size,sizeof(row_size)); + row_size = row_pos; + tds_put_smallint(tds,row_size); + tds_put_n(tds,rowbuffer,row_size); + + /* row is done, now handle any text/image data */ + blob_cols = 0; + for (i=0;ibcp_colcount;i++) { + bcpcol=dbproc->bcp_columns[i]; + if (is_blob_type(bcpcol->db_type)) { + /* unknown but zero */ + tds_put_smallint(tds,0); + tds_put_byte(tds,bcpcol->db_type); + tds_put_byte(tds,0xff - blob_cols); + /* offset of txptr we stashed during variable + ** column processing */ + tds_put_smallint(tds, bcpcol->txptr_offset); + tds_put_int(tds, bcpcol->data_size); + tds_put_n(tds,bcpcol->data, bcpcol->data_size); + blob_cols++; + } + } + } + + fclose(hostfile); + + /* tds_put_n(tds,magic1,8); */ + tds_flush_packet(tds); + + do { + marker = tds_get_byte(tds); + if (marker==TDS_DONE_TOKEN) { + *rows_copied = tds_process_end(tds,marker,NULL,NULL); + } else { + tds_process_default_tokens(tds,marker); + } + } while (marker!=TDS_DONE_TOKEN); + + return SUCCEED; +} +RETCODE bcp_exec(DBPROCESS *dbproc, DBINT *rows_copied) +{ + if (dbproc->bcp_hostfile) { + if (dbproc->bcp_direction==DB_OUT) { + return _bcp_exec_out(dbproc,rows_copied); + } else if (dbproc->bcp_direction==DB_IN) { + return _bcp_exec_in(dbproc,rows_copied); + } + } + return FAIL; +} +RETCODE bcp_sendrow(DBPROCESS *dbproc) +{ + return SUCCEED; +} +RETCODE bcp_readfmt(DBPROCESS *dbproc, char *filename) +{ + return SUCCEED; +} +RETCODE bcp_writefmt(DBPROCESS *dbproc, char *filename) +{ + return SUCCEED; +} +RETCODE bcp_moretext(DBPROCESS *dbproc, DBINT size, BYTE *text) +{ + return SUCCEED; +} +RETCODE bcp_batch(DBPROCESS *dbproc) +{ + return SUCCEED; +} +RETCODE bcp_done(DBPROCESS *dbproc) +{ + return SUCCEED; +} +RETCODE bcp_bind(DBPROCESS *dbproc, BYTE *varaddr, int prefixlen, DBINT varlen, + BYTE *terminator, int termlen, int type, int table_column) +{ + return SUCCEED; +} diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c new file mode 100644 index 000000000..be23eb978 --- /dev/null +++ b/src/dblib/dblib.c @@ -0,0 +1,2077 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tdsutil.h" +#include "tds.h" +#include "sybfront.h" +#include "sybdb.h" +#include "dblib.h" +#include "tdsconvert.h" +#include +#include +#include +#include +#include + +static char software_version[] = "$Id: dblib.c,v 1.1 2001-10-12 23:29:09 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +static int _db_get_server_type(int bindtype); +static int _get_printable_size(TDSCOLINFO *colinfo); + +/* info/err message handler functions (or rather pointers to them) */ +int (*g_dblib_msg_handler)() = NULL; +int (*g_dblib_err_handler)() = NULL; +TDSCONTEXT *g_tds_context = NULL; +extern int (*g_tds_msg_handler)(); +extern int (*g_tds_err_handler)(); +#ifdef TDS42 +int g_dblib_version = DBVERSION_42; +#endif +#ifdef TDS50 +int g_dblib_version = DBVERSION_100; +#endif +#ifdef TDS46 +int g_dblib_version = DBVERSION_46; +#endif +/* I'm taking some liberties here, there is no such thing as DBVERSION_70 in +** the real world, so we make it up as we go along */ +#ifdef TDS70 +int g_dblib_version = DBVERSION_70; +#endif + + +static void buffer_init(DBPROC_ROWBUF *buf) +{ + memset(buf, 0xad, sizeof(*buf)); + + buf->buffering_on = 0; + buf->first_in_buf = 0; + buf->newest = -1; + buf->oldest = 0; + buf->elcount = 0; + buf->element_size = 0; + buf->rows_in_buf = 0; + buf->rows = NULL; + buf->next_row = 1; +} /* buffer_init() */ + +static void buffer_clear(DBPROC_ROWBUF *buf) +{ + buf->next_row = 1; + buf->first_in_buf = 0; + buf->newest = -1; + buf->oldest = 0; + buf->rows_in_buf = 0; + if (buf->rows) { + free(buf->rows); + } + buf->rows = NULL; +} /* buffer_clear() */ + + +static void buffer_free(DBPROC_ROWBUF *buf) +{ + if (buf->rows != NULL) + { + free(buf->rows); + } + buf->rows = NULL; +} /* clear_buffer() */ + +static void buffer_delete_rows( + DBPROC_ROWBUF *buf, /* (U) buffer to clear */ + int count) /* (I) number of elements to purge */ +{ + assert(count <= buf->elcount); /* possibly a little to pedantic */ + + if (count > buf->rows_in_buf) + { + count = buf->rows_in_buf; + } + + + buf->oldest = (buf->oldest + count) % buf->elcount; + buf->rows_in_buf -= count; + buf->first_in_buf = count==buf->rows_in_buf ? buf->next_row-1 : buf->first_in_buf + count; + + + assert(buf->first_in_buf >= 0); +} /* buffer_delete_rows() */ + + +static int buffer_start_resultset( + DBPROC_ROWBUF *buf, /* (U) buffer to clear */ + int element_size) /* */ +{ + int space_needed = -1; + + assert(element_size > 0); + + if (buf->rows != NULL) + { + memset(buf->rows, 0xad, buf->element_size*buf->rows_in_buf); + free(buf->rows); + } + + buf->first_in_buf = 0; + buf->next_row = 1; + buf->newest = -1; + buf->oldest = 0; + buf->elcount = buf->buffering_on ? buf->elcount : 1; + buf->element_size = element_size; + buf->rows_in_buf = 0; + space_needed = element_size * buf->elcount; + buf->rows = malloc(space_needed); + + return buf->rows==NULL ? FAIL : SUCCEED; +} /* buffer_start_resultset() */ + + +static void buffer_delete_all_rows( + DBPROC_ROWBUF *buf) /* (U) buffer to clear */ +{ + buffer_delete_rows(buf, buf->rows_in_buf); +} /* delete_all_buffer_rows() */ + +static int buffer_index_of_resultset_row( + DBPROC_ROWBUF *buf, /* (U) buffer to clear */ + int row_number) /* (I) */ +{ + int result = -1; + + if (row_number < buf->first_in_buf) + { + result = -1; + } + else if (row_number > ((buf->rows_in_buf + buf->first_in_buf) -1)) + { + result = -1; + } + else + { + result = ((row_number - buf->first_in_buf) + + buf->oldest) % buf->elcount; + } + return result; +} /* buffer_index_of_resultset_row() */ + + +static void *buffer_row_address( + DBPROC_ROWBUF *buf, /* (U) buffer to clear */ + int index) /* (I) raw index of row to return */ +{ + void *result = NULL; + + assert(index >= 0); + assert(index < buf->elcount); + + if (index>=buf->elcount || index<0) + { + result = NULL; + } + else + { + int offset = buf->element_size * (index % buf->elcount); + result = (char *)buf->rows + offset; + } + return result; +} /* buffer_row_address() */ + + +static void buffer_add_row( + DBPROC_ROWBUF *buf, /* (U) buffer to add row into */ + void *row, /* (I) pointer to the row data */ + int row_size) +{ + void *dest = NULL; + + assert(row_size > 0); + assert(row_size == buf->element_size); + + assert(buf->elcount >= 1); + + buf->newest = (buf->newest + 1) % buf->elcount; + if (buf->rows_in_buf==0 && buf->first_in_buf==0) + { + buf->first_in_buf = 1; + } + buf->rows_in_buf++; + + /* + * if we have wrapped around we need to adjust oldest + * and rows_in_buf + */ + if (buf->rows_in_buf > buf->elcount) + { + buf->oldest = (buf->oldest + 1) % buf->elcount; + buf->first_in_buf++; + buf->rows_in_buf--; + } + + assert(buf->elcount >= buf->rows_in_buf); + assert( buf->rows_in_buf==0 + || (((buf->oldest+buf->rows_in_buf) - 1)%buf->elcount)==buf->newest); + assert(buf->rows_in_buf>0 || (buf->first_in_buf==buf->next_row-1)); + assert(buf->rows_in_buf==0 || + (buf->first_in_buf<=buf->next_row)); + assert(buf->next_row-1 <= (buf->first_in_buf + buf->rows_in_buf)); + + dest = buffer_row_address(buf, buf->newest); + memcpy(dest, row, row_size); +} /* buffer_add_row() */ + + +static int buffer_is_full(DBPROC_ROWBUF *buf) +{ + return buf->rows_in_buf==buf->elcount; +} /* buffer_is_full() */ + +static void buffer_set_buffering( + DBPROC_ROWBUF *buf, /* (U) */ + int buf_size) /* (I) number of rows to buffer, 0 to turn off */ +{ + /* XXX If the user calls this routine in the middle of + * a result set and changes the size of the buffering + * they are pretty much toast. + * + * We need to figure out what to do if the user shrinks the + * size of the row buffer. What rows should be thrown out, + * what should happen to the current row, etc? + */ + + assert(buf_size >= 0); + + if (buf_size < 0) + { + /* XXX is it okay to ignore this? */ + } + else if (buf_size == 0) + { + buf->buffering_on = 0; + buf->elcount = 1; + buffer_delete_all_rows(buf); + } + else + { + buf->buffering_on = 1; + buffer_clear(buf); + buffer_free(buf); + buf->elcount = buf_size; + if (buf->element_size > 0) + { + buf->rows = malloc(buf->element_size * buf->elcount); + } + else + { + buf->rows = NULL; + } + } +} /* buffer_set_buffering() */ + +static void buffer_transfer_bound_data( + DBPROC_ROWBUF *buf, /* (U) */ + DBPROCESS *dbproc, /* (I) */ + int row_num) /* (I) resultset row number */ +{ + int i, j; + TDSCOLINFO *curcol; + TDSRESULTINFO *resinfo; + TDSSOCKET *tds; + int srctype; + char *src; + int desttype; + /* this should probably go somewhere else */ + TDS_NUMERIC numeric; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + + for (i=0;inum_cols;i++) + { + curcol = resinfo->columns[i]; + if (curcol->column_nullbind) + { + if (tds_get_null(resinfo->current_row,i)) { + *((DBINT *)curcol->column_nullbind)=-1; + } else { + *((DBINT *)curcol->column_nullbind)=0; + } + } + if (curcol->varaddr && !tds_get_null(resinfo->current_row,i)) + { + int index = buffer_index_of_resultset_row(buf, row_num); + + if (index<0) + { + assert(1==0); + /* XXX now what? */ + } + else + { + DBINT srclen = -1; + + if (is_blob_type(curcol->column_type)) { + srclen = curcol->column_textsize; + src = curcol->column_textvalue; + } else { + src = ((char*)buffer_row_address(buf, index)) + + curcol->column_offset; + } + desttype = _db_get_server_type(curcol->column_bindtype); + srctype = tds_get_conversion_type(curcol->column_type, + curcol->column_size); + + dbconvert(dbproc, + srctype, /* srctype */ + src, /* src */ + srclen, /* srclen */ + desttype, /* desttype */ + curcol->varaddr, /* dest */ + curcol->column_bindlen); /* destlen */ + /* dbconvert will null terminate the string + ** if bindtype is STRINGBIND it should be + ** space padded to column_size + */ + if (curcol->column_type==SYBCHAR && + curcol->column_bindtype==STRINGBIND) { + for (j=strlen(curcol->varaddr);jcolumn_size;j++) { + curcol->varaddr[j]=' '; + } + curcol->varaddr[j]='\0'; + } + } + + } + } +} /* buffer_transfer_bound_data() */ + +RETCODE dbinit() +{ + /* set the functions in the TDS layer to point to the correct info/err + * message handler functions */ + g_tds_msg_handler = dblib_handle_info_message; + g_tds_err_handler = dblib_handle_err_message; + /* TDSCONTEXT stores a list of current connections so they may be closed + ** with dbexit() */ + g_tds_context = (TDSCONTEXT *) malloc(sizeof(TDSCONTEXT)); + memset(g_tds_context,'\0',sizeof(TDSCONTEXT)); + + return SUCCEED; +} +LOGINREC *dblogin() +{ +LOGINREC * loginrec; + + loginrec = (LOGINREC *) malloc(sizeof(LOGINREC)); + loginrec->tds_login = (void *) tds_alloc_login(); + + /* set default values for loginrec */ + tds_set_library(loginrec->tds_login,"DB-Library"); + /* tds_set_charset(loginrec->tds_login,"iso_1"); */ + /* tds_set_packet(loginrec->tds_login,TDS_DEF_BLKSZ); */ + + return loginrec; +} +void dbloginfree(LOGINREC *login) +{ + if (login) { + tds_free_login(login->tds_login); + free(login); + } +} +RETCODE DBSETLCHARSET(LOGINREC *login, char *charset) +{ + tds_set_charset(login->tds_login,charset); +} +RETCODE DBSETLPACKET(LOGINREC *login, short packet_size) +{ + tds_set_packet(login->tds_login,packet_size); + return SUCCEED; +} +RETCODE DBSETLPWD(LOGINREC *login, char *password) +{ + tds_set_passwd(login->tds_login,password); + return SUCCEED; +} +RETCODE DBSETLUSER(LOGINREC *login, char *username) +{ + tds_set_user(login->tds_login,username); + return SUCCEED; +} +RETCODE DBSETLHOST(LOGINREC *login, char *hostname) +{ + tds_set_host(login->tds_login,hostname); + return SUCCEED; +} +RETCODE DBSETLAPP(LOGINREC *login, char *application) +{ + tds_set_app(login->tds_login,application); + return SUCCEED; +} +#ifdef DBMFIX +DBPROCESS *tdsdbopen(LOGINREC *login,char *server) +#else +DBPROCESS *dbopen(LOGINREC *login,char *server) +#endif +{ + DBPROCESS *dbproc; + char *envbuf; + int version_value; + + dbproc = (DBPROCESS *) malloc(sizeof(DBPROCESS)); + memset(dbproc,'\0',sizeof(DBPROCESS)); + tds_set_server(login->tds_login,server); + + dbproc->tds_socket = (void *) tds_connect(login->tds_login); + dbproc->dbbuf = NULL; + dbproc->dbbufsz = 0; + + if(dbproc->tds_socket) { + tds_set_parent( dbproc->tds_socket, dbproc); + tds_add_connection(g_tds_context, dbproc->tds_socket); + } else { + fprintf(stderr,"DB-Library: Login incorrect.\n"); + return NULL; + } + + buffer_init(&(dbproc->row_buf)); + + return dbproc; +} + +RETCODE dbfcmd(DBPROCESS *dbproc, char *fmt, ...) +{ +va_list ap; +char *tmpstr; +int n, size = 1024; +int done = 0; +RETCODE ret; + + tmpstr = (char *)malloc (size); + if (!tmpstr) return FAIL; + + while (1) { + va_start(ap, fmt); + n = vsnprintf (tmpstr, size, fmt, ap); + va_end(ap); + if (n > size) { + size = n+1; + } else if (n<0) { + size *= 2; + } else { + /* we had enough space */ + break; + } + tmpstr = realloc (tmpstr, size); + if (!tmpstr) return FAIL; + } + + ret = dbcmd(dbproc, tmpstr); + free(tmpstr); + + return ret; +} + +RETCODE dbcmd(DBPROCESS *dbproc, char *cmdstring) +{ +int newsz; +void *p; + + if(dbproc == NULL) { + return FAIL; + } + if(dbproc->dbbufsz == 0) { + dbproc->dbbuf = (unsigned char *) malloc(strlen(cmdstring)+1); + if(dbproc->dbbuf == NULL) { + return FAIL; + } + strcpy(dbproc->dbbuf,cmdstring); + dbproc->dbbufsz = strlen(cmdstring) + 1; + } else { + newsz = strlen(cmdstring) + dbproc->dbbufsz; + if((p=realloc(dbproc->dbbuf,newsz)) == NULL) { + return FAIL; + } + dbproc->dbbuf = (unsigned char *)p; + strcat(dbproc->dbbuf,cmdstring); + dbproc->dbbufsz = newsz; + } + + return SUCCEED; +} +RETCODE dbsqlexec(DBPROCESS *dbproc) +{ +RETCODE rc = FAIL; +TDSSOCKET *tds; + + if (dbproc == NULL) { + return FAIL; + } + tds = (TDSSOCKET *) dbproc->tds_socket; + if (!tds || !tds->s) return FAIL; + + if (tds->res_info && tds->res_info->more_results) + /* if (dbproc->more_results && tds_is_end_of_results(dbproc->tds_socket)) */ + { + dbresults(dbproc); + } + + if (SUCCEED == (rc = dbsqlsend(dbproc))) + { + /* + * XXX We need to observe the timeout value and abort + * if this times out. + */ + rc = dbsqlok(dbproc); + } + dbproc->empty_res_hack = 0; + return rc; +} + +RETCODE dbuse(DBPROCESS *dbproc,char *dbname) +{ +char query[255]; +/* int retval; */ + + if (dbproc == NULL) return FAIL; + sprintf(query,"use %s",dbname); + dbcmd(dbproc,query); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + while (dbnextrow(dbproc)!=NO_MORE_ROWS); + return SUCCEED; +} + +RETCODE dbclose(DBPROCESS *dbproc) +{ +TDSRESULTINFO *resinfo; +TDSSOCKET *tds; +int i; + + tds = (TDSSOCKET *) dbproc->tds_socket; + if (tds) { + buffer_free(&(dbproc->row_buf)); + tds_free_socket(tds); + } + if (dbproc->bcp_tablename) + free(dbproc->bcp_tablename); + if (dbproc->bcp_hostfile) + free(dbproc->bcp_hostfile); + if (dbproc->bcp_errorfile) + free(dbproc->bcp_errorfile); + if (dbproc->bcp_columns) { + for (i=0;ibcp_colcount;i++) { + if (dbproc->bcp_columns[i]->terminator) + free(dbproc->bcp_columns[i]->terminator); + if (dbproc->bcp_columns[i]->data) + free(dbproc->bcp_columns[i]->data); + free(dbproc->bcp_columns[i]); + } + free(dbproc->bcp_columns); + } + + dbfreebuf(dbproc); + tds_del_connection(g_tds_context, dbproc->tds_socket); + free(dbproc); + + return SUCCEED; +} +void dbexit() +{ +TDSSOCKET *tds; +DBPROCESS *dbproc; +int i; + + /* FIX ME -- this breaks if ctlib/dblib used in same process */ + for (i=0;iconnection_list[i]; + if (tds) { + dbproc = (DBPROCESS *) tds->parent; + dbclose(dbproc); + } + } +} + + +RETCODE dbresults_r(DBPROCESS *dbproc, int recursive) +{ +RETCODE retcode = FAIL; +unsigned char marker; +TDSSOCKET *tds; + + + /* + * For now let's assume we have only 5 possible classes of tokens + * at the next byte in the TDS stream + * 1) The start of a result set, either TDS_RESULT_TOKEN (tds ver 5.0) + * or TDS_COL_NAME_TOKEN (tds ver 4.2). + * 2) A row token (TDS_ROW_TOKEN) + * 3) An end token (either 0xFD or 0xFE) + * 4) A done in proc token (0xFF) + * 5) A message or error token + */ + + if (dbproc == NULL) return FAIL; + buffer_clear(&(dbproc->row_buf)); + + tds = dbproc->tds_socket; + if (!tds || !tds->s) return FAIL; + + retcode = tds_process_result_tokens(tds); + + if (retcode == TDS_NO_MORE_RESULTS) { + if (tds->res_info && tds->res_info->rows_exist) { + return NO_MORE_RESULTS; + } else { + if (!dbproc->empty_res_hack) { + dbproc->empty_res_hack = 1; + return SUCCEED; + } else { + dbproc->empty_res_hack = 0; + return NO_MORE_RESULTS; + } + } + } + if (retcode == TDS_SUCCEED) { + retcode = buffer_start_resultset(&(dbproc->row_buf), + tds->res_info->row_size); + } + return retcode; +} + +/* =============================== dbresults() =============================== + * + * Def: + * + * Ret: SUCCEED, FAIL, NO_MORE_RESULTS, or NO_MORE_RPC_RESULTS + * + * =========================================================================== + */ +RETCODE dbresults(DBPROCESS *dbproc) +{ +RETCODE rc; + tdsdump_log(TDS_DBG_FUNC, "%L inside dbresults()\n"); + if (dbproc == NULL) return FAIL; + rc = dbresults_r(dbproc, 0); + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbresults() returning %d\n",rc); + return rc; +} + + +int dbnumcols(DBPROCESS *dbproc) +{ +TDSRESULTINFO *resinfo; +TDSSOCKET *tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (resinfo) + return resinfo->num_cols; + return 0; +} +char *dbcolname(DBPROCESS *dbproc, int column) +{ +static char buf[255]; +TDSRESULTINFO *resinfo; +TDSSOCKET *tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (column < 1 || column > resinfo->num_cols) return NULL; + strcpy (buf,resinfo->columns[column-1]->column_name); + return buf; +} + +RETCODE dbgetrow( + DBPROCESS *dbproc, + DBINT row) +{ + RETCODE result = FAIL; + int index = buffer_index_of_resultset_row(&(dbproc->row_buf), row); + if (-1 == index) + { + result = NO_MORE_ROWS; + } + else + { + dbproc->row_buf.next_row = row; + buffer_transfer_bound_data(&(dbproc->row_buf), dbproc, row); + dbproc->row_buf.next_row++; + result = REG_ROW; + } + + return result; +} + +RETCODE dbnextrow(DBPROCESS *dbproc) +{ + TDSRESULTINFO *resinfo; + TDSSOCKET *tds; + int rc; + RETCODE result = FAIL; + int marker; + + tdsdump_log(TDS_DBG_FUNC, "%L inside dbnextrow()\n"); + + if (dbproc == NULL) return FAIL; + tds = (TDSSOCKET *) dbproc->tds_socket; + if (!tds || !tds->s) { + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbnextrow() returning %d\n",FAIL); + return FAIL; + } + + resinfo = tds->res_info; + if (!resinfo) { + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbnextrow() returning %d\n",NO_MORE_ROWS); + return NO_MORE_ROWS; + } + + if (dbproc->row_buf.buffering_on && buffer_is_full(&(dbproc->row_buf)) + && (-1 == buffer_index_of_resultset_row(&(dbproc->row_buf), + dbproc->row_buf.next_row))) + { + result = BUF_FULL; + } + else + { + /* + * Now try to get the dbproc->row_buf.next_row item into the row + * buffer + */ + if (-1 != buffer_index_of_resultset_row(&(dbproc->row_buf), + dbproc->row_buf.next_row)) + { + /* + * Cool, the item we want is already there + */ + rc = TDS_SUCCEED; + result = REG_ROW; + } + else + { + /* + * XXX Note- we need to handle "compute" results as well. + * I don't believe the current src/tds/token.c handles those + * so we don't handle them yet either. + */ + + /* + * Get the row from the TDS stream. + */ + rc = tds_process_row_tokens(dbproc->tds_socket); + if (rc == TDS_SUCCEED) + { + /* + * Add the row to the row buffer + */ + buffer_add_row(&(dbproc->row_buf), resinfo->current_row, + resinfo->row_size); + result = REG_ROW; + } + else if (rc == TDS_NO_MORE_ROWS) + { + result = NO_MORE_ROWS; + } + else + { + result = FAIL; + } + } + + if (result == REG_ROW) + { + /* + * The data is in the row buffer, now transfer it to the + * bound variables + */ + buffer_transfer_bound_data(&(dbproc->row_buf), dbproc, + dbproc->row_buf.next_row); + dbproc->row_buf.next_row++; + } + } + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbnextrow() returning %d\n",result); + return result; +} /* dbnextrow() */ + +static int _db_get_server_type(int bindtype) +{ + switch (bindtype) { + case CHARBIND: + case STRINGBIND: + case NTBSTRINGBIND: + return SYBCHAR; + break; + case FLT8BIND: + return SYBFLT8; + break; + case REALBIND: + return SYBREAL; + break; + case INTBIND: + return SYBINT4; + break; + case SMALLBIND: + return SYBINT2; + break; + case TINYBIND: + return SYBINT1; + break; + default: + return -1; + break; + } +} +/* Notes on changes: +** conversion functions are now handled in the TDS layer. +** The main reason for this is that ctlib and ODBC (and presumably DBI) need +** to be able to do conversions between datatypes. This is possible because +** the format of complex data (dates, money, numeric, decimal) is defined by +** its representation on the wire, thus what we call DBMONEY is exactly its +** format on the wire. CLIs that need a differtent representation (ODBC?) +** need to convert from this format anyway, so the code would already be in +** place. +** The datatypes are also defined by its Server-type so all CLIs should be +** able to map native types to server types as well. +*/ +DBINT dbconvert(DBPROCESS *dbproc, + int srctype, + BYTE *src, + DBINT srclen, + int desttype, + BYTE *dest, + DBINT destlen) +{ + if (srclen==-1) srclen = strlen(src); + return tds_convert(srctype, src, srclen, desttype, dest, destlen); +} +RETCODE dbbind( + DBPROCESS *dbproc, + int column, + int vartype, + DBINT varlen, + BYTE *varaddr) +{ + TDSCOLINFO *colinfo = NULL; + TDSRESULTINFO *resinfo = NULL; + TDSSOCKET *tds = NULL; + int srctype = -1; + int okay = TRUE; /* so far, so good */ + + /* + * Note on logic- I'm using a boolean variable 'okay' to tell me if + * everything that has happened so far has gone okay. Basically if + * something happened that wasn't okay we don't want to keep doing + * things, but I also don't want to have a half dozen exit points from + * this function. So basically I've wrapped each set of operation in a + * "if (okay)" statement. Once okay becomes false we skip everything + * else. + */ + okay = (dbproc!=NULL && dbproc->tds_socket!=NULL && varaddr!=NULL); + + if (okay) + { + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + } + + okay = okay && ((column >= 1) && (column <= resinfo->num_cols)); + + if (okay) + { + colinfo = resinfo->columns[column-1]; + srctype = tds_get_conversion_type(colinfo->column_type, + colinfo->column_size); + okay = okay && dbwillconvert(srctype, vartype); + } + + if (okay) + { + colinfo->varaddr = (char *)varaddr; + colinfo->column_bindtype = vartype; + colinfo->column_bindlen = varlen; + } + + return okay ? SUCCEED : FAIL; +} /* dbbind() */ + +void dbsetifile(char *filename) +{ + set_interfaces_file_loc(filename); +} +RETCODE dbnullbind(DBPROCESS *dbproc, int column, DBINT *indicator) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + /* + * XXX Need to check for possibly problems before assuming + * everything is okay + */ + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + colinfo = resinfo->columns[column-1]; + colinfo->column_nullbind = (TDS_CHAR *) indicator; + + return SUCCEED; +} +DBINT DBCOUNT(DBPROCESS *dbproc) +{ +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (resinfo) + return resinfo->row_count; + else return tds->rows_affected; +} +void dbclrbuf(DBPROCESS *dbproc, DBINT n) +{ + if (n <= 0) return; + + if (dbproc->row_buf.buffering_on) + { + if (n >= dbproc->row_buf.rows_in_buf) { + buffer_delete_rows(&(dbproc->row_buf), dbproc->row_buf.rows_in_buf - 1); + } else { + buffer_delete_rows(&(dbproc->row_buf), n); + } + } +} +DBBOOL dbwillconvert(int srctype, int desttype) +{ + /* XXX */ + return TRUE; +} +int dbcoltype(DBPROCESS *dbproc,int column) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + colinfo = resinfo->columns[column-1]; + switch (colinfo->column_type) { + case SYBVARCHAR: + return SYBCHAR; + case SYBVARBINARY: + return SYBBINARY; + case SYBDATETIMN: + if (colinfo->column_size==8) + return SYBDATETIME; + else if (colinfo->column_size==4) + return SYBDATETIME4; + case SYBMONEYN: + return SYBMONEY; + case SYBFLTN: + if (colinfo->column_size==8) + return SYBFLT8; + else if (colinfo->column_size==4) + return SYBREAL; + case SYBINTN: + if (colinfo->column_size==4) + return SYBINT4; + else if (colinfo->column_size==2) + return SYBINT2; + else if (colinfo->column_size==1) + return SYBINT1; + default: + return colinfo->column_type; + } + return 0; /* something went wrong */ +} +DBTYPEINFO *dbcoltypeinfo(DBPROCESS *dbproc, int column) +{ +/* FIXME -- this is not thread safe, we would need to move typeinfo into +** the dbproc structure, however that seems a waste for such a little used +** function...maybe malloc it when used, cleanup on dbclose() */ +static DBTYPEINFO typeinfo; +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + colinfo = resinfo->columns[column-1]; + typeinfo.precision = colinfo->column_prec; + typeinfo.scale = colinfo->column_scale; + return &typeinfo; +} +char *dbcolsource(DBPROCESS *dbproc,int colnum) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + colinfo = resinfo->columns[colnum-1]; + return colinfo->column_name; +} +DBINT dbcollen(DBPROCESS *dbproc, int column) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (column<1 || column>resinfo->num_cols) return -1; + colinfo = resinfo->columns[column-1]; + return colinfo->column_size; +} +DBINT dbdatlen(DBPROCESS *dbproc, int column) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +DBINT ret; + + /* FIX ME -- this is the columns info, need per row info */ + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (column<1 || column>resinfo->num_cols) return -1; + colinfo = resinfo->columns[column-1]; + tdsdump_log(TDS_DBG_INFO1, "%L dbdatlen() type = %d\n",colinfo->column_type); + + if (tds_get_null(resinfo->current_row,column-1)) { + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning 0\n"); + return 0; + } else if (colinfo->column_type==SYBVARCHAR) { + ret = strlen(&resinfo->current_row[colinfo->column_offset]); + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning %d\n",ret); + return(ret); + } else if (is_blob_type(colinfo->column_type)) { + ret = colinfo->column_textsize; + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning %d\n",ret); + return(ret); + } else { + ret = colinfo->column_size; + tdsdump_log(TDS_DBG_FUNC, "%L leaving dbdatlen() returning %d\n",ret); + return ret; + } +} +BYTE *dbdata(DBPROCESS *dbproc, int column) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +TDS_VARBINARY *varbin; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + if (column<1 || column>resinfo->num_cols) return NULL; + + colinfo = resinfo->columns[column-1]; + if (tds_get_null(resinfo->current_row,column-1)) { + return NULL; + } + if (is_blob_type(colinfo->column_type)) { + return colinfo->column_textvalue; + } + if (colinfo->column_type == SYBVARBINARY) { + varbin = (TDS_VARBINARY *) + &(resinfo->current_row[colinfo->column_offset]); + return varbin->array; + } + + /* else */ + return &resinfo->current_row[colinfo->column_offset]; +} +RETCODE dbcancel(DBPROCESS *dbproc) +{ + tds_send_cancel(dbproc->tds_socket); + tds_process_cancel(dbproc->tds_socket); + /* tds_process_default_tokens(dbproc->tds_socket,CANCEL); */ + return SUCCEED; +} +DBINT dbspr1rowlen(DBPROCESS *dbproc) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +int i,col,len=0,collen,namlen; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + + for (col=0;colnum_cols;col++) + { + colinfo = resinfo->columns[col]; + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len += collen > namlen ? collen : namlen; + } + /* the space between each column */ + len += resinfo->num_cols - 1; + /* the newline */ + len++; + + return len; +} +RETCODE dbspr1row(DBPROCESS *dbproc, char *buffer, DBINT buf_len) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +int i,col,collen,namlen,len; +char dest[256]; +int desttype, srctype; +int buf_cur=0; +RETCODE ret; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + + buffer[0]='\0'; + + if ((ret = dbnextrow(dbproc))!=REG_ROW) + return ret; + + for (col=0;colnum_cols;col++) + { + colinfo = resinfo->columns[col]; + if (tds_get_null(resinfo->current_row,col)) { + strcpy(dest,"NULL"); + } else { + desttype = _db_get_server_type(STRINGBIND); + srctype = tds_get_conversion_type(colinfo->column_type,colinfo->column_size); + dbconvert(dbproc, srctype ,dbdata(dbproc,col+1), -1, desttype, dest, 255); + + } + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + for (i=strlen(dest);itds_socket; + resinfo = tds->res_info; + + while(dbnextrow(dbproc)==REG_ROW) { + for (col=0;colnum_cols;col++) + { + colinfo = resinfo->columns[col]; + if (tds_get_null(resinfo->current_row,col)) { + strcpy(dest,"NULL"); + } else { + desttype = _db_get_server_type(STRINGBIND); + srctype = tds_get_conversion_type(colinfo->column_type,colinfo->column_size); + dbconvert(dbproc, srctype ,dbdata(dbproc,col+1), -1, desttype, dest, 255); + + /* printf ("some data\t"); */ + } + printf("%s",dest); + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + for (i=strlen(dest);icolumn_type) { + case SYBINTN: + switch(colinfo->column_size) { + case 1: return 3; + case 2: return 6; + case 4: return 11; + } + case SYBINT1: + return 3; + case SYBINT2: + return 6; + case SYBINT4: + return 11; + case SYBVARCHAR: + case SYBCHAR: + return colinfo->column_size; + case SYBFLT8: + return 11; /* FIX ME -- we do not track precision */ + case SYBREAL: + return 11; /* FIX ME -- we do not track precision */ + case SYBMONEY: + return 12; /* FIX ME */ + case SYBMONEY4: + return 12; /* FIX ME */ + case SYBDATETIME: + return 26; /* FIX ME */ + case SYBDATETIME4: + return 26; /* FIX ME */ + case SYBBIT: + case SYBBITN: + return 1; + /* FIX ME -- not all types present */ + default: + return 0; + } + +} +RETCODE dbsprline(DBPROCESS *dbproc,char *buffer, DBINT buf_len, DBCHAR line_char) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +int i,col, len, collen, namlen; +char line_str[2],dest[256]; +int buf_cur=0; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + + buffer[0]='\0'; + line_str[0]=line_char; + line_str[1]='\0'; + + for (col=0;colnum_cols;col++) + { + dest[0]='\0'; + colinfo = resinfo->columns[col]; + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + for (i=0;itds_socket; + resinfo = tds->res_info; + + buffer[0]='\0'; + + for (col=0;colnum_cols;col++) + { + colinfo = resinfo->columns[col]; + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + strcpy(dest,colinfo->column_name); + for (i=strlen(colinfo->column_name);itds_socket; + resinfo = tds->res_info; + for (col=0;colnum_cols;col++) + { + colinfo = resinfo->columns[col]; + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + printf("%s",colinfo->column_name); + for (i=strlen(colinfo->column_name);inum_cols;col++) + { + colinfo = resinfo->columns[col]; + collen = _get_printable_size(colinfo); + namlen = strlen(colinfo->column_name); + len = collen > namlen ? collen : namlen; + for (i=0;itds_socket; + resinfo = tds->res_info; + if (resinfo->rows_exist) return TRUE; + else return FALSE; +} +/* STUBS */ +RETCODE dbsetdeflang(char *language) +{ + return SUCCEED; +} +int dbgetpacket(DBPROCESS *dbproc) +{ +TDSSOCKET *tds = dbproc->tds_socket; + + if (!tds || !tds->env) { + return TDS_DEF_BLKSZ; + } else { + return tds->env->block_size; + } +} +RETCODE dbsetmaxprocs(int maxprocs) +{ + return SUCCEED; +} +RETCODE dbsettime(int seconds) +{ + return SUCCEED; +} +RETCODE dbsetlogintime(int seconds) +{ + return SUCCEED; +} +DBBOOL dbhasretstat(DBPROCESS *dbproc) +{ +TDSSOCKET *tds = (TDSSOCKET *) dbproc->tds_socket; + if (tds->has_status) { + return TRUE; + } else { + return FALSE; + } +} +DBINT dbretstatus(DBPROCESS *dbproc) +{ +TDSSOCKET *tds = (TDSSOCKET *) dbproc->tds_socket; + return tds->ret_status; +} +RETCODE DBCMDROW(DBPROCESS *dbproc) +{ + TDSSOCKET *tds = (TDSSOCKET *) dbproc->tds_socket; + if (tds->res_info) + return SUCCEED; + return TDS_FAIL; +} +int dbaltcolid(DBPROCESS *dbproc, int computeid, int column) +{ + return -1; +} +DBINT dbadlen(DBPROCESS *dbproc,int computeid, int column) +{ + return 0; +} +int dbalttype(DBPROCESS *dbproc, int computeid, int column) +{ + return 0; +} +BYTE *dbadata(DBPROCESS *dbproc, int computeid, int column) +{ + return ""; +} +int dbaltop(DBPROCESS *dbproc, int computeid, int column) +{ + return -1; +} +RETCODE dbsetopt(DBPROCESS *dbproc, int option, char *char_param, int int_param) +{ + switch (option) { + case DBBUFFER: + { + /* XXX should be more robust than just a atoi() */ + buffer_set_buffering(&(dbproc->row_buf), atoi(char_param)); + break; + } + default: + { + break; + } + } + return SUCCEED; +} +void dbsetinterrupt(DBPROCESS *dbproc, int (*ckintr)(),int (*hndlintr)()) +{ +} +int dbnumrets(DBPROCESS *dbproc) +{ + return 0; +} +char *dbretname(DBPROCESS *dbproc, int retnum) +{ + return NULL; +} +BYTE *dbretdata(DBPROCESS *dbproc, int retnum) +{ + return NULL; +} +int dbretlen(DBPROCESS *dbproc, int retnum) +{ + return -1; +} +RETCODE dbsqlok(DBPROCESS *dbproc) +{ +unsigned char marker; +RETCODE rc = SUCCEED; +TDSSOCKET *tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + + if (dbproc->text_sent) { + tds_flush_packet(tds); + dbproc->text_sent = 0; + + do { + marker = tds_get_byte(tds); + tds_process_default_tokens(tds, marker); + } while (marker!=TDS_DONE_TOKEN); + + return SUCCEED; + } + /* + * See what the next packet from the server is. If it is an error + * then we should return FAIL + */ +/* Calling dbsqlexec on an update only stored proc should read all tokens + while (is_msg_token(tds_peek(tds))) { + marker = tds_get_byte(tds); + if (tds_process_default_tokens(tds, marker)!=TDS_SUCCEED) { + rc=FAIL; + } + } +*/ + do { + marker = tds_peek(tds); + if (!is_result_token(marker)) { + marker = tds_get_byte(tds); + if (tds_process_default_tokens(tds, marker)!=TDS_SUCCEED) { + rc=FAIL; + } + } + } while (!is_hard_end_token(marker) && !is_result_token(marker)); + + /* clean up */ + if (rc==TDS_ERROR && !is_end_token(marker)) { + do { + marker = tds_get_byte(tds); + tds_process_default_tokens(tds, marker); + } while (marker!=TDS_DONE_TOKEN); + } + return rc; +} +int dbnumalts(DBPROCESS *dbproc,int computeid) +{ + return 0; +} +BYTE *dbbylist(DBPROCESS *dbproc, int computeid, int size) +{ + return NULL; +} +DBBOOL DBDEAD(DBPROCESS *dbproc) +{ + if(dbproc && + dbproc->tds_socket && + dbproc->tds_socket->s) + return FALSE; + else + return TRUE; +} + +int (*dberrhandle(int (*handler)())) () +{ + int (*retFun)() = g_dblib_err_handler; + + g_dblib_err_handler = handler; + return retFun; +} + +int (*dbmsghandle(int (*handler)()))() +{ + int (*retFun)() = g_dblib_msg_handler; + + g_dblib_msg_handler = handler; + return retFun; +} + +RETCODE dbmnyadd(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY *sum) +{ + return SUCCEED; +} +RETCODE dbmnysub(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY *diff) +{ + return SUCCEED; +} +RETCODE dbmnymul(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY *prod) +{ + return SUCCEED; +} +RETCODE dbmnydivide(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2, DBMONEY *quotient) +{ + return SUCCEED; +} +RETCODE dbmnycmp(DBPROCESS *dbproc, DBMONEY *m1, DBMONEY *m2) +{ + return SUCCEED; +} +RETCODE dbmnyscale(DBPROCESS *dbproc, DBMONEY *dest, int multiplier, int addend) +{ + return SUCCEED; +} +RETCODE dbmnyzero(DBPROCESS *dbproc, DBMONEY *dest) +{ + return SUCCEED; +} +RETCODE dbmnymaxpos(DBPROCESS *dbproc, DBMONEY *dest) +{ + return SUCCEED; +} +RETCODE dbmnymaxneg(DBPROCESS *dbproc, DBMONEY *dest) +{ + return SUCCEED; +} +RETCODE dbmnyndigit(DBPROCESS *dbproc, DBMONEY *mnyptr,DBCHAR *value, DBBOOL *zero) +{ + return SUCCEED; +} +RETCODE dbmnyinit(DBPROCESS *dbproc,DBMONEY *mnyptr, int trim, DBBOOL *negative) +{ + return SUCCEED; +} +RETCODE dbmnydown(DBPROCESS *dbproc,DBMONEY *mnyptr, int divisor, int *remainder) +{ + return SUCCEED; +} +RETCODE dbmnyinc(DBPROCESS *dbproc,DBMONEY *mnyptr) +{ + return SUCCEED; +} +RETCODE dbmnydec(DBPROCESS *dbproc,DBMONEY *mnyptr) +{ + return SUCCEED; +} +RETCODE dbmnyminus(DBPROCESS *dbproc,DBMONEY *src, DBMONEY *dest) +{ + return SUCCEED; +} +RETCODE dbmny4minus(DBPROCESS *dbproc, DBMONEY4 *src, DBMONEY4 *dest) +{ + return SUCCEED; +} +RETCODE dbmny4zero(DBPROCESS *dbproc, DBMONEY4 *dest) +{ + return SUCCEED; +} +RETCODE dbmny4add(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, DBMONEY4 *sum) +{ + return SUCCEED; +} +RETCODE dbmny4sub(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, DBMONEY4 *diff) +{ + return SUCCEED; +} +RETCODE dbmny4mul(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, DBMONEY4 *prod) +{ + return SUCCEED; +} +RETCODE dbmny4divide(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2, DBMONEY4 *quotient) +{ + return SUCCEED; +} +RETCODE dbmny4cmp(DBPROCESS *dbproc, DBMONEY4 *m1, DBMONEY4 *m2) +{ + return SUCCEED; +} +RETCODE dbdatecmp(DBPROCESS *dbproc, DBDATETIME *d1, DBDATETIME *d2) +{ + return SUCCEED; +} +RETCODE dbdatecrack(DBPROCESS *dbproc, DBDATEREC *di, DBDATETIME *dt) +{ +struct tm *t; +time_t secs_from_epoch; +int millis; + + secs_from_epoch = ((dt->dtdays - 25567)*24*60*60) + (dt->dttime/300); + millis = dt->dttime%300; + t = (struct tm *) gmtime(&secs_from_epoch); +#ifndef MSDBLIB + di->dateyear = t->tm_year + 1900; + di->datemonth = t->tm_mon; + di->datedmonth = t->tm_mday; + di->datedyear = t->tm_yday + 1; + di->datedweek = t->tm_wday; + di->datehour = t->tm_hour; + di->dateminute = t->tm_min; + di->datesecond = t->tm_sec; + di->datemsecond = (1000/300) * millis; + /* dblib manual indicates that tzone is not set by dbdate crack */ + /* di->datetzone = 0; */ +#else + di->year = t->tm_year + 1900; + di->month = t->tm_mon; + di->day = t->tm_mday; + di->dayofyear = t->tm_yday + 1; + di->weekday = t->tm_wday; + di->hour = t->tm_hour; + di->minute = t->tm_min; + di->second = t->tm_sec; + di->millisecond = (1000/300) * millis; + /* dblib manual indicates that tzone is not set by dbdate crack */ + /* di->tzone = 0; */ +#endif + return SUCCEED; +} +void dbrpwclr(LOGINREC *login) +{ +} +RETCODE dbrpwset(LOGINREC *login, char *srvname, char *password, int pwlen) +{ + return SUCCEED; +} +int dbspid(DBPROCESS *dbproc) +{ + return 0; +} +RETCODE dbsetuserdata(DBPROCESS *dbproc, BYTE *ptr) +{ + dbproc->user_data = ptr; + return SUCCEED; +} +BYTE *dbgetuserdata(DBPROCESS *dbproc) +{ + return dbproc->user_data; +} +RETCODE dbsetversion(DBINT version) +{ + g_dblib_version = version; + return SUCCEED; +} +RETCODE dbmnycopy(DBPROCESS *dbproc, DBMONEY *src, DBMONEY *dest) +{ + return SUCCEED; +} +RETCODE dbcanquery(DBPROCESS *dbproc) +{ + return SUCCEED; +} + +void dbfreebuf(DBPROCESS *dbproc) +{ + if(dbproc->dbbuf) { + free(dbproc->dbbuf); + dbproc->dbbuf = NULL; + } + dbproc->dbbufsz = 0; +} /* dbfreebuf() */ + +RETCODE dbclropt(DBPROCESS *dbproc,int option, char *param) +{ + return SUCCEED; +} +DBBOOL dbisopt(DBPROCESS *dbproc,int option, char *param) +{ + return TRUE; +} +DBINT DBCURROW(DBPROCESS *dbproc) +{ + return 0; +} +int DBCURCMD(DBPROCESS *dbproc) +{ + return 0; +} +RETCODE DBMORECMDS(DBPROCESS *dbproc) +{ + return SUCCEED; +} +int dbrettype(DBPROCESS *dbproc,int retnum) +{ + return 0; +} +int dbstrlen(DBPROCESS *dbproc) +{ + return dbproc->dbbufsz; +} +RETCODE dbstrcpy(DBPROCESS *dbproc, int start, int numbytes, char *dest) +{ + dest[0] = 0; /* start with empty string being returned */ + if (dbproc->dbbufsz>0) { + strncpy(dest, (char*)&dbproc->dbbuf[start], numbytes); + } + return SUCCEED; +} +RETCODE dbsafestr(DBPROCESS *dbproc,char *src, DBINT srclen, char *dest, DBINT destlen, int quotetype) +{ + return SUCCEED; +} +char *dbprtype(int token) +{ + char *result = NULL; + + + switch (token) + { + case SYBINT1: result = "tinyint"; break; + case SYBINT2: result = "smallint"; break; + case SYBINT4: result = "int"; break; + case SYBMONEY: result = "money"; break; + case SYBFLT8: result = "float"; break; + case SYBDATETIME: result = "datetime"; break; + case SYBBIT: result = "bit"; break; + case SYBBITN: result = "bit-null"; break; + case SYBCHAR: result = "char"; break; + case SYBVARCHAR: result = "varchar"; break; + case SYBTEXT: result = "text"; break; + case SYBBINARY: result = "binary"; break; + case SYBVARBINARY: result = "varbinary"; break; + case SYBIMAGE: result = "image"; break; + case SYBDECIMAL: result = "decimal"; break; + case SYBNUMERIC: result = "numeric"; break; + case SYBINTN: result = "integer-null"; break; + case SYBDATETIMN: result = "datetime-null"; break; + case SYBMONEYN: result = "money-null"; break; + case SYBFLTN: result = "float-null"; break; + case SYBAOPSUM: result = "sum"; break; + case SYBAOPAVG: result = "avg"; break; + case SYBAOPCNT: result = "count"; break; + case SYBAOPMIN: result = "min"; break; + case SYBAOPMAX: result = "max"; break; + case SYBDATETIME4: result = "smalldatetime"; break; + case SYBMONEY4: result = "smallmoney"; break; + case SYBREAL: result = "real"; break; + default: result = ""; break; + } + return result; +} /* dbprtype() */ +DBBINARY *dbtxtimestamp(DBPROCESS *dbproc, int column) +{ +TDSSOCKET *tds; +TDSRESULTINFO * resinfo; + + tds = (TDSSOCKET *) dbproc->tds_socket; + if (!tds->res_info) return NULL; + resinfo = tds->res_info; + if (column < 1 || column > resinfo->num_cols) return NULL; + /* else */ + return (DBBINARY *) resinfo->columns[column-1]->column_timestamp; +} +DBBINARY *dbtxptr(DBPROCESS *dbproc,int column) +{ +TDSSOCKET *tds; +TDSRESULTINFO * resinfo; + + tds = (TDSSOCKET *) dbproc->tds_socket; + if (!tds->res_info) return NULL; + resinfo = tds->res_info; + if (column < 1 || column > resinfo->num_cols) return NULL; + /* else */ + return (DBBINARY *) &resinfo->columns[column-1]->column_textptr; +} +RETCODE dbwritetext(DBPROCESS *dbproc,char *objname, DBBINARY *textptr,DBTINYINT textptrlen, DBBINARY *timestamp, DBBOOL log, DBINT size, BYTE *text) +{ +char query[1024]; +char textptr_string[35]; /* 16 * 2 + 2 (0x) + 1 */ +char timestamp_string[19]; /* 8 * 2 + 2 (0x) + 1 */ +int marker; + + tds_convert(SYBBINARY, textptr, textptrlen, SYBCHAR, textptr_string, 35); + tds_convert(SYBBINARY, timestamp, 8, SYBCHAR, timestamp_string, 19); + sprintf(query, "writetext bulk %s %s timestamp = %s", + objname, textptr_string, timestamp_string); + if (tds_submit_query(dbproc->tds_socket, query)!=TDS_SUCCEED) { + return FAIL; + } + + /* read the end token */ + marker = tds_get_byte(dbproc->tds_socket); + + if (!dbproc->tds_socket->s) return FAIL; + + tds_process_default_tokens(dbproc->tds_socket, marker); + if (marker != TDS_DONE_TOKEN) { + return FAIL; + } + + dbproc->tds_socket->out_flag=0x07; + tds_put_int(dbproc->tds_socket, size); + + if (!text) { + dbproc->text_size = size; + dbproc->text_sent = 0; + return SUCCEED; + } + + tds_put_bulk_data(dbproc->tds_socket, text, size); + tds_flush_packet(dbproc->tds_socket); + + do { + marker = tds_get_byte(dbproc->tds_socket); + tds_process_default_tokens(dbproc->tds_socket, marker); + } while (marker!=TDS_DONE_TOKEN); + + return SUCCEED; +} +STATUS dbreadtext(DBPROCESS *dbproc, void *buf, DBINT bufsize) +{ +TDSSOCKET *tds; +TDSCOLINFO *curcol; +int cpbytes, bytes_avail, rc; + + tds = dbproc->tds_socket; + + if (!tds || !tds->res_info || !tds->res_info->columns[0]) + return -1; + + curcol = tds->res_info->columns[0]; + + /* if the current position is beyond the end of the text + ** set pos to 0 and return 0 to denote the end of the + ** text */ + if (curcol->column_textpos && + curcol->column_textpos>=curcol->column_textsize) { + curcol->column_textpos = 0; + return 0; + } + + /* if pos is 0 (first time through or last call exhausted the text) + ** then read another row */ + if (curcol->column_textpos==0) { + rc = tds_process_row_tokens(dbproc->tds_socket); + if (rc != TDS_SUCCEED) { + return NO_MORE_ROWS; + } + } + + /* find the number of bytes to return */ + bytes_avail = curcol->column_textsize - curcol->column_textpos; + cpbytes = bytes_avail > bufsize ? bufsize : bytes_avail; + memcpy(buf,&curcol->column_textvalue[curcol->column_textpos],cpbytes); + curcol->column_textpos += cpbytes; + return cpbytes; +} +RETCODE dbmoretext(DBPROCESS *dbproc, DBINT size, BYTE *text) +{ +int marker; + + tds_put_bulk_data(dbproc->tds_socket, text, size); + dbproc->text_sent += size; + + return SUCCEED; +} +void dbrecftos(char *filename) +{ +} +char *dbversion() +{ + return NULL; +} +RETCODE dbsetdefcharset(char *charset) +{ + return SUCCEED; +} +RETCODE dbreginit( + DBPROCESS *dbproc, + DBCHAR *procedure_name, + DBSMALLINT namelen ) +{ + return SUCCEED; +} +RETCODE dbreglist(DBPROCESS *dbproc) +{ + return SUCCEED; +} +RETCODE dbregparam( + DBPROCESS *dbproc, + char *param_name, + int type, + DBINT datalen, + BYTE *data ) +{ + return SUCCEED; +} +RETCODE dbregexec( + DBPROCESS *dbproc, + DBSMALLINT options) +{ + return SUCCEED; +} +char *dbmonthname(DBPROCESS *dbproc,char *language,int monthnum,DBBOOL shortform) +{ +char *shortmon[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"}; +char *longmon[] = {"January","February","March","April","May","June","July","August","September","October","November","December"}; + + if (shortform) + return shortmon[monthnum-1]; + else + return longmon[monthnum-1]; +} +char *dbname(DBPROCESS *dbproc) +{ + return NULL; +} +RETCODE dbsqlsend(DBPROCESS *dbproc) +{ +int result = FAIL; +TDSSOCKET *tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + if (tds->res_info && tds->res_info->more_results) + { + /* + * XXX If I read the documentation correctly it gets a + * bit more complicated than this. + * + * You see if the person did a query and retrieved all + * the rows but didn't call dbresults() and if the query + * didn't return multiple results then this routine should + * just end the TDS_DONE_TOKEN packet and be done with it. + * + * Unfortunately the only way we can know that is by peeking + * ahead to the next byte. Peeking could block and this is supposed + * to be a non-blocking call. + * + */ + + result = FAIL; + } + else + { + dbproc->more_results = TRUE; + dbproc->empty_res_hack = 0; + if (tds_submit_query(dbproc->tds_socket, dbproc->dbbuf)!=TDS_SUCCEED) { + return FAIL; + } + if (! dbproc->noautofree) + { + dbfreebuf(dbproc); + } + result = SUCCEED; + } + return result; +} +RETCODE dbaltutype(DBPROCESS *dbproc, int computeid, int column) +{ + return SUCCEED; +} +RETCODE dbaltlen(DBPROCESS *dbproc, int computeid, int column) +{ + return SUCCEED; +} +RETCODE dbpoll(DBPROCESS *dbproc, long milliseconds, DBPROCESS **ready_dbproc, int *return_reason) +{ + return SUCCEED; +} + +DBINT DBLASTROW(DBPROCESS *dbproc) +{ +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; + + tds = (TDSSOCKET *) dbproc->tds_socket; + resinfo = tds->res_info; + return resinfo->row_count; +#if 0 + DBINT result; + + if (dbproc->row_buf.rows_in_buf == 0) + { + result = 0; + } + else + { + /* rows returned from the row buffer start with 1 instead of 0 + ** newest is 0 based. */ + result = dbproc->row_buf.newest + 1; + } + return result; +#endif +} + +DBINT DBFIRSTROW(DBPROCESS *dbproc) +{ + DBINT result; + + if (dbproc->row_buf.rows_in_buf == 0) + { + result = 0; + } + else + { + result = dbproc->row_buf.oldest; + } + return result; +} +int DBIORDESC(DBPROCESS *dbproc) +{ + return dbproc->tds_socket->s; +} +int DBIOWDESC(DBPROCESS *dbproc) +{ + return dbproc->tds_socket->s; +} + diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c new file mode 100644 index 000000000..f904b064c --- /dev/null +++ b/src/dblib/dbutil.c @@ -0,0 +1,126 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "sybdb.h" +#include "dblib.h" +/* #include "fortify.h" */ + + +static char software_version[] = "$Id: dbutil.c,v 1.1 2001-10-12 23:29:09 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +extern int (*g_dblib_msg_handler)(); +extern int (*g_dblib_err_handler)(); + +/* The next 2 functions will be the reciever for the info and error messages + * that come from the TDS layer. The address of this function is passed to + * the TDS layer in the dbinit function. This way, when the TDS layer + * recieves an informational message from the server that it can be dealt with + * immediately (or so). It takes a pointer to a DBPROCESS, its just that the + * TDS layer didn't what it really was */ +int dblib_handle_info_message(void *aStruct) +{ + DBPROCESS* dbproc = (DBPROCESS*)aStruct; + TDSSOCKET* tds = dbproc->tds_socket; + if( tds->msg_info->msg_number > 0 ) + { + /* now check to see if the user supplied a function, if not ignore the + * problem */ + if(g_dblib_msg_handler) + { + g_dblib_msg_handler(dbproc, + tds->msg_info->msg_number, + tds->msg_info->msg_state, + tds->msg_info->msg_level, + tds->msg_info->message, + tds->msg_info->server, + tds->msg_info->proc_name); + } + else + { +#if 0 + fprintf (stderr, "INFO..No User supplied info msg handler..Msg %d, Level %d, State %d, Server %s, Line %d\n%s\n", + tds->msg_info->msg_number, + tds->msg_info->msg_level, + tds->msg_info->msg_state, + tds->msg_info->server, + tds->msg_info->line_number, + tds->msg_info->message); +#endif + } + + /* and now clean up the structure for next time */ + tds_reset_msg_info(dbproc->tds_socket); + } + return 1; +} + +int dblib_handle_err_message(void *aStruct) +{ + DBPROCESS* dbproc = (DBPROCESS*)aStruct; + TDSSOCKET* tds = dbproc->tds_socket; + if( tds->msg_info->msg_number > 0 ) + { + /* now check to see if the user supplied a function, if not ignore the + * problem */ + if(g_dblib_err_handler) + { + g_dblib_err_handler(dbproc, + tds->msg_info->msg_level, + tds->msg_info->msg_number, + tds->msg_info->msg_state, + tds->msg_info->message, + tds->msg_info->server); + } + else + { +#if 0 + fprintf (stderr, "ERR..No User supplied err msg handler..Msg %d, Level %d, State %d, Server %s, Line %d\n%s\n", + tds->msg_info->msg_number, + tds->msg_info->msg_level, + tds->msg_info->msg_state, + tds->msg_info->server, + tds->msg_info->line_number, + tds->msg_info->message); +#endif + } + + /* and now clean up the structure for next time */ + tds_reset_msg_info(dbproc->tds_socket); + } + return 1; +} + +void dblib_setTDS_version(TDSLOGIN *tds_login, DBINT version) +{ + switch(version) + { + case DBVERSION_42: + tds_set_version(tds_login, 4, 2); + break; + case DBVERSION_46: + tds_set_version(tds_login, 4, 6); + break; + case DBVERSION_100: + tds_set_version(tds_login, 5, 0); + break; + } +} diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c new file mode 100644 index 000000000..0fbc1a2f9 --- /dev/null +++ b/src/dblib/rpc.c @@ -0,0 +1,45 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tdsutil.h" +#include "tds.h" +#include "sybfront.h" +#include "sybdb.h" +#include "dblib.h" +#include + + +static char software_version[] = "$Id: rpc.c,v 1.1 2001-10-12 23:29:09 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +RETCODE dbrpcinit(DBPROCESS *dbproc,char *rpcname,DBSMALLINT options) +{ + return SUCCEED; +} +RETCODE dbrpcparam(DBPROCESS *dbproc, char *paramname, BYTE status, int type, + DBINT maxlen, DBINT datalen, BYTE *value) +{ + return SUCCEED; +} +RETCODE dbrpcsend(DBPROCESS *dbproc) +{ + return SUCCEED; +} diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am new file mode 100644 index 000000000..f6de5c582 --- /dev/null +++ b/src/dblib/unittests/Makefile.am @@ -0,0 +1,27 @@ +TESTS = t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 t0010 t0011 t0012 t0013 t0014 t0015 t0016 t0017 t0018 t0019 t0020 +EXTRA_PROGRAMS = t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 t0010 t0011 t0012 t0013 t0014 t0015 t0016 t0017 t0018 t0019 t0020 + +t0001_SOURCES = t0001.c common.c pwd.c +t0002_SOURCES = t0002.c common.c pwd.c +t0003_SOURCES = t0003.c common.c pwd.c +t0004_SOURCES = t0004.c common.c pwd.c +t0005_SOURCES = t0005.c common.c pwd.c +t0006_SOURCES = t0006.c common.c pwd.c +t0007_SOURCES = t0007.c common.c pwd.c +t0008_SOURCES = t0008.c common.c pwd.c +t0009_SOURCES = t0009.c common.c pwd.c +t0010_SOURCES = t0010.c common.c pwd.c +t0011_SOURCES = t0011.c common.c pwd.c +t0012_SOURCES = t0012.c common.c pwd.c +t0013_SOURCES = t0013.c common.c pwd.c +t0014_SOURCES = t0014.c common.c pwd.c +t0015_SOURCES = t0015.c common.c pwd.c +t0016_SOURCES = t0016.c common.c pwd.c +t0017_SOURCES = t0017.c common.c pwd.c +t0018_SOURCES = t0018.c common.c pwd.c +t0019_SOURCES = t0018.c common.c pwd.c +t0020_SOURCES = t0020.c common.c pwd.c + +LIBS = ../libsybdb.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h diff --git a/src/dblib/unittests/Makefile.in b/src/dblib/unittests/Makefile.in new file mode 100644 index 000000000..c5557d0d3 --- /dev/null +++ b/src/dblib/unittests/Makefile.in @@ -0,0 +1,500 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +TESTS = t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 t0010 t0011 t0012 t0013 t0014 t0015 t0016 t0017 t0018 t0019 t0020 +EXTRA_PROGRAMS = t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 t0010 t0011 t0012 t0013 t0014 t0015 t0016 t0017 t0018 t0019 t0020 + +t0001_SOURCES = t0001.c common.c pwd.c +t0002_SOURCES = t0002.c common.c pwd.c +t0003_SOURCES = t0003.c common.c pwd.c +t0004_SOURCES = t0004.c common.c pwd.c +t0005_SOURCES = t0005.c common.c pwd.c +t0006_SOURCES = t0006.c common.c pwd.c +t0007_SOURCES = t0007.c common.c pwd.c +t0008_SOURCES = t0008.c common.c pwd.c +t0009_SOURCES = t0009.c common.c pwd.c +t0010_SOURCES = t0010.c common.c pwd.c +t0011_SOURCES = t0011.c common.c pwd.c +t0012_SOURCES = t0012.c common.c pwd.c +t0013_SOURCES = t0013.c common.c pwd.c +t0014_SOURCES = t0014.c common.c pwd.c +t0015_SOURCES = t0015.c common.c pwd.c +t0016_SOURCES = t0016.c common.c pwd.c +t0017_SOURCES = t0017.c common.c pwd.c +t0018_SOURCES = t0018.c common.c pwd.c +t0019_SOURCES = t0018.c common.c pwd.c +t0020_SOURCES = t0020.c common.c pwd.c + +LIBS = ../libsybdb.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +t0001_OBJECTS = t0001.o common.o pwd.o +t0001_LDADD = $(LDADD) +t0001_DEPENDENCIES = +t0001_LDFLAGS = +t0002_OBJECTS = t0002.o common.o pwd.o +t0002_LDADD = $(LDADD) +t0002_DEPENDENCIES = +t0002_LDFLAGS = +t0003_OBJECTS = t0003.o common.o pwd.o +t0003_LDADD = $(LDADD) +t0003_DEPENDENCIES = +t0003_LDFLAGS = +t0004_OBJECTS = t0004.o common.o pwd.o +t0004_LDADD = $(LDADD) +t0004_DEPENDENCIES = +t0004_LDFLAGS = +t0005_OBJECTS = t0005.o common.o pwd.o +t0005_LDADD = $(LDADD) +t0005_DEPENDENCIES = +t0005_LDFLAGS = +t0006_OBJECTS = t0006.o common.o pwd.o +t0006_LDADD = $(LDADD) +t0006_DEPENDENCIES = +t0006_LDFLAGS = +t0007_OBJECTS = t0007.o common.o pwd.o +t0007_LDADD = $(LDADD) +t0007_DEPENDENCIES = +t0007_LDFLAGS = +t0008_OBJECTS = t0008.o common.o pwd.o +t0008_LDADD = $(LDADD) +t0008_DEPENDENCIES = +t0008_LDFLAGS = +t0009_OBJECTS = t0009.o common.o pwd.o +t0009_LDADD = $(LDADD) +t0009_DEPENDENCIES = +t0009_LDFLAGS = +t0010_OBJECTS = t0010.o common.o pwd.o +t0010_LDADD = $(LDADD) +t0010_DEPENDENCIES = +t0010_LDFLAGS = +t0011_OBJECTS = t0011.o common.o pwd.o +t0011_LDADD = $(LDADD) +t0011_DEPENDENCIES = +t0011_LDFLAGS = +t0012_OBJECTS = t0012.o common.o pwd.o +t0012_LDADD = $(LDADD) +t0012_DEPENDENCIES = +t0012_LDFLAGS = +t0013_OBJECTS = t0013.o common.o pwd.o +t0013_LDADD = $(LDADD) +t0013_DEPENDENCIES = +t0013_LDFLAGS = +t0014_OBJECTS = t0014.o common.o pwd.o +t0014_LDADD = $(LDADD) +t0014_DEPENDENCIES = +t0014_LDFLAGS = +t0015_OBJECTS = t0015.o common.o pwd.o +t0015_LDADD = $(LDADD) +t0015_DEPENDENCIES = +t0015_LDFLAGS = +t0016_OBJECTS = t0016.o common.o pwd.o +t0016_LDADD = $(LDADD) +t0016_DEPENDENCIES = +t0016_LDFLAGS = +t0017_OBJECTS = t0017.o common.o pwd.o +t0017_LDADD = $(LDADD) +t0017_DEPENDENCIES = +t0017_LDFLAGS = +t0018_OBJECTS = t0018.o common.o pwd.o +t0018_LDADD = $(LDADD) +t0018_DEPENDENCIES = +t0018_LDFLAGS = +t0019_OBJECTS = t0018.o common.o pwd.o +t0019_LDADD = $(LDADD) +t0019_DEPENDENCIES = +t0019_LDFLAGS = +t0020_OBJECTS = t0020.o common.o pwd.o +t0020_LDADD = $(LDADD) +t0020_DEPENDENCIES = +t0020_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(include_HEADERS) + +DIST_COMMON = README Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(t0001_SOURCES) $(t0002_SOURCES) $(t0003_SOURCES) $(t0004_SOURCES) $(t0005_SOURCES) $(t0006_SOURCES) $(t0007_SOURCES) $(t0008_SOURCES) $(t0009_SOURCES) $(t0010_SOURCES) $(t0011_SOURCES) $(t0012_SOURCES) $(t0013_SOURCES) $(t0014_SOURCES) $(t0015_SOURCES) $(t0016_SOURCES) $(t0017_SOURCES) $(t0018_SOURCES) $(t0019_SOURCES) $(t0020_SOURCES) +OBJECTS = $(t0001_OBJECTS) $(t0002_OBJECTS) $(t0003_OBJECTS) $(t0004_OBJECTS) $(t0005_OBJECTS) $(t0006_OBJECTS) $(t0007_OBJECTS) $(t0008_OBJECTS) $(t0009_OBJECTS) $(t0010_OBJECTS) $(t0011_OBJECTS) $(t0012_OBJECTS) $(t0013_OBJECTS) $(t0014_OBJECTS) $(t0015_OBJECTS) $(t0016_OBJECTS) $(t0017_OBJECTS) $(t0018_OBJECTS) $(t0019_OBJECTS) $(t0020_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/dblib/unittests/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +t0001: $(t0001_OBJECTS) $(t0001_DEPENDENCIES) + @rm -f t0001 + $(LINK) $(t0001_LDFLAGS) $(t0001_OBJECTS) $(t0001_LDADD) $(LIBS) + +t0002: $(t0002_OBJECTS) $(t0002_DEPENDENCIES) + @rm -f t0002 + $(LINK) $(t0002_LDFLAGS) $(t0002_OBJECTS) $(t0002_LDADD) $(LIBS) + +t0003: $(t0003_OBJECTS) $(t0003_DEPENDENCIES) + @rm -f t0003 + $(LINK) $(t0003_LDFLAGS) $(t0003_OBJECTS) $(t0003_LDADD) $(LIBS) + +t0004: $(t0004_OBJECTS) $(t0004_DEPENDENCIES) + @rm -f t0004 + $(LINK) $(t0004_LDFLAGS) $(t0004_OBJECTS) $(t0004_LDADD) $(LIBS) + +t0005: $(t0005_OBJECTS) $(t0005_DEPENDENCIES) + @rm -f t0005 + $(LINK) $(t0005_LDFLAGS) $(t0005_OBJECTS) $(t0005_LDADD) $(LIBS) + +t0006: $(t0006_OBJECTS) $(t0006_DEPENDENCIES) + @rm -f t0006 + $(LINK) $(t0006_LDFLAGS) $(t0006_OBJECTS) $(t0006_LDADD) $(LIBS) + +t0007: $(t0007_OBJECTS) $(t0007_DEPENDENCIES) + @rm -f t0007 + $(LINK) $(t0007_LDFLAGS) $(t0007_OBJECTS) $(t0007_LDADD) $(LIBS) + +t0008: $(t0008_OBJECTS) $(t0008_DEPENDENCIES) + @rm -f t0008 + $(LINK) $(t0008_LDFLAGS) $(t0008_OBJECTS) $(t0008_LDADD) $(LIBS) + +t0009: $(t0009_OBJECTS) $(t0009_DEPENDENCIES) + @rm -f t0009 + $(LINK) $(t0009_LDFLAGS) $(t0009_OBJECTS) $(t0009_LDADD) $(LIBS) + +t0010: $(t0010_OBJECTS) $(t0010_DEPENDENCIES) + @rm -f t0010 + $(LINK) $(t0010_LDFLAGS) $(t0010_OBJECTS) $(t0010_LDADD) $(LIBS) + +t0011: $(t0011_OBJECTS) $(t0011_DEPENDENCIES) + @rm -f t0011 + $(LINK) $(t0011_LDFLAGS) $(t0011_OBJECTS) $(t0011_LDADD) $(LIBS) + +t0012: $(t0012_OBJECTS) $(t0012_DEPENDENCIES) + @rm -f t0012 + $(LINK) $(t0012_LDFLAGS) $(t0012_OBJECTS) $(t0012_LDADD) $(LIBS) + +t0013: $(t0013_OBJECTS) $(t0013_DEPENDENCIES) + @rm -f t0013 + $(LINK) $(t0013_LDFLAGS) $(t0013_OBJECTS) $(t0013_LDADD) $(LIBS) + +t0014: $(t0014_OBJECTS) $(t0014_DEPENDENCIES) + @rm -f t0014 + $(LINK) $(t0014_LDFLAGS) $(t0014_OBJECTS) $(t0014_LDADD) $(LIBS) + +t0015: $(t0015_OBJECTS) $(t0015_DEPENDENCIES) + @rm -f t0015 + $(LINK) $(t0015_LDFLAGS) $(t0015_OBJECTS) $(t0015_LDADD) $(LIBS) + +t0016: $(t0016_OBJECTS) $(t0016_DEPENDENCIES) + @rm -f t0016 + $(LINK) $(t0016_LDFLAGS) $(t0016_OBJECTS) $(t0016_LDADD) $(LIBS) + +t0017: $(t0017_OBJECTS) $(t0017_DEPENDENCIES) + @rm -f t0017 + $(LINK) $(t0017_LDFLAGS) $(t0017_OBJECTS) $(t0017_LDADD) $(LIBS) + +t0018: $(t0018_OBJECTS) $(t0018_DEPENDENCIES) + @rm -f t0018 + $(LINK) $(t0018_LDFLAGS) $(t0018_OBJECTS) $(t0018_LDADD) $(LIBS) + +t0019: $(t0019_OBJECTS) $(t0019_DEPENDENCIES) + @rm -f t0019 + $(LINK) $(t0019_LDFLAGS) $(t0019_OBJECTS) $(t0019_LDADD) $(LIBS) + +t0020: $(t0020_OBJECTS) $(t0020_DEPENDENCIES) + @rm -f t0020 + $(LINK) $(t0020_LDFLAGS) $(t0020_OBJECTS) $(t0020_LDADD) $(LIBS) + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/dblib/unittests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-compile mostlyclean-libtool \ + mostlyclean-tags mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-compile clean-libtool clean-tags clean-generic \ + mostlyclean-am + +clean: clean-am + +distclean-am: distclean-compile distclean-libtool distclean-tags \ + distclean-generic clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-compile distclean-compile clean-compile \ +maintainer-clean-compile mostlyclean-libtool distclean-libtool \ +clean-libtool maintainer-clean-libtool uninstall-includeHEADERS \ +install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir check-TESTS info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/dblib/unittests/README b/src/dblib/unittests/README new file mode 100644 index 000000000..6bf6cdb78 --- /dev/null +++ b/src/dblib/unittests/README @@ -0,0 +1,21 @@ +Oct 13, 1999 +------------ +Added test.sh to run all tests from 'make test', reduced the rows_to_add to 50 +and relocated the user/password/server/database information to a common file to +be used for all CLIs. + +------------- +The programs in this directory will test the dblib routines. Tests +that dblib passes will print "dblib okay for t000X.c" as the last line +of output and exit with a status of 0. If the test does not print +that message for the last line of output it means that dblib failed +that test. + +Some of the tests are designed to dump core if an error is detected. +This is to assist with post-mortem debugging of the dblib routines. + + +**** Notice **** +As of January 20, 1999 t0003.c is broken. The test +fails on Microsoft's DB Library. + diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c new file mode 100644 index 000000000..6dfae2e55 --- /dev/null +++ b/src/dblib/unittests/common.c @@ -0,0 +1,199 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +static char software_version[] = "$Id: common.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +typedef struct _tag_memcheck_t +{ + int item_number; + int special; + struct _tag_memcheck_t *next; +} memcheck_t; + + +static memcheck_t *breadcrumbs = NULL; +static int num_breadcrumbs = 0; +static const int BREADCRUMB = 0xABCD7890; + + +void check_crumbs() +{ + int i; + memcheck_t *ptr = breadcrumbs; + + i = num_breadcrumbs; + while(ptr != NULL) + { + if (ptr->special!=BREADCRUMB || ptr->item_number!=i) + { + fprintf(stderr, "Somebody overwrote one of the bread crumbs!!!\n"); + abort(); + } + + i--; + ptr = ptr->next; + } +} + + + +void add_bread_crumb() +{ + memcheck_t *tmp; + + check_crumbs(); + + tmp = (memcheck_t *)calloc(sizeof(memcheck_t), 1); + if (tmp==NULL) + { + fprintf(stderr, "Out of memory"); + abort(); + exit(1); + } + + num_breadcrumbs++; + + tmp->item_number = num_breadcrumbs; + tmp->special = BREADCRUMB; + tmp->next = breadcrumbs; + + breadcrumbs = tmp; +} + +int syb_msg_handler( + DBPROCESS *dbproc, + DBINT msgno, + int msgstate, + int severity, + char *msgtext, + char *srvname, + char *procname, + int line) +{ + char var_value[31] ; + int i ; + char *c ; + + /* + * Check for "database changed", or "language changed" messages from + * the client. If we get one of these, then we need to pull the + * name of the database or charset from the message and set the + * appropriate variable. + */ + if( msgno == 5701 || /* database context change */ + msgno == 5703 || /* language changed */ + msgno == 5704 ) { /* charset changed */ + + /* fprintf( stderr, "msgno = %d: %s\n", msgno, msgtext ) ; */ + + if( msgtext != NULL && (c = strchr( msgtext, '\'' )) != NULL ) { + i = 0 ; + for( ++c; i <= 30 && *c != '\0' && *c != '\''; ++c ) + var_value[i++] = *c ; + var_value[i] = '\0' ; + +#if 0 + switch(msgno) { + case 5701 : + env_set( g_env, "database", var_value ) +; + break ; + case 5703 : + env_set( g_env, "language", var_value ) +; + break ; + case 5704 : + env_set( g_env, "charset", var_value ) ;- break ; + default : + break ; + } +#endif + } + return 0 ; + } + + /* + * If the severity is something other than 0 or the msg number is + * 0 (user informational messages). + */ + if( severity >= 0 || msgno == 0 ) { + /* + * If the message was something other than informational, and + * the severity was greater than 0, then print information to + * stderr with a little pre-amble information. + */ + if( msgno > 0 && severity > 0 ) { + fprintf( stderr, "Msg %d, Level %d, State %d\n", + (int)msgno, (int)severity, (int)msgstate ) ; + fprintf( stderr, "Server '%s'", srvname ) ; + if( procname != NULL && *procname != '\0' ) + fprintf( stderr, ", Procedure '%s'", procname ) +; + if( line > 0 ) + fprintf( stderr, ", Line %d", line ) ; + fprintf( stderr, "\n" ) ; + fprintf( stderr,"%s\n", msgtext ) ; + fflush( stderr ) ; + } else { + /* + * Otherwise, it is just an informational (e.g. print) message + * from the server, so send it to stdout. + */ + fprintf( stdout, "%s\n", msgtext ) ; + fflush( stdout ) ; + } + } + + return 0 ; +} + +int syb_err_handler( + DBPROCESS *dbproc, + int severity, + int dberr, + int oserr, + char *dberrstr, + char *oserrstr) +{ + +#if 0 + /* + * For fatal server messages, cancel the query and rely on the + * message handler to spew the appropriate error messages out. + */ + if (severity == EXSERVER ) + return INT_CANCEL ; + + /* + * For any other type of severity (that is not a server + * message), we increment the batch_failcount. + */ + env_set( g_env, "batch_failcount", "1" ) ; +#endif + + fprintf( stderr, "DB-LIBRARY error (severity %d):\n", severity ) ; + fprintf( stderr, " %s\n", dberrstr ) ; + fflush( stderr ) ; + + /* + * If the dbprocess is dead or the dbproc is a NULL pointer and + * we are not in the middle of logging in, then we need to exit. + * We can't do anything from here on out anyway. + */ + if( (dbproc == NULL || DBDEAD(dbproc)) ) + exit(255) ; + + return INT_CANCEL ; +} diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h new file mode 100644 index 000000000..dfb0aeb13 --- /dev/null +++ b/src/dblib/unittests/common.h @@ -0,0 +1,33 @@ + +#ifndef COMMON_h +#define COMMON_h + +static char rcsid_common_h [ ] = + "$Id: common.h,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_common_h_warn[]={rcsid_common_h, no_unused_common_h_warn}; + +extern char PASSWORD[512]; +extern char USER[512]; +extern char SERVER[512]; +extern char DATABASE[512]; + +extern void check_crumbs(); +extern void add_bread_crumb(); +extern int syb_msg_handler( + DBPROCESS *dbproc, + DBINT msgno, + int msgstate, + int severity, + char *msgtext, + char *srvname, + char *procname, + int line); +extern int syb_err_handler( + DBPROCESS *dbproc, + int severity, + int dberr, + int oserr, + char *dberrstr, + char *oserrstr); + +#endif diff --git a/src/dblib/unittests/pwd.c b/src/dblib/unittests/pwd.c new file mode 100644 index 000000000..ee435447e --- /dev/null +++ b/src/dblib/unittests/pwd.c @@ -0,0 +1,35 @@ +#include +#include + +char USER[512]; +char SERVER[512]; +char PASSWORD[512]; +char DATABASE[512]; + +int read_login_info() +{ +FILE *in; +char line[512]; +char *s1, *s2; + + in = fopen("../../../PWD","r"); + if (!in) { + fprintf(stderr,"Can not open PWD file\n\n"); + return 1; + } + while (fgets(line, 512, in)) { + s1=strtok(line,"="); + s2=strtok(NULL,"\n"); + if (!s1 || !s2) continue; + if (!strcmp(s1,"UID")) { + strcpy(USER,s2); + } else if (!strcmp(s1,"SRV")) { + strcpy(SERVER,s2); + } else if (!strcmp(s1,"PWD")) { + strcpy(PASSWORD,s2); + } else if (!strcmp(s1,"DB")) { + strcpy(DATABASE,s2); + } + } + return 0; +} diff --git a/src/dblib/unittests/t0001.c b/src/dblib/unittests/t0001.c new file mode 100644 index 000000000..f1af94269 --- /dev/null +++ b/src/dblib/unittests/t0001.c @@ -0,0 +1,200 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +static char software_version[] = "$Id: t0001.c,v 1.1 2001-10-12 23:29:10 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +int main() +{ + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0001"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0001"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)==SUCCEED) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0001 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)==SUCCEED) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=0; i %d %s\n", (int)testint, teststr); + } + + + add_bread_crumb(); + if (dbnextrow(dbproc)!=NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows\n"); + exit(1); + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c new file mode 100644 index 000000000..58fe46b8a --- /dev/null +++ b/src/dblib/unittests/t0002.c @@ -0,0 +1,222 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + +static char software_version[] = "$Id: t0002.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +static void verify(int i, int testint, char *teststr) +{ + char expected[1024]; + + sprintf(expected, "row %03d", i); + + if (testint!=i) + { + failed = 1; + fprintf(stderr, "Failed. Expected i to be %d, was %d\n", i, testint); + abort(); + } + if (0!= strncmp(teststr, expected, strlen(expected))) + { + failed = 1; + fprintf(stderr, "Failed. Expected s to be |%s|, was |%s|\n", + expected, teststr); + abort(); + } + printf("Read a row of data -> %d %s\n", testint, teststr); +} + + +int main() +{ + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + STATUS rc; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0002"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + dbsetopt(dbproc, DBBUFFER, "10", 0); + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0002"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0002 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i<=rows_to_add; i++) + { + char cmd[1024]; + + sprintf(cmd, "insert into dblib0002 values (%d, 'row %03d')", i, i); + dbcmd(dbproc, cmd); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + } + + fprintf(stdout, "select\n"); + dbcmd(dbproc,"select * from dblib0002 order by i"); + dbsqlexec(dbproc); + add_bread_crumb(); + + + if (dbresults(dbproc)!=SUCCEED) + { + add_bread_crumb(); + fprintf(stderr, "Was expecting a result set."); + exit(1); + } + add_bread_crumb(); + + for (i=1;i<=dbnumcols(dbproc);i++) + { + add_bread_crumb(); + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + add_bread_crumb(); + } + + add_bread_crumb(); + dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint); + add_bread_crumb(); + dbbind(dbproc,2,STRINGBIND,-1,(BYTE *) teststr); + add_bread_crumb(); + + add_bread_crumb(); + + for(i=1; i<=10; i++) + { + add_bread_crumb(); + if (REG_ROW != dbnextrow(dbproc)) + { + failed = 1; + fprintf(stderr, "Failed. Expected a row\n"); + exit(1); + } + add_bread_crumb(); + verify(i, testint, teststr); + } + + rc = dbgetrow(dbproc, 1); + add_bread_crumb(); + assert(rc == REG_ROW); + verify(1, testint, teststr); + + rc = dbnextrow(dbproc); + add_bread_crumb(); + assert(rc == REG_ROW); + verify(2, testint, teststr); + + rc = dbgetrow(dbproc, 11); + add_bread_crumb(); + assert(rc==NO_MORE_ROWS); + + rc = dbgetrow(dbproc, 10); + add_bread_crumb(); + assert(rc==REG_ROW); + verify(10, testint, teststr); + + rc = dbnextrow(dbproc); + assert(rc==BUF_FULL); + + dbclrbuf(dbproc, 3); + + rc = dbnextrow(dbproc); + add_bread_crumb(); + assert(rc == REG_ROW); + verify(11, testint, teststr); + + rc = dbnextrow(dbproc); + add_bread_crumb(); + assert(rc == REG_ROW); + verify(12, testint, teststr); + + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + diff --git a/src/dblib/unittests/t0003.c b/src/dblib/unittests/t0003.c new file mode 100644 index 000000000..df3a8509a --- /dev/null +++ b/src/dblib/unittests/t0003.c @@ -0,0 +1,201 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + +static char software_version[] = "$Id: t0003.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0003"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + dbsetopt(dbproc, DBBUFFER, "100", 0); + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0003"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0003 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i %d %s\n", (int)testint, teststr); + } + + + add_bread_crumb(); + dbclrbuf(dbproc, 1); + rc = dbnextrow(dbproc); + if (rc != NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows. (rc=%d)\n", rc); + exit(1); + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c new file mode 100644 index 000000000..3520f8d3d --- /dev/null +++ b/src/dblib/unittests/t0004.c @@ -0,0 +1,203 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + +static char software_version[] = "$Id: t0004.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int main() +{ + char cmd[1024]; + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + int failed = 0; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0004"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0004"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0004 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i %d %s\n", (int)testint, teststr); + } + + + + fprintf(stdout, "second select\n"); + + sprintf(cmd, "select * from dblib0004 where i>950 order by i"); + fprintf(stdout, "%s\n", cmd); + if (SUCCEED != dbcmd(dbproc, cmd)) + { + fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__); + failed = 1; + } + fprintf(stdout, "About to exec for the second time. Should fail\n"); + if (FAIL != dbsqlexec(dbproc)) + { + fprintf(stderr, "%s:%d: dbsqlexec should have failed but didn't\n", + __FILE__, __LINE__); + failed = 1; + } + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c new file mode 100644 index 000000000..4662f0ee0 --- /dev/null +++ b/src/dblib/unittests/t0005.c @@ -0,0 +1,226 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#ifndef _WIN32 +#include +#endif + +#include "common.h" + + + +static char software_version[] = "$Id: t0005.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + char cmd[1024]; + int failed = 0; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(""); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0005"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0005"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + if (SUCCEED != dbcmd(dbproc, + "create table dblib0005 " + "(i int not null, s char(10) not null)")) + { + fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__); + failed = 1; + } + + if (SUCCEED != dbsqlexec(dbproc)) + { + fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__); + failed = 1; + } + + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i %d %s\n", (int)testint, teststr); + } + +#if 0 + add_bread_crumb(); + rc = dbnextrow(dbproc); + if (rc != NO_MORE_ROWS) + { + fprintf(stderr, "Was expecting no more rows. (rc=%d)\n", rc); + exit(1); + } + add_bread_crumb(); +#endif + + sprintf(cmd, "select * from dblib0005 where i>950 order by i"); + fprintf(stdout, "%s\n", cmd); + if (SUCCEED != dbcmd(dbproc, cmd)) + { + fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__); + failed = 1; + } + if (SUCCEED == dbsqlexec(dbproc)) + { + fprintf(stderr, "%s:%d: dbsqlexec should have failed but didn't\n", + __FILE__, __LINE__); + failed = 1; + } + add_bread_crumb(); + + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0006.c b/src/dblib/unittests/t0006.c new file mode 100644 index 000000000..0d087b4e3 --- /dev/null +++ b/src/dblib/unittests/t0006.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#ifndef _WIN32 +#include +#endif + +#include "common.h" + + +static char software_version[] = "$Id: t0006.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +static char teststr[1024]; +static DBINT testint; + +static int failed = 0; + + +static void get_results(DBPROCESS *dbproc, int start) +{ + int current = start-1; + while (REG_ROW == dbnextrow(dbproc)) + { + char expected[1024]; + + current++; + sprintf(expected, "row %04d", current); + + add_bread_crumb(); + + if (testint!=current) + { + fprintf(stderr, "Failed. Expected i to be %d, was %d\n", current, + (int)testint); + abort(); + } + if (0!= strncmp(teststr, expected, strlen(expected))) + { + fprintf(stdout, "Failed. Expected s to be |%s|, was |%s|\n", + expected, teststr); + abort(); + } + printf("Read a row of data -> %d %s\n", (int)testint, teststr); + } +} + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + + + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(""); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0006"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + +#ifdef MICROSOFT_DBLIB + dbsetopt(dbproc, DBBUFFER, "5000"); +#else + dbsetopt(dbproc, DBBUFFER, "5000", 0); +#endif + + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0006"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0006 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i=25 order by i"); + dbsqlexec(dbproc); + add_bread_crumb(); + + + if ((rc = dbresults(dbproc)) != SUCCEED) + { + add_bread_crumb(); + fprintf(stdout, "%s:%d: Was expecting a result set. (rc=%d)\n", + __FILE__, __LINE__, rc); + failed = 1; + } + + if (!failed) + { + add_bread_crumb(); + + add_bread_crumb(); + dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint); + add_bread_crumb(); + dbbind(dbproc,2,STRINGBIND,-1,(BYTE *) teststr); + add_bread_crumb(); + + get_results(dbproc, 25); + } + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + diff --git a/src/dblib/unittests/t0007.c b/src/dblib/unittests/t0007.c new file mode 100644 index 000000000..520832452 --- /dev/null +++ b/src/dblib/unittests/t0007.c @@ -0,0 +1,225 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + +static char software_version[] = "$Id: t0007.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +static void create_tables( + DBPROCESS *dbproc, + int rows_to_add) +{ + int i; + char cmd[1024]; + + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0007"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0007 (i int not null, s char(12) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i %d %s\n", (int)testint, teststr); + } + + + fprintf(stdout, "second select\n"); + + if (start_query(dbproc, "select * from dblib0007 where i>=5 order by i")) + { + fprintf(stderr, "%s:%d: start_query should have failed but didn't\n", + __FILE__, __LINE__); + failed = 1; + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0008.c b/src/dblib/unittests/t0008.c new file mode 100644 index 000000000..1c2b39789 --- /dev/null +++ b/src/dblib/unittests/t0008.c @@ -0,0 +1,189 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + +static char software_version[] = "$Id: t0008.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + DBINT last_read = -1; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0008"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + +#ifdef MICROSOFT_DBLIB + dbsetopt(dbproc, DBBUFFER, "25"); +#else + dbsetopt(dbproc, DBBUFFER, "25", 0); +#endif + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0008"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0008 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=1; i %d %s\n", (int)testint, teststr); + } + + fprintf(stderr, "dblib failed for %s\n", __FILE__); + return 1; +} + + + + + diff --git a/src/dblib/unittests/t0009.c b/src/dblib/unittests/t0009.c new file mode 100644 index 000000000..93d2c8963 --- /dev/null +++ b/src/dblib/unittests/t0009.c @@ -0,0 +1,182 @@ +/* ================================= t0009.c ================================= + * + * Def: Test to see if dbbind can handle a varlen of 0 with a + * column bound as STRINGBIND and a database column of CHAR. + * + * =========================================================================== + */ + +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + +static char software_version[] = "$Id: t0009.c,v 1.1 2001-10-12 23:29:11 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + DBINT last_read = -1; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0009"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + +#ifdef MICROSOFT_DBLIB + dbsetopt(dbproc, DBBUFFER, "100"); +#else + dbsetopt(dbproc, DBBUFFER, "100", 0); +#endif + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0009"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0009 (i int not null, s varchar(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + dbcmd(dbproc, "insert into dblib0009 values (1, 'abcdef')"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + dbcmd(dbproc, "insert into dblib0009 values (2, 'abc')"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + + fprintf(stdout, "select\n"); + dbcmd(dbproc,"select * from dblib0009 order by i"); + dbsqlexec(dbproc); + add_bread_crumb(); + + + if (dbresults(dbproc)!=SUCCEED) + { + add_bread_crumb(); + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + add_bread_crumb(); + + for (i=1;i<=dbnumcols(dbproc);i++) + { + add_bread_crumb(); + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + add_bread_crumb(); + } + + add_bread_crumb(); + dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint); + add_bread_crumb(); + dbbind(dbproc,2,STRINGBIND, 0,(BYTE *) teststr); + add_bread_crumb(); + + add_bread_crumb(); + + + if (REG_ROW != dbnextrow(dbproc)) + { + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + if (0 != strcmp("abcdef ", teststr)) + { + fprintf(stderr, "Expected |%s|, found |%s|\n", "abcdef", teststr); + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + + if (REG_ROW != dbnextrow(dbproc)) + { + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + if (0 != strcmp("abc ", teststr)) + { + fprintf(stderr, "Expected |%s|, found |%s|\n", "abc", teststr); + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + + fprintf(stderr, "dblib passed for %s\n", __FILE__); + return 0; +} + + + + + diff --git a/src/dblib/unittests/t0010.c b/src/dblib/unittests/t0010.c new file mode 100644 index 000000000..cb2e57b75 --- /dev/null +++ b/src/dblib/unittests/t0010.c @@ -0,0 +1,182 @@ +/* ================================= t0010.c ================================= + * + * Def: Test to see if dbbind can handle a varlen of 0 with a + * column bound as STRINGBIND and a database column of VARCHAR. + * + * =========================================================================== + */ + +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + +static char software_version[] = "$Id: t0010.c,v 1.1 2001-10-12 23:29:12 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int main() +{ + RETCODE rc; + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + DBINT last_read = -1; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0010"); + DBSETLHOST(login,"ntbox.dntis.ro"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + +#ifdef MICROSOFT_DBLIB + dbsetopt(dbproc, DBBUFFER, "100"); +#else + dbsetopt(dbproc, DBBUFFER, "100", 0); +#endif + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0010"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0010 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + dbcmd(dbproc, "insert into dblib0010 values (1, 'abcdef')"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + dbcmd(dbproc, "insert into dblib0010 values (2, 'abc')"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + + fprintf(stdout, "select\n"); + dbcmd(dbproc,"select * from dblib0010 order by i"); + dbsqlexec(dbproc); + add_bread_crumb(); + + + if (dbresults(dbproc)!=SUCCEED) + { + add_bread_crumb(); + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + add_bread_crumb(); + + for (i=1;i<=dbnumcols(dbproc);i++) + { + add_bread_crumb(); + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + add_bread_crumb(); + } + + add_bread_crumb(); + dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint); + add_bread_crumb(); + dbbind(dbproc,2,STRINGBIND, 0,(BYTE *) teststr); + add_bread_crumb(); + + add_bread_crumb(); + + + if (REG_ROW != dbnextrow(dbproc)) + { + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + if (0 != strcmp("abcdef ", teststr)) + { + fprintf(stderr, "Expected |%s|, found |%s|\n", "abcdef", teststr); + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + + if (REG_ROW != dbnextrow(dbproc)) + { + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + if (0 != strcmp("abc ", teststr)) + { + fprintf(stderr, "Expected |%s|, found |%s|\n", "abc", teststr); + fprintf(stderr, "dblib failed for %s\n", __FILE__); + exit(1); + } + + fprintf(stderr, "dblib passed for %s\n", __FILE__); + return 0; +} + + + + + diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c new file mode 100644 index 000000000..66ddba306 --- /dev/null +++ b/src/dblib/unittests/t0011.c @@ -0,0 +1,169 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +/* + * Test binding of string types + * + */ + + +static char software_version[] = "$Id: t0011.c,v 1.1 2001-10-12 23:29:12 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; +const char long_column[] = "This is a really long column to ensure that the next row ends properly."; +const char short_column[] = "Short column"; + +void insert_row(DBPROCESS *dbproc, char *cmd); + +int main() +{ + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char cmd[2048]; + + read_login_info(); + fprintf(stdout, "Start\n"); + + dbinit(); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0011"); + +fprintf(stdout, "About to open\n"); + + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + + fprintf(stdout, "Dropping table\n"); + dbcmd(dbproc, "drop table dblib0011"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, "create table dblib0011 (i int not null, c1 char(200) not null, c2 char(200) null, vc varchar(200) null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + + sprintf(cmd, "insert into dblib0011 values (1, '%s','%s','%s')", long_column, long_column, long_column); + insert_row(dbproc,cmd); + sprintf(cmd, "insert into dblib0011 values (2, '%s','%s','%s')", short_column, short_column, short_column); + insert_row(dbproc,cmd); + sprintf(cmd, "insert into dblib0011 values (3, '%s',NULL,NULL)", short_column); + insert_row(dbproc,cmd); + + failed = select_rows(dbproc, STRINGBIND); + + dbexit(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + +int select_rows(DBPROCESS *dbproc, int bind_type) +{ + char teststr[1024]; + char teststr2[1024]; + char testvstr[1024]; + DBINT testint; + DBINT i; + + + fprintf(stdout, "select\n"); + dbcmd(dbproc,"select * from dblib0011 order by i"); + dbsqlexec(dbproc); + + + if (dbresults(dbproc)!=SUCCEED) + { + failed = 1; + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + + for (i=1;i<=dbnumcols(dbproc);i++) + { + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + } + + if (SUCCEED != dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint)) + { + fprintf(stderr, "Had problem with bind\n"); + return 1; + } + if (SUCCEED != dbbind(dbproc,2,bind_type,-1,(BYTE *) teststr)) + { + fprintf(stderr, "Had problem with bind\n"); + return 1; + } + if (SUCCEED != dbbind(dbproc,3,bind_type,-1,(BYTE *) teststr2)) + { + fprintf(stderr, "Had problem with bind\n"); + return 1; + } + if (SUCCEED != dbbind(dbproc,4,bind_type,-1,(BYTE *) testvstr)) + { + fprintf(stderr, "Had problem with bind\n"); + return 1; + } + + i=0; + while (dbnextrow(dbproc)==REG_ROW) + { + i++; + if (testint != i) + { + fprintf(stdout, "Failed. Expected i to be |%d|, was |%d|\n", + testint); + return 1; + } + printf("c: %s$\n",teststr); + printf("c2: %s$\n",teststr2); + printf("vc: %s$\n",testvstr); + if (bind_type == STRINGBIND) + { + } else { + } + } + return 0; +} + +void insert_row(DBPROCESS *dbproc, char *cmd) +{ + fprintf(stdout, "%s\n",cmd); + dbcmd(dbproc, cmd); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } +} diff --git a/src/dblib/unittests/t0012.c b/src/dblib/unittests/t0012.c new file mode 100644 index 000000000..d7db89517 --- /dev/null +++ b/src/dblib/unittests/t0012.c @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + + +static char software_version[] = "$Id: t0012.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; +int failed = 0; + + +int main(int argc, char *argv[]) +{ + const int rows_to_add = 3; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + char sqlCmd[256]; + char datestring[256]; + DBDATEREC dateinfo; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + dbinit(); + + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0012"); + + fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", + "","",""); // PASSWORD, USER, SERVER); + + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) { + dbuse(dbproc,DATABASE); + } + fprintf(stdout, "After logon\n"); + + sprintf(sqlCmd, "SELECT name, crdate FROM master..sysdatabases where name='%s'", DATABASE); + dbcmd(dbproc, sqlCmd); + dbsqlexec(dbproc); + dbresults(dbproc); + + while (dbnextrow(dbproc) != NO_MORE_ROWS) + { + // Print the database name and its date info + dbconvert(dbproc, dbcoltype(dbproc, 2), + dbdata(dbproc, 2), + dbdatlen(dbproc, 2), SYBCHAR, datestring, -1); + printf("%s: %s\n", (char *) (dbdata(dbproc, 1)), datestring); + + // Break up the creation date into its constituent parts + dbdatecrack(dbproc, &dateinfo, (DBDATETIME *) (dbdata(dbproc, 2))); + + // Print the parts of the creation date +#if MSDBLIB + printf("\tYear = %d.\n", dateinfo.year); + printf("\tMonth = %d.\n", dateinfo.month); + printf("\tDay of month = %d.\n", dateinfo.day); + printf("\tDay of year = %d.\n", dateinfo.dayofyear); + printf("\tDay of week = %d.\n", dateinfo.weekday); + printf("\tHour = %d.\n", dateinfo.hour); + printf("\tMinute = %d.\n", dateinfo.minute); + printf("\tSecond = %d.\n", dateinfo.second); + printf("\tMillisecond = %d.\n", dateinfo.millisecond); +#else + printf("\tYear = %d.\n", dateinfo.dateyear); + printf("\tMonth = %d.\n", dateinfo.datemonth); + printf("\tDay of month = %d.\n", dateinfo.datedmonth); + printf("\tDay of year = %d.\n", dateinfo.datedyear); + printf("\tDay of week = %d.\n", dateinfo.datedweek); + printf("\tHour = %d.\n", dateinfo.datehour); + printf("\tMinute = %d.\n", dateinfo.dateminute); + printf("\tSecond = %d.\n", dateinfo.datesecond); + printf("\tMillisecond = %d.\n", dateinfo.datemsecond); +#endif + } + + dbclose(dbproc); + dbexit(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c new file mode 100644 index 000000000..d3c0f8ec6 --- /dev/null +++ b/src/dblib/unittests/t0013.c @@ -0,0 +1,269 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + + +static char software_version[] = "$Id: t0013.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; +#define BLOB_BLOCK_SIZE 4096 + +int failed = 0; + + +int main(int argc, char *argv[]) +{ + const int rows_to_add = 3; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + FILE *fp; + long result, isiz; + char *blob, *rblob; + unsigned char *textPtr, *timeStamp; + char objname[256]; + char sqlCmd[256]; + char rbuf[BLOB_BLOCK_SIZE]; + long numread, numwritten, numtowrite; + BOOL readFirstImage; + char cmd[1024]; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + dbinit(); + + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0013"); + + fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", + "","",""); // PASSWORD, USER, SERVER); + + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) { + dbuse(dbproc,DATABASE); + } + fprintf(stdout, "After logon\n"); + + fprintf(stdout, "About to read binary input file\n"); + + if (argc < 3) { + fprintf(stderr, "Usage: %s infile outfile\n", argv[0]); + return 1; + } + + if ((fp = fopen(argv[1], "rb")) == NULL) { + fprintf(stderr, "Cannot open input file: %s\n", argv[1]); + return 2; + } + result = fseek( fp, 0, SEEK_END); + isiz = ftell(fp); + result = fseek( fp, 0, SEEK_SET); + + blob = (char *)malloc(isiz); + fread((void *)blob, isiz, 1, fp); + fclose (fp); + + fprintf(stdout, "Dropping table\n"); + dbcmd(dbproc, "drop table dblib0013"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0013 (i int not null, PigTure image not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + + fprintf(stdout, "insert\n"); + + sprintf(cmd, "insert into dblib0013 values (1, '')"); + fprintf(stdout, "%s\n",cmd); + dbcmd(dbproc, cmd); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + sprintf(sqlCmd, "SELECT PigTure FROM dblib0013 WHERE i = 1"); + dbcmd(dbproc, sqlCmd); + dbsqlexec(dbproc); + if (dbresults(dbproc) != SUCCEED) { + fprintf(stderr, "Error inserting blob\n"); + return 4; + } + + while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) { + result = REG_ROW ; + result = DBTXPLEN; + strcpy(objname, "dblib0013.PigTure"); + textPtr = dbtxptr(dbproc, 1); + timeStamp = dbtxtimestamp(dbproc, 1); + } + + // Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps) + // Use #ifndef for big buffer version (32-bit) +#ifndef DBWRITE_OK_FOR_OVER_4K + if (dbwritetext(dbproc, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, blob) != SUCCEED) + return 5; +#else + if (dbwritetext(dbproc, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, NULL) != SUCCEED) + return 15; + dbsqlok(dbproc); + dbresults(dbproc); + + numtowrite = 0; + // Send the update value in chunks. + for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) { + numtowrite = (isiz - numwritten); + if (numtowrite > BLOB_BLOCK_SIZE) + numtowrite = BLOB_BLOCK_SIZE; + dbmoretext(dbproc, (DBINT)numtowrite, blob + numwritten); + } + dbsqlok(dbproc); + while (dbresults(dbproc) != NO_MORE_RESULTS); + } +#endif + + fprintf(stdout, "select\n"); + + dbcmd(dbproc,"select * from dblib0013 order by i"); + dbsqlexec(dbproc); + + if (dbresults(dbproc)!=SUCCEED) + { + failed = 1; + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + + for (i=1;i<=dbnumcols(dbproc);i++) + { + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + } + + if (SUCCEED != dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint)) + { + failed = 1; + fprintf(stderr, "Had problem with bind\n"); + abort(); + } + + if (REG_ROW != dbnextrow(dbproc)) + { + failed = 1; + fprintf(stderr, "Failed. Expected a row\n"); + exit(1); + } + if (testint!=1) + { + failed = 1; + fprintf(stderr, "Failed. Expected i to be %d, was %d\n", i, + (int)testint); + abort(); + } + dbnextrow(dbproc); + + // get the image + strcpy(sqlCmd, "SET TEXTSIZE 2147483647"); + dbcmd(dbproc, sqlCmd); + dbsqlexec(dbproc); + dbresults(dbproc); + + fprintf(stdout, "select 2\n"); + + sprintf(sqlCmd, "SELECT PigTure FROM dblib0013 WHERE i = 1"); + dbcmd(dbproc, sqlCmd); + dbsqlexec(dbproc); + if (dbresults(dbproc) != SUCCEED) { + fprintf(stderr, "Error extracting blob\n"); + return 6; + } + + numread = 0; + rblob = NULL; + readFirstImage = FALSE; + while ((result = dbreadtext(dbproc, rbuf, BLOB_BLOCK_SIZE)) != NO_MORE_ROWS) + { + if (result == 0) // this indicates end of row + { + readFirstImage = TRUE; + } else { + rblob = realloc(rblob, result + numread); + memcpy((void *)(rblob + numread), (void *)rbuf, result); + numread += result; + } + } + + printf("Saving first blob data row to file: %s\n", argv[2]); + if ((fp = fopen(argv[2], "wb")) == NULL) { + fprintf(stderr, "Unable to open output file: %s\n", argv[2]); + return 3; + } + result = fwrite((void *)rblob, numread, 1, fp); + fclose (fp); + + printf("Read blob data row %d --> %s %d byte comparison\n", + (int)testint, (memcmp(blob, rblob, numread)) ? "failed" + : "PASSED", numread); + free(rblob); + + if (dbnextrow(dbproc)!=NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows\n"); + exit(1); + } + + dbexit(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c new file mode 100644 index 000000000..c9077c84c --- /dev/null +++ b/src/dblib/unittests/t0014.c @@ -0,0 +1,290 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + + +static char software_version[] = "$Id: t0014.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; +#define BLOB_BLOCK_SIZE 4096 + +int failed = 0; + + +int main(int argc, char *argv[]) +{ + const int rows_to_add = 3; + LOGINREC *login; + DBPROCESS *dbproc; + DBPROCESS *blobproc; + int i; + char teststr[1024]; + DBINT testint; + FILE *fp; + long result, isiz; + char *blob, *rblob; + unsigned char *textPtr, *timeStamp; + char objname[256]; + char sqlCmd[256]; + char rbuf[BLOB_BLOCK_SIZE]; + long numread, numwritten, numtowrite; + BOOL readFirstImage; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + dbinit(); + + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0014"); + + fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", + "","",""); // PASSWORD, USER, SERVER); + + dbproc = dbopen(login, SERVER); + blobproc = dbopen(login, SERVER); + if (strlen(DATABASE)) { + dbuse(dbproc,DATABASE); + dbuse(blobproc,DATABASE); + } + fprintf(stdout, "After logon\n"); + + fprintf(stdout, "About to read binary input file\n"); + + if (argc < 3) { + fprintf(stderr, "Usage: %s infile outfile\n", argv[0]); + return 1; + } + + if ((fp = fopen(argv[1], "rb")) == NULL) { + fprintf(stderr, "Cannot open input file: %s\n", argv[1]); + return 2; + } + result = fseek( fp, 0, SEEK_END); + isiz = ftell(fp); + result = fseek( fp, 0, SEEK_SET); + + blob = (char *)malloc(isiz); + fread((void *)blob, isiz, 1, fp); + fclose (fp); + + fprintf(stdout, "Dropping table\n"); + dbcmd(dbproc, "drop table dblib0013"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0013 (i int not null, PigTure image not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + + fprintf(stdout, "insert\n"); + for(i=0; i BLOB_BLOCK_SIZE) + numtowrite = BLOB_BLOCK_SIZE; + dbmoretext(blobproc, (DBINT)numtowrite, blob + numwritten); + } + dbsqlok(blobproc); + while (dbresults(blobproc) != NO_MORE_RESULTS); + +#endif + } + } + + fprintf(stdout, "select\n"); + + dbcmd(dbproc,"select * from dblib0013 order by i"); + dbsqlexec(dbproc); + + if (dbresults(dbproc)!=SUCCEED) + { + failed = 1; + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + + for (i=1;i<=dbnumcols(dbproc);i++) + { + printf ("col %d is %s\n",i,dbcolname(dbproc,i)); + } + + if (SUCCEED != dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint)) + { + failed = 1; + fprintf(stderr, "Had problem with bind\n"); + abort(); + } + + for(i=0; i %s %d byte comparison\n", + (int)testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", numread); + free(rblob); + } + + if (dbnextrow(dbproc)!=NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows\n"); + exit(1); + } + + dbexit(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0015.c b/src/dblib/unittests/t0015.c new file mode 100644 index 000000000..df7cec3dd --- /dev/null +++ b/src/dblib/unittests/t0015.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + + +static char software_version[] = "$Id: t0015.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +int main() +{ + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0015"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0015"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0015 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=0; i 25 order by i"); + dbsqlexec(dbproc); + + if (dbresults(dbproc)!=SUCCEED) + { + add_bread_crumb(); + failed = 1; + fprintf(stdout, "Was expecting a result set."); + exit(1); + } + + add_bread_crumb(); + if (SUCCEED != dbbind(dbproc,1,INTBIND,-1,(BYTE *) &testint)) + { + failed = 1; + fprintf(stderr, "Had problem with bind\n"); + abort(); + } + add_bread_crumb(); + if (SUCCEED != dbbind(dbproc,2,STRINGBIND,-1,(BYTE *) teststr)) + { + failed = 1; + fprintf(stderr, "Had problem with bind\n"); + abort(); + } + add_bread_crumb(); + + for(i=26; i %d %s\n", (int)testint, teststr); + } + + add_bread_crumb(); + if (dbnextrow(dbproc)!=NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows\n"); + exit(1); + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c new file mode 100644 index 000000000..8ff3c3b99 --- /dev/null +++ b/src/dblib/unittests/t0016.c @@ -0,0 +1,157 @@ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +static char software_version[] = "$Id: t0016.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; +int failed = 0; + + +int main(int argc, char *argv[]) +{ + const int rows_to_add = 3; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + char sqlCmd[256]; + char datestring[256]; + DBDATEREC dateinfo; + RETCODE ret; + char *out_file = "t0016.out"; + char *in_file = "t0016.in"; + char *err_file = "t0016.err"; + DBINT rows_copied; + int num_cols; + int col_type[256]; + int prefix_len; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + dbinit(); + + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + BCP_SETL(login,TRUE); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0016"); + + fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", + "","",""); // PASSWORD, USER, SERVER); + + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) { + dbuse(dbproc,DATABASE); + } + fprintf(stdout, "After logon\n"); + + fprintf(stdout, "Dropping table\n"); + dbcmd(dbproc, "drop table dblib0016"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "Creating table\n"); + dbcmd(dbproc, "create table dblib0016 (f1 int not null, s1 int null, f2 real null, f3 varchar(255) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + /* BCP in */ + + ret = bcp_init(dbproc, "tempdb..dblib0016", in_file, err_file, DB_IN); + + fprintf(stderr, "select\n"); + dbcmd(dbproc, "select * from dblib0016 where 0=1"); + dbsqlexec(dbproc); + if (dbresults(dbproc) != FAIL) { + num_cols = dbnumcols(dbproc); + for (i=0;i +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +static char software_version[] = "$Id: t0017.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; +int failed = 0; + + +int main(int argc, char *argv[]) +{ + const int rows_to_add = 3; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + char sqlCmd[256]; + char datestring[256]; + DBDATEREC dateinfo; + RETCODE ret; + char *out_file = "t0017.out"; + char *in_file = "t0017.in"; + char *err_file = "t0017.err"; + DBINT rows_copied; + int num_cols; + int col_type[256]; + int prefix_len; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + dbinit(); + + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + login = dblogin(); + BCP_SETL(login,TRUE); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0017"); + + fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", + "","",""); // PASSWORD, USER, SERVER); + + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) { + dbuse(dbproc,DATABASE); + } + fprintf(stdout, "After logon\n"); + + fprintf(stdout, "Dropping table\n"); + dbcmd(dbproc, "drop table dblib0017"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "Creating table\n"); + dbcmd(dbproc, "create table dblib0017 (c1 int, c2 text)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + /* BCP in */ + + ret = bcp_init(dbproc, "tempdb..dblib0017", in_file, err_file, DB_IN); + + fprintf(stderr, "select\n"); + dbcmd(dbproc, "select * from dblib0017 where 0=1"); + dbsqlexec(dbproc); + if (dbresults(dbproc) != FAIL) { + num_cols = dbnumcols(dbproc); + for (i=0;i +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + + + + +static char software_version[] = "$Id: t0018.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +int main() +{ + const int rows_to_add = 50; + LOGINREC *login; + DBPROCESS *dbproc; + int i; + char teststr[1024]; + DBINT testint; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + read_login_info(); + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0018"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + fprintf(stdout, "Dropping table\n"); + add_bread_crumb(); + dbcmd(dbproc, "drop table dblib0018"); + add_bread_crumb(); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + add_bread_crumb(); + + fprintf(stdout, "creating table\n"); + dbcmd(dbproc, + "create table dblib0018 (i int not null, s char(10) not null)"); + dbsqlexec(dbproc); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + + fprintf(stdout, "insert\n"); + for(i=0; i %d %s\n", (int)testint, teststr); + } + + + add_bread_crumb(); + if (dbnextrow(dbproc)!=NO_MORE_ROWS) + { + failed = 1; + fprintf(stderr, "Was expecting no more rows\n"); + exit(1); + } + if (DBCOUNT(dbproc)!=rows_to_add) { + failed = 1; + fprintf(stdout, "Was expecting a rows affect to be %d was %d.\n", + rows_to_add, DBCOUNT(dbproc)); + exit(1); + } + + dbcmd(dbproc,"update dblib0018 set s = 'row 000'"); + dbsqlexec(dbproc); + add_bread_crumb(); + while (dbresults(dbproc)!=NO_MORE_RESULTS) + { + /* nop */ + } + if (DBCOUNT(dbproc)!=rows_to_add) { + failed = 1; + fprintf(stdout, "Was expecting a rows affect to be %d was %d.\n", + rows_to_add, DBCOUNT(dbproc)); + exit(1); + } else { + fprintf(stdout, "Number of rows affected by update = %d.\n", DBCOUNT(dbproc)); + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/unittests/t0020.c b/src/dblib/unittests/t0020.c new file mode 100644 index 000000000..18beb49f4 --- /dev/null +++ b/src/dblib/unittests/t0020.c @@ -0,0 +1,107 @@ +/* +** test for proper return code from dbsqlexec() +*/ +#include +#include +#include +#include +#ifdef _WIN32 +#define DBNTWIN32 +#include +#endif +#include +#include + +#include "common.h" + +static char software_version[] = "$Id: t0020.c,v 1.1 2001-10-12 23:29:13 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +int failed = 0; + + +int main() +{ +LOGINREC *login; +DBPROCESS *dbproc; +int i; +RETCODE ret; + +#ifdef __FreeBSD__ + /* + * Options for malloc A- all warnings are fatal, J- init memory to 0xD0, + * R- always move memory block on a realloc. + */ + extern char *malloc_options; + malloc_options = "AJR"; +#endif + + read_login_info(); + +#ifndef _WIN32 + tdsdump_open(NULL); +#endif + + fprintf(stdout, "Start\n"); + add_bread_crumb(); + + /* Fortify_EnterScope(); */ + dbinit(); + + add_bread_crumb(); + dberrhandle( syb_err_handler ); + dbmsghandle( syb_msg_handler ); + + fprintf(stdout, "About to logon\n"); + + add_bread_crumb(); + login = dblogin(); + DBSETLPWD(login,PASSWORD); + DBSETLUSER(login,USER); + DBSETLAPP(login,"t0020"); + +fprintf(stdout, "About to open\n"); + + add_bread_crumb(); + dbproc = dbopen(login, SERVER); + if (strlen(DATABASE)) dbuse(dbproc,DATABASE); + add_bread_crumb(); + + dbcmd(dbproc,"select dsjfkl dsjf"); + fprintf(stderr, "The following invalid column error is normal.\n"); + ret = dbsqlexec(dbproc); + if (ret!=FAIL) { + failed = 1; + fprintf(stderr, "Failed. Expected FAIL to be returned.\n"); + exit(1); + } + + dbcmd(dbproc,"select db_name()"); + ret = dbsqlexec(dbproc); + if (ret!=SUCCEED) { + failed = 1; + fprintf(stderr, "Failed. Expected SUCCEED to be returned.\n"); + exit(1); + } + + while (dbresults(dbproc)!=NO_MORE_RESULTS) { + while (dbnextrow(dbproc)!=NO_MORE_ROWS); + } + + add_bread_crumb(); + dbexit(); + add_bread_crumb(); + + fprintf(stdout, "dblib %s on %s\n", + (failed?"failed!":"okay"), + __FILE__); + return failed ? 1 : 0; +} + + + + + diff --git a/src/dblib/xact.c b/src/dblib/xact.c new file mode 100644 index 000000000..c10a08f23 --- /dev/null +++ b/src/dblib/xact.c @@ -0,0 +1,65 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tdsutil.h" +#include "tds.h" +#include "sybfront.h" +#include "sybdb.h" +#include "dblib.h" +#include + +static char software_version[] = "$Id: xact.c,v 1.1 2001-10-12 23:29:10 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +void build_xact_string(char *xact_name, char *service_name, DBINT commid, char *result) +{ +} +RETCODE remove_xact(DBPROCESS *connect, DBINT commid, int n) +{ + return SUCCEED; +} +RETCODE abort_xact(DBPROCESS *connect, DBINT commid) +{ + return SUCCEED; +} +void close_commit(DBPROCESS *connect) +{ +} +RETCODE commit_xact(DBPROCESS *connect, DBINT commid) +{ + return SUCCEED; +} +DBPROCESS *open_commit(LOGINREC *login, char *servername) +{ + return NULL; +} +RETCODE scan_xact(DBPROCESS *connect, DBINT commid) +{ + return SUCCEED; +} +DBINT start_xact(DBPROCESS *connect, char *application_name, char *xact_name, int site_count) +{ + return 0; +} +DBINT stat_xact(DBPROCESS *connect, DBINT commid) +{ + return 0; +} diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am new file mode 100644 index 000000000..8f1ba63e9 --- /dev/null +++ b/src/odbc/Makefile.am @@ -0,0 +1,14 @@ +include_HEADERS = connectparams.h +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libtdsodbc.la +##EXTRA_LTLIBRARIES = libtdsodbc.la +libtdsodbc_la_SOURCES= odbc.c connectparams.c +libtdsodbc_la_LIBADD= $(patsubst %, $(TDSDIR)/%, \ + $(patsubst %.c, %.lo, $(TDSSOURCES))) -lglib +INCLUDES = -I$(top_srcdir)/include `glib-config --cflags glib` -I$(ODBC_INC) + +## Need blank statement to avoid compiling odbc.c +odbc: $(EXTRA_LTLIBRARIES) + @echo '' + diff --git a/src/odbc/Makefile.in b/src/odbc/Makefile.in new file mode 100644 index 000000000..018d9b382 --- /dev/null +++ b/src/odbc/Makefile.in @@ -0,0 +1,343 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +include_HEADERS = connectparams.h +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libtdsodbc.la +libtdsodbc_la_SOURCES = odbc.c connectparams.c +libtdsodbc_la_LIBADD = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, %.lo, $(TDSSOURCES))) -lglib + +INCLUDES = -I$(top_srcdir)/include `glib-config --cflags glib` -I$(ODBC_INC) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libtdsodbc_la_LDFLAGS = +libtdsodbc_la_DEPENDENCIES = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, \ +%.lo, $(TDSSOURCES))) +libtdsodbc_la_OBJECTS = odbc.lo connectparams.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(include_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libtdsodbc_la_SOURCES) +OBJECTS = $(libtdsodbc_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/odbc/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libtdsodbc.la: $(libtdsodbc_la_OBJECTS) $(libtdsodbc_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libtdsodbc_la_LDFLAGS) $(libtdsodbc_la_OBJECTS) $(libtdsodbc_la_LIBADD) $(LIBS) + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/odbc + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +connectparams.lo connectparams.o : connectparams.c connectparams.h +odbc.lo odbc.o : odbc.c ../../include/tdsodbc.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + connectparams.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool uninstall-includeHEADERS \ +install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir info-am info dvi-am dvi check check-am \ +installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +odbc: $(EXTRA_LTLIBRARIES) + @echo '' + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c new file mode 100644 index 000000000..403c10cb0 --- /dev/null +++ b/src/odbc/connectparams.c @@ -0,0 +1,447 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include + +#include "connectparams.h" + +#ifndef SYS_ODBC_INI +#define SYS_ODBC_INI "/etc/odbc.ini" +#endif + +#define max_line 256 +static char line[max_line]; + +static guint HashFunction (gconstpointer key); +static GString* GetIniFileName (); +static int FileExists (const gchar* name); +static int FindSection (FILE* stream, const char* section); +static int GetNextItem (FILE* stream, char** name, char** value); + +static void visit (gpointer key, gpointer value, gpointer user_data); +static gboolean cleanup (gpointer key, gpointer value, gpointer user_data); + +/* + * Allocate create a ConnectParams object + */ + +ConnectParams* NewConnectParams () +{ + ConnectParams* params = malloc (sizeof (ConnectParams)); + if (!params) + return params; + + params->dsnName = g_string_new (""); + params->iniFileName = NULL; + params->table = g_hash_table_new (HashFunction, g_str_equal); + + return params; +} + +/* + * Destroy a ConnectParams object + */ + +void FreeConnectParams (ConnectParams* params) +{ + if (params) + { + if (params->dsnName) + g_string_free (params->dsnName, TRUE); + if (params->iniFileName) + g_string_free (params->iniFileName, TRUE); + if (params->table) + { + g_hash_table_foreach_remove (params->table, cleanup, NULL); + g_hash_table_destroy (params->table); + } + } +} + +/* + * Find the settings for the specified ODBC DSN + */ + +gboolean LookupDSN (ConnectParams* params, const gchar* dsnName) +{ + if (!params) { + fprintf(stderr,"LookupDSN: no parameters, returning FALSE"); + return FALSE; + } + /* + * Set the DSN name property + */ + /* params->dsnName = g_string_assign (params->dsnName, dsnName); */ + /* + * Search for the ODBC ini file + */ + if (!(params->iniFileName = GetIniFileName ())) { + fprintf(stderr,"LookupDSN: GetIniFileName returned FALSE"); + return FALSE; + } + + if (!LoadDSN (params->iniFileName->str, dsnName, params->table)) { + fprintf(stderr,"LookupDSN: LoadDSN returned FALSE"); + return FALSE; + } + + return TRUE; +} + +/* + * Get the value of a given ODBC Connection Parameter + */ + +gchar* GetConnectParam (ConnectParams* params, const gchar* paramName) +{ + if (!params || !params->table) + return NULL; + + return g_hash_table_lookup (params->table, paramName); +} + +/* + * Apply a connection string to the ODBC Parameter Settings + */ + +void SetConnectString (ConnectParams* params, const gchar* connectString) +{ + int end; + char *cs, *s, *p, *name, *value; + gpointer key; + gpointer oldvalue; + + if (!params) + return; + /* + * Make a copy of the connection string so we can modify it + */ + cs = strdup (connectString); + s = cs; + /* + * Loop over ';' seperated name=value pairs + */ + p = strchr (s, '='); + while (p) + { + if (p) *p = '\0'; + /* + * Extract name + */ + name = s; + if (p) s = p + 1; + /* + * Extract value + */ + p = strchr (s, ';'); + if (p) *p = '\0'; + value = s; + if (p) s = p + 1; + /* + * remove trailing spaces from name + */ + end = strlen (name) - 1; + while (end > 0 && isspace(name[end])) + name[end--] = '\0'; + /* + * remove leading spaces from value + */ + while (isspace(*value)) + value++; + + if (g_hash_table_lookup_extended (params->table, name, &key, &oldvalue)) + { + /* + * remove previous value + */ + g_hash_table_remove (params->table, key); + /* + * cleanup strings + */ + free (key); + free (oldvalue); + } + /* + * Insert the name/value pair into the hash table. + * + * Note that these strdup allocations are freed in cleanup, + * which is called by FreeConnectParams. + */ + g_hash_table_insert (params->table, strdup (name), strdup (value)); + + p = strchr (s, '='); + } + + free (cs); +} + +/* + * Dump all the ODBC Connection Paramters to a file (e.g. stdout) + */ + +void DumpParams (ConnectParams* params, FILE* output) +{ + if (!params) + { + g_printerr ("NULL ConnectionParams pointer\n"); + return; + } + + if (params->dsnName) + g_printerr ("Parameter values for DSN: %s\n", params->dsnName->str); + + if (params->iniFileName) + g_printerr ("Ini File is %s\n", params->iniFileName->str); + + g_hash_table_foreach (params->table, visit, output); +} + +/* + * Return the value of the DSN from the conneciton string + */ + +gchar* ExtractDSN (ConnectParams* params, const gchar* connectString) +{ + char *p, *q, *s; + + if (!params) + return NULL; + /* + * Position ourselves to the beginning of "DSN" + */ + p = strstr (connectString, "DSN"); + if (!p) return NULL; + /* + * Position ourselves to the "=" + */ + q = strchr (p, '='); + if (!q) return NULL; + /* + * Skip over any leading spaces + */ + q++; + while (isspace(*q)) + q++; + /* + * Copy the DSN value to a buffer + */ + s = line; + while (*q && *q != ';') + *s++ = *q++; + *s = '\0'; + /* + * Save it as a string in the params object + */ + params->dsnName = g_string_assign (params->dsnName, line); + + return params->dsnName->str; +} + +/* + * Begin local function definitions + */ + +static GString* GetIniFileName () +{ + char* setting; + GString* iniFileName = g_string_new (""); + /* + * First, try the ODBCINI environment variable + */ + if ((setting = getenv ("ODBCINI")) != NULL) + { + g_string_assign (iniFileName, getenv ("ODBCINI")); + + if (FileExists (iniFileName->str)) + return iniFileName; + + g_string_assign (iniFileName, ""); + } + /* + * Second, try the HOME environment variable + */ + if ((setting = getenv ("HOME")) != NULL) + { + g_string_assign (iniFileName, setting); + iniFileName = g_string_append (iniFileName, "/.odbc.ini"); + + if (FileExists (iniFileName->str)) + return iniFileName; + + g_string_assign (iniFileName, ""); + } + /* + * As a last resort, try SYS_ODBC_INI + */ + g_string_assign (iniFileName, SYS_ODBC_INI); + if (FileExists (iniFileName->str)) + return iniFileName; + + g_string_assign (iniFileName, ""); + + return iniFileName; +} + +static int FileExists (const gchar* name) +{ + struct stat fileStat; + + return (stat (name, &fileStat) == 0); +} + +static int FindSection (FILE* stream, const char* section) +{ + char* s; + char sectionPattern[max_line]; + int len; + + strcpy (sectionPattern, "["); + strcat (sectionPattern, section); + strcat (sectionPattern, "]"); + + s = fgets (line, max_line, stream); + while (s != NULL) + { + /* + * Get rid of the newline character + */ + len = strlen (line); + if (len > 0) line[strlen (line) - 1] = '\0'; + /* + * look for the section header + */ + if (strcmp (line, sectionPattern) == 0) + return 1; + + s = fgets (line, max_line, stream); + } + + return 0; +} + +int LoadDSN ( + const gchar* iniFileName, const gchar* dsnName, GHashTable* table) +{ + FILE* stream; + gchar* name; + gchar* value; + + if ((stream = fopen (iniFileName, "r" )) != NULL ) + { + if (!FindSection (stream, dsnName)) + { + g_printerr ("Couldn't find DSN %s in %s\n", iniFileName, dsnName); + fclose (stream); + return 0; + } + else + { + while (GetNextItem (stream, &name, &value)) + { + g_hash_table_insert (table, strdup (name), strdup (value)); + } + } + + fclose( stream ); + } + + return 1; +} + +/* + * Make a hash from all the characters + */ +static guint HashFunction (gconstpointer key) +{ + guint value = 0; + const char* s = key; + + while (*s) value += *s++; + + return value; +} + +static int GetNextItem (FILE* stream, char** name, char** value) +{ + char* s; + int len; + char equals[] = "="; /* used for seperator for strtok */ + char* token; + + if (name == NULL || value == NULL) + { + g_printerr ("GetNextItem, invalid parameters"); + return 0; + } + + s = fgets (line, max_line, stream); + if (s == NULL) + { + perror ("fgets"); + return 0; + } + /* + * Get rid of the newline character + */ + len = strlen (line); + if (len > 0) line[strlen (line) - 1] = '\0'; + /* + * Extract name from name = value + */ + if ((token = strtok (line, equals)) == NULL) return 0; + + len = strlen (token); + while (len > 0 && isspace(token[len-1])) + { + len--; + token[len] = '\0'; + } + *name = token; + /* + * extract value from name = value + */ + token = strtok (NULL, equals); + if (token == NULL) return 0; + while (*token && isspace(token[0])) + token++; + + *value = token; + + return 1; +} + +static void visit (gpointer key, gpointer value, gpointer user_data) +{ + FILE* output = (FILE*) user_data; + + g_printerr ("Parameter: %s, Value: %s\n", key, value); +} + +static gboolean cleanup (gpointer key, gpointer value, gpointer user_data) +{ + free (key); + free (value); + + return TRUE; +} + + diff --git a/src/odbc/connectparams.h b/src/odbc/connectparams.h new file mode 100644 index 000000000..edd2e3251 --- /dev/null +++ b/src/odbc/connectparams.h @@ -0,0 +1,42 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef _ODBC_INI_LOAD_ +#define _ODBC_INI_LOAD_ + +#include + +typedef struct +{ + GString* dsnName; + GString* iniFileName; + GHashTable* table; +} ConnectParams; + +ConnectParams* NewConnectParams (); +void FreeConnectParams (ConnectParams* params); + +gboolean LookupDSN (ConnectParams* params, const gchar* dsnName); +gchar* GetConnectParam (ConnectParams* params, const gchar* paramName); +void SetConnectString (ConnectParams* params, const gchar* connectString); +void DumpParams (ConnectParams* params, FILE* output); + +gchar* ExtractDSN (ConnectParams* params, const gchar* connectString); + +#endif diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c new file mode 100644 index 000000000..734f65399 --- /dev/null +++ b/src/odbc/odbc.c @@ -0,0 +1,1425 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifdef UNIXODBC +#include +#include +#else +#include "isql.h" +#include "isqlext.h" +#endif + +#include +#include + +#include +#include + +#include "connectparams.h" + +static char software_version[] = "$Id: odbc.c,v 1.1 2001-10-12 23:29:15 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +static SQLSMALLINT _odbc_get_client_type(int srv_type); +static int _odbc_fix_literals(struct _hstmt *stmt); +static int _odbc_get_server_type(int clt_type); +static int _odbc_get_string_size(int size, char *str); +static SQLRETURN SQL_API _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR *phdbc); +static SQLRETURN SQL_API _SQLAllocEnv(SQLHENV FAR *phenv); +static SQLRETURN SQL_API _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR *phstmt); +static SQLRETURN SQL_API _SQLFreeConnect(SQLHDBC hdbc); +static SQLRETURN SQL_API _SQLFreeEnv(SQLHENV henv); +static SQLRETURN SQL_API _SQLFreeStmt(SQLHSTMT hstmt, SQLUSMALLINT fOption); + +#define _MAX_ERROR_LEN 255 +static char lastError[_MAX_ERROR_LEN+1]; + +static void LogError (const char* error) +{ + /* + * Someday, I might make this store more than one error. + */ + if (error) { + strncpy (lastError, error, _MAX_ERROR_LEN); + lastError[_MAX_ERROR_LEN] = '\0'; /* in case we had a long message */ + } +} + +/* + * Driver specific connectionn information + */ + +typedef struct +{ + struct _hdbc hdbc; + ConnectParams* params; +} ODBCConnection; + +/* +** +** Note: I *HATE* hungarian notation, it has to be the most idiotic thing +** I've ever seen. So, you will note it is avoided other than in the function +** declarations. "Gee, let's make our code totally hard to read and they'll +** beg for GUI tools" +** Bah! +*/ + +static SQLRETURN change_database (SQLHDBC hdbc, char *database) +{ + SQLRETURN ret; + TDSSOCKET *tds; + int marker; + struct _hdbc *dbc = (struct _hdbc *) hdbc; + char *query; + + tds = (TDSSOCKET *) dbc->tds_socket; + query = (char *) malloc(strlen(database)+5); + sprintf(query,"use %s", database); + ret = tds_submit_query(tds,query); + free(query); + if (ret != TDS_SUCCEED) { + LogError ("Could not change Database"); + return SQL_ERROR; + } + + do { + marker=tds_get_byte(tds); + tds_process_default_tokens(tds,marker); + } while (marker!=TDS_DONE_TOKEN); + + return SQL_SUCCESS; +} + +static SQLRETURN do_connect ( + SQLHDBC hdbc, + SQLCHAR FAR *server, + SQLCHAR FAR *user, + SQLCHAR FAR *passwd +) +{ + struct _hdbc *dbc = (struct _hdbc *) hdbc; + + tds_set_server (dbc->tds_login, server); + tds_set_user (dbc->tds_login, user); + tds_set_passwd (dbc->tds_login, passwd); + dbc->tds_socket = (void *) tds_connect(dbc->tds_login); + + if (dbc->tds_socket == NULL) + { + LogError ("tds_connect failed"); + return SQL_ERROR; + } + + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLDriverConnect( + SQLHDBC hdbc, + SQLHWND hwnd, + SQLCHAR FAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR FAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT FAR *pcbConnStrOut, + SQLUSMALLINT fDriverCompletion) +{ + SQLCHAR FAR* server = NULL; + SQLCHAR FAR* dsn = NULL; + SQLCHAR FAR* uid = NULL; + SQLCHAR FAR* pwd = NULL; + SQLCHAR FAR* database = NULL; + ConnectParams* params; + SQLRETURN ret; + + strcpy (lastError, ""); + + params = ((ODBCConnection*) hdbc)->params; + + if (!(dsn = ExtractDSN (params, szConnStrIn))) + { + LogError ("Could not find DSN in connect string"); + return SQL_ERROR; + } + else if (!LookupDSN (params, dsn)) + { + LogError ("Could not find DSN in odbc.ini"); + return SQL_ERROR; + } + else + { + SetConnectString (params, szConnStrIn); + + if (!(server = GetConnectParam (params, "Servername"))) + { + LogError ("Could not find Database parameter"); + return SQL_ERROR; + } + else if (!(uid = GetConnectParam (params, "UID"))) + { + LogError ("Could not find UID parameter"); + return SQL_ERROR; + } + else if (!(pwd = GetConnectParam (params, "PWD"))) + { + LogError ("Could not find PWD parameter"); + return SQL_ERROR; + } + } + if ((ret = do_connect (hdbc, server, uid, pwd))!=SQL_SUCCESS) + { + return ret; + } + if (!(database = GetConnectParam (params, "Database"))) + { + /* use the default database */ + return SQL_SUCCESS; + } + else + { + return change_database(hdbc, database); + } +} + +SQLRETURN SQL_API SQLBrowseConnect( + SQLHDBC hdbc, + SQLCHAR FAR *szConnStrIn, + SQLSMALLINT cbConnStrIn, + SQLCHAR FAR *szConnStrOut, + SQLSMALLINT cbConnStrOutMax, + SQLSMALLINT FAR *pcbConnStrOut) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLColumnPrivileges( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLDescribeParam( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT FAR *pfSqlType, + SQLUINTEGER FAR *pcbParamDef, + SQLSMALLINT FAR *pibScale, + SQLSMALLINT FAR *pfNullable) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLExtendedFetch( + SQLHSTMT hstmt, + SQLUSMALLINT fFetchType, + SQLINTEGER irow, + SQLUINTEGER FAR *pcrow, + SQLUSMALLINT FAR *rgfRowStatus) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLForeignKeys( + SQLHSTMT hstmt, + SQLCHAR FAR *szPkCatalogName, + SQLSMALLINT cbPkCatalogName, + SQLCHAR FAR *szPkSchemaName, + SQLSMALLINT cbPkSchemaName, + SQLCHAR FAR *szPkTableName, + SQLSMALLINT cbPkTableName, + SQLCHAR FAR *szFkCatalogName, + SQLSMALLINT cbFkCatalogName, + SQLCHAR FAR *szFkSchemaName, + SQLSMALLINT cbFkSchemaName, + SQLCHAR FAR *szFkTableName, + SQLSMALLINT cbFkTableName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLMoreResults( + SQLHSTMT hstmt) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLNativeSql( + SQLHDBC hdbc, + SQLCHAR FAR *szSqlStrIn, + SQLINTEGER cbSqlStrIn, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStrMax, + SQLINTEGER FAR *pcbSqlStr) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLNumParams( + SQLHSTMT hstmt, + SQLSMALLINT FAR *pcpar) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLParamOptions( + SQLHSTMT hstmt, + SQLUINTEGER crow, + SQLUINTEGER FAR *pirow) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLPrimaryKeys( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLProcedureColumns( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szProcName, + SQLSMALLINT cbProcName, + SQLCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLProcedures( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szProcName, + SQLSMALLINT cbProcName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLSetPos( + SQLHSTMT hstmt, + SQLUSMALLINT irow, + SQLUSMALLINT fOption, + SQLUSMALLINT fLock) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLTablePrivileges( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLDrivers( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR FAR *szDriverDesc, + SQLSMALLINT cbDriverDescMax, + SQLSMALLINT FAR *pcbDriverDesc, + SQLCHAR FAR *szDriverAttributes, + SQLSMALLINT cbDrvrAttrMax, + SQLSMALLINT FAR *pcbDrvrAttr) +{ + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLSetEnvAttr ( + SQLHENV EnvironmentHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER StringLength) +{ + return SQL_SUCCESS; +} + + +SQLRETURN SQL_API SQLBindParameter( + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fParamType, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLUINTEGER cbColDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER FAR *pcbValue) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +struct _hstmt *stmt; + + stmt = (struct _hstmt *) hstmt; + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + colinfo = tds->res_info->columns[ipar-1]; + colinfo->varaddr = (char *)rgbValue; + colinfo->column_bindtype = fCType; + colinfo->column_bindlen = cbValueMax; + colinfo->column_lenbind = pcbValue; + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLAllocHandle( + SQLSMALLINT HandleType, + SQLHANDLE InputHandle, + SQLHANDLE * OutputHandle) +{ + switch(HandleType) { + case SQL_HANDLE_STMT: + return _SQLAllocStmt(InputHandle,OutputHandle); + break; + case SQL_HANDLE_DBC: + return _SQLAllocConnect(InputHandle,OutputHandle); + break; + case SQL_HANDLE_ENV: + return _SQLAllocEnv(OutputHandle); + break; + } +} +static SQLRETURN SQL_API _SQLAllocConnect( + SQLHENV henv, + SQLHDBC FAR *phdbc) +{ +struct _henv *env; +ODBCConnection* dbc; + + env = (struct _henv *) henv; + dbc = (SQLHDBC) malloc (sizeof (ODBCConnection)); + memset(dbc,'\0',sizeof (ODBCConnection)); + dbc->hdbc.henv=env; + dbc->hdbc.tds_login= (void *) tds_alloc_login(); + dbc->params = NewConnectParams (); + *phdbc=dbc; + + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLAllocConnect( + SQLHENV henv, + SQLHDBC FAR *phdbc) +{ + return _SQLAllocConnect(henv, phdbc); +} + +static SQLRETURN SQL_API _SQLAllocEnv( + SQLHENV FAR *phenv) +{ +struct _henv *env; + + env = (SQLHENV) malloc(sizeof(struct _henv)); + memset(env,'\0',sizeof(struct _henv)); + *phenv=env; + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLAllocEnv( + SQLHENV FAR *phenv) +{ + return _SQLAllocEnv(phenv); +} + +static SQLRETURN SQL_API _SQLAllocStmt( + SQLHDBC hdbc, + SQLHSTMT FAR *phstmt) +{ +struct _hdbc *dbc; +struct _hstmt *stmt; + + dbc = (struct _hdbc *) hdbc; + + stmt = (SQLHSTMT) malloc(sizeof(struct _hstmt)); + memset(stmt,'\0',sizeof(struct _hstmt)); + stmt->hdbc=hdbc; + *phstmt = stmt; + + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLAllocStmt( + SQLHDBC hdbc, + SQLHSTMT FAR *phstmt) +{ + return _SQLAllocStmt(hdbc,phstmt); +} + +SQLRETURN SQL_API SQLBindCol( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER FAR *pcbValue) +{ + /* + * Copied this code from SQLBindParameter because it looks like it + * belongs here. - Ken + */ + TDSCOLINFO * colinfo; + TDSRESULTINFO * resinfo; + TDSSOCKET * tds; + struct _hstmt *stmt; + + stmt = (struct _hstmt *) hstmt; + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + colinfo = tds->res_info->columns[icol-1]; + colinfo->varaddr = (char *)rgbValue; + colinfo->column_bindtype = fCType; + colinfo->column_bindlen = cbValueMax; + colinfo->column_lenbind = pcbValue; + + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLCancel( + SQLHSTMT hstmt) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLConnect( + SQLHDBC hdbc, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSN, + SQLCHAR FAR *szUID, + SQLSMALLINT cbUID, + SQLCHAR FAR *szAuthStr, + SQLSMALLINT cbAuthStr) +{ + SQLCHAR FAR* server = NULL; + SQLCHAR FAR* database = NULL; + SQLCHAR FAR* uid = NULL; + SQLCHAR FAR* pwd = NULL; + ConnectParams* params; + SQLRETURN ret; + + strcpy (lastError, ""); + + params = ((ODBCConnection*) hdbc)->params; + + if (!LookupDSN (params, szDSN)) + { + LogError ("Could not find DSN in odbc.ini"); + return SQL_ERROR; + } + else if (!(server = GetConnectParam (params, "Servername"))) + { + LogError ("Could not find Database parameter"); + return SQL_ERROR; + } + if (!szUID || !strlen(szUID)) { + if (!(uid = GetConnectParam (params, "UID"))) { + LogError ("Could not find UID parameter"); + return SQL_ERROR; + } + } else { + uid = szUID; + } + if (!szAuthStr || !strlen(szAuthStr)) { + if (!(pwd = GetConnectParam (params, "PWD"))) + { + LogError ("Could not find PWD parameter"); + return SQL_ERROR; + } + } else { + pwd = szAuthStr; + } + if ((ret = do_connect (hdbc, server, uid, pwd))!=SQL_SUCCESS) + { + return ret; + } + if (!(database = GetConnectParam (params, "Database"))) + { + /* use the default database */ + return SQL_SUCCESS; + } + else + { + return change_database(hdbc, database); + } +} + +SQLRETURN SQL_API SQLDescribeCol( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLCHAR FAR *szColName, + SQLSMALLINT cbColNameMax, + SQLSMALLINT FAR *pcbColName, + SQLSMALLINT FAR *pfSqlType, + SQLUINTEGER FAR *pcbColDef, + SQLSMALLINT FAR *pibScale, + SQLSMALLINT FAR *pfNullable) +{ +TDSSOCKET *tds; +TDSRESULTINFO * resinfo; +TDSCOLINFO *colinfo; +int cplen, namelen, i; +struct _hstmt *stmt = (struct _hstmt *) hstmt; + + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + if (icol == 0 || icol > tds->res_info->num_cols) + { + LogError ("SQLDescribeCol: Column out of range"); + return SQL_ERROR; + } + colinfo = tds->res_info->columns[icol-1]; + + if (szColName) { + namelen = strlen(colinfo->column_name); + cplen = namelen >= cbColNameMax ? + cbColNameMax - 1 : namelen; + strncpy(szColName,colinfo->column_name, cplen); + for (i=0;icolumn_name, szColName); + } + if (pcbColName) { + *pcbColName = strlen(colinfo->column_name); + } + if (pfSqlType) { + *pfSqlType=_odbc_get_client_type(colinfo->column_type); + } + + if (pcbColDef) { + if (is_numeric_type(colinfo->column_type)) { + *pcbColDef = colinfo->column_prec; + } else { + *pcbColDef = colinfo->column_size; + } + } + if (pibScale) { + if (is_numeric_type(colinfo->column_type)) { + *pibScale = colinfo->column_scale; + } else { + *pibScale = 0; + } + } + if (pfNullable) { + *pfNullable = is_nullable_type(colinfo->column_type) ? 1 : 0; + } + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLColAttributes( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLUSMALLINT fDescType, + SQLPOINTER rgbDesc, + SQLSMALLINT cbDescMax, + SQLSMALLINT FAR *pcbDesc, + SQLINTEGER FAR *pfDesc) +{ +TDSSOCKET *tds; +TDSCOLINFO *colinfo; +int cplen, len = 0; +struct _hstmt *stmt; +struct _hdbc *dbc; + + stmt = (struct _hstmt *) hstmt; + dbc = (struct _hdbc *) stmt->hdbc; + tds = (TDSSOCKET *) dbc->tds_socket; + + + /* dont check column index for these */ + switch(fDescType) { + case SQL_COLUMN_COUNT: + if (!tds->res_info) { + *pfDesc = 0; + } else { + *pfDesc = tds->res_info->num_cols; + } + return SQL_SUCCESS; + break; + } + + if (!tds->res_info) { + LogError ("SQLDescribeCol: Query Returned No Result Set!"); + return SQL_ERROR; + } + + if (icol == 0 || icol > tds->res_info->num_cols) + { + LogError ("SQLDescribeCol: Column out of range"); + return SQL_ERROR; + } + colinfo = tds->res_info->columns[icol-1]; + + tdsdump_log(TDS_DBG_INFO1, "SQLColAttributes: fDescType is %d\n", fDescType); + switch(fDescType) { + case SQL_COLUMN_NAME: + len = strlen(colinfo->column_name); + cplen = len > cbDescMax ? cbDescMax : len; + tdsdump_log(TDS_DBG_INFO2, "SQLColAttributes: copying %d bytes, len = %d, cbDescMax = %d\n",cplen, len, cbDescMax); + strncpy(rgbDesc,colinfo->column_name,cplen); + ((char *)rgbDesc)[cplen]='\0'; + if (pcbDesc) { + *pcbDesc = cplen; + } + break; + case SQL_COLUMN_TYPE: + *pfDesc=_odbc_get_client_type(colinfo->column_type); + break; + case SQL_COLUMN_LENGTH: + *pfDesc = colinfo->column_size; + break; + case SQL_COLUMN_DISPLAY_SIZE: + switch(_odbc_get_client_type(colinfo->column_type)) { + case SQL_CHAR: + case SQL_VARCHAR: + *pfDesc = colinfo->column_size; + break; + case SQL_INTEGER: + *pfDesc = 8; + break; + case SQL_SMALLINT: + *pfDesc = 6; + break; + case SQL_TINYINT: + *pfDesc = 4; + break; + } + break; + } + return SQL_SUCCESS; +} + + +SQLRETURN SQL_API SQLDisconnect( + SQLHDBC hdbc) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLError( + SQLHENV henv, + SQLHDBC hdbc, + SQLHSTMT hstmt, + SQLCHAR FAR *szSqlState, + SQLINTEGER FAR *pfNativeError, + SQLCHAR FAR *szErrorMsg, + SQLSMALLINT cbErrorMsgMax, + SQLSMALLINT FAR *pcbErrorMsg) +{ + SQLRETURN result = SQL_NO_DATA_FOUND; + + if (strlen (lastError) > 0) + { + strcpy (szSqlState, "08001"); + strcpy (szErrorMsg, lastError); + if (pcbErrorMsg) + *pcbErrorMsg = strlen (lastError); + if (pfNativeError) + *pfNativeError = 1; + + result = SQL_SUCCESS; + strcpy (lastError, ""); + } + + return result; +} + +static SQLRETURN SQL_API _SQLExecute( SQLHSTMT hstmt) +{ +struct _hstmt *stmt = (struct _hstmt *) hstmt; +int ret; +TDSSOCKET *tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + + fprintf(stderr,"query = %s\n",stmt->query); + _odbc_fix_literals(stmt); + + if (!(tds_submit_query(tds, stmt->query)==TDS_SUCCEED)) { + LogError (tds->msg_info->message); + return SQL_ERROR; + } + /* does anyone know how ODBC deals with multiple result sets? */ + ret = tds_process_result_tokens(tds); + if (ret==TDS_NO_MORE_RESULTS) { + /* DBD::ODBC expect SQL_SUCCESS on non-result returning queries */ + return SQL_SUCCESS; + } else if (ret==TDS_SUCCEED) { + return SQL_SUCCESS; + } +} + +SQLRETURN SQL_API SQLExecDirect( + SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr) +{ +struct _hstmt *stmt = (struct _hstmt *) hstmt; +int ret; + + strcpy(stmt->query, szSqlStr); + + return _SQLExecute(hstmt); +} + +SQLRETURN SQL_API SQLExecute( + SQLHSTMT hstmt) +{ + return _SQLExecute(hstmt); +} + +SQLRETURN SQL_API SQLFetch( + SQLHSTMT hstmt) +{ +int ret; +TDSSOCKET *tds; +TDSRESULTINFO * resinfo; +TDSCOLINFO *colinfo; +int i; +struct _hstmt *stmt; +SQLINTEGER len=0; +unsigned char *src; +int srclen; + + stmt=(struct _hstmt *)hstmt; + + tds = stmt->hdbc->tds_socket; + + ret = tds_process_row_tokens(stmt->hdbc->tds_socket); + if (ret==TDS_NO_MORE_ROWS) { + return SQL_NO_DATA_FOUND; + } + resinfo = tds->res_info; + if (!resinfo) { + return SQL_NO_DATA_FOUND; + } + for (i=0;inum_cols;i++) { + colinfo = resinfo->columns[i]; + if (colinfo->varaddr) { + if (is_blob_type(colinfo->column_type)) { + src = colinfo->column_textvalue; + srclen = colinfo->column_textsize + 1; + } else { + src = &resinfo->current_row[colinfo->column_offset]; + srclen = -1; + } + len = tds_convert( + tds_get_conversion_type(colinfo->column_type, colinfo->column_size), + src, + srclen, + _odbc_get_server_type(colinfo->column_bindtype), + colinfo->varaddr, + colinfo->column_bindlen); +/* + strcpy(colinfo->varaddr, + &resinfo->current_row[colinfo->column_offset]); +*/ + } + if (colinfo->column_lenbind) { + *((SQLINTEGER *)colinfo->column_lenbind)=len; + } + } + if (ret==TDS_SUCCEED) + return SQL_SUCCESS; + else { + return SQL_ERROR; + } +} + +SQLRETURN SQL_API SQLFreeHandle( + SQLSMALLINT HandleType, + SQLHANDLE Handle) +{ + switch(HandleType) { + case SQL_HANDLE_STMT: + _SQLFreeStmt(Handle,SQL_DROP); + break; + case SQL_HANDLE_DBC: + _SQLFreeConnect(Handle); + break; + case SQL_HANDLE_ENV: + _SQLFreeEnv(Handle); + break; + } +} + +static SQLRETURN SQL_API _SQLFreeConnect( + SQLHDBC hdbc) +{ + ODBCConnection* dbc = (ODBCConnection*) hdbc; + + + FreeConnectParams (dbc->params); + free (dbc); + + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLFreeConnect( + SQLHDBC hdbc) +{ + return _SQLFreeConnect(hdbc); +} + +static SQLRETURN SQL_API _SQLFreeEnv( + SQLHENV henv) +{ + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLFreeEnv( + SQLHENV henv) +{ + return _SQLFreeEnv(henv); +} + +static SQLRETURN SQL_API _SQLFreeStmt( + SQLHSTMT hstmt, + SQLUSMALLINT fOption) +{ +TDSSOCKET * tds; +struct _hstmt *stmt=(struct _hstmt *)hstmt; + + if (fOption==SQL_DROP) { + free (hstmt); + } else if (fOption==SQL_CLOSE) { + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + /* + ** FIX ME -- otherwise make sure the current statement is complete + */ + if (tds->state==TDS_PENDING) { + tds_send_cancel(tds); + tds_process_cancel(tds); + } + } else { + tdsdump_log(TDS_DBG_ERROR, "SQLFreeStmt: Unknown option %d\n", fOption); + } + return SQL_SUCCESS; +} +SQLRETURN SQL_API SQLFreeStmt( + SQLHSTMT hstmt, + SQLUSMALLINT fOption) +{ + return _SQLFreeStmt(hstmt, fOption); +} + +SQLRETURN SQL_API SQLGetStmtAttr ( + SQLHSTMT StatementHandle, + SQLINTEGER Attribute, + SQLPOINTER Value, + SQLINTEGER BufferLength, + SQLINTEGER * StringLength) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetCursorName( + SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursorMax, + SQLSMALLINT FAR *pcbCursor) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLNumResultCols( + SQLHSTMT hstmt, + SQLSMALLINT FAR *pccol) +{ +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +struct _hstmt *stmt; + + stmt=(struct _hstmt *)hstmt; + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + resinfo = tds->res_info; + if (resinfo == NULL) + { + /* 3/15/2001 bsb - DBD::ODBC calls SQLNumResultCols on non-result + ** generating queries such as 'drop table' */ + *pccol = 0; + return SQL_SUCCESS; +/* + if (tds && tds->msg_info && tds->msg_info->message) + LogError (tds->msg_info->message); + else + LogError ("SQLNumResultCols: resinfo is NULL"); + + return SQL_ERROR; +*/ + } + + *pccol= resinfo->num_cols; + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLPrepare( + SQLHSTMT hstmt, + SQLCHAR FAR *szSqlStr, + SQLINTEGER cbSqlStr) +{ + struct _hstmt *stmt=(struct _hstmt *)hstmt; + + if (cbSqlStr!=SQL_NTS) { + strncpy(stmt->query, szSqlStr, cbSqlStr); + stmt->query[cbSqlStr]='\0'; + } else { + strcpy(stmt->query, szSqlStr); + } + + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLRowCount( + SQLHSTMT hstmt, + SQLINTEGER FAR *pcrow) +{ +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +struct _hstmt *stmt; + +/* 7/28/2001 begin l@poliris.com */ + stmt=(struct _hstmt *)hstmt; + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + resinfo = tds->res_info; + if (resinfo == NULL) { + *pcrow = 0; + return SQL_SUCCESS; +/* + if (tds && tds->msg_info && tds->msg_info->message) + LogError (tds->msg_info->message); + else + LogError ("SQLRowCount: resinfo is NULL"); + + return SQL_ERROR; +*/ + } + *pcrow= resinfo->row_count; + +/* end l@poliris.com */ + + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLSetCursorName( + SQLHSTMT hstmt, + SQLCHAR FAR *szCursor, + SQLSMALLINT cbCursor) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLTransact( + SQLHENV henv, + SQLHDBC hdbc, + SQLUSMALLINT fType) +{ + return SQL_SUCCESS; +} + + +SQLRETURN SQL_API SQLSetParam( /* Use SQLBindParameter */ + SQLHSTMT hstmt, + SQLUSMALLINT ipar, + SQLSMALLINT fCType, + SQLSMALLINT fSqlType, + SQLUINTEGER cbParamDef, + SQLSMALLINT ibScale, + SQLPOINTER rgbValue, + SQLINTEGER FAR *pcbValue) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLColumns( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szColumnName, + SQLSMALLINT cbColumnName) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetConnectOption( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLPOINTER pvParam) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetData( + SQLHSTMT hstmt, + SQLUSMALLINT icol, + SQLSMALLINT fCType, + SQLPOINTER rgbValue, + SQLINTEGER cbValueMax, + SQLINTEGER FAR *pcbValue) +{ +TDSCOLINFO * colinfo; +TDSRESULTINFO * resinfo; +TDSSOCKET * tds; +struct _hstmt *stmt; +unsigned char *src; +int srclen; + + stmt = (struct _hstmt *) hstmt; + tds = (TDSSOCKET *) stmt->hdbc->tds_socket; + resinfo = tds->res_info; + if (icol == 0 || icol > tds->res_info->num_cols) + { + LogError ("SQLGetData: Column out of range"); + return SQL_ERROR; + } + colinfo = resinfo->columns[icol-1]; + + if (tds_get_null(resinfo->current_row, icol-1)) { + *pcbValue=SQL_NULL_DATA; + } else { + if (is_blob_type(colinfo->column_type)) { + src = colinfo->column_textvalue; + srclen = colinfo->column_textsize + 1; + } else { + src = &resinfo->current_row[colinfo->column_offset]; + srclen = -1; + } + *pcbValue=tds_convert( + tds_get_conversion_type(colinfo->column_type, colinfo->column_size), + src, + srclen, + _odbc_get_server_type(fCType), + rgbValue, + cbValueMax); + } + /* + memcpy(rgbValue,&resinfo->current_row[colinfo->column_offset], + colinfo->column_size); + */ + return 0; +} + +SQLRETURN SQL_API SQLGetFunctions( + SQLHDBC hdbc, + SQLUSMALLINT fFunction, + SQLUSMALLINT FAR *pfExists) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetInfo( + SQLHDBC hdbc, + SQLUSMALLINT fInfoType, + SQLPOINTER rgbInfoValue, + SQLSMALLINT cbInfoValueMax, + SQLSMALLINT FAR *pcbInfoValue) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetStmtOption( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLPOINTER pvParam) +{ + return SQL_SUCCESS; +} + +SQLRETURN SQL_API SQLGetTypeInfo( + SQLHSTMT hstmt, + SQLSMALLINT fSqlType) +{ +struct _hstmt *stmt; + + stmt = (struct _hstmt *) hstmt; + if (!fSqlType) { + strcpy(stmt->query, "SELECT * FROM tds_typeinfo"); + } else { + sprintf(stmt->query, "SELECT * FROM tds_typeinfo WHERE SQL_DATA_TYPE = %d", fSqlType); + } + + return _SQLExecute(hstmt); + } + + SQLRETURN SQL_API SQLParamData( + SQLHSTMT hstmt, + SQLPOINTER FAR *prgbValue) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLPutData( + SQLHSTMT hstmt, + SQLPOINTER rgbValue, + SQLINTEGER cbValue) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLSetConnectOption( + SQLHDBC hdbc, + SQLUSMALLINT fOption, + SQLUINTEGER vParam) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLSetStmtOption( + SQLHSTMT hstmt, + SQLUSMALLINT fOption, + SQLUINTEGER vParam) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLSpecialColumns( + SQLHSTMT hstmt, + SQLUSMALLINT fColType, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fScope, + SQLUSMALLINT fNullable) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLStatistics( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLUSMALLINT fUnique, + SQLUSMALLINT fAccuracy) + { + return SQL_SUCCESS; + } + + SQLRETURN SQL_API SQLTables( + SQLHSTMT hstmt, + SQLCHAR FAR *szCatalogName, + SQLSMALLINT cbCatalogName, + SQLCHAR FAR *szSchemaName, + SQLSMALLINT cbSchemaName, + SQLCHAR FAR *szTableName, + SQLSMALLINT cbTableName, + SQLCHAR FAR *szTableType, + SQLSMALLINT cbTableType) + { + char *query, *p; + char *sptables = "exec sp_tables "; + int querylen, clen, slen, tlen, ttlen; + int first = 1; + struct _hstmt *stmt; + + stmt = (struct _hstmt *) hstmt; + + clen = _odbc_get_string_size(cbCatalogName, szCatalogName); + slen = _odbc_get_string_size(cbSchemaName, szSchemaName); + tlen = _odbc_get_string_size(cbTableName, szTableName); + ttlen = _odbc_get_string_size(cbTableType, szTableType); + + querylen = strlen(sptables) + clen + slen + tlen + ttlen + 40; /* a little padding for quotes and commas */ + query = (char *) malloc(querylen); + p = query; + + strcpy(p, sptables); + p += strlen(sptables); + + if (tlen) { + *p++ = '"'; + strncpy(p, szTableName, tlen); *p+=tlen; + *p++ = '"'; + first = 0; + } + if (slen) { + if (!first) *p++ = ','; + *p++ = '"'; + strncpy(p, szSchemaName, slen); *p+=slen; + *p++ = '"'; + first = 0; + } + if (clen) { + if (!first) *p++ = ','; + *p++ = '"'; + strncpy(p, szCatalogName, clen); *p+=clen; + *p++ = '"'; + first = 0; + } + if (ttlen) { + if (!first) *p++ = ','; + *p++ = '"'; + strncpy(p, szTableType, ttlen); *p+=ttlen; + *p++ = '"'; + first = 0; + } + *p++ = '\0'; + // fprintf(stderr,"\nquery = %s\n",query); + + strcpy(stmt->query, query); + return _SQLExecute(hstmt); +} + + +SQLRETURN SQL_API SQLDataSources( + SQLHENV henv, + SQLUSMALLINT fDirection, + SQLCHAR FAR *szDSN, + SQLSMALLINT cbDSNMax, + SQLSMALLINT FAR *pcbDSN, + SQLCHAR FAR *szDescription, + SQLSMALLINT cbDescriptionMax, + SQLSMALLINT FAR *pcbDescription) +{ + return SQL_SUCCESS; +} +static int _odbc_fix_literals(struct _hstmt *stmt) +{ +char tmp[4096],begin_tag[11]; +char *s, *d, *p; +int i, quoted = 0, find_end = 0; +char quote_char; + + s=stmt->query; + d=tmp; + while (*s) { + if (!quoted && (*s=='"' || *s=='\'')) { + quoted = 1; + quote_char = *s; + } else if (quoted && *s==quote_char) { + quoted = 0; + } + if (!quoted && find_end && *s=='}') { + s++; /* ignore the end of tag */ + } else if (!quoted && *s=='{') { + for (p=s,i=0;*p && *p!=' ';p++) i++; + if (i>10) { + /* garbage */ + *d++=*s++; + } else { + strncpy(begin_tag, s, i); + begin_tag[i] = '\0'; + /* printf("begin tag %s\n", begin_tag); */ + s += i; + find_end = 1; + } + } else { + *d++=*s++; + } + } + *d='\0'; + strcpy(stmt->query,tmp); +} + +static int _odbc_get_string_size(int size, char *str) +{ + if (!str) { + return 0; + } + if (size==SQL_NTS) { + return strlen(str); + } else { + return size; + } +} +static int _odbc_get_server_type(int clt_type) +{ + switch (clt_type) { + case SQL_CHAR: + case SQL_VARCHAR: + return SYBCHAR; + case SQL_BIT: + return SYBBIT; + case SQL_TINYINT: + return SYBINT1; + case SQL_SMALLINT: + return SYBINT2; + case SQL_INTEGER: + return SYBINT4; + case SQL_DOUBLE: + return SYBFLT8; + case SQL_DECIMAL: + return SYBDECIMAL; + case SQL_NUMERIC: + return SYBNUMERIC; + case SQL_FLOAT: + return SYBREAL; + } +} +static SQLSMALLINT _odbc_get_client_type(int srv_type) +{ + switch (srv_type) { + case SYBCHAR: + return SQL_CHAR; + case SYBVARCHAR: + return SQL_VARCHAR; + case SYBTEXT: + return SQL_LONGVARCHAR; + break; + case SYBBIT: + return SQL_BIT; + case SYBINT4: + return SQL_INTEGER; + break; + case SYBINT2: + return SQL_SMALLINT; + break; + case SYBINT1: + return SQL_TINYINT; + break; + case SYBREAL: + return SQL_FLOAT; + break; + case SYBFLT8: + return SQL_DOUBLE; + break; + case SYBMONEY: + break; + case SYBMONEY4: + break; + case SYBDATETIME: + return SQL_DATE; + break; + } +} diff --git a/src/server/Makefile.am b/src/server/Makefile.am new file mode 100644 index 000000000..6b7f493c9 --- /dev/null +++ b/src/server/Makefile.am @@ -0,0 +1,14 @@ +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libtdssrv.la +##EXTRA_LTLIBRARIES = libtdssrv.la +libtdssrv_la_SOURCES= query.c server.c login.c +libtdssrv_la_LDFLAGS= -rpath $(libdir) +libtdssrv_la_LIBADD= $(patsubst %, $(TDSDIR)/%, \ + $(patsubst %.c, %.lo, $(TDSSOURCES))) +INCLUDES = -I$(top_srcdir)/include + +## Need a blank statement to avoid compiling server.c +server: $(EXTRA_LTLIBRARIES) + @echo '' + diff --git a/src/server/Makefile.in b/src/server/Makefile.in new file mode 100644 index 000000000..68c286921 --- /dev/null +++ b/src/server/Makefile.in @@ -0,0 +1,328 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +TDSDIR = ../tds +TDSSOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +lib_LTLIBRARIES = libtdssrv.la +libtdssrv_la_SOURCES = query.c server.c login.c +libtdssrv_la_LDFLAGS = -rpath $(libdir) +libtdssrv_la_LIBADD = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, %.lo, $(TDSSOURCES))) + +INCLUDES = -I$(top_srcdir)/include +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libtdssrv_la_DEPENDENCIES = $(patsubst %, $(TDSDIR)/%, $(patsubst %.c, \ +%.lo, $(TDSSOURCES))) +libtdssrv_la_OBJECTS = query.lo server.lo login.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libtdssrv_la_SOURCES) +OBJECTS = $(libtdssrv_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/server/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libtdssrv.la: $(libtdssrv_la_OBJECTS) $(libtdssrv_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libtdssrv_la_LDFLAGS) $(libtdssrv_la_OBJECTS) $(libtdssrv_la_LIBADD) $(LIBS) + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/server + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done +login.lo login.o : login.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +query.lo query.o : query.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +server.lo server.o : server.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h + +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-am + +install-data-am: +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-am +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool tags mostlyclean-tags distclean-tags \ +clean-tags maintainer-clean-tags distdir info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +server: $(EXTRA_LTLIBRARIES) + @echo '' + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/server/login.c b/src/server/login.c new file mode 100644 index 000000000..8cd50322c --- /dev/null +++ b/src/server/login.c @@ -0,0 +1,111 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" +#include + +static char software_version[] = "$Id: login.c,v 1.1 2001-10-12 23:29:16 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +TDSSOCKET *tds_listen(int ip_port) +{ +TDSSOCKET *tds; +struct sockaddr_in sin; +unsigned char buf[BUFSIZ]; +int fd, s; +int len; + + sin.sin_addr.s_addr = INADDR_ANY; + sin.sin_port = htons((short)ip_port); + sin.sin_family = AF_INET; + + if ((s = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + perror ("socket"); + exit (1); + } + if (bind (s, (struct sockaddr *) &sin, sizeof (sin)) < 0) { + perror("bind"); + exit (1); + } + listen (s, 5); + if ((fd = accept (s, (struct sockaddr *) &sin, &len)) < 0) { + perror("accept"); + exit(1); + } + tds = tds_alloc_socket(BUFSIZ); + tds->s = fd; + tds->out_flag=0x02; + /* get_incoming(tds->s); */ + return tds; +} +int tds_read_login(TDSSOCKET *tds, TDSLOGIN *login) +{ +int len,i; +char blockstr[7]; +/* + while (len = tds_read_packet(tds)) { + for (i=0;iin_buf[i], (tds->in_buf[i]>=' ' && tds->in_buf[i]<='z') ? tds->in_buf[i] : ' '); + } +*/ + tds_read_string(tds, login->host_name, 30); + tds_read_string(tds, login->user_name, 30); + tds_read_string(tds, login->password, 30); + tds_read_string(tds, NULL, 30); /* host process, junk for now */ + tds_read_string(tds, NULL, 15); /* magic */ + tds_read_string(tds, login->app_name, 30); + tds_read_string(tds, login->server_name, 30); + tds_read_string(tds, NULL, 255); /* secondary passwd...encryption? */ + login->major_version = tds_get_byte(tds); + login->minor_version = tds_get_byte(tds); + tds_get_smallint(tds); /* unused part of protocol field */ + tds_read_string(tds, login->library, 10); + tds_get_byte(tds); /* program version, junk it */ + tds_get_byte(tds); + tds_get_smallint(tds); + tds_get_n(tds, NULL, 3); /* magic */ + tds_read_string(tds, login->language, 30); + tds_get_n(tds, NULL, 14); /* magic */ + tds_read_string(tds, login->char_set, 30); + tds_get_n(tds, NULL, 1); /* magic */ + tds_read_string(tds, blockstr, 6); + printf("block size %s\n",blockstr); + login->block_size=atoi(blockstr); + tds_get_n(tds, NULL, tds->in_len - tds->in_pos); /* read junk at end */ +} +int tds_read_string(TDSSOCKET *tds, char *dest, int size) +{ +char *tempbuf; +int len; + + tempbuf = (char *) malloc(size+1); + tds_get_n(tds,tempbuf,size); + len=tds_get_byte(tds); + if (dest) { + memcpy(dest,tempbuf,len); + dest[len]='\0'; + } + free(tempbuf); + + return len; +} diff --git a/src/server/query.c b/src/server/query.c new file mode 100644 index 000000000..d74cfba50 --- /dev/null +++ b/src/server/query.c @@ -0,0 +1,40 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" +#include + +static char software_version[] = "$Id: query.c,v 1.1 2001-10-12 23:29:16 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + + +char *tds_get_query(TDSSOCKET *tds) +{ +static unsigned char query[BUFSIZ]; +int len; + + tds_get_byte(tds); /* 33 */ + len = tds_get_smallint(tds); /* query size +1 */ + tds_get_n(tds,NULL,3); + tds_get_n(tds, query, len - 1); + return query; +} diff --git a/src/server/server.c b/src/server/server.c new file mode 100644 index 000000000..31b4695fd --- /dev/null +++ b/src/server/server.c @@ -0,0 +1,285 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +static char software_version[] = "$Id: server.c,v 1.1 2001-10-12 23:29:16 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +tds_env_change(TDSSOCKET *tds,int type, char *oldvalue, char *newvalue) +{ +TDS_SMALLINT totsize; + + tds_put_byte(tds,TDS_ENV_CHG_TOKEN); + switch(type) { + /* database */ + case 1: + /* totsize = type + newlen + newvalue + oldlen + oldvalue */ + totsize = strlen(oldvalue) + strlen(newvalue) + 3; + tds_put_smallint(tds, totsize); + tds_put_byte(tds,type); + tds_put_byte(tds,strlen(newvalue)); + tds_put_n(tds,newvalue,strlen(newvalue)); + tds_put_byte(tds,strlen(oldvalue)); + tds_put_n(tds,oldvalue,strlen(oldvalue)); + break; + /* language */ + case 2: + /* totsize = type + len + string + \0 */ + totsize = strlen(newvalue) + 3; + tds_put_smallint(tds, totsize); + tds_put_byte(tds,type); + tds_put_byte(tds,strlen(newvalue)); + tds_put_n(tds,newvalue,strlen(newvalue)); + tds_put_byte(tds,'\0'); + break; + /* code page would be 3 */ + /* packet size */ + case 4: + /* totsize = type + len + string + \0 */ + totsize = strlen(newvalue) + 3; + tds_put_smallint(tds, totsize); + tds_put_byte(tds,type); + tds_put_byte(tds,strlen(newvalue)); + tds_put_n(tds,newvalue,strlen(newvalue)); + tds_put_byte(tds,'\0'); + break; + } +} + +void tds_send_eed(TDSSOCKET *tds,int msgno, int msgstate, int severity, + char *msgtext, char *srvname, char *procname, int line) +{ +int totsize; + + tds_put_byte(tds,TDS_EED_TOKEN); + totsize = 7 + strlen(procname) + 5 + strlen(msgtext) + 2 + strlen(srvname) + 3; + tds_put_smallint(tds,totsize); + tds_put_smallint(tds,msgno); + tds_put_smallint(tds,0); /* unknown */ + tds_put_byte(tds, msgstate); + tds_put_byte(tds, severity); + tds_put_byte(tds,strlen(procname)); + tds_put_n(tds,procname,strlen(procname)); + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,1); /* unknown */ + tds_put_byte(tds,0); /* unknown */ + tds_put_smallint(tds,strlen(msgtext)+1); + tds_put_n(tds,msgtext,strlen(msgtext)); + tds_put_byte(tds, severity); + tds_put_byte(tds,strlen(srvname)); + tds_put_n(tds,srvname,strlen(srvname)); + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,1); /* unknown */ + tds_put_byte(tds,0); /* unknown */ +} +void tds_send_msg(TDSSOCKET *tds,int msgno, int msgstate, int severity, + char *msgtext, char *srvname, char *procname, int line) +{ +int msgsz; + + tds_put_byte(tds,TDS_MSG_TOKEN); + msgsz = 4 /* msg no */ + + 1 /* msg state */ + + 1 /* severity */ + + strlen(msgtext) + 1 + + strlen(srvname) + 1 + + strlen(procname) + 1 + + 2; /* line number */ + tds_put_smallint(tds,msgsz); + tds_put_int(tds, msgno); + tds_put_byte(tds, msgstate); + tds_put_byte(tds, severity); + tds_put_smallint(tds, strlen(msgtext)); + tds_put_n(tds, msgtext, strlen(msgtext)); + tds_put_byte(tds,strlen(srvname)); + tds_put_n(tds,srvname,strlen(srvname)); + if (procname && strlen(procname)) { + tds_put_byte(tds,strlen(procname)); + tds_put_n(tds,procname,strlen(procname)); + } else { + tds_put_byte(tds,0); + } + tds_put_smallint(tds,line); +} +void tds_send_err(TDSSOCKET *tds,int severity, int dberr, int oserr, char *dberrstr, char *oserrstr) +{ + tds_put_byte(tds,TDS_ERR_TOKEN); +} +void tds_send_login_ack(TDSSOCKET *tds, char *progname) +{ + tds_put_byte(tds,TDS_LOGIN_ACK_TOKEN); + tds_put_smallint(tds,10+strlen(progname)); /* length of message */ + if IS_TDS42(tds) { + tds_put_byte(tds,1); + tds_put_byte(tds,4); + tds_put_byte(tds,2); + } else { + tds_put_byte(tds,5); + tds_put_byte(tds,5); + tds_put_byte(tds,0); + } + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,strlen(progname)); + tds_put_n(tds,progname,strlen(progname)); + tds_put_byte(tds,1); /* unknown */ + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,0); /* unknown */ + tds_put_byte(tds,1); /* unknown */ +} +tds_send_capabilities_token(TDSSOCKET *tds) +{ + tds_put_byte(tds,TDS_CAP_TOKEN); + tds_put_byte(tds,18); + tds_put_byte(tds,0); + tds_put_byte(tds,1); + tds_put_byte(tds,7); + tds_put_byte(tds,7); + tds_put_byte(tds,97); + tds_put_byte(tds,65); + tds_put_byte(tds,207); + tds_put_byte(tds,255); + tds_put_byte(tds,255); + tds_put_byte(tds,230); + tds_put_byte(tds,2); + tds_put_byte(tds,7); + tds_put_byte(tds,0); + tds_put_byte(tds,0); + tds_put_byte(tds,2); + tds_put_byte(tds,0); + tds_put_byte(tds,0); + tds_put_byte(tds,0); + tds_put_byte(tds,0); +} +tds_send_253_token(TDSSOCKET *tds, TDS_TINYINT flags, TDS_INT numrows) +{ + tds_put_byte(tds,253); + tds_put_byte(tds,flags); + tds_put_byte(tds,0); + tds_put_byte(tds,2); + tds_put_byte(tds,0); + tds_put_int(tds,numrows); +} +tds_send_174_token(TDSSOCKET *tds, TDS_SMALLINT numcols) +{ +int i; + + tds_put_byte(tds,174); + tds_put_smallint(tds,numcols); + for (i=0;inum_cols;col++) { + curcol=resinfo->columns[col]; + hdrsize += strlen(curcol->column_name) + 2; + } + + tds_put_smallint(tds,hdrsize); + for (col=0;colnum_cols;col++) { + curcol=resinfo->columns[col]; + tds_put_byte(tds, strlen(curcol->column_name)); + /* include the null */ + tds_put_n(tds, curcol->column_name, strlen(curcol->column_name)+1); + } +} +void tds_send_col_info(TDSSOCKET *tds, TDSRESULTINFO *resinfo) +{ +int col, hdrsize=0; +TDSCOLINFO *curcol; + + tds_put_byte(tds,TDS_COL_INFO_TOKEN); + + for (col=0;colnum_cols;col++) { + curcol=resinfo->columns[col]; + hdrsize += 5; + if (!is_fixed_type(curcol->column_type)) { + hdrsize++; + } + } + tds_put_smallint(tds,hdrsize); + + for (col=0;colnum_cols;col++) { + curcol=resinfo->columns[col]; + tds_put_n(tds,"\0\0\0\0",4); + tds_put_byte(tds,curcol->column_type); + if (!is_fixed_type(curcol->column_type)) { + tds_put_byte(tds,curcol->column_size); + } + } +} +tds_send_result(TDSSOCKET *tds, TDSRESULTINFO *resinfo) +{ +TDSCOLINFO *curcol; +int i, totlen; + + tds_put_byte(tds,TDS_RESULT_TOKEN); + totlen = 2; + for (i=0;inum_cols;i++) { + curcol = resinfo->columns[i]; + totlen += 8; + totlen += strlen(curcol->column_name); + curcol = resinfo->columns[i]; + if (!is_fixed_type(curcol->column_type)) { + totlen++; + } + } + tds_put_smallint(tds,totlen); + tds_put_smallint(tds,resinfo->num_cols); + for (i=0;inum_cols;i++) { + curcol = resinfo->columns[i]; + tds_put_byte(tds,strlen(curcol->column_name)); + tds_put_n(tds,curcol->column_name,strlen(curcol->column_name)); + tds_put_byte(tds,'0'); + tds_put_smallint(tds, curcol->column_usertype); + tds_put_smallint(tds,0); + tds_put_byte(tds, curcol->column_type); + if (!is_fixed_type(curcol->column_type)) { + tds_put_byte(tds, curcol->column_size); + } + tds_put_byte(tds,0); + } +} +tds_send_row(TDSSOCKET *tds, TDSRESULTINFO *resinfo) +{ +TDSCOLINFO *curcol; +int colsize, i; + + tds_put_byte(tds,TDS_ROW_TOKEN); + for (i=0;inum_cols;i++) { + curcol = resinfo->columns[i]; + if (!is_fixed_type(curcol->column_type)) { + /* FIX ME -- I have no way of knowing the actual length of non character variable data (eg nullable int) */ + colsize = strlen(&(resinfo->current_row[curcol->column_offset])); + tds_put_byte(tds, colsize); + tds_put_n(tds,&(resinfo->current_row[curcol->column_offset]), colsize); + } else { + tds_put_n(tds,&(resinfo->current_row[curcol->column_offset]), get_size_by_type(curcol->column_type)); + } + } +} diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am new file mode 100644 index 000000000..6f963bf70 --- /dev/null +++ b/src/tds/Makefile.am @@ -0,0 +1,5 @@ +SUBDIRS = unittests + +lib_LTLIBRARIES = libtds.la +libtds_la_SOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +INCLUDES = -I$(top_srcdir)/include diff --git a/src/tds/Makefile.in b/src/tds/Makefile.in new file mode 100644 index 000000000..1b02ee36f --- /dev/null +++ b/src/tds/Makefile.in @@ -0,0 +1,417 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +SUBDIRS = unittests + +lib_LTLIBRARIES = libtds.la +libtds_la_SOURCES = mem.c token.c util.c login.c read.c write.c convert.c numeric.c config.c query.c +INCLUDES = -I$(top_srcdir)/include +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = +LTLIBRARIES = $(lib_LTLIBRARIES) + + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +LIBS = @LIBS@ +libtds_la_LDFLAGS = +libtds_la_LIBADD = +libtds_la_OBJECTS = mem.lo token.lo util.lo login.lo read.lo write.lo \ +convert.lo numeric.lo config.lo query.lo +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(libtds_la_SOURCES) +OBJECTS = $(libtds_la_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/tds/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-libLTLIBRARIES: + +clean-libLTLIBRARIES: + -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) + +distclean-libLTLIBRARIES: + +maintainer-clean-libLTLIBRARIES: + +install-libLTLIBRARIES: $(lib_LTLIBRARIES) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(libdir) + @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + if test -f $$p; then \ + echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \ + $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \ + else :; fi; \ + done + +uninstall-libLTLIBRARIES: + @$(NORMAL_UNINSTALL) + list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \ + done + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +libtds.la: $(libtds_la_OBJECTS) $(libtds_la_DEPENDENCIES) + $(LINK) -rpath $(libdir) $(libtds_la_LDFLAGS) $(libtds_la_OBJECTS) $(libtds_la_LIBADD) $(LIBS) + +# This directory's subdirectories are mostly independent; you can cd +# into them and run `make' without going through this Makefile. +# To change the values of `make' variables: instead of editing Makefiles, +# (1) if the variable is set in `config.status', edit `config.status' +# (which will cause the Makefiles to be regenerated when you run `make'); +# (2) otherwise, pass the desired values on the `make' command line. + +@SET_MAKE@ + +all-recursive install-data-recursive install-exec-recursive \ +installdirs-recursive install-recursive uninstall-recursive \ +check-recursive installcheck-recursive info-recursive dvi-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + target=`echo $@ | sed s/-recursive//`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + dot_seen=yes; \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done; \ + if test "$$dot_seen" = "no"; then \ + $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \ + fi; test -z "$$fail" + +mostlyclean-recursive clean-recursive distclean-recursive \ +maintainer-clean-recursive: + @set fnord $(MAKEFLAGS); amf=$$2; \ + dot_seen=no; \ + rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \ + rev="$$subdir $$rev"; \ + test "$$subdir" = "." && dot_seen=yes; \ + done; \ + test "$$dot_seen" = "no" && rev=". $$rev"; \ + target=`echo $@ | sed s/-recursive//`; \ + for subdir in $$rev; do \ + echo "Making $$target in $$subdir"; \ + if test "$$subdir" = "."; then \ + local_target="$$target-am"; \ + else \ + local_target="$$target"; \ + fi; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \ + || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \ + done && test -z "$$fail" +tags-recursive: + list='$(SUBDIRS)'; for subdir in $$list; do \ + test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" = .; then :; else \ + test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \ + fi; \ + done; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/tds + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + for subdir in $(SUBDIRS); do \ + if test "$$subdir" = .; then :; else \ + test -d $(distdir)/$$subdir \ + || mkdir $(distdir)/$$subdir \ + || exit 1; \ + chmod 777 $(distdir)/$$subdir; \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(top_distdir) distdir=../$(distdir)/$$subdir distdir) \ + || exit 1; \ + fi; \ + done +config.lo config.o : config.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +convert.lo convert.o : convert.c ../../include/tdsutil.h \ + ../../include/tds.h ../../include/tds_configs.h \ + ../../include/tdsver.h ../../include/tdsconvert.h +login.lo login.o : login.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +mem.lo mem.o : mem.c ../../include/tds.h ../../include/tds_configs.h \ + ../../include/tdsver.h ../../include/tdsutil.h +numeric.lo numeric.o : numeric.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h +query.lo query.o : query.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +read.lo read.o : read.c ../../include/tds.h ../../include/tds_configs.h \ + ../../include/tdsver.h ../../include/tdsutil.h +token.lo token.o : token.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h +util.lo util.o : util.c ../../include/tdsutil.h ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h +write.lo write.o : write.c ../../include/tds.h \ + ../../include/tds_configs.h ../../include/tdsver.h \ + ../../include/tdsutil.h + +info-am: +info: info-recursive +dvi-am: +dvi: dvi-recursive +check-am: all-am +check: check-recursive +installcheck-am: +installcheck: installcheck-recursive +install-exec-am: install-libLTLIBRARIES +install-exec: install-exec-recursive + +install-data-am: +install-data: install-data-recursive + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-recursive +uninstall-am: uninstall-libLTLIBRARIES +uninstall: uninstall-recursive +all-am: Makefile $(LTLIBRARIES) +all-redirect: all-recursive +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: installdirs-recursive +installdirs-am: + $(mkinstalldirs) $(DESTDIR)$(libdir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-recursive + +clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-recursive + +distclean-am: distclean-libLTLIBRARIES distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-recursive + +maintainer-clean-am: maintainer-clean-libLTLIBRARIES \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-recursive + +.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \ +clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \ +uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool install-data-recursive \ +uninstall-data-recursive install-exec-recursive \ +uninstall-exec-recursive installdirs-recursive uninstalldirs-recursive \ +all-recursive check-recursive installcheck-recursive info-recursive \ +dvi-recursive mostlyclean-recursive distclean-recursive clean-recursive \ +maintainer-clean-recursive tags tags-recursive mostlyclean-tags \ +distclean-tags clean-tags maintainer-clean-tags distdir info-am info \ +dvi-am dvi check check-am installcheck-am installcheck install-exec-am \ +install-exec install-data-am install-data install-am install \ +uninstall-am uninstall all-redirect all-am all installdirs-am \ +installdirs mostlyclean-generic distclean-generic clean-generic \ +maintainer-clean-generic clean mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/tds/config.c b/src/tds/config.c new file mode 100644 index 000000000..4c18ed01a --- /dev/null +++ b/src/tds/config.c @@ -0,0 +1,705 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef __DGUX__ +#include +#endif +#ifdef __FreeBSD__ +#include +#endif +#ifdef WIN32 +#include +#include +#define PATH_MAX 255 +#endif +#ifndef WIN32 +#include +#include +#include +#include +#endif +#include "tds.h" +#include "tdsutil.h" + +static char software_version[] = "$Id: config.c,v 1.1 2001-10-12 23:29:02 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +static void tds_config_login(TDSCONFIGINFO *config, TDSLOGIN *login); +static void tds_config_env_dsquery(TDSCONFIGINFO *config); +static void tds_config_env_tdsdump(TDSCONFIGINFO *config); +static void tds_config_env_tdsver(TDSCONFIGINFO *config); +static void tds_config_env_tdsport(TDSCONFIGINFO *config); +static int tds_read_conf_file(char *server, TDSCONFIGINFO *config); +static int tds_read_conf_sections(FILE *in, char *server, TDSCONFIGINFO *config); +static int tds_read_conf_section(FILE *in, char *section, TDSCONFIGINFO *config); +static void tds_read_interfaces(char *server, TDSCONFIGINFO *config); +static void tds_config_verstr(char *tdsver, TDSCONFIGINFO *config); +static int tds_config_boolean(char *value); +static void lookup_host(const char *servername, const char *portname, char *ip, char *port); + +static char interf_file[MAXPATH]; + +/* +** tds_get_config() will fill the tds config structure based on configuration +** information gathered in the following order: +** 1) Program specified in TDSLOGIN structure +** 2) The environment variables TDSVER, TDSDUMP, TDSPORT +** 3) ~/.interfaces if exists +** 4) $SYBASE/interfaces if exists +** 5) TDS_DEF_* default values +** +** .tdsrc and freetds.conf have been added to make the package easier to +** integration with various Linux and *BSD distributions. +*/ +TDSCONFIGINFO *tds_get_config(TDSSOCKET *tds, TDSLOGIN *login) +{ +TDSCONFIGINFO *config; + + + /* allocate a new structure with hard coded and build-time defaults */ + config = tds_alloc_config(); + + if (! tds_read_conf_file(login->server_name, config)) { + /* fallback to interfaces file */ + tds_read_interfaces(login->server_name, config); + } + + /* Now check the environment variables */ + tds_config_env_tdsver(config); + tds_config_env_tdsdump(config); + tds_config_env_tdsport(config); + tds_config_env_dsquery(config); + + /* And finally the login structure */ + tds_config_login(config, login); + + return config; +} +static int tds_read_conf_file(char *server, TDSCONFIGINFO *config) +{ +FILE *in; +char *section; +int i; +char *home, *path; +int found = 0; + + in = fopen(FREETDS_SYSCONFFILE, "r"); + if (in) { + found = tds_read_conf_sections(in, server, config); + fclose(in); + } + + home = getenv("HOME"); + if (home!=NULL && home[0]!='\0') { + path = malloc(strlen(home) + 14 + 1); /* strlen("/.freetds.conf")=14 */ + sprintf(path,"%s/.freetds.conf",home); + in = fopen(path, "r"); + if (in) { + found = tds_read_conf_sections(in, server, config); + fclose(in); + } + free(path); + } + + return found; +} +static int tds_read_conf_sections(FILE *in, char *server, TDSCONFIGINFO *config) +{ +char *section; +int i, found = 0; + + tds_read_conf_section(in, "global", config); + rewind(in); + section = strdup(server); + for (i=0;iblock_size = atoi(value); + } else if (!strcmp(option,TDS_STR_SWAPDT)) { + config->broken_dates = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_SWAPMNY)) { + config->broken_money = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_TRYSVR)) { + config->try_server_login = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_TRYDOM)) { + config->try_domain_login = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_DOMAIN)) { + if (config->default_domain) free(config->default_domain); + config->default_domain = strdup(value); + } else if (!strcmp(option,TDS_STR_XDOMAUTH)) { + config->xdomain_auth = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_DUMPFILE)) { + if (config->dump_file) free(config->dump_file); + config->dump_file = strdup(value); + } else if (!strcmp(option,TDS_STR_DEBUGLVL)) { + if (atoi(value)) + config->debug_level = atoi(value); + } else if (!strcmp(option,TDS_STR_TIMEOUT )) { + if (atoi(value)) + config->timeout = atoi(value); + } else if (!strcmp(option,TDS_STR_CONNTMOUT)) { + if (atoi(value)) + config->connect_timeout = atoi(value); + } else if (!strcmp(option,TDS_STR_HOST)) { + lookup_host(value, NULL, tmp, NULL); + if (config->ip_addr) free(config->ip_addr); + config->ip_addr = strdup(tmp); + } else if (!strcmp(option,TDS_STR_PORT)) { + if (atoi(value)) + config->port = atoi(value); + } else if (!strcmp(option,TDS_STR_EMUL_LE)) { + config->emul_little_endian = tds_config_boolean(value); + } else if (!strcmp(option,TDS_STR_TEXTSZ)) { + if (atoi(value)) + config->text_size = atoi(value); + } else if (!strcmp(option,TDS_STR_CHARSET)) { + if (config->char_set) free(config->char_set); + config->char_set = strdup(value); + } else if (!strcmp(option,TDS_STR_LANGUAGE)) { + if (config->language) free(config->language); + config->language = strdup(value); + } + } + + } + return found; +} + +static void tds_read_interfaces(char *server, TDSCONFIGINFO *config) +{ +char ip_addr[255], ip_port[255], tds_ver[255]; + + /* read $SYBASE/interfaces */ + /* This needs to be cleaned up */ + get_server_info(server, ip_addr, ip_port, tds_ver); + if (strlen(ip_addr)) { + if (config->ip_addr) free(config->ip_addr); + config->ip_addr = (char *) malloc(strlen(ip_addr)+1); + strcpy(config->ip_addr, ip_addr); + } + if (atoi(ip_port)) { + config->port = atoi(ip_port); + } + if (strlen(tds_ver)) { + tds_config_verstr(tds_ver, config); + /* if it doesn't match a known version do nothing with it */ + } +} +static void tds_config_login(TDSCONFIGINFO *config, TDSLOGIN *login) +{ + if (strlen(login->server_name)) { + if (config->server_name) free(config->server_name); + config->server_name = strdup(login->server_name); + } + if (login->major_version || login->minor_version) { + config->major_version = login->major_version; + config->minor_version = login->minor_version; + } + if (strlen(login->language)) { + if (config->language) free(config->language); + config->language = strdup(login->language); + } + if (strlen(login->char_set)) { + if (config->char_set) free(config->char_set); + config->char_set = strdup(login->char_set); + } + if (strlen(login->host_name)) { + if (config->host_name) free(config->host_name); + config->host_name = strdup(login->host_name); + } + if (strlen(login->app_name)) { + if (config->app_name) free(config->app_name); + config->app_name = strdup(login->app_name); + } + if (strlen(login->user_name)) { + if (config->user_name) free(config->user_name); + config->user_name = strdup(login->user_name); + } + if (strlen(login->password)) { + if (config->password) free(config->password); + config->password = strdup(login->password); + } + if (strlen(login->library)) { + if (config->library) free(config->library); + config->library = strdup(login->library); + } + if (login->encrypted) { + config->encrypted = 1; + } + if (login->suppress_language) { + config->suppress_language = 1; + } + if (login->bulk_copy) { + config->bulk_copy = 1; + } + if (login->block_size) { + config->block_size = login->block_size; + } + if (login->port) { + config->port = login->port; + } + +} + +static void tds_config_env_dsquery(TDSCONFIGINFO *config) +{ +char *s; + + if (s=getenv("DSQUERY")) { + if (s && strlen(s)) { + if (config->server_name) free(config->server_name); + config->server_name = strdup(s); + } + } +} +static void tds_config_env_tdsdump(TDSCONFIGINFO *config) +{ +char *s; +char path[255]; +pid_t pid; + + if (s=getenv("TDSDUMP")) { + if (!strlen(s)) { + pid = getpid(); + sprintf(path,"/tmp/freetds.log.%d",pid); + if (config->dump_file) free(config->dump_file); + config->dump_file = strdup(path); + } else { + if (config->dump_file) free(config->dump_file); + config->dump_file = strdup(s); + } + } +} +static void tds_config_env_tdsport(TDSCONFIGINFO *config) +{ +char *s; + + if (s=getenv("TDSPORT")) { + config->port=atoi(s); + } + return; +} +static void tds_config_env_tdsver(TDSCONFIGINFO *config) +{ +char *tdsver; + + if (tdsver=getenv("TDSVER")) { + tds_config_verstr(tdsver, config); + } + return; +} +static void tds_config_verstr(char *tdsver, TDSCONFIGINFO *config) +{ + if (!strcmp(tdsver,"42") || !strcmp(tdsver,"4.2")) { + config->major_version=4; + config->minor_version=2; + return; + } else if (!strcmp(tdsver,"46") || !strcmp(tdsver,"4.6")) { + config->major_version=4; + config->minor_version=6; + return; + } else if (!strcmp(tdsver,"50") || !strcmp(tdsver,"5.0")) { + config->major_version=5; + config->minor_version=0; + return; + } else if (!strcmp(tdsver,"70") || !strcmp(tdsver,"7.0")) { + config->major_version=7; + config->minor_version=0; + return; + } else if (!strcmp(tdsver,"80") || !strcmp(tdsver,"8.0")) { + config->major_version=8; + config->minor_version=0; + return; + } +} +int set_interfaces_file_loc(char *interf) +{ + if (strlen(interf)>MAXPATH) return 0; + + strcpy(interf_file,interf); + return 1; /* SUCCEED */ +} + +/* ============================== lookup_host() ============================== + * + * Def: Given a servername and port name or number, lookup the + * hostname and service. The server ip will be stored in the + * string 'servername' in dotted-decimal notation. The service port + * number will be stored in string form in the 'port' parameter. + * + * If we can't determine both the IP address and port number then + * 'ip' and 'port' will be set to empty strings. + * + * Ret: void + * + * =========================================================================== + */ +static void lookup_host( + const char *servername, /* (I) name of the server */ + const char *portname, /* (I) name or number of the port */ + char *ip, /* (O) dotted-decimal ip address of server */ + char *port) /* (O) port number of the service */ +{ + struct hostent *host = gethostbyname(servername); + struct servent *service = NULL; + int num = 0; + +/* froy@singleentry.com 12/21/2000 */ + if (host==NULL) { + char addr [4]; + int a0, a1, a2, a3; + sscanf (servername, "%d.%d.%d.%d", &a0, &a1, &a2, &a3); + addr [0] = a0; + addr [1] = a1; + addr [2] = a2; + addr [3] = a3; + host = gethostbyaddr (addr, 4, AF_INET); + } +/* end froy */ + if (!host) { + ip[0] = '\0'; + } else { + struct in_addr *ptr = (struct in_addr *) host->h_addr; + strncpy(ip, inet_ntoa(*ptr), 17); + } + if (portname) { + service = getservbyname(portname, "tcp"); + if (service==NULL) { + num = atoi(portname); + } else { + num = ntohs(service->s_port); + } + } + + if (num==0) { + if (port) port[0] = '\0'; + } else { + sprintf(port, "%d", num); + } +} /* lookup_host() */ + +static int hexdigit(char c) +{ + if (c>='a' && c<='f') { + return c - 'a' + 10; + } else if (c>='A' && c<='F') { + return c - 'A' + 10; + } else if (c>='0' && c<='9') { + return c - '0'; + } else { + return 0; /* bad hex digit */ + } +} +static int hex2num(char *hex) +{ + return hexdigit(hex[0])*16 + hexdigit(hex[1]); +} +/* ========================= search_interface_file() ========================= + * + * Def: Open and read the file 'file' searching for a logical server + * by the name of 'host'. If one is found then lookup + * the IP address and port number and store them in 'ip_addr', and + * 'ip_port'. + * + * Ret: void + * + * =========================================================================== + */ +static void search_interface_file( + const char *dir, /* (I) Name of base directory for interface file */ + const char *file, /* (I) Name of the interface file */ + const char *host, /* (I) Logical host to search for */ + char *ip_addr, /* (O) dotted-decimal IP address */ + char *ip_port, /* (O) Port number for database server */ + char *tds_ver) /* (O) Protocol version to use when connecting */ +{ +char *pathname; +char line[255]; +char tmp_ip[sizeof(line)]; +char tmp_port[sizeof(line)]; +char tmp_ver[sizeof(line)]; +FILE *in; +char *field; +int found=0; + + ip_addr[0] = '\0'; + ip_port[0] = '\0'; + line[0] = '\0'; + tmp_ip[0] = '\0'; + tmp_port[0] = '\0'; + tmp_ver[0] = '\0'; + + pathname = (char *) malloc(strlen(dir) + strlen(file) + 10); + + /* + * create the full pathname to the interface file + */ + if (file==NULL || file[0]=='\0') { + pathname[0] = '\0'; + } else { + if (dir==NULL || dir[0]=='\0') { + pathname[0] = '\0'; + } else { + strcpy(pathname, dir); + strcat(pathname, "/"); + } + strcat(pathname, file); + } + + + /* + * parse the interfaces file and find the server and port + */ + if ((in = fopen(pathname,"r"))==NULL) { + free(pathname); + return; + } + + while (fgets(line,sizeof(line)-1,in)) { + if (line[0]=='#') continue; /* comment */ + + if (!isspace(line[0])) { + field = strtok(line,"\n\t "); + if (!strcmp(field,host)) found=1; + else found=0; + } else if (found && isspace(line[0])) { + field = strtok(line,"\n\t "); + if (field!=NULL && !strcmp(field,"query")) { + field = strtok(NULL,"\n\t "); /* tcp or tli */ + if (!strcmp(field,"tli")) { + field = strtok(NULL,"\n\t "); /* tcp */ + field = strtok(NULL,"\n\t "); /* device */ + field = strtok(NULL,"\n\t "); /* host/port */ + if (strlen(field)>=18) { + sprintf(tmp_port,"%d", hex2num(&field[6])*256 + + hex2num(&field[8])); + sprintf(tmp_ip,"%d.%d.%d.%d", hex2num(&field[10]), + hex2num(&field[12]), hex2num(&field[14]), + hex2num(&field[16])); + } + } else { + field = strtok(NULL,"\n\t "); /* ether */ + strcpy(tmp_ver,field); + field = strtok(NULL,"\n\t "); /* host */ + strcpy(tmp_ip,field); + field = strtok(NULL,"\n\t "); /* port */ + strcpy(tmp_port,field); + } /* else */ + } /* if */ + } /* else if */ + } /* while */ +fclose(in); +free(pathname); + + + /* + * Look up the host and service + */ + lookup_host(tmp_ip, tmp_port, ip_addr, ip_port); + strcpy(tds_ver,tmp_ver); +} /* search_interface_file() */ + + +/* ============================ get_server_info() ============================ + * + * Def: Try to find the IP number and port for a (possibly) logical server + * name. + * + * Note: It is the callers responsibility to supply large enough buffers + * to hold the ip and port numbers. ip_addr should be at least 17 + * bytes long and ip_port should be at least 6 bytes long. + * + * Ret: True if it found the server, false otherwise. + * + * =========================================================================== + */ +int get_server_info( + char *server, /* (I) logical or physical server name */ + char *ip_addr, /* (O) string representation of IP address */ + char *ip_port, /* (O) string representation of port number */ + char *tds_ver) /* (O) string value specifying which protocol version */ +{ + ip_addr[0] = '\0'; + ip_port[0] = '\0'; + tds_ver[0] = '\0'; + + if(!server || strlen(server) == 0) { + server = getenv("DSQUERY"); + if(!server || strlen(server) == 0) { + server = "SYBASE"; + } + } + /* + * Look for the server in the interf_file iff interf_file has been set. + */ + if (ip_addr[0]=='\0' && interf_file[0]!='\0') + { + search_interface_file("", interf_file, server, ip_addr, ip_port, tds_ver); + } + + /* + * if we haven't found the server yet then look for a $HOME/.interfaces file + */ + if (ip_addr[0]=='\0') + { + char *home = getenv("HOME"); + if (home!=NULL && home[0]!='\0') + { + search_interface_file(home, ".interfaces", server, ip_addr, ip_port, tds_ver); + } + } + + /* + * if we haven't found the server yet then look in $SYBBASE/interfaces file + */ + if (ip_addr[0]=='\0') + { + char *sybase = getenv("SYBASE"); + if (sybase!=NULL && sybase[0]!='\0') + { + search_interface_file(sybase, "interfaces", server, ip_addr, ip_port, tds_ver); + } else { + search_interface_file("/etc/freetds", "interfaces", server, ip_addr, ip_port, tds_ver); + } + } + + /* + * If we still don't have the server and port then assume the user + * typed an actual server name. + */ + if (ip_addr[0]=='\0') + { + char *tmp_port; + + /* + * Make a guess about the port number + */ +#ifdef TDS50 + tmp_port = "4000"; +#else + tmp_port = "1433"; +#endif + /* FIX ME -- Need a symbolic constant for the environment variable */ + if (getenv("TDSPORT")!=NULL && getenv("DBLIB_PORT")[-1]!='\0') + { + tmp_port = getenv("TDSPORT"); + } + + /* + * lookup the host and service + */ + lookup_host(server, tmp_port, ip_addr, ip_port); + } + + return ip_addr[0]!='\0' && ip_port[0]!='\0'; +} /* get_server_info() */ + diff --git a/src/tds/convert.c b/src/tds/convert.c new file mode 100644 index 000000000..1a13143a3 --- /dev/null +++ b/src/tds/convert.c @@ -0,0 +1,849 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tdsutil.h" +#include "tds.h" +#include "tdsconvert.h" +#include +#include + +static char software_version[] = "$Id: convert.c,v 1.1 2001-10-12 23:29:01 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +typedef union dbany { + TDS_TINYINT ti; + TDS_SMALLINT si; + TDS_INT i; + TDS_FLOAT f; + TDS_REAL r; + TDS_CHAR *c; + TDS_MONEY m; + TDS_MONEY4 m4; + TDS_DATETIME dt; + TDS_DATETIME4 dt4; +/* + TDS_NUMERIC n; +*/ +} DBANY; + +typedef unsigned short utf16_t; + +TDS_INT tds_convert_any(unsigned char *dest, TDS_INT dtype, TDS_INT dlen, DBANY *any); +static int _string_to_tm(char *datestr, struct tm *t); +static int _tds_pad_string(char *dest, int destlen); +extern char *tds_numeric_to_string(TDS_NUMERIC *numeric, char *s); +extern char *tds_money_to_string(TDS_MONEY *money, char *s); + + +/* +this needs to go... +it won't handle binary or text/image when they are added +it's not thread safe +it works for the moment though til i decide how i really want to handle it +*/ +static TDS_CHAR tmp_str[4096]; + + +int tds_get_conversion_type(int srctype, int colsize) +{ + if (srctype == SYBINTN) { + if (colsize==8) + return SYBINT8; + if (colsize==4) + return SYBINT4; + else if (colsize==2) + return SYBINT2; + else if (colsize==1) + return SYBINT1; + } else if (srctype == SYBFLTN) { + if (colsize==8) + return SYBFLT8; + else if (colsize==4) + return SYBREAL; + } else if (srctype == SYBDATETIMN) { + if (colsize==8) + return SYBDATETIME; + else if (colsize==4) + return SYBDATETIME4; + } else if (srctype == SYBMONEYN) { + if (colsize==8) + return SYBMONEY; + else if (colsize==4) + return SYBMONEY4; + } + return srctype; +} +TDS_INT tds_convert_text(int srctype,unsigned char *src,TDS_UINT srclen, + int desttype,unsigned char *dest,TDS_UINT destlen) +{ +int cplen; + + switch(desttype) { + case SYBTEXT: + cplen = srclen > destlen ? destlen : srclen; + memcpy(dest, src, cplen); + /* 2001-06-15 Deutsch changed [cplen-1] to [cplen] */ + dest[cplen] = '\0'; + return strlen(dest); + case SYBCHAR: + cplen = srclen > destlen ? destlen : srclen; + /* if (cplen>255) cplen=255; */ + memcpy(dest, src, cplen); + dest[cplen]='\0'; + return strlen(dest); + } + return 0; +} +static TDS_UINT utf16len(const utf16_t* s) +{ + const utf16_t* p = s; + while (*p++) + ; + return p - s; +} + +TDS_INT tds_convert_ntext(int srctype,unsigned char *src,TDS_UINT srclen, + int desttype,unsigned char *dest,TDS_UINT destlen) +{ + /* + * XXX Limit of 255 + 1 needs to be fixed by determining what the + * real limit of [N][VAR]CHAR columns is. + * XXX What about NCHAR? Don't see a constant for it in tds.h. + * XXX Case for -1 in switch statement because upper levels don't + * have a way to bind to wide-character types. + */ + TDS_UINT i, cplen, char_limit = 256; + utf16_t* wsrc = (utf16_t*)src; + utf16_t* wdest = (utf16_t*)dest; + assert(sizeof(utf16_t) == 2); + switch (desttype) { + case SYBNVARCHAR: + if (destlen > char_limit * sizeof(utf16_t)) + destlen = char_limit * sizeof(utf16_t); + /* Fall through ... */ + case SYBNTEXT: + case -1: + cplen = srclen > destlen ? destlen : srclen; + memcpy(dest, src, cplen); + if (destlen < srclen + sizeof(utf16_t)) { + size_t term_pos = destlen - sizeof(utf16_t); + size_t odd_bytes = term_pos % sizeof(utf16_t); + term_pos -= odd_bytes; + wdest[term_pos / sizeof(utf16_t)] = 0; + } + else + wdest[cplen / sizeof(utf16_t)] = 0; + return utf16len(wdest) * 2; + default: + /* Assume caller wants conversion to narrow string. */ + if (destlen > char_limit && desttype != SYBTEXT) + destlen = char_limit; + cplen = srclen > destlen ? destlen : srclen; + for (i = 0; i < cplen; ++i) + dest[i] = (unsigned char)wsrc[i]; + dest[cplen-1] = 0; + return strlen(dest); + } + return 0; +} + + +TDS_INT tds_convert_binary(int srctype,unsigned char *src,TDS_INT srclen, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +int cplen; +int d, s; +TDS_VARBINARY *varbin; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + /* FIX ME */ + if (destlen>=0 && destlen<3) { + return 0; + } + d=0; + dest[d++]='0'; + dest[d++]='x'; + + /* length = -1 means assume dest is large enough, ugly */ + if (destlen==-1) { + for (s=0;s 9 ? 87 + (src[s]/16) : '0' + (src[s]/16); + dest[d+1]=src[s]%16 > 9 ? 87 + (src[s]%16) : '0' + (src[s]%16); + } + } else { + for (s=0;s 9 ? 87 + (src[s]/16) : '0' + (src[s]/16); + dest[d+1]=src[s]%16 > 9 ? 87 + (src[s]%16) : '0' + (src[s]%16); + } + } + dest[d++]='\0'; + return d; + case SYBIMAGE: + case SYBBINARY: + cplen = srclen > destlen ? destlen : srclen; + memcpy(dest, src, cplen); + return cplen; + case SYBVARBINARY: + cplen = srclen > destlen ? destlen : srclen; + varbin = (TDS_VARBINARY *) dest; + varbin->len = cplen; + memcpy(varbin->array, src, cplen); + return sizeof(TDS_VARBINARY); + } +} + +TDS_INT tds_convert_char(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +DBANY any; +struct tm t; +time_t secs_from_epoch; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + case SYBNVARCHAR: + any.c = src; + break; + case SYBTEXT: + break; + case SYBBINARY: + case SYBIMAGE: + break; + case SYBINT1: + any.ti = atoi(src); + break; + case SYBINT2: + any.si = atoi(src); + break; + case SYBINT4: + any.i = atol(src); + break; + case SYBFLT8: + any.f = atof(src); + break; + case SYBREAL: + any.r = atof(src); + break; + case SYBBIT: + case SYBBITN: + any.ti = (atoi(src)>0) ? 1 : 0; + break; + case SYBMONEY: + break; + case SYBMONEY4: + break; + case SYBDATETIME: + _string_to_tm(src, &t); + secs_from_epoch = mktime(&t); + any.dt.dtdays = (secs_from_epoch/60/60/24)+25567; + any.dt.dttime = (secs_from_epoch%60%60%24)*300; + break; + case SYBDATETIME4: + _string_to_tm(src, &t); + secs_from_epoch = mktime(&t); + any.dt4.days = (secs_from_epoch/60/60/24)+25567; + any.dt4.minutes = (secs_from_epoch%60%60%24)/60; + break; + case SYBNUMERIC: + case SYBDECIMAL: + break; +/* + case SYBBOUNDRY: + break; + case SYBSENSITIVITY: + break; +*/ + default: + return TDS_FAIL; + } + return tds_convert_any(dest, desttype, destlen, &any); +} +TDS_INT tds_convert_bit(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +DBANY any; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + sprintf(tmp_str,"%c",src[0] ? '1' : '0'); + any.c = tmp_str; + break; + case SYBTEXT: + break; + case SYBBINARY: + case SYBIMAGE: + break; + case SYBINT1: + any.ti = src[0] ? 1 : 0; + break; + case SYBINT2: + any.si = src[0] ? 1 : 0; + break; + case SYBINT4: + any.i = src[0] ? 1 : 0; + break; + case SYBFLT8: + any.f = src[0] ? 1.0 : 0.0; + break; + case SYBREAL: + any.r = src[0] ? 1.0 : 0.0; + break; + case SYBBIT: + case SYBBITN: + any.ti = src[0]; + break; + case SYBMONEY: + break; + case SYBMONEY4: + break; + case SYBNUMERIC: + case SYBDECIMAL: + break; +/* + case SYBBOUNDRY: + break; + case SYBSENSITIVITY: + break; +*/ + } + return tds_convert_any(dest, desttype, destlen, &any); +} +TDS_INT tds_convert_int1(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +DBANY any; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + sprintf(tmp_str,"%d",src[0]); + any.c = tmp_str; + break; + case SYBINT1: + any.ti = *((TDS_TINYINT *) src); + break; + case SYBINT2: + any.si = *((TDS_TINYINT *) src); + break; + case SYBINT4: + any.i = *((TDS_TINYINT *) src); + break; + default: + return TDS_FAIL; + } + return tds_convert_any(dest, desttype, destlen, &any); +} +TDS_INT tds_convert_int2(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +unsigned char buf[4]; +DBANY any; + + memcpy(buf,src,2); + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + sprintf(tmp_str,"%d",*((TDS_SMALLINT *) buf)); + any.c = tmp_str; + break; + case SYBINT1: + any.ti = *((TDS_SMALLINT *) buf); + break; + case SYBINT2: + any.si = *((TDS_SMALLINT *) buf); + break; + case SYBINT4: + any.i = *((TDS_SMALLINT *) buf); + break; + } + return tds_convert_any(dest, desttype, destlen, &any); +} +TDS_INT tds_convert_int4(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +unsigned char buf[4]; +DBANY any; + + memcpy(buf,src,4); + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + sprintf(tmp_str,"%ld",*((TDS_INT *) buf)); + any.c = tmp_str; + break; + case SYBINT1: + any.ti = *((TDS_INT *) buf); + break; + case SYBINT2: + any.si = *((TDS_INT *) buf); + break; + case SYBINT4: + any.i = *((TDS_INT *) buf); + break; + default: + return TDS_FAIL; + } + return tds_convert_any(dest, desttype, destlen, &any); +} +TDS_INT tds_convert_numeric(int srctype,TDS_NUMERIC *src,TDS_INT srclen, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +char tmpstr[MAXPRECISION]; +TDS_FLOAT d; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + tds_numeric_to_string(src,dest); + return strlen(dest); + break; + case SYBNUMERIC: + case SYBDECIMAL: + memcpy(dest, src, sizeof(TDS_NUMERIC)); + return sizeof(TDS_NUMERIC); + break; + case SYBFLT8: + /* FIX ME -- temporary fix */ + tds_numeric_to_string(src,tmpstr); + d = atof(tmpstr); + memcpy(dest,&d,sizeof(double)); + break; + default: + return TDS_FAIL; + break; + } + return TDS_FAIL; +} +TDS_INT tds_convert_money4(int srctype,unsigned char *src, int srclen, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +TDS_MONEY4 mny; +long dollars, fraction; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + mny = *((TDS_MONEY4 *) src); + dollars = mny.mny4 / 10000; + fraction = mny.mny4 % 10000; + if (fraction < 0) { fraction = -fraction; } + sprintf(dest,"%ld.%02lu",dollars,fraction/100); + if (desttype==SYBCHAR) { + /* ugly hack to emulate sybase behaviour + ** which PHP relies on */ + if (destlen==-1) + _tds_pad_string(dest,srclen); + else + _tds_pad_string(dest,destlen); + } + return strlen(dest); + break; + case SYBFLT8: + memcpy(&dollars, src, 4); + *(TDS_FLOAT *)dest = ((TDS_FLOAT)dollars) / 10000; + break; + case SYBMONEY4: + memcpy(dest, src, sizeof(TDS_MONEY4)); + break; + default: + return TDS_FAIL; + break; + } + return sizeof(TDS_MONEY4); +} +TDS_INT tds_convert_money(int srctype,unsigned char *src, + int desttype,unsigned char *dest,TDS_INT destlen) +{ +TDS_INT high; +TDS_UINT low; +double dmoney; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + return (int)tds_money_to_string((TDS_MONEY *)src, dest); + break; + case SYBFLT8: + /* Used memcpy to avoid alignment/bus errors */ + memcpy(&high, src, 4); + memcpy(&low, src+4, 4); + dmoney = (TDS_FLOAT)high * 65536 * 65536 + (TDS_FLOAT)low; + dmoney = dmoney / 10000; + *(TDS_FLOAT *)dest = dmoney; + break; + case SYBMONEY: + memcpy(dest, src, sizeof(TDS_MONEY)); + break; + default: + return TDS_FAIL; + break; + } + return TDS_FAIL; +} +TDS_INT tds_convert_datetime(int srctype,unsigned char *src,int desttype,unsigned char *dest,TDS_INT destlen) +{ +TDS_INT dtdays, dttime; +time_t tmp_secs_from_epoch; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + /* FIX ME -- This fails for dates before 1902 or after 2038 */ + if (destlen<0) { + memset(dest,' ',30); + } else { + memset(dest,' ',destlen); + } + if (!src) { + *dest='\0'; + return 0; + } + memcpy(&dtdays, src, 4); + memcpy(&dttime, src+4, 4); + tmp_secs_from_epoch = ((dtdays - 25567)*24*60*60) + (dttime/300); + if (strlen(src)>destlen) { + strftime(dest, destlen-1, "%b %d %Y %I:%M%p", + (struct tm*)gmtime(&tmp_secs_from_epoch)); + return destlen; + } else { + strftime(dest, 20, "%b %d %Y %I:%M%p", + (struct tm*)gmtime(&tmp_secs_from_epoch)); + return (strlen(dest)); + } + break; + case SYBDATETIME: + memcpy(dest,src,sizeof(TDS_DATETIME)); + return sizeof(TDS_DATETIME); + break; + case SYBDATETIME4: + break; + default: + return TDS_FAIL; + break; + } + return TDS_FAIL; +} +TDS_INT tds_convert_datetime4(int srctype,unsigned char *src,int desttype,unsigned char *dest,TDS_INT destlen) +{ + TDS_USMALLINT days, minutes; + time_t tmp_secs_from_epoch; + + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + if (destlen<0) { + memset(dest,' ',30); + } else { + memset(dest,' ',destlen); + } + if (!src) { + *dest='\0'; + return 0; + } + memcpy(&days, src, 2); + memcpy(&minutes, src+2, 2); + tdsdump_log(TDS_DBG_INFO1, "%L inside tds_convert_datetime4() days = %d minutes = %d\n", days, minutes); + tmp_secs_from_epoch = (days - 25567)*(24*60*60) + (minutes*60); + if (strlen(src)>destlen) { + strftime(dest, destlen-1, "%b %d %Y %I:%M%p", + (struct tm*)gmtime(&tmp_secs_from_epoch)); + return destlen; + } else { + strftime(dest, 20, "%b %d %Y %I:%M%p", + (struct tm*)gmtime(&tmp_secs_from_epoch)); + return (strlen(dest)); + } + break; + case SYBDATETIME: + break; + case SYBDATETIME4: + memcpy(dest,src,sizeof(TDS_DATETIME4)); + return(sizeof(TDS_DATETIME4)); + default: + return TDS_FAIL; + break; + } + return TDS_FAIL; +} + +TDS_INT tds_convert_real(int srctype,unsigned char *src,int desttype,unsigned +char *dest,TDS_INT destlen) +{ +TDS_REAL the_value; + + memcpy(&the_value, src, 4); + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + /* A real type has a 7 digit precision plus a two digit exponent + * "-d.dddddde+dd" + * so it should have >=14 bytes allocated (one for the terminating + * NULL), right? + */ + if (destlen >= 0 && destlen < 14) return TDS_FAIL; + sprintf(dest,"%.7g", the_value); + return strlen(dest); + case SYBFLT8: + *((TDS_FLOAT *)dest) = the_value; + return sizeof(TDS_FLOAT); + case SYBREAL: + memcpy(dest,src,sizeof(TDS_REAL)); + return sizeof(TDS_REAL); + } + return TDS_FAIL; +} + +TDS_INT tds_convert_flt8(int srctype,unsigned char *src,int desttype,unsigned +char *dest,TDS_INT destlen) +{ +TDS_FLOAT the_value; + + memcpy(&the_value, src, 8); + switch(desttype) { + case SYBCHAR: + case SYBVARCHAR: + /* A flt8 type has a 15 digit precision plus a three digit exponent + * "-d.dddddddddddddde+ddd" + * so it should have >=23 bytes allocated (one for the terminating + * NULL), right? + */ + if (destlen >= 0 && destlen < 23) return TDS_FAIL; + sprintf(dest,"%.15g", the_value); + return strlen(dest); + case SYBREAL: + *((TDS_REAL *)dest) = the_value; + return sizeof(TDS_REAL); + case SYBFLT8: + memcpy(dest,src,sizeof(TDS_FLOAT)); + return sizeof(TDS_FLOAT); + } + return TDS_FAIL; +} + +TDS_INT tds_convert_any(unsigned char *dest, TDS_INT dtype, TDS_INT dlen, DBANY *any) +{ +int i; + + switch(dtype) { + case SYBCHAR: + case SYBVARCHAR: + tdsdump_log(TDS_DBG_INFO1, "%L converting string dlen = %d dtype = %d string = %s\n",dlen,dtype,any->c); + if (dlen && strlen(any->c)>dlen) { + strncpy(dest,any->c,dlen-1); + dest[dlen-1]='\0'; + for (i=strlen(dest)-1;dest[i]==' ';i--) + dest[i]='\0'; + return dlen; + } else { + strcpy(dest, any->c); + for (i=strlen(dest)-1;dest[i]==' ';i--) + dest[i]='\0'; + return strlen(dest); + } + break; + case SYBTEXT: + break; + case SYBBINARY: + case SYBIMAGE: + break; + case SYBINT1: + memcpy(dest,&(any->ti),1); + return 1; + break; + case SYBINT2: + memcpy(dest,&(any->si),2); + return 2; + break; + case SYBINT4: + memcpy(dest,&(any->i),4); + return 4; + break; + case SYBFLT8: + memcpy(dest,&(any->f),8); + return 8; + break; + case SYBREAL: + memcpy(dest,&(any->r),4); + return 4; + break; + case SYBBIT: + case SYBBITN: + memcpy(dest,&(any->ti),1); + return 1; + break; + case SYBMONEY: + break; + case SYBMONEY4: + break; + case SYBDATETIME: + memcpy(dest,&(any->dt),sizeof(TDS_DATETIME)); + break; + case SYBDATETIME4: + memcpy(dest,&(any->dt4),sizeof(TDS_DATETIME4)); + break; + case SYBNUMERIC: + case SYBDECIMAL: + break; +/* + case SYBBOUNDRY: + break; + case SYBSENSITIVITY: + break; +*/ + } + return TDS_FAIL; +} +TDS_INT tds_convert(int srctype, + TDS_CHAR *src, + TDS_UINT srclen, + int desttype, + TDS_CHAR *dest, + TDS_UINT destlen) +{ +TDS_VARBINARY *varbin; + + switch(srctype) { + case SYBCHAR: + case SYBVARCHAR: + case SYBNVARCHAR: + return tds_convert_char(srctype,src, + desttype,dest,destlen); + break; + case SYBMONEY4: + return tds_convert_money4(srctype,src,srclen, + desttype,dest,destlen); + break; + case SYBMONEY: + return tds_convert_money(srctype,src, + desttype,dest,destlen); + break; + case SYBNUMERIC: + case SYBDECIMAL: + return tds_convert_numeric(srctype,(TDS_NUMERIC *) src,srclen, + desttype,dest,destlen); + break; + case SYBBIT: + case SYBBITN: + return tds_convert_bit(srctype,src, + desttype,dest,destlen); + break; + case SYBINT1: + return tds_convert_int1(srctype,src, + desttype,dest,destlen); + break; + case SYBINT2: + return tds_convert_int2(srctype,src, + desttype,dest,destlen); + break; + case SYBINT4: + return tds_convert_int4(srctype,src, + desttype,dest,destlen); + break; + case SYBREAL: + return tds_convert_real(srctype,src, + desttype,dest,destlen); + break; + case SYBFLT8: + return tds_convert_flt8(srctype,src, + desttype,dest,destlen); + break; + case SYBDATETIME: + return tds_convert_datetime(srctype,src, + desttype,dest,destlen); + break; + case SYBDATETIME4: + return tds_convert_datetime4(srctype,src, + desttype,dest,destlen); + break; + case SYBVARBINARY: + varbin = (TDS_VARBINARY *)src; + return tds_convert_binary(srctype,varbin->array, + varbin->len,desttype,dest,destlen); + break; + case SYBIMAGE: + case SYBBINARY: + return tds_convert_binary(srctype,src,srclen, + desttype,dest,destlen); + break; + case SYBTEXT: + return tds_convert_text(srctype,src,srclen, + desttype,dest,destlen); + break; + case SYBNTEXT: + return tds_convert_ntext(srctype,src,srclen, + desttype,dest,destlen); + break; + default: + fprintf(stderr,"Attempting to convert unknown source type %d\n",srctype); + + } + return TDS_FAIL; +} +static int _string_to_tm(char *datestr, struct tm *t) +{ +enum {TDS_MONTH = 1, TDS_DAY, TDS_YEAR, TDS_HOUR, TDS_MIN, TDS_SEC, TDS_MILLI}; +int state = TDS_MONTH; +char last_char=0, *s; + + memset(t,'\0',sizeof(struct tm)); + + for (s=datestr;*s;s++) { + if (! isdigit(*s) && isdigit(last_char)) { + state++; + } else switch(state) { + case TDS_MONTH: + t->tm_mon = (t->tm_mon * 10) + (*s - '0'); + break; + case TDS_DAY: + t->tm_mday = (t->tm_mday * 10) + (*s - '0'); + break; + case TDS_YEAR: + t->tm_year = (t->tm_year * 10) + (*s - '0'); + break; + case TDS_HOUR: + t->tm_hour = (t->tm_hour * 10) + (*s - '0'); + break; + case TDS_MIN: + t->tm_min = (t->tm_min * 10) + (*s - '0'); + break; + case TDS_SEC: + t->tm_sec = (t->tm_sec * 10) + (*s - '0'); + break; + } + last_char=*s; + } + return 0; +} +static int _tds_pad_string(char *dest, int destlen) +{ +int i=0; + + if (destlen>strlen(dest)) { + for (i=strlen(dest)+1;imajor_version=major_ver; + tds_login->minor_version=minor_ver; +} +void tds_set_packet(TDSLOGIN *tds_login, short packet_size) +{ + tds_login->block_size=packet_size; +} +void tds_set_port(TDSLOGIN *tds_login, int port) +{ + tds_login->port=port; +} +void tds_set_passwd(TDSLOGIN *tds_login, char *password) +{ + if (password) { + strncpy(tds_login->password, password, TDS_MAX_LOGIN_STR_SZ); + } +} +void tds_set_bulk(TDSLOGIN *tds_login, TDS_TINYINT enabled) +{ + tds_login->bulk_copy = enabled ? 0 : 1; +} +void tds_set_user(TDSLOGIN *tds_login, char *username) +{ + strncpy(tds_login->user_name, username, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_host(TDSLOGIN *tds_login, char *hostname) +{ + strncpy(tds_login->host_name, hostname, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_app(TDSLOGIN *tds_login, char *application) +{ + strncpy(tds_login->app_name, application, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_server(TDSLOGIN *tds_login, char *server) +{ + if(!server || strlen(server) == 0) { + server = getenv("DSQUERY"); + if(!server || strlen(server) == 0) { + server = "SYBASE"; + } + } + strncpy(tds_login->server_name, server, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_library(TDSLOGIN *tds_login, char *library) +{ + strncpy(tds_login->library, library, 10); +} +void tds_set_charset(TDSLOGIN *tds_login, char *charset) +{ + strncpy(tds_login->char_set, charset, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_language(TDSLOGIN *tds_login, char *language) +{ + strncpy(tds_login->language, language, TDS_MAX_LOGIN_STR_SZ); +} +void tds_set_timeouts(TDSLOGIN *tds_login, int connect, int query, int longquery) /* Jeffs' hack to support timeouts */ +{ + tds_login->connect_timeout = connect; + tds_login->query_timeout = query; + tds_login->longquery_timeout = longquery; +} +void tds_set_longquery_handler(TDSLOGIN * tds_login, void * longquery_func, long longquery_param) /* Jeff's hack */ +{ + tds_login->longquery_func = longquery_func; + tds_login->longquery_param = longquery_param; +} +extern void tds_set_capabilities(TDSLOGIN *tds_login, unsigned char *capabilities, int size) +{ + memcpy(tds_login->capabilities, capabilities, + size > TDS_MAX_CAPABILITY ? TDS_MAX_CAPABILITY : size); +} + +TDSSOCKET *tds_connect(TDSLOGIN *login) +{ +TDSSOCKET *tds; +struct sockaddr_in sin; +char *s; +/* Jeff's hack - begin */ +unsigned long ioctl_blocking = 1; +struct timeval selecttimeout; +fd_set fds; +int retval; +time_t start, now; +char path[100]; +pid_t pid; +TDSCONFIGINFO *config; +/* 13 + max string of 32bit int, 30 should cover it */ +char query[30]; + +FD_ZERO (&fds); +/* end */ + + config = tds_get_config(tds, login); + + /* + ** If a dump file has been specified, start logging + */ + if (config->dump_file) { + tdsdump_open(config->dump_file); + } + + /* + ** The initial login packet must have a block size of 512. + ** Once the connection is established the block size can be changed + ** by the server with TDS_ENV_CHG_TOKEN + */ + tds = tds_alloc_socket(512); + + tds->major_version=config->major_version; + tds->minor_version=config->minor_version; + tds->emul_little_endian=config->emul_little_endian; +#ifdef WORDS_BIGENDIAN + if (IS_TDS70(tds) || IS_TDS80(tds)) { + /* TDS 7/8 only supports little endian */ + tds->emul_little_endian=1; + } +#endif + + /* Jeff's hack - begin */ + tds->timeout = (login->connect_timeout) ? login->query_timeout : 0; + tds->longquery_timeout = (login->connect_timeout) ? login->longquery_timeout : 0; + tds->longquery_func = login->longquery_func; + tds->longquery_param = login->longquery_param; + /* end */ + + + sin.sin_addr.s_addr = inet_addr(config->ip_addr); + sin.sin_family = AF_INET; + sin.sin_port = htons(config->port); + + memcpy(tds->capabilities,login->capabilities,TDS_MAX_CAPABILITY); + + tdsdump_log(TDS_DBG_INFO1, "%L Connecting addr %s port %d\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); + if ((tds->s = socket (AF_INET, SOCK_STREAM, 0)) < 0) { + perror ("socket"); + tds_free_config(config); + return NULL; + } + + /* Jeff's hack *** START OF NEW CODE *** */ + if (login->connect_timeout) { + start = time (NULL); + ioctl_blocking = 1; /* ~0; //TRUE; */ + if (IOCTL(tds->s, FIONBIO, &ioctl_blocking) < 0) { + tds_free_config(config); + return NULL; + } + connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)); + /* Select on writeability for connect_timeout */ + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + + FD_SET (tds->s, &fds); + retval = 0; + retval = select(tds->s + 1, NULL, &fds, NULL, &selecttimeout); + /* patch from Kostya Ivanov */ + if (retval < 0 && errno == EINTR) + retval = 0; + /* end patch */ + + now = time (NULL); + + while ((retval == 0) && ((now-start) < login->connect_timeout)) { + tds_msleep(1); + FD_SET (tds->s, &fds); + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + retval = select(tds->s + 1, NULL, &fds, NULL, &selecttimeout); + now = time (NULL); + } + + if ((now-start) > login->connect_timeout) { + tds_free_config(config); + return NULL; + } + } else { + if (connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)) <0) { + perror("connect"); + tds_free_config(config); + return NULL; + } + } + /* END OF NEW CODE */ + + if (IS_TDS70(tds) || IS_TDS80(tds)) { + tds->out_flag=0x10; + tds7_send_login(tds,config); + } else { + tds->out_flag=0x02; + tds_send_login(tds,config); + } + /* get_incoming(tds->s); */ + if (!tds_process_login_tokens(tds)) { + tds_free_socket(tds); + tds = NULL; + } + if (tds && config->text_size) { + sprintf(query,"set textsize %d", config->text_size); + retval = tds_submit_query(tds,query); + if (retval == TDS_SUCCEED) { + while (tds_process_result_tokens(tds)==TDS_SUCCEED); + } + } + tds_free_config(config); + return tds; +} +int tds_send_login(TDSSOCKET *tds, TDSCONFIGINFO *config) +{ + unsigned char be1[]= {0x02,0x00,0x06,0x04,0x08,0x01}; + unsigned char le1[]= {0x03,0x01,0x06,0x0a,0x09,0x01}; + unsigned char magic2[]={0x00,0x00}; + + unsigned char magic3[]= {0x00,0x00,0x00}; + +/* these seem to endian flags as well 13,17 on intel/alpha 12,16 on power */ + + unsigned char be2[]= {0x00,12,16}; + unsigned char le2[]= {0x00,13,17}; + + /* + ** the former byte 0 of magic5 causes the language token and message to be + ** absent from the login acknowledgement if set to 1. There must be a way + ** of setting this in the client layer, but I am not aware of any thing of + ** the sort -- bsb 01/17/99 + */ + unsigned char magic5[]= {0x00,0x00}; + unsigned char magic6[]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char magic7= 0x01; + + unsigned char magic42[]= {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}; + unsigned char magic50[]= {0x00,0x00,0x00,0x00}; +/* +** capabilities are now part of the tds structure. + unsigned char capabilities[]= {0x01,0x07,0x03,109,127,0xFF,0xFF,0xFF,0xFE,0x02,0x07,0x00,0x00,0x0A,104,0x00,0x00,0x00}; +*/ +/* +** This is the original capabilities packet we were working with (sqsh) + unsigned char capabilities[]= {0x01,0x07,0x03,109,127,0xFF,0xFF,0xFF,0xFE,0x02,0x07,0x00,0x00,0x0A,104,0x00,0x00,0x00}; +** original with 4.x messages + unsigned char capabilities[]= {0x01,0x07,0x03,109,127,0xFF,0xFF,0xFF,0xFE,0x02,0x07,0x00,0x00,0x00,120,192,0x00,0x0D}; +** This is isql 11.0.3 + unsigned char capabilities[]= {0x01,0x07,0x00,96, 129,207, 0xFF,0xFE,62, 0x02,0x07,0x00,0x00,0x00,120,192,0x00,0x0D}; +** like isql but with 5.0 messages + unsigned char capabilities[]= {0x01,0x07,0x00,96, 129,207, 0xFF,0xFE,62, 0x02,0x07,0x00,0x00,0x00,120,192,0x00,0x00}; +** +*/ + + unsigned char protocol_version[4]; + unsigned char program_version[4]; + + int rc; + char blockstr[10], passwdstr[255]; + + if (IS_TDS42(tds)) { + memcpy(protocol_version,"\004\002\000\000",4); + memcpy(program_version,"\004\002\000\000",4); + } else if (IS_TDS46(tds)) { + memcpy(protocol_version,"\004\006\000\000",4); + memcpy(program_version,"\004\002\000\000",4); + } else if (IS_TDS50(tds)) { + memcpy(protocol_version,"\005\000\000\000",4); + memcpy(program_version,"\005\000\000\000",4); + } else { + fprintf(stderr,"Unknown protocol version!"); + exit(1); + } + /* + ** the following code is adapted from Arno Pedusaar's + ** (psaar@fenar.ee) MS-SQL Client. His was a much better way to + ** do this, (well...mine was a kludge actually) so here's mostly his + */ + + rc=tds_put_string(tds,config->host_name,TDS_MAX_LOGIN_STR_SZ); /* client host name */ + rc|=tds_put_string(tds,config->user_name,TDS_MAX_LOGIN_STR_SZ); /* account name */ + rc|=tds_put_string(tds,config->password,TDS_MAX_LOGIN_STR_SZ); /* account password */ + rc|=tds_put_string(tds,"37876",TDS_MAX_LOGIN_STR_SZ); /* host process */ +#ifdef WORDS_BIGENDIAN + if (tds->emul_little_endian) { + rc|=tds_put_n(tds,le1,6); + } else { + rc|=tds_put_n(tds,be1,6); + } +#else + rc|=tds_put_n(tds,le1,6); +#endif + rc|=tds_put_byte(tds,config->bulk_copy); + rc|=tds_put_n(tds,magic2,2); + if (IS_TDS42(tds)) { + rc|=tds_put_int(tds,512); + } else { + rc|=tds_put_int(tds,0); + } + rc|=tds_put_n(tds,magic3,3); + rc|=tds_put_string(tds,config->app_name,TDS_MAX_LOGIN_STR_SZ); + rc|=tds_put_string(tds,config->server_name,TDS_MAX_LOGIN_STR_SZ); + if (IS_TDS42(tds)) { + rc|=tds_put_string(tds,config->password,255); + } else { + sprintf(passwdstr,"%c%c%s",0,(unsigned char) strlen(config->password),config->password); + rc|=tds_put_buf(tds,passwdstr,255,(unsigned char)strlen(config->password)+2); + } + + rc|=tds_put_n(tds,protocol_version,4); /* TDS version; { 0x04,0x02,0x00,0x00 } */ + rc|=tds_put_string(tds,config->library,10); /* client program name */ + if (IS_TDS42(tds)) { + rc|=tds_put_int(tds,0); + } else { + rc|=tds_put_n(tds,program_version,4); /* program version ? */ + } +#ifdef WORDS_BIGENDIAN + if (tds->emul_little_endian) { + rc|=tds_put_n(tds,le2,3); + } else { + rc|=tds_put_n(tds,be2,3); + } +#else + rc|=tds_put_n(tds,le2,3); +#endif + rc|=tds_put_string(tds,config->language,TDS_MAX_LOGIN_STR_SZ); /* language */ + rc|=tds_put_byte(tds,config->suppress_language); + rc|=tds_put_n(tds,magic5,2); + rc|=tds_put_byte(tds,config->encrypted); + rc|=tds_put_n(tds,magic6,10); + rc|=tds_put_string(tds,config->char_set,TDS_MAX_LOGIN_STR_SZ); /* charset */ + rc|=tds_put_byte(tds,magic7); + sprintf(blockstr,"%d",config->block_size); + rc|=tds_put_string(tds,blockstr,6); /* network packet size */ + if (IS_TDS42(tds)) { + rc|=tds_put_n(tds,magic42,8); + } else if (IS_TDS46(tds)) { + rc|=tds_put_n(tds,magic42,4); + } else if (IS_TDS50(tds)) { + rc|=tds_put_n(tds,magic50,4); + rc|=tds_put_byte(tds, TDS_CAP_TOKEN); + rc|=tds_put_smallint(tds, 18); + rc|=tds_put_n(tds,tds->capabilities,TDS_MAX_CAPABILITY); + } + + rc|=tds_flush_packet(tds); + /* get_incoming(tds->s); */ + return 0; +} + +/* +** tds7_send_login() -- Send a TDS 7.0 login packet +** TDS 7.0 login packet is vastly different and so gets its own function +*/ +int tds7_send_login(TDSSOCKET *tds, TDSCONFIGINFO *config) +{ +int rc; +unsigned char magic1[] = + {6,0x83,0xf2,0xf8,0xff,0x0,0x0,0x0,0x0, + 0xe0,0x03,0x0,0x0,0x88,0xff,0xff,0xff, + 0x36,0x04,0x00,0x00}; +/* also seen + {6,0x7d,0x0f,0xfd,0xff,0x0,0x0,0x0,0x0, + 0xe0,0x83,0x0,0x0,0x68,0x01,0x00,0x00, + 0x09,0x04,0x00,0x00}; +*/ +unsigned char magic2[] = {0x00,0x40,0x33,0x9a,0x6b,0x50}; +/* 0xb4,0x00,0x30,0x00,0xe4,0x00,0x00,0x00}; */ +unsigned char magic3[] = "NTLMSSP"; +unsigned char unicode_string[255]; +int packet_size; +int size1; +int current_pos; +int domain_login = 0; + + + if (!domain_login) { + size1 = 86 + (strlen(config->host_name) + + strlen(config->user_name) + + strlen(config->app_name) + + strlen(config->password) + + strlen(config->server_name) + + strlen(config->library) + + strlen(config->language))*2; + } else { + size1 = 86 + (strlen(config->host_name) + + strlen(config->app_name) + + strlen(config->server_name) + + strlen(config->library) + + strlen(config->language))*2; + } + packet_size = size1 + 48; + tds_put_smallint(tds,packet_size); + tds_put_n(tds,NULL,5); + if (IS_TDS80(tds)) { + tds_put_byte(tds,0x70); + } else { + tds_put_byte(tds,0x80); + } + tds_put_n(tds,NULL,7); + tds_put_n(tds,magic1,21); + + current_pos = 86; /* ? */ + /* host name */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->host_name)); + current_pos += strlen(config->host_name)*2; + if (!domain_login) { + /* username */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->user_name)); + current_pos += strlen(config->user_name)*2; + /* password */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->password)); + current_pos += strlen(config->password)*2; + } else { + tds_put_smallint(tds,0); + tds_put_smallint(tds,0); + tds_put_smallint(tds,0); + tds_put_smallint(tds,0); + } + /* app name */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->app_name)); + current_pos += strlen(config->app_name)*2; + /* server name */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->server_name)); + current_pos += strlen(config->server_name)*2; + /* unknown */ + tds_put_smallint(tds,0); + tds_put_smallint(tds,0); + /* library name */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->library)); + current_pos += strlen(config->library)*2; + /* language - kostya@warmcat.excom.spb.su */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,strlen(config->language)); + current_pos += strlen(config->language)*2; + /* database name */ + tds_put_smallint(tds,current_pos); + tds_put_smallint(tds,0); + + tds_put_n(tds,magic2,6); + tds_put_smallint(tds, size1); + tds_put_smallint(tds, 0x30); /* this matches numbers at end of packet */ + tds_put_smallint(tds, packet_size); + tds_put_smallint(tds, 0); + + tds7_ascii2unicode(config->host_name, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->host_name)*2); + if (!domain_login) { + tds7_ascii2unicode(config->user_name, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->user_name)*2); + tds7_ascii2unicode(config->password, unicode_string, 255); + tds7_crypt_pass(unicode_string, strlen(config->password)*2, unicode_string); + tds_put_n(tds,unicode_string,strlen(config->password)*2); + } + tds7_ascii2unicode(config->app_name, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->app_name)*2); + tds7_ascii2unicode(config->server_name, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->server_name)*2); + tds7_ascii2unicode(config->library, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->library)*2); + tds7_ascii2unicode(config->language, unicode_string, 255); + tds_put_n(tds,unicode_string,strlen(config->language)*2); + + /* from here to the end of the packet is totally unknown */ + tds_put_n(tds,magic3,7); + /* next two bytes -- possibly version number (NTLMSSP v1) */ + tds_put_byte(tds,0); + tds_put_byte(tds,1); + tds_put_n(tds,NULL,3); + tds_put_byte(tds,6); + tds_put_byte(tds,130); + tds_put_n(tds,NULL,22); + tds_put_byte(tds,48); + tds_put_n(tds,NULL,7); + tds_put_byte(tds,48); + tds_put_n(tds,NULL,3); + + rc|=tds_flush_packet(tds); + + return 0; +} + +/* +** tds7_unicode2ascii() +** Note: The dest buf must be large enough to handle 'len' + 1 bytes. +*/ +char *tds7_unicode2ascii(const char *in_string, char *out_string, int len) +{ +int i; + + for (i=0;i> 4; + hi_nibble = (clear_pass[i] ^ xormask) << 4; + crypt_pass[i] = hi_nibble | lo_nibble; + } + return crypt_pass; +} diff --git a/src/tds/mem.c b/src/tds/mem.c new file mode 100644 index 000000000..bfd3b79f1 --- /dev/null +++ b/src/tds/mem.c @@ -0,0 +1,383 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" + +static char software_version[] = "$Id: mem.c,v 1.1 2001-10-12 23:28:58 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +TDSENVINFO *tds_alloc_env(TDSSOCKET *tds); +void tds_free_env(TDSSOCKET *tds); + +TDSDYNAMIC *tds_alloc_dynamic(TDSSOCKET *tds, char *id) +{ +int i; + + /* if this is the first dynamic stmt */ + if (!tds->num_dyns) { + tds->dyns = (TDSDYNAMIC **) malloc(sizeof(TDSDYNAMIC *)); + tds->dyns[0] = (TDSDYNAMIC *) malloc(sizeof(TDSDYNAMIC)); + memset(tds->dyns[0], 0, sizeof(TDSDYNAMIC)); + strncpy(tds->dyns[0]->id, id, TDS_MAX_DYNID_LEN); + tds->dyns[0]->id[TDS_MAX_DYNID_LEN-1]='\0'; + tds->num_dyns++; + return tds->dyns[0]; + } + /* otherwise check to see if id already exists (shouldn't) */ + for (i=0;inum_dyns;i++) { + if (!strcmp(tds->dyns[i]->id, id)) { + /* id already exists! just return it */ + return(tds->dyns[i]); + } + } + + /* ok, we have a list and need to add another */ + tds->dyns = (TDSDYNAMIC **) + realloc(tds->dyns, sizeof(TDSDYNAMIC *) * tds->num_dyns); + tds->dyns[tds->num_dyns] = (TDSDYNAMIC *) malloc(sizeof(TDSDYNAMIC)); + memset(tds->dyns[tds->num_dyns], 0, sizeof(TDSDYNAMIC)); + strncpy(tds->dyns[tds->num_dyns]->id, id, TDS_MAX_DYNID_LEN); + tds->dyns[tds->num_dyns]->id[TDS_MAX_DYNID_LEN-1]='\0'; + tds->num_dyns++; + + return tds->dyns[tds->num_dyns-1]; +} + +void tds_free_dynamic(TDSSOCKET *tds) +{ +int i; + + for (i=0;inum_dyns;i++) { + free(tds->dyns[i]); + } + free(tds->dyns); + tds->dyns = NULL; + tds->num_dyns = 0; + + return; +} + +/* +** tds_alloc_param_result() works a bit differently than the other alloc result +** functions. Output parameters come in individually with no total number +** given in advance, so we simply call this func every time with get a +** TDS_PARAM_TOKEN and let it realloc the columns struct one bigger. +** tds_free_all_results() usually cleans up after us. +*/ +TDSPARAMINFO *tds_alloc_param_result(TDSPARAMINFO *old_param) +{ +TDSPARAMINFO *param_info; + + if (!old_param) { + param_info = (TDSPARAMINFO *) malloc(sizeof(TDSPARAMINFO)); + memset(param_info,'\0',sizeof(TDSPARAMINFO)); + param_info->num_cols=1; + param_info->columns = (TDSCOLINFO **) + malloc(sizeof(TDSCOLINFO *)); + memset(param_info->columns[0],'\0',sizeof(TDSCOLINFO)); + } else { + param_info = old_param; + param_info->num_cols++; + param_info->columns = (TDSCOLINFO **) + realloc(param_info->columns, + sizeof(TDSCOLINFO *) * param_info->num_cols); + memset(param_info->columns[param_info->num_cols-1],'\0', + sizeof(TDSCOLINFO)); + } + return param_info; +} +TDSCOMPUTEINFO *tds_alloc_compute_results(int num_cols) +{ +/*TDSCOLINFO *curcol; + */ +TDSCOMPUTEINFO *comp_info; +int col; + + comp_info = (TDSCOMPUTEINFO *) malloc(sizeof(TDSCOMPUTEINFO)); + memset(comp_info,'\0',sizeof(TDSCOMPUTEINFO)); + comp_info->columns = (TDSCOLINFO **) + malloc(sizeof(TDSCOLINFO *) * num_cols); + for (col=0;colcolumns[col] = (TDSCOLINFO *) malloc(sizeof(TDSCOLINFO)); + memset(comp_info->columns[col],'\0',sizeof(TDSCOLINFO)); + } + comp_info->num_cols = num_cols; + return comp_info; +} + +TDSRESULTINFO *tds_alloc_results(int num_cols) +{ +/*TDSCOLINFO *curcol; + */ +TDSRESULTINFO *res_info; +int col; +int null_sz; + + res_info = (TDSRESULTINFO *) malloc(sizeof(TDSRESULTINFO)); + memset(res_info,'\0',sizeof(TDSRESULTINFO)); + res_info->columns = (TDSCOLINFO **) + malloc(sizeof(TDSCOLINFO *) * num_cols); + for (col=0;colcolumns[col] = (TDSCOLINFO *) malloc(sizeof(TDSCOLINFO)); + memset(res_info->columns[col],'\0',sizeof(TDSCOLINFO)); + } + res_info->num_cols = num_cols; + null_sz = (num_cols/8) + 1; + /* 4 byte alignment fix -- should be ifdef'ed to only platforms that + ** need it */ + if (null_sz % 4) null_sz = ((null_sz/4)+1)*4; + res_info->null_info_size = null_sz; + /* set the initial row size to the size of the null info */ + res_info->row_size = res_info->null_info_size; + return res_info; +} + +void *tds_alloc_row(TDSRESULTINFO *res_info) +{ +void *ptr; + + ptr = (void *) malloc(res_info->row_size); + memset(ptr,'\0',res_info->row_size); + return ptr; +} + +void tds_free_param_results(TDSPARAMINFO *param_info) +{ +int i; + + if(param_info) + { + for (i=0;inum_cols;i++) + { + if(param_info->columns[i]) + TDS_ZERO_FREE(param_info->columns[i]); + } + if (param_info->num_cols) TDS_ZERO_FREE(param_info->columns); + if (param_info->current_row) TDS_ZERO_FREE(param_info->current_row); + TDS_ZERO_FREE(param_info); + } +} +void tds_free_compute_results(TDSCOMPUTEINFO *comp_info) +{ +int i; + + if(comp_info) + { + for (i=0;inum_cols;i++) + { + if(comp_info->columns[i]) + TDS_ZERO_FREE(comp_info->columns[i]); + } + if (comp_info->num_cols) TDS_ZERO_FREE(comp_info->columns); + if (comp_info->current_row) TDS_ZERO_FREE(comp_info->current_row); + TDS_ZERO_FREE(comp_info); + } +} + +void tds_free_results(TDSRESULTINFO *res_info) +{ +int i; + + + if(res_info) + { + if (res_info->current_row) TDS_ZERO_FREE(res_info->current_row); + for (i=0;inum_cols;i++) + { + if(res_info->columns[i]) + tds_free_column(res_info->columns[i]); + } + if (res_info->num_cols) TDS_ZERO_FREE(res_info->columns); + TDS_ZERO_FREE(res_info); + } + +} +void tds_free_all_results(TDSSOCKET *tds) +{ + tds_free_results(tds->res_info); + tds->res_info = NULL; + tds_free_param_results(tds->param_info); + tds->param_info = NULL; + tds_free_compute_results(tds->comp_info); + tds->comp_info = NULL; +} +void tds_free_column(TDSCOLINFO *column) +{ + if (column->column_textvalue) TDS_ZERO_FREE(column->column_textvalue); + TDS_ZERO_FREE(column); +} +TDSCONFIGINFO *tds_alloc_config() +{ +TDSCONFIGINFO *config; + + config = (TDSCONFIGINFO *) malloc(sizeof(TDSCONFIGINFO)); + memset(config, '\0', sizeof(TDSCONFIGINFO)); + + /* fill in all hardcoded defaults */ + config->server_name = strdup(TDS_DEF_SERVER); + config->major_version = TDS_DEF_MAJOR; + config->minor_version = TDS_DEF_MINOR; + config->port = TDS_DEF_PORT; + config->block_size = TDS_DEF_BLKSZ; + config->language = strdup(TDS_DEF_LANG); + config->char_set = strdup(TDS_DEF_CHARSET); + config->try_server_login = 1; + + return config; +} +TDSLOGIN *tds_alloc_login() +{ +TDSLOGIN *tds_login; +unsigned char defaultcaps[] = {0x01,0x07,0x03,109,127,0xFF,0xFF,0xFF,0xFE,0x02,0x07,0x00,0x00,0x0A,104,0x00,0x00,0x00}; +char *tdsver; + + tds_login = (TDSLOGIN *) malloc(sizeof(TDSLOGIN)); + memset(tds_login, '\0', sizeof(TDSLOGIN)); + if (tdsver=getenv("TDSVER")) { + if (!strcmp(tdsver,"42")) { + tds_login->major_version=4; + tds_login->minor_version=2; + } else if (!strcmp(tdsver,"46")) { + tds_login->major_version=4; + tds_login->minor_version=6; + } else if (!strcmp(tdsver,"50")) { + tds_login->major_version=5; + tds_login->minor_version=0; + } else if (!strcmp(tdsver,"70")) { + tds_login->major_version=7; + tds_login->minor_version=0; + } else if (!strcmp(tdsver,"80")) { + tds_login->major_version=8; + tds_login->minor_version=0; + } + /* else unrecognized...use compile time default above */ + } + memcpy(tds_login->capabilities,defaultcaps,TDS_MAX_CAPABILITY); + return tds_login; +} +void tds_free_login(TDSLOGIN *login) +{ + if (login) free(login); +} +TDSSOCKET *tds_alloc_socket(int bufsize) +{ +TDSSOCKET *tds_socket; + + tds_socket = (TDSSOCKET *) malloc(sizeof(TDSSOCKET)); + memset(tds_socket, '\0', sizeof(TDSSOCKET)); + tds_socket->in_buf_max=0; + tds_socket->out_buf = (unsigned char *) malloc(bufsize); + tds_socket->msg_info = (TDSMSGINFO *) malloc(sizeof(TDSMSGINFO)); + memset(tds_socket->msg_info,'\0',sizeof(TDSMSGINFO)); + tds_socket->parent = (char*)NULL; + tds_socket->env = tds_alloc_env(tds_socket); + /* Jeff's hack, init to no timeout */ + tds_socket->timeout = 0; + tds_init_write_buf(tds_socket); + return tds_socket; +} +TDSSOCKET *tds_realloc_socket(int bufsize) +{ + return NULL; /* XXX */ +} +void tds_free_socket(TDSSOCKET *tds) +{ + if (tds) { + tds_free_all_results(tds); + tds_free_env(tds); + tds_free_dynamic(tds); + if (tds->msg_info) TDS_ZERO_FREE(tds->msg_info); + if (tds->in_buf) TDS_ZERO_FREE(tds->in_buf); + if (tds->out_buf) TDS_ZERO_FREE(tds->out_buf); + if (tds->s) close(tds->s); + TDS_ZERO_FREE(tds); + } +} +void tds_free_config(TDSCONFIGINFO *config) +{ + if (config->server_name) free(config->server_name); + if (config->host_name) free(config->host_name); + if (config->ip_addr) free(config->ip_addr); + if (config->language) free(config->language); + if (config->char_set) free(config->char_set); + if (config->database) free(config->database); + if (config->dump_file) free(config->dump_file); + if (config->default_domain) free(config->default_domain); + TDS_ZERO_FREE(config); +} +TDSENVINFO *tds_alloc_env(TDSSOCKET *tds) +{ +TDSENVINFO *env; + + env = (TDSENVINFO *) malloc(sizeof(TDSENVINFO)); + memset(env,'\0',sizeof(TDSENVINFO)); + env->block_size = 512; + + return env; +} +void tds_free_env(TDSSOCKET *tds) +{ + if (tds->env) { + if (tds->env->language) + TDS_ZERO_FREE(tds->env->language); + if (tds->env->charset) + TDS_ZERO_FREE(tds->env->charset); + if (tds->env->database) + TDS_ZERO_FREE(tds->env->database); + TDS_ZERO_FREE(tds->env); + } +} +void tds_free_msg(TDSMSGINFO *msg_info) +{ + if (msg_info) { + if(msg_info->message) TDS_ZERO_FREE(msg_info->message); + if(msg_info->server) TDS_ZERO_FREE(msg_info->server); + if(msg_info->proc_name) TDS_ZERO_FREE(msg_info->proc_name); + if(msg_info->sql_state) TDS_ZERO_FREE(msg_info->sql_state); + } +} +int tds_add_connection(TDSCONTEXT *ctx, TDSSOCKET *tds) +{ +int i = 0; + + while (iconnection_list[i]) i++; + if (i==TDS_MAX_CONN) { + fprintf(stderr,"Max connections reached, increase value of TDS_MAX_CONN\n"); + return 1; + } else { + ctx->connection_list[i] = tds; + return 0; + } + +} +void tds_del_connection(TDSCONTEXT *ctx, TDSSOCKET *tds) +{ +int i=0; + + while (iconnection_list[i]!=tds) i++; + if (i==TDS_MAX_CONN) { + /* connection wasn't on the free list...now what */ + } else { + /* remove it */ + ctx->connection_list[i] = NULL; + } +} diff --git a/src/tds/numeric.c b/src/tds/numeric.c new file mode 100644 index 000000000..e230b21f4 --- /dev/null +++ b/src/tds/numeric.c @@ -0,0 +1,193 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +/* +** these routines use arrays of unsigned char to handle arbitrary +** precision numbers. All-in-all it's probably pretty slow, but it +** does work. I just heard of a GNU lib for arb. precision math, so +** that might be an option in the future. +*/ + +static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier); +static int do_carry(unsigned char *product); +static char *array_to_string(unsigned char *array, int scale, char *s); + +/* +** The following little table is indexed by precision-1 and will +** tell us the number of bytes required to store the specified +** precision (with the sign). +*/ +int g__numeric_bytes_per_prec[] = +{ + -1, 2, 2, 3, 3, 4, 4, 4, 5, 5, + 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, + 10, 10, 11, 11, 11, 12, 12, 13, 13, 14, + 14, 14, 15, 15, 16, 16, 16, 17, 17, 18, + 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, + 22, 23, 23, 24, 24, 24, 25, 25, 26, 26, + 26, 27, 27, 28, 28, 28, 29, 29, 30, 30, + 31, 31, 31, 32, 32, 33, 33, 33 +}; + + + +/* +** money is a special case of numeric really...that why its here +*/ +char *tds_money_to_string(TDS_MONEY *money, char *s) +{ +unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION]; +unsigned char product[MAXPRECISION]; +unsigned char *number; +#ifndef WORDS_BIGENDIAN +unsigned char reorder[8]; +#endif +int num_bytes = 8; +int i; +int pos; +int neg=0; + + memset(multiplier,0,MAXPRECISION); + memset(product,0,MAXPRECISION); + multiplier[0]=1; + +#ifdef WORDS_BIGENDIAN + /* big endian makes things easy */ + number = (unsigned char *) money; +#else + /* money is two 32 bit ints and thus is out of order on + ** little endian machines. Proof of the superiority of + ** big endian design. ;) + */ + number = (unsigned char *) money; + for (i=0;i<4;i++) + reorder[3-i] = number[i]; + for (i=4;i<8;i++) + reorder[7-i+4] = number[i]; + number = reorder; +#endif + + if (number[0] && 0x80) { + /* negative number -- preform two's complement */ + neg = 1; + for (i=0;i<8;i++) { + number[i] = ~number[i]; + } + for (i=7; i>=0; i--) { + number[i] += 1; + if (number[i]!=0) break; + } + } + for (pos=num_bytes-1;pos>=0;pos--) { + multiply_byte(product, number[pos], multiplier); + + memcpy(temp, multiplier, MAXPRECISION); + memset(multiplier,0,MAXPRECISION); + multiply_byte(multiplier, 256, temp); + } + if (neg) { + s[0]='-'; + array_to_string(product, 4, &s[1]); + } else { + array_to_string(product, 4, s); + } + return s; +} +char *tds_numeric_to_string(TDS_NUMERIC *numeric, char *s) +{ +unsigned char multiplier[MAXPRECISION], temp[MAXPRECISION]; +unsigned char product[MAXPRECISION]; +unsigned char *number; +int num_bytes; +int pos; + + memset(multiplier,0,MAXPRECISION); + memset(product,0,MAXPRECISION); + multiplier[0]=1; + number = numeric->array; + num_bytes = g__numeric_bytes_per_prec[numeric->precision]; + + if (numeric->array[0] == 1) + *s++ = '-'; + + for (pos=num_bytes-1;pos>0;pos--) { + multiply_byte(product, number[pos], multiplier); + + memcpy(temp, multiplier, MAXPRECISION); + memset(multiplier,0,MAXPRECISION); + multiply_byte(multiplier, 256, temp); + } + array_to_string(product, numeric->scale, s); + return s; +} +static int multiply_byte(unsigned char *product, int num, unsigned char *multiplier) +{ +unsigned char number[3]; +int i, top, j, start; + + number[0]=num%10; + number[1]=(num/10)%10; + number[2]=(num/100)%10; + + for (top=MAXPRECISION-1;top>=0 && !multiplier[top];top--); + start=0; + for (i=0;i<=top;i++) { + for (j=0;j<3;j++) { + product[j+start]+=multiplier[i]*number[j]; + } + do_carry(product); + start++; + } + return 0; +} +static int do_carry(unsigned char *product) +{ +int j; + + for (j=0;j9) { + product[j+1]+=product[j]/10; + product[j]=product[j]%10; + } + } + return 0; +} +static char *array_to_string(unsigned char *array, int scale, char *s) +{ +int top, i, j; + + for (top=MAXPRECISION-1;top>=0 && top>scale && !array[top];top--); + + if (top == -1) + { + s[0] = '0'; + s[1] = '\0'; + return s; + } + + j=0; + for (i=top;i>=0;i--) { + if (top+1-j == scale) s[j++]='.'; + s[j++]=array[i]+'0'; + } + s[j]='\0'; +} diff --git a/src/tds/query.c b/src/tds/query.c new file mode 100644 index 000000000..5bf2f37ec --- /dev/null +++ b/src/tds/query.c @@ -0,0 +1,151 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" + +static char software_version[] = "$Id: query.c,v 1.1 2001-10-12 23:29:02 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +/* All manner of client to server submittal functions */ + +/* +** tds_submit_query() sends a language string to the database server for +** processing. TDS 4.2 is a plain text message with a packet type of 0x01, +** TDS 7.0 is a unicode string with packet type 0x01, and TDS 5.0 uses a +** TDS_LANG_TOKEN to encapsulate the query and a packet type of 0x0f. +*/ +int tds_submit_query(TDSSOCKET *tds, char *query) +{ +unsigned char *buf; +int bufsize; +TDS_INT bufsize2; + + if (!query) return TDS_FAIL; + + /* Jeff's hack to handle long query timeouts */ + tds->queryStarttime = time(NULL); + + if (tds->state==TDS_PENDING) { + /* FIX ME -- get real message number et al. + ** if memory serves the servername is + ** OpenClient for locally generated messages, + ** but this needs to be verified too. + */ + tds_client_msg(tds,10000,7,0,1, + "Attempt to initiate a new SQL Server operation with results pending."); + return TDS_FAIL; + } + + tds_free_all_results(tds); + + tds->rows_affected = 0; + tds->state = TDS_QUERYING; + if (IS_TDS50(tds)) { + bufsize = strlen(query)+6; + buf = (unsigned char *) malloc(bufsize); + memset(buf,'\0',bufsize); + buf[0]=TDS_LANG_TOKEN; + + bufsize2 = strlen(query) + 1; + memcpy(buf+1, (void *)&bufsize2, 4); + + memcpy(&buf[6],query,strlen(query)); + tds->out_flag=0x0F; + } else if (IS_TDS70(tds)) { + bufsize = strlen(query)*2; + buf = (unsigned char *) malloc(bufsize); + memset(buf,'\0',bufsize); + tds7_ascii2unicode(query, buf, bufsize); + tds->out_flag=0x01; + } else { /* 4.2 */ + bufsize = strlen(query); + buf = (unsigned char *) malloc(bufsize); + memset(buf,'\0',bufsize); + memcpy(&buf[0],query,strlen(query)); + tds->out_flag=0x01; + } + tds_put_n(tds, buf, bufsize); + tds_flush_packet(tds); + + free(buf); + + return TDS_SUCCEED; +} +/* +** tds_submit_prepare() creates a temporary stored procedure in the server. +** Currently works only with TDS 5.0 +*/ +int tds_submit_prepare(TDSSOCKET *tds, char *query, char *id) +{ +int id_len, query_len; + + if (!query || !id) return TDS_FAIL; + + if (!IS_TDS50(tds)) { + tds_client_msg(tds,10000,7,0,1, + "Dynamic placeholders only supported under TDS 5.0"); + return TDS_FAIL; + } + if (tds->state==TDS_PENDING) { + tds_client_msg(tds,10000,7,0,1, + "Attempt to initiate a new SQL Server operation with results pending."); + return TDS_FAIL; + } + tds_free_all_results(tds); + + /* allocate a structure for this thing */ + tds_alloc_dynamic(tds, id); + + tds->rows_affected = 0; + tds->state = TDS_QUERYING; + id_len = strlen(id); + query_len = strlen(query); + + tds_put_byte(tds,0xe7); + tds_put_smallint(tds,query_len + id_len*2 + 21); + tds_put_byte(tds,0x01); + tds_put_byte(tds,0x00); + tds_put_byte(tds,id_len); + tds_put_n(tds, id, id_len); + tds_put_smallint(tds,query_len + id_len + 16); + tds_put_n(tds, "create proc ", 12); + tds_put_n(tds, id, id_len); + tds_put_n(tds, " as ", 4); + tds_put_n(tds, query, query_len); + + tds->out_flag=0x0F; + tds_flush_packet(tds); + + return TDS_SUCCEED; +} + +/* +** tds_send_cancel() sends an empty packet (8 byte header only) +** tds_process_cancel should be called directly after this. +*/ +int tds_send_cancel(TDSSOCKET *tds) +{ + tds->out_flag=0x06; + tds_flush_packet(tds); + + return 0; +} + diff --git a/src/tds/read.c b/src/tds/read.c new file mode 100644 index 000000000..e4bdebbdd --- /dev/null +++ b/src/tds/read.c @@ -0,0 +1,365 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" + +#ifdef WIN32 +#define CLOSE(a) closesocket(a) +#define READ(a,b,c) recv (a, b, c, 0L); +#else +#define CLOSE(a) close(a) +#define READ(a,b,c) read (a, b, c); +#endif + +#include "tdsutil.h" + + +static char software_version[] = "$Id: read.c,v 1.1 2001-10-12 23:29:01 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +/* Loops until we have received buflen characters */ +int goodread (TDSSOCKET *tds, char * buf, int buflen) +{ +int got = 0; +int len, retcode; +fd_set fds; +time_t start, now; +struct timeval selecttimeout; + + if (tds->timeout) { + start = time(NULL); + now = time(NULL); + + while ((buflen > 0) && ((now-start) < tds->timeout)) { + len = 0; + retcode = 0; + + FD_ZERO (&fds); + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + + now = time(NULL); + + FD_SET (tds->s, &fds); + retcode = select (tds->s + 1, &fds, NULL, NULL, &selecttimeout); + + while ((retcode == 0) && ((now-start) < tds->timeout)) { + tds_msleep(1); + + FD_SET (tds->s, &fds); + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + retcode = select (tds->s + 1, &fds, NULL, NULL, &selecttimeout); + + now = time (NULL); + } + len = READ(tds->s, buf+got, buflen); + + if (len < 0) { + return (-1); /* SOCKET_ERROR); */ + } + + buflen -= len; + got += len; + now = time (NULL); + + if (tds->queryStarttime && tds->longquery_timeout) { + if ((now-(tds->queryStarttime)) >= tds->longquery_timeout) { + (*tds->longquery_func)(tds->longquery_param); + } + } + } /* while buflen... */ + } else { + /* got = READ(tds->s, buf, buflen); */ + while (got < buflen) { + got += READ(tds->s, buf + got, buflen - got); + } + + } + + return (got); +} + +/* +** Return a single byte from the input buffer +*/ +unsigned char tds_get_byte(TDSSOCKET *tds) +{ + if (tds->in_pos >= tds->in_len) { + if(!tds->s || !tds_read_packet(tds)) + return (0); + } + return tds->in_buf[tds->in_pos++]; +} +/* +** Unget will always work as long as you don't call it twice in a row. It +** it may work if you call it multiple times as long as you don't backup +** over the beginning of network packet boundary which can occur anywhere in +** the token stream. +*/ +void tds_unget_byte(TDSSOCKET *tds) +{ + /* this is a one trick pony...don't call it twice */ + tds->in_pos--; +} + +unsigned char tds_peek(TDSSOCKET *tds) +{ + unsigned char result = tds_get_byte(tds); + tds_unget_byte(tds); + return result; +} /* tds_peek() */ + + +/* +** Get an int16 from the server. +*/ +TDS_SMALLINT tds_get_smallint(TDSSOCKET *tds) +{ +unsigned char bytes[2]; + + tds_get_n(tds, bytes, 2); +#if WORDS_BIGENDIAN + if (tds->emul_little_endian) { + return TDS_BYTE_SWAP16(*(TDS_SMALLINT *)bytes); + } +#endif + return *(TDS_SMALLINT *)bytes; +} + + +/* +** Get an int32 from the server. +*/ +TDS_INT tds_get_int(TDSSOCKET *tds) +{ +unsigned char bytes[4]; + + tds_get_n(tds, bytes, 4); +#if WORDS_BIGENDIAN + if (tds->emul_little_endian) { + return TDS_BYTE_SWAP32(*(TDS_INT *)bytes); + } +#endif + return *(TDS_INT *)bytes; +} + + +char *tds_get_string(TDSSOCKET *tds, void *dest, int need) +{ +char *temp; + + /* + ** FIX: 02-Jun-2000 by Scott C. Gray (SCG) + ** + ** Bug to malloc(0) on some platforms. + */ + if (need == 0) { + return dest; + } + + if (IS_TDS70(tds) || IS_TDS80(tds)) { + if (dest==NULL) { + tds_get_n(tds,NULL,need*2); + return(NULL); + } + temp = (char *) malloc(need*2); + tds_get_n(tds,temp,need*2); + tds7_unicode2ascii(temp,dest,need); + free(temp); + return(dest); + + } else { + return tds_get_n(tds,dest,need); + } +} +/* +** Get N bytes from the buffer and return them in the already allocated space +** given to us. We ASSUME that the person calling this function has done the +** bounds checking for us since they know how many bytes they want here. +** dest of NULL means we just want to eat the bytes. (tetherow@nol.org) +*/ +char *tds_get_n(TDSSOCKET *tds, void *dest, int need) +{ +int pos,have; + + pos = 0; + + have=(tds->in_len-tds->in_pos); + while (need>have) { + /* We need more than is in the buffer, copy what is there */ + if (dest!=NULL) { + memcpy((char*)dest+pos, tds->in_buf+tds->in_pos, have); + } + pos+=have; + need-=have; + tds_read_packet(tds); + have=tds->in_len; + } + if (need>0) { + /* get the remainder if there is any */ + if (dest!=NULL) { + memcpy((char*)dest+pos, tds->in_buf+tds->in_pos, need); + } + tds->in_pos+=need; + } + return dest; +} +/* +** Return the number of bytes needed by specified type. +*/ +int get_size_by_type(int servertype) +{ + switch(servertype) + { + case SYBINT1: return 1; break; + case SYBINT2: return 2; break; + case SYBINT4: return 4; break; + case SYBINT8: return 8; break; + case SYBREAL: return 4; break; + case SYBFLT8: return 8; break; + case SYBDATETIME: return 8; break; + case SYBDATETIME4: return 4; break; + case SYBBIT: return 1; break; + case SYBBITN: return 1; break; + case SYBMONEY: return 8; break; + case SYBMONEY4: return 4; break; + case SYBUNIQUE: return 16; break; + default: return -1; break; + } +} +/* +** Read in one 'packet' from the server. This is a wrapped outer packet of +** the protocol (they bundle resulte packets into chunks and wrap them at +** what appears to be 512 bytes regardless of how that breaks internal packet +** up. (tetherow@nol.org) +*/ +int tds_read_packet (TDSSOCKET *tds) +{ +unsigned char header[8]; +int len; +int x, have, need; + + + /* Read in the packet header. We use this to figure out our packet + ** length */ + + if ((len = goodread(tds, header, 8)) < 8 ) { + /* GW ADDED */ + if (len<0) { + /* FIX ME -- get the exact err num and text */ + tds_client_msg(tds,10018, 9, 0, 0, "The connection was closed"); + CLOSE(tds->s); + tds->s=0; + tds->in_len=0; + tds->in_pos=0; + return 0; + } + /* GW ADDED */ + /* Not sure if this is the best way to do the error + ** handling here but this is the way it is currently + ** being done. */ + tds->in_len=0; + tds->in_pos=0; + tds->last_packet=1; + if (len==0) { + CLOSE(tds->s); + tds->s=0; + } + return 0; + } + +/* Note: +** this was done by Gregg, I don't think its the real solution (it breaks +** under 5.0, but I haven't gotten a result big enough to test this yet. +*/ + if (IS_TDS42(tds)) { + if (header[0]!=0x04) { + fprintf(stderr, "Invalid packet header %d\n", header[0]); + /* Not sure if this is the best way to do the error + ** handling here but this is the way it is currently + ** being done. */ + tds->in_len=0; + tds->in_pos=0; + tds->last_packet=1; + return(0); + } + } + + /* Convert our packet length from network to host byte order */ + /* Only safe as long as local short length is 2 bytes */ + len = ntohs(*(short*)&header[2])-8; + need=len; + + /* If this packet size is the largest we have gotten allocate + ** space for it */ + if (len > tds->in_buf_max) { + if (! tds->in_buf) { + tds->in_buf = (unsigned char*)malloc(len); + } else { + tds->in_buf = (unsigned char*)realloc(tds->in_buf, len); + } + /* Set the new maximum packet size */ + tds->in_buf_max = len; + } + + /* Clean out the in_buf so we don't use old stuff by mistake */ + memset(tds->in_buf, 0, tds->in_buf_max); + + /* Now get exactly how many bytes the server told us to get */ + have=0; + while(need>0) { + if ((x=goodread(tds, tds->in_buf+have, need))<1) { + /* Not sure if this is the best way to do the error + ** handling here but this is the way it is currently + ** being done. */ + tds->in_len=0; + tds->in_pos=0; + tds->last_packet=1; + if (len==0) { + CLOSE(tds->s); + tds->s=0; + } + return(0); + } + have+=x; + need-=x; + } + if (x < 1 ) { + /* Not sure if this is the best way to do the error handling + ** here but this is the way it is currently being done. */ + tds->in_len=0; + tds->in_pos=0; + tds->last_packet=1; + return(0); + } + + /* Set the last packet flag */ + if (header[1]) { tds->last_packet = 1; } + else { tds->last_packet = 0; } + + /* Set the length and pos (not sure what pos is used for now */ + tds->in_len = have; + tds->in_pos = 0; + tdsdump_log(TDS_DBG_NETWORK, "Received packet @ %L\n%D\n", tds->in_buf, tds->in_len); + + return (tds->in_len); +} diff --git a/src/tds/token.c b/src/tds/token.c new file mode 100644 index 000000000..5d388991e --- /dev/null +++ b/src/tds/token.c @@ -0,0 +1,1528 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" + +static char software_version[] = "$Id: token.c,v 1.1 2001-10-12 23:28:59 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +/* +** All these functions process the input from the wire so it +** may be used by the upper level functions. +*/ + +int (*g_tds_msg_handler)() = NULL; +int (*g_tds_err_handler)() = NULL; + + +static int tds_process_msg(TDSSOCKET *tds,int marker); +static int tds_process_compute_result(TDSSOCKET *tds); +static int tds_process_result(TDSSOCKET *tds); +static int tds_process_col_name(TDSSOCKET *tds); +static int tds_process_col_info(TDSSOCKET *tds); +static int tds_process_compute(TDSSOCKET *tds); +static int tds_process_row(TDSSOCKET *tds); +static int tds_process_param_result(TDSSOCKET *tds); +static int tds7_process_result(TDSSOCKET *tds); +static int tds_process_param_result_tokens(TDSSOCKET *tds); +static int tds_process_dyn_result(TDSSOCKET *tds); +int tds_swap_datatype(int coltype, unsigned char *buf); + +/* +** The following little table is indexed by precision and will +** tell us the number of bytes required to store the specified +** precision. +*/ +extern int g__numeric_bytes_per_prec[]; + + +/* +** tds_process_default_tokens() is a catch all function that is called to +** process tokens not known to other tds_process_* routines +*/ +int tds_process_default_tokens(TDSSOCKET *tds, int marker) +{ +int order_len; +int tok_size; +int more_results; +int cancelled; + + tdsdump_log(TDS_DBG_FUNC, "%L inside tds_process_default_tokens() marker is %x\n", marker); + + if (!tds->s) { + tdsdump_log(TDS_DBG_FUNC, "%L leaving tds_process_default_tokens() connection dead\n"); + tds->state=TDS_DEAD; + return TDS_FAIL; + } + + switch(marker) { + case TDS_ENV_CHG_TOKEN: + { + tds_process_env_chg(tds); + break; + } + case TDS_DONE_TOKEN: + case TDS_DONEPROC_TOKEN: + case TDS_DONEINPROC_TOKEN: + { + tds_process_end(tds, marker, &more_results, &cancelled); + if (!more_results) tds->state=TDS_COMPLETED; + break; + } + case TDS_124_TOKEN: + tds_get_n(tds,NULL,8); + break; + case TDS_RET_STAT_TOKEN: + tds->has_status=1; + tds->ret_status=tds_get_int(tds); + break; + case TDS_ERR_TOKEN: + case TDS_MSG_TOKEN: + case TDS_EED_TOKEN: + return tds_process_msg(tds,marker); + break; + case TDS_CAP_TOKEN: + tok_size = tds_get_smallint(tds); + tds_get_n(tds,tds->capabilities,tok_size > TDS_MAX_CAPABILITY ? TDS_MAX_CAPABILITY : tok_size); + break; + case TDS_LOGIN_ACK_TOKEN: + tds_get_n(tds,NULL,tds_get_smallint(tds)); + break; + case TDS_ORDER_BY_TOKEN: + order_len = tds_get_smallint(tds); + tds_get_n(tds, NULL, order_len); + /* get the next token which is ROW_TOKEN (209) + tds_get_byte(tds); + if(orderLen > 1) + tds_process_column_row(tds); */ + break; + case TDS_168_TOKEN: + tds_process_compute_result(tds); + break; + case TDS_PARAM_TOKEN: + tds_unget_byte(tds); + tds_process_param_result_tokens(tds); + break; + /* 167 is somehow related to compute columns */ + case TDS_167_TOKEN: + case TDS_174_TOKEN: + tds_get_n(tds, NULL, tds_get_smallint(tds)); + break; + case TDS7_RESULT_TOKEN: + tds7_process_result(tds); + break; + case TDS_RESULT_TOKEN: + tds_process_result(tds); + break; + case TDS_COL_NAME_TOKEN: + tds_process_col_name(tds); + break; + case TDS_COL_INFO_TOKEN: + tds_process_col_info(tds); + break; + case TDS_CMP_ROW_TOKEN: + tds_process_compute(tds); + break; + case TDS_ROW_TOKEN: + tds_process_row(tds); + break; + case TDS5_DYN_TOKEN: + case TDS5_DYNRES_TOKEN: + case TDS5_DYN3_TOKEN: + fprintf(stderr, "eating token %d\n",marker); + tds_get_n(tds, NULL, tds_get_smallint(tds)); + break; + default: + fprintf(stderr,"Unknown marker: %d!!\n",marker); + return TDS_FAIL; + } + return TDS_SUCCEED; +} + +/* +** tds_process_login_tokens() is called after sending the login packet +** to the server. It returns the success or failure of the login +** dependent on the protocol version. 4.2 sends an ACK token only when +** successful, TDS 5.0 sends it always with a success byte within +*/ +int tds_process_login_tokens(TDSSOCKET *tds) +{ +int succeed=0; +int marker; +int len; +unsigned char major_ver, minor_ver; +unsigned char ack; +#ifdef WORDS_BIGENDIAN +char *tmpbuf; +#endif + + tdsdump_log(TDS_DBG_FUNC, "%L inside tds_process_login_tokens()\n"); + /* get_incoming(tds->s); */ + do { + marker=tds_get_byte(tds); + switch(marker) { + case TDS_LOGIN_ACK_TOKEN: + len = tds_get_smallint(tds); + ack = tds_get_byte(tds); + major_ver = tds_get_byte(tds); + minor_ver = tds_get_byte(tds); + tds_get_n(tds, NULL, len-4); + tds_get_byte(tds); +#ifdef WORDS_BIGENDIAN +/* + if (major_ver==7) { + tds->broken_dates=1; + } +*/ +#endif +/* + tmpbuf = (char *) malloc(len); + tds_get_n(tds, tmpbuf, len); + tdsdump_log(TDS_DBG_INFO1, "%L login ack marker = %d\n%D\n", marker, tmpbuf, len); + free(tmpbuf); +*/ + /* TDS 5.0 reports 5 on success 6 on failure + ** TDS 4.2 reports 1 on success and is not + ** present on failure */ + if (ack==5 || ack==1) succeed=TDS_SUCCEED; + break; + default: + if (tds_process_default_tokens(tds,marker)==TDS_FAIL) + return TDS_FAIL; + break; + } + } while (marker!=TDS_DONE_TOKEN); + tdsdump_log(TDS_DBG_FUNC, "%L leaving tds_process_login_tokens() returning %d\n",succeed); + return succeed; +} +/* +** tds_process_result_tokens() is called after submitting a query with +** tds_submit_query() and is responsible for calling the routines to +** populate tds->res_info if appropriate (some query have no result sets) +*/ +int tds_process_result_tokens(TDSSOCKET *tds) +{ +int result=0; +int marker; +int more_results = 0; +int cancelled; +int retcode=TDS_NO_MORE_RESULTS; + + if (tds->state==TDS_COMPLETED) { + /* tds_process_row() now eats the end marker and sets + ** state to TDS_COMPLETED + */ + return TDS_NO_MORE_RESULTS; + } + + /* get_incoming(tds->s); */ + do { + marker=tds_get_byte(tds); +tdsdump_log(TDS_DBG_INFO1, "%L processing result tokens. marker is %x\n", marker); + + switch(marker) { + case TDS_ERR_TOKEN: + case TDS_MSG_TOKEN: + case TDS_EED_TOKEN: + tds_process_msg(tds,marker); + if (tds->msg_info && + tds->msg_info->priv_msg_type==1) + /* don't fail until we get a DONE */ + retcode=TDS_FAIL; + break; + case TDS7_RESULT_TOKEN: + if (!result) { + tds7_process_result(tds); + result++; + } else { + tds_unget_byte(tds); + return TDS_SUCCEED; + } + break; + case TDS_RESULT_TOKEN: + if (!result) { + tds_process_result(tds); + result++; + } else { + tds_unget_byte(tds); + return TDS_SUCCEED; + } + break; + case TDS_COL_NAME_TOKEN: + if (!result) { + tds_process_col_name(tds); + result++; + } else { + tds_unget_byte(tds); + return TDS_SUCCEED; + } + break; + case TDS_ROW_TOKEN: + if (!result) { + } else { + tds->res_info->rows_exist=1; + tds_unget_byte(tds); + return TDS_SUCCEED; + } + case TDS_RET_STAT_TOKEN: + tds->has_status=1; + tds->ret_status=tds_get_int(tds); + /* return TDS_SUCCEED; */ + break; + case TDS5_DYN_TOKEN: + tds->cur_dyn_elem = tds_process_dynamic(tds); + break; + case TDS5_DYNRES_TOKEN: + tds_process_dyn_result(tds); + break; + case TDS_DONE_TOKEN: + case TDS_DONEPROC_TOKEN: + case TDS_DONEINPROC_TOKEN: + tds_process_end(tds, marker, + &more_results, + &cancelled); + break; + default: + if (tds_process_default_tokens(tds, marker)==TDS_FAIL) + return TDS_FAIL; + break; + } + } while (!is_end_token(marker) || more_results); + + tds->state=TDS_COMPLETED; + + return retcode; +} + +/* +** tds_process_row_tokens() is called once a result set has been obtained +** with tds_process_result_tokens(). It calls tds_process_row() to copy +** data into the row buffer. +*/ +int tds_process_row_tokens(TDSSOCKET *tds) +{ +int marker; +int more_results; +int cancelled; + + if (tds->state==TDS_COMPLETED) { + return TDS_NO_MORE_ROWS; + } + + while (1) { + marker=tds_get_byte(tds); +tdsdump_log(TDS_DBG_INFO1, "%L processing row tokens. marker is %x\n", marker); + switch(marker) { + case TDS_RESULT_TOKEN: + case TDS7_RESULT_TOKEN: + tds_unget_byte(tds); + return TDS_NO_MORE_ROWS; + case TDS_ROW_TOKEN: + tds_process_row(tds); + return TDS_SUCCEED; + case TDS_DONE_TOKEN: + case TDS_DONEPROC_TOKEN: + case TDS_DONEINPROC_TOKEN: + tds_process_end(tds, marker, + &more_results, + &cancelled); + tds->res_info->more_results = more_results; + return TDS_NO_MORE_ROWS; + default: + if (tds_process_default_tokens(tds,marker)==TDS_FAIL) + return TDS_FAIL; + break; + } + } + /* make lint happy */ + return TDS_SUCCEED; +} + +/* +** tds_process_col_name() is one half of the result set under TDS 4.2 +** it contains all the column names, a TDS_COLINFO_TOKEN should +** immediately follow this token with the datatype/size information +** This is a 4.2 only function +*/ +static int tds_process_col_name(TDSSOCKET *tds) +{ +int hdrsize, len=0; +int col,num_cols=0; +int colnamelen; +struct tmp_col_struct { + char *column_name; + struct tmp_col_struct *next; +}; +struct tmp_col_struct *head=NULL, *cur=NULL, *prev; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; + + hdrsize = tds_get_smallint(tds); + + /* this is a little messy...TDS 5.0 gives the number of columns + ** upfront, while in TDS 4.2, you're expected to figure it out + ** by the size of the message. So, I use a link list to get the + ** colum names and then allocate the result structure, copy + ** and delete the linked list */ + while (lennext=cur; + if (!head) head = cur; + + colnamelen = tds_get_byte(tds); + cur->column_name = (char *) malloc(colnamelen+1); + tds_get_n(tds,cur->column_name, colnamelen); + cur->column_name[colnamelen]='\0'; + cur->next=NULL; + + len += colnamelen + 1; + num_cols++; + } + + /* free results/computes/params etc... */ + tds_free_all_results(tds); + + tds->res_info = tds_alloc_results(num_cols); + info = tds->res_info; + /* tell the upper layers we are processing results */ + tds->state = TDS_PENDING; + cur=head; + for (col=0;colnum_cols;col++) + { + curcol=info->columns[col]; + strncpy(curcol->column_name, cur->column_name, + sizeof(curcol->column_name)); + prev=cur; cur=cur->next; + free(prev->column_name); + free(prev); + } + return TDS_SUCCEED; +} + +/* +** tds_process_col_info() is the other half of result set processing +** under TDS 4.2. It follows tds_process_col_name(). It contains all the +** column type and size information. +** This is a 4.2 only function +*/ +static int tds_process_col_info(TDSSOCKET *tds) +{ +int col,hdrsize; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; +TDS_SMALLINT tabnamesize; +int bytes_read = 0; +int rest; +/* XXX this 4 should be a machine dependent #define */ +int align = 4; +int remainder; + + + hdrsize = tds_get_smallint(tds); + + info = tds->res_info; + for (col=0; colnum_cols; col++) + { + curcol=info->columns[col]; + tds_get_n(tds, NULL, 4); + curcol->column_type = tds_get_byte(tds); + if (is_blob_type(curcol->column_type)) { + curcol->column_size = tds_get_int(tds); + tabnamesize = tds_get_smallint(tds); + tds_get_n(tds,NULL,tabnamesize); + bytes_read += 5+4+2+tabnamesize; + } else if (!is_fixed_type(curcol->column_type)) { + curcol->column_size = tds_get_byte(tds); + bytes_read += 5+1; + } else { + curcol->column_size = get_size_by_type(curcol->column_type); + bytes_read += 5+0; + } + if (is_blob_type(curcol->column_type)) { + curcol->column_offset = info->row_size; + } else { + curcol->column_offset = info->row_size; + info->row_size += curcol->column_size + 1; + } + if (IS_TDS42(tds)) { + remainder = info->row_size % align; + if (remainder) + info->row_size += (align - remainder); + } + } + + /* get the rest of the bytes */ + rest = hdrsize - bytes_read; + if (rest > 0) { + fprintf(stderr,"NOTE:tds_process_col_info: draining %d bytes\n", rest); + tds_get_n(tds, NULL, rest); + } + + info->current_row = tds_alloc_row(info); + + return TDS_SUCCEED; +} + +/* +** tds_process_param_result() processes output parameters of a stored +** procedure. This differs from regular row/compute results in that there +** is no total number of parameters given, they just show up singley. +*/ +static int tds_process_param_result(TDSSOCKET *tds) +{ +int hdrsize; +int column_type; +int column_size, actual_size; + + hdrsize = tds_get_smallint(tds); + tds_get_string(tds, NULL, tds_get_byte(tds)); /* column name */ + tds_get_n(tds, NULL, 5); /* unknown */ + column_type = tds_get_byte(tds); /* datatype */ + if (!is_fixed_type(column_type)) { + column_size = tds_get_byte(tds); + actual_size = tds_get_byte(tds); + tds_get_n(tds, NULL, actual_size); + } else { + column_size = get_size_by_type(column_type); + tds_get_n(tds, NULL, column_size); + } + return TDS_SUCCEED; +} +static int tds_process_param_result_tokens(TDSSOCKET *tds) +{ +int marker; + + while ((marker=tds_get_byte(tds))==TDS_PARAM_TOKEN) { + tds_process_param_result(tds); + } + tds_unget_byte(tds); + return TDS_SUCCEED; +} +/* +** tds_process_compute_result() processes compute result sets. These functions +** need work but since they get little use, nobody has complained! +** It is very similar to normal result sets. +*/ +static int tds_process_compute_result(TDSSOCKET *tds) +{ +int hdrsize; +int col, num_cols; +TDSCOLINFO *curcol; +TDSCOMPUTEINFO *info; +int remainder; + + info = tds->comp_info; + + /* should not occur...but just in case */ + if (info) tds_free_compute_results(info); + + hdrsize = tds_get_smallint(tds); + /* unknown always 1 ? */ + tds_get_smallint(tds); + num_cols = tds_get_byte(tds); + tds->comp_info = tds_alloc_compute_results(num_cols); + info = tds->comp_info; + + for (col=0;colcolumns[col]; + /* user type and some other stuff? */ + tds_get_n(tds,NULL,6); + /* column type */ + curcol->column_type = tds_get_byte(tds); + /* column size */ + if (!is_fixed_type(curcol->column_type)) { + curcol->column_size = tds_get_byte(tds); + } else { + curcol->column_size = get_size_by_type(curcol->column_type); + } + curcol->column_offset = info->row_size; + info->row_size += curcol->column_size + 1; + /* actually this 4 should be a machine dependent #define */ + remainder = info->row_size % 4; + if (remainder) info->row_size += (4 - remainder); + + tds_get_byte(tds); + } + tds_get_n(tds,NULL,tds_get_smallint(tds)); + + return TDS_SUCCEED; +} + +/* +** tds7_process_result() is the TDS 7.0 result set processing routine. It +** is responsible for populating the tds->res_info structure. +** This is a TDS 7.0 only function +*/ +static int tds7_process_result(TDSSOCKET *tds) +{ +int col, num_cols; +int colnamelen; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; + + tds_free_all_results(tds); + + /* read number of columns and allocate the columns structure */ + num_cols = tds_get_smallint(tds); + tds->res_info = tds_alloc_results(num_cols); + info = tds->res_info; + + /* tell the upper layers we are processing results */ + tds->state = TDS_PENDING; + + /* loop through the columns populating COLINFO struct from + ** server response */ + for (col=0;colcolumns[col]; + tds_get_smallint(tds); /* ? 00 */ + tds_get_smallint(tds); /* ? 01 */ + curcol->column_type = tds_get_byte(tds); + + /* large types (2 byte size field) are the type + 128 + ** except for nvarchar which is a varchar under 4.2 and + ** doesn't have its own value + */ + if (is_large_type(curcol->column_type)) { + curcol->column_xtype = curcol->column_type; + curcol->column_type -= 128; + if (curcol->column_xtype==XSYBNVARCHAR) + curcol->column_type=SYBVARCHAR; + if (curcol->column_xtype==XSYBNCHAR) + curcol->column_type=SYBCHAR; + } + + /* text and image have 4 byte size field */ + if (is_blob_type(curcol->column_type)) { + curcol->column_size = tds_get_int(tds); + tds_get_string(tds,NULL,tds_get_smallint(tds)); + /* fixed types have no size field */ + } else if (is_fixed_type(curcol->column_type)) { + curcol->column_size = + get_size_by_type(curcol->column_type); + /* large char types have 2 byte field */ + } else if (is_large_type(curcol->column_xtype)) { + curcol->column_size = tds_get_smallint(tds); + /* all others have 1 byte size */ + } else { + curcol->column_size = tds_get_byte(tds); + + /* numeric and decimal have extra info */ + if (is_numeric_type(curcol->column_type)) { + curcol->column_prec = tds_get_byte(tds); /* precision */ + curcol->column_scale = tds_get_byte(tds); /* scale */ + } + + } + + /* under 7.0 lengths are number of characters not + ** number of bytes...tds_get_string handles this */ + colnamelen = tds_get_byte(tds); + tds_get_string(tds,curcol->column_name, colnamelen); + + /* the column_offset is the offset into the row buffer + ** where this column begins, text types are no longer + ** stored in the row buffer because the max size can + ** be too large (2gig) to allocate */ + curcol->column_offset = info->row_size; + if (!is_blob_type(curcol->column_type)) { + info->row_size += curcol->column_size + 1; + } + if (is_numeric_type(curcol->column_type)) { + info->row_size += sizeof(TDS_NUMERIC) + 1; + } + } + + /* all done now allocate a row for tds_process_row to use */ + info->current_row = tds_alloc_row(info); + + return TDS_SUCCEED; + +} + +/* +** tds_process_result() is the TDS 5.0 result set processing routine. It +** is responsible for populating the tds->res_info structure. +** This is a TDS 5.0 only function +*/ +static int tds_process_result(TDSSOCKET *tds) +{ +int hdrsize; +int colnamelen; +int col, num_cols; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; +int remainder; + + tds_free_all_results(tds); + + hdrsize = tds_get_smallint(tds); + + /* read number of columns and allocate the columns structure */ + num_cols = tds_get_smallint(tds); + tds->res_info = tds_alloc_results(num_cols); + info = tds->res_info; + + /* tell the upper layers we are processing results */ + tds->state = TDS_PENDING; + + /* loop through the columns populating COLINFO struct from + ** server response */ + for (col=0;colnum_cols;col++) + { + curcol=info->columns[col]; + + colnamelen = tds_get_byte(tds); + tds_get_n(tds,curcol->column_name, colnamelen); + curcol->column_name[colnamelen]='\0'; + + tds_get_byte(tds); /* unknown */ + curcol->column_usertype = tds_get_smallint(tds); + tds_get_smallint(tds); /* another unknown */ + curcol->column_type = tds_get_byte(tds); + + if (is_blob_type(curcol->column_type)) { + curcol->column_size = tds_get_int(tds); + /* junk the table name -- for now */ + tds_get_n(tds,NULL,tds_get_smallint(tds)); + } else if (!is_fixed_type(curcol->column_type)) { + curcol->column_size = tds_get_byte(tds); + } else { + curcol->column_size = get_size_by_type(curcol->column_type); + } + + + /* numeric and decimal have extra info */ + if (is_numeric_type(curcol->column_type)) { + curcol->column_prec = tds_get_byte(tds); /* precision */ + curcol->column_scale = tds_get_byte(tds); /* scale */ + } + + curcol->column_offset = info->row_size; + if (is_numeric_type(curcol->column_type)) { + info->row_size += sizeof(TDS_NUMERIC) + 1; + } else if (!is_blob_type(curcol->column_type)) { + info->row_size += curcol->column_size + 1; + } + + + /* actually this 4 should be a machine dependent #define */ + remainder = info->row_size % 4; + if (remainder) info->row_size += (4 - remainder); + + tds_get_byte(tds); /* ? */ + } + info->current_row = tds_alloc_row(info); + + return TDS_SUCCEED; +} + +/* +** tds_process_compute() processes compute rows and places them in the row +** buffer. It's in a bit of disrepair and may not have tracked the row +** buffer changes completely. +*/ +static int tds_process_compute(TDSSOCKET *tds) +{ +int colsize, i; +TDSCOLINFO *curcol; +TDSCOMPUTEINFO *info; +int compid; +unsigned char *dest; + + info = tds->comp_info; + + compid = tds_get_smallint(tds); /* compute id? */ + for (i=0;inum_cols;i++) + { + curcol = info->columns[i]; + if (!is_fixed_type(curcol->column_type)) { + colsize = tds_get_byte(tds); + } else { + colsize = get_size_by_type(curcol->column_type); + } + dest = &(info->current_row[curcol->column_offset]); + tds_get_n(tds,dest,colsize); + dest[colsize]='\0'; + } + return TDS_SUCCEED; +} + +/* +** tds_process_row() processes rows and places them in the row buffer. There +** is also some special handling for some of the more obscure datatypes here. +*/ +static int tds_process_row(TDSSOCKET *tds) +{ +int colsize, i, j, sign, num_pos; +unsigned char b_val; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; +unsigned char *dest; +TDS_NUMERIC *num; +TDS_VARBINARY *varbin; +unsigned char temp_buf[8]; +int len; + + info = tds->res_info; + info->row_count++; + for (i=0;inum_cols;i++) + { + curcol = info->columns[i]; + if (is_blob_type(curcol->column_type)) { + /* length is always 16, if not we are in trouble */ + len = tds_get_byte(tds); + if (len == 16) { /* Jeff's hack */ + tds_get_n(tds,curcol->column_textptr,16); + tds_get_n(tds,curcol->column_timestamp,8); + colsize = tds_get_int(tds); + } else { + colsize = 0; + } + } else if (is_large_type(curcol->column_xtype)) { + colsize = tds_get_smallint(tds); + if (colsize==-1) colsize=0; + } else if (!is_fixed_type(curcol->column_type)) { + colsize = tds_get_byte(tds); + } else { + colsize = get_size_by_type(curcol->column_type); + } + + /* set NULL flag in the row buffer */ + if (colsize==0) { + tds_set_null(info->current_row, i); + } else { + tds_clr_null(info->current_row, i); + + if (is_numeric_type(curcol->column_type)) { + /* + ** handling NUMERIC datatypes: + ** since these can be passed around independent + ** of the original column they were from, I decided + ** to embed the TDS_NUMERIC datatype in the row buffer + ** instead of using the wire representation even though + ** it uses a few more bytes + */ + num = (TDS_NUMERIC *) &(info->current_row[curcol->column_offset]); + num->precision = curcol->column_prec; + num->scale = curcol->column_scale; + + /* + tds_get_n(tds,num->array,colsize); + info->current_row[curcol->column_offset + sizeof(TDS_NUMERIC)]='\0'; + */ + /* + ** FIX: 02-Jan-2000 by Scott C. Gray (SCG) + ** BUG: TDS70 Numeric Support + ** + ** I can think of _no_ reason why M$ decided to do this, but + ** a TDS70 numeric seems to have the following properties over + ** Sybase's. + ** + ** 1. The sign bit is flipped. 1 = Positive, 0 = Negative + ** 2. The byte order is exactly opposite. That is, in a + ** NUMERIC(10,0), the value '256' looks like: + ** + ** sign + ** sybase = 000 000 000 000 001 000 + ** microsoft = 001 000 001 000 000 + ** + ** Also note that TDS 7.0 has two behaviors depending on which + ** patch level you are running. On SP1, the size of the numeric + ** is always reports as 17 (the maximum number of bytes). It + ** seems that on SP2, M$ wised up and started packing the packet + ** with only the required length to store the precision. Thus + ** a NUMERIC(10,0) would look like: + ** + ** SP1 = 17 bytes + ** SP2 = 5 bytes + */ + if (IS_TDS70(tds) || IS_TDS80(tds)) { + sign = tds_get_byte(tds); + num->array[0] = (sign == 0) ? 1 : 0; + + num_pos = g__numeric_bytes_per_prec[curcol->column_prec]-1; + for (j = 0; j < colsize - 1; j++) + { + b_val = tds_get_byte(tds); + + if ((num_pos - j) > 0) + num->array[num_pos - j] = b_val; + } + } else { + tds_get_n(tds, num->array, colsize); + } + + } else if (curcol->column_type == SYBVARBINARY) { + varbin = (TDS_VARBINARY *) &(info->current_row[curcol->column_offset]); + varbin->len = colsize; + /* It is important to re-zero out the whole + column_size varbin array here because the result + of the query ("colsize") may be any number of + bytes <= column_size (because the result + will be truncated if the rest of the data + in the column would be all zeros). */ + memset(varbin->array,'\0',curcol->column_size); + + tds_get_n(tds,varbin->array,colsize); + } else if (is_blob_type(curcol->column_type)) { + curcol->column_textvalue = realloc(curcol->column_textvalue,colsize); + curcol->column_textsize = colsize; + tds_get_n(tds,curcol->column_textvalue,colsize); + } else { + dest = &(info->current_row[curcol->column_offset]); + if (is_unicode(curcol->column_xtype)) { + tds_get_string(tds,dest,colsize/2); + } else { + tds_get_n(tds,dest,colsize); + } + dest[colsize]='\0'; + } + if (curcol->column_type == SYBDATETIME4) { + tdsdump_log(TDS_DBG_INFO1, "%L datetime4 %d %d %d %d\n", dest[0], dest[1], dest[2], dest[3]); + } + +#ifdef WORDS_BIGENDIAN + /* MS SQL Server 7.0 has broken date types from big endian + ** machines, this swaps the low and high halves of the + ** affected datatypes + ** + ** Thought - this might be because we don't have the + ** right flags set on login. -mjs + ** + ** Nope its an actual MS SQL bug -bsb + */ + if (tds->broken_dates && + (curcol->column_type == SYBDATETIME || + curcol->column_type == SYBDATETIME4 || + curcol->column_type == SYBDATETIMN || + curcol->column_type == SYBMONEY || + curcol->column_type == SYBMONEY4 || + curcol->column_type == SYBMONEYN)) { + memcpy(temp_buf,dest,colsize/2); + memcpy(dest,&dest[colsize/2],colsize/2); + memcpy(&dest[colsize/2],temp_buf,colsize/2); + } + if (tds->emul_little_endian) { + tdsdump_log(TDS_DBG_INFO1, "%L swapping coltype %d\n", + tds_get_conversion_type(curcol->column_type,colsize)); + if (is_numeric_type(curcol->column_type)) { + tds_swap_datatype(curcol->column_type, &num); + } else { + tds_swap_datatype( + tds_get_conversion_type(curcol->column_type,colsize), + dest); + } + } +#endif + } + } + return TDS_SUCCEED; +} + +/* +** tds_process_end() processes any of the DONE, DONEPROC, or DONEINPROC +** tokens. +*/ +TDS_INT tds_process_end( + TDSSOCKET *tds, + int marker, + int *more_results_parm, + int *was_cancelled_parm) +{ +int more_results, was_cancelled; +int tmp = tds_get_smallint(tds); + + more_results = (tmp & 0x1) != 0; + was_cancelled = (tmp & 0x20) != 0; + if (tds->res_info) { + tds->res_info->more_results=more_results; + if (was_cancelled || !(more_results)) { + tds->state = TDS_COMPLETED; + } + } + if (more_results_parm) + *more_results_parm = more_results; + if (was_cancelled_parm) + *was_cancelled_parm = was_cancelled; + tds_get_smallint(tds); + /* rows affected is in the tds struct because a query may affect rows but + ** have no result set. */ + tds->rows_affected = tds_get_int(tds); + return tds->rows_affected; +} + +/* +** tds_client_msg() sends a message to the client application from the CLI or +** TDS layer. A client message is one that is generated from with the library +** and not from the server. The message is sent to the CLI (the +** g_tds_err_handler) so that it may forward it to the client application or +** discard it if no msg handler has been by the application. tds->parent +** contains a void pointer to the parent of the tds socket. This can be cast +** back into DBPROCESS or CS_CONNECTION by the CLI and used to determine the +** proper recipient function for this message. +*/ +int tds_client_msg(TDSSOCKET *tds, int msgnum, int level, int state, int line, char *message) +{ +int ret; + if(tds->parent) { + tds->msg_info->msg_number=msgnum; + tds->msg_info->msg_level=level; /* severity? */ + tds->msg_info->msg_state=state; + tds->msg_info->server=strdup("OpenClient"); + tds->msg_info->line_number=line; + tds->msg_info->message=strdup(message); + ret = g_tds_err_handler(tds->parent); + /* message handler returned FAIL/CS_FAIL + ** mark socket as dead */ + if (ret) { + tds->state=TDS_DEAD; + } + } + return 0; +} + +/* +** tds_process_env_chg() +** when ever certain things change on the server, such as database, character +** set, language, or block size. A environment change message is generated +** There is no action taken currently, but certain functions at the CLI level +** that return the name of the current database will need to use this. +*/ +extern int tds_process_env_chg(TDSSOCKET *tds) +{ +int size, type; +char *oldval, *newval; +int new_block_size; +TDSENVINFO *env = tds->env; + + size = tds_get_smallint(tds); + /* this came in a patch, apparently someone saw an env message + ** that was different from what we are handling? -- brian + ** changed back because it won't handle multibyte chars -- 7.0 + */ + /* tds_get_n(tds,NULL,size); */ + + type = tds_get_byte(tds); + + /* fetch the new value */ + size = tds_get_byte(tds); + newval = (char *) malloc((size+1)*2); + tds_get_string(tds,newval,size); + newval[size]='\0'; + + /* fetch the old value */ + size = tds_get_byte(tds); + oldval = (char *) malloc((size+1)*2); /* may be a unicode string */ + tds_get_string(tds,oldval,size); + oldval[size]='\0'; + + switch (type) { + case TDS_ENV_BLOCKSIZE: + new_block_size = atoi(newval); + if (new_block_size > env->block_size) { + tdsdump_log(TDS_DBG_INFO1, "%L increasing block size from %s to %d\n", oldval, new_block_size); + /* + ** I'm not aware of any way to shrink the + ** block size but if it is possible, we don't + ** handle it. + */ + tds->out_buf = (unsigned char*) realloc(tds->out_buf, new_block_size); + env->block_size = new_block_size; + } + break; + } + free(oldval); + free(newval); + + return TDS_SUCCEED; +} + +int tds_process_column_row(TDSSOCKET *tds) +{ +int colsize, i; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; +unsigned char *dest; + + + info = tds->res_info; + info->row_count++; + + for (i=0;i<(info->num_cols -1);i++) + { + curcol = info->columns[i]; + if (!is_fixed_type(curcol->column_type)) { + colsize = tds_get_byte(tds); + } else { + colsize = get_size_by_type(curcol->column_type); + } + dest = &(info->current_row[curcol->column_offset]); + tds_get_n(tds,dest,colsize); + dest[colsize]='\0'; + /* printf("%s\n",curcol->column_value); */ + } + + /* now skip over some stuff and get the rest of the columns */ + tds_get_n(tds,NULL,25); + colsize = tds_get_byte(tds); + tds_get_n(tds,NULL,3); + curcol = info->columns[i]; + dest = &(info->current_row[curcol->column_offset]); + tds_get_n(tds,dest,colsize); + dest[colsize]='\0'; + + return TDS_SUCCEED; +} + +/* +** tds_process_msg() is called for MSG, ERR, or EED tokens and is responsible +** for calling the CLI's message handling routine +** returns TDS_SUCCEED if informational, TDS_ERROR if error. +*/ +static int tds_process_msg(TDSSOCKET *tds,int marker) +{ +int rc; +int len; +int len_msg; +int len_svr; +int len_sqlstate; + + /* packet length */ + len = tds_get_smallint(tds); + + /* message number */ + tds->msg_info->msg_number = tds_get_int(tds); + + /* msg state */ + tds->msg_info->msg_state = tds_get_byte(tds); + + /* msg level */ + tds->msg_info->msg_level = tds_get_byte(tds); + + /* determine if msg or error */ + if (marker==TDS_EED_TOKEN) { + if (tds->msg_info->msg_level<=10) + tds->msg_info->priv_msg_type = 0; + else + tds->msg_info->priv_msg_type = 1; + /* junk this info for now */ + len_sqlstate = tds_get_byte(tds); + tds->msg_info->sql_state = (char*)malloc(len_sqlstate+1); + tds_get_n(tds, tds->msg_info->sql_state,len_sqlstate); + tds->msg_info->sql_state[len_sqlstate] = '\0'; + + /* unknown values */ + tds_get_byte(tds); + tds_get_smallint(tds); + } + else if (marker==TDS_MSG_TOKEN) { + tds->msg_info->priv_msg_type = 0; + } else if (marker==TDS_ERR_TOKEN) { + tds->msg_info->priv_msg_type = 1; + } else { + fprintf(stderr,"tds_process_msg() called with unknown marker!\n"); + return TDS_FAIL; + } + + /* the message */ + len_msg = tds_get_smallint(tds); + tds->msg_info->message = (char*)malloc(len_msg+1); + tds_get_string(tds, tds->msg_info->message, len_msg); + tds->msg_info->message[len_msg] = '\0'; + + /* server name */ + len_svr = tds_get_byte(tds); + tds->msg_info->server = (char*)malloc(len_svr+1); + tds_get_string(tds, tds->msg_info->server, len_svr); + tds->msg_info->server[len_svr] = '\0'; + + /* stored proc name if available */ + rc = tds_get_byte(tds); + if (rc) { + tds_unget_byte(tds); + tds->msg_info->proc_name=tds_msg_get_proc_name(tds); + } else { + tds->msg_info->proc_name=NULL; + } + + /* line number in the sql statement where the problem occured */ + tds->msg_info->line_number = tds_get_smallint(tds); + + if (tds->msg_info->priv_msg_type) { + rc = TDS_ERROR; + } else { + rc = TDS_SUCCEED; + } + /* call the global_tds_msg_handler that was set by an upper layer + ** (dblib, ctlib or some other one). Call it with the pointer to + ** the "parent" structure. + */ + + if(tds->parent) { + if (tds->msg_info->priv_msg_type) + g_tds_err_handler(tds->parent); + else + g_tds_msg_handler(tds->parent); + } else { + if(tds->msg_info->msg_number) + tdsdump_log(TDS_DBG_WARN, + "%L Msg %d, Level %d, State %d, Server %s, Line %d\n%s\n", + tds->msg_info->msg_number, + tds->msg_info->msg_level, + tds->msg_info->msg_state, + tds->msg_info->server, + tds->msg_info->line_number, + tds->msg_info->message); + tds_free_msg(tds->msg_info); + } + return rc; +} + +char *tds_msg_get_proc_name(TDSSOCKET *tds) +{ +int len_proc; +char *proc_name; + + len_proc = tds_get_byte(tds); + + if (len_proc > 0) { + /* its the length of a stored procedure name */ + proc_name = (char*)malloc(len_proc+1); + tds_get_string(tds, proc_name, len_proc); + proc_name[len_proc] = '\0'; + } else { + + /* set the procname to null since there isn't one in the stream */ + proc_name = (char*)NULL; + } + + return proc_name; + +} + +int tds_reset_msg_info(TDSSOCKET *tds) +{ + tds->msg_info->priv_msg_type = 0; + tds->msg_info->msg_number = 0; + tds->msg_info->msg_state = 0; + tds->msg_info->msg_level = 0; + tds->msg_info->line_number = 0; + + if( tds->msg_info->message) + TDS_ZERO_FREE(tds->msg_info->message); + + if(tds->msg_info->server) + TDS_ZERO_FREE(tds->msg_info->server); + if(tds->msg_info->proc_name) + TDS_ZERO_FREE(tds->msg_info->proc_name); + return 0; +} + +/* +** tds_process_cancel() processes the incoming token stream until it finds +** an end token (DONE, DONEPROC, DONEINPROC) with the cancel flag set. +** a that point the connetion should be ready to handle a new query. +*/ +int tds_process_cancel(TDSSOCKET *tds) +{ +int marker, cancelled=0; + + do { + marker=tds_get_byte(tds); + if (marker==TDS_DONE_TOKEN) { + tds_process_end(tds, marker, NULL, &cancelled); + } else { + tds_process_default_tokens(tds,marker); + } + } while (!cancelled); + tds->state = TDS_COMPLETED; + + return 0; +} +/* =========================== tds_is_result_row() =========================== + * + * Def: does the next token in stream signify a result row? + * + * Ret: true if stream is positioned at a row, false otherwise + * + * =========================================================================== + */ +int tds_is_result_row(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + if (marker==TDS_ROW_TOKEN) + { + result = 1; + } + return result; +} /* tds_is_result_row() */ + + +int tds_is_result_set(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = (marker==TDS_COL_NAME_TOKEN + || marker==TDS_COL_INFO_TOKEN + || marker==TDS_RESULT_TOKEN + || marker==TDS7_RESULT_TOKEN); + return result; +} /* tds_is_result_set() */ + + +int tds_is_end_of_results(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = marker==TDS_DONE_TOKEN || marker==TDS_DONEPROC_TOKEN; + return result; +} /* tds_is_end_of_results() */ + + +int tds_is_doneinproc(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = marker==TDS_DONEINPROC_TOKEN; + return result; +} /* tds_is_end_of_results() */ + + +int tds_is_error(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = marker==TDS_ERR_TOKEN; + return result; +} /* tds_is_error() */ + +int tds_is_message(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = marker==TDS_MSG_TOKEN; + return result; +} /* tds_is_message() */ +int tds_is_control(TDSSOCKET *tds) +{ + const int marker = tds_peek(tds); + int result = 0; + + result = (marker==TDS_174_TOKEN || marker==TDS_167_TOKEN); + return result; +} +/* +** set the null bit for the given column in the row buffer +*/ +void tds_set_null(unsigned char *current_row, int column) +{ +int bytenum = column / 8; +int bit = column % 8; +unsigned char mask = 1 << bit; + + tdsdump_log(TDS_DBG_INFO1,"%L setting column %d NULL bit\n", column); + current_row[bytenum] |= mask; +} +/* +** clear the null bit for the given column in the row buffer +*/ +void tds_clr_null(unsigned char *current_row, int column) +{ +int bytenum = column / 8; +int bit = column % 8; +unsigned char mask = ~(1 << bit); + + tdsdump_log(TDS_DBG_INFO1, "%L clearing column %d NULL bit\n", column); + current_row[bytenum] &= mask; +} +/* +** return the null bit for the given column in the row buffer +*/ +int tds_get_null(unsigned char *current_row, int column) +{ +int bytenum = column / 8; +int bit = column % 8; +unsigned char mask = 1 << bit; + + return (current_row[bytenum] & mask) ? 1 : 0; +} + +int tds_lookup_dynamic(TDSSOCKET *tds, char *id) +{ +int i; + + for (i=0;inum_dyns;i++) { + if (!strcmp(tds->dyns[i]->id, id)) { + return i; + } + } + return -1; +} +/* +** tds_process_dynamic() +** finds the element of the dyns array for the id +*/ +int tds_process_dynamic(TDSSOCKET *tds) +{ +int token_sz; +char subtoken[2]; +int id_len; +char id[TDS_MAX_DYNID_LEN+1]; +int drain = 0; + + token_sz = tds_get_smallint(tds); + subtoken[0] = tds_get_byte(tds); + subtoken[1] = tds_get_byte(tds); + if (subtoken[0]!=0x20 || subtoken[1]!=0x00) { + fprintf(stderr,"Unrecognized TDS5_DYN subtoken %02x%02x\n"); + tds_get_n(tds, NULL, token_sz-2); + return -1; + } + id_len = tds_get_byte(tds); + if (id_len > TDS_MAX_DYNID_LEN) { + drain = id_len - TDS_MAX_DYNID_LEN; + id_len = TDS_MAX_DYNID_LEN; + } + tds_get_string(tds, id, id_len); + id[id_len]='\0'; + if (drain) { + tds_get_string(tds, NULL, drain); + } + return tds_lookup_dynamic(tds,id); +} + +static int tds_process_dyn_result(TDSSOCKET *tds) +{ +int hdrsize; +int colnamelen; +int col, num_cols; +TDSCOLINFO *curcol; +TDSRESULTINFO *info; +TDSDYNAMIC *dyn; +int remainder; + + dyn = tds->dyns[tds->cur_dyn_elem]; + tds_free_results(dyn->res_info); + + hdrsize = tds_get_smallint(tds); + + /* read number of columns and allocate the columns structure */ + num_cols = tds_get_smallint(tds); + dyn->res_info = tds_alloc_results(num_cols); + info = dyn->res_info; + + for (col=0;colnum_cols;col++) { + curcol=info->columns[col]; + tds_get_n(tds,NULL,6); + /* column type */ + curcol->column_type = tds_get_byte(tds); + /* column size */ + if (!is_fixed_type(curcol->column_type)) { + curcol->column_size = tds_get_byte(tds); + } else { + curcol->column_size = get_size_by_type(curcol->column_type); + } + tds_get_byte(tds); + fprintf(stderr,"elem %d coltype %d size %d\n",tds->cur_dyn_elem, curcol->column_type, curcol->column_size); + } +} + +/* +** tds_is_fixed_token() +** some tokens are fixed length while others are variable. This function is +** used by tds_process_cancel() to determine how to read past a token +*/ +int tds_is_fixed_token(int marker) +{ + switch (marker) { + case TDS_DONE_TOKEN: + case TDS_DONEPROC_TOKEN: + case TDS_DONEINPROC_TOKEN: + case TDS_RET_STAT_TOKEN: + return 1; + default: + return 0; + } +} + +/* +** tds_get_token_size() returns the size of a fixed length token +** used by tds_process_cancel() to determine how to read past a token +*/ +int tds_get_token_size(int marker) +{ + switch(marker) { + case TDS_DONE_TOKEN: + case TDS_DONEPROC_TOKEN: + case TDS_DONEINPROC_TOKEN: + return 8; + case TDS_RET_STAT_TOKEN: + return 4; + case TDS_124_TOKEN: + return 8; + default: + return 0; + } +} +int tds_swap_datatype(int coltype, unsigned char *buf) +{ +int len; +TDS_NUMERIC *num; + + switch(coltype) { + case SYBINT2: + tds_swap_bytes(buf,2); break; + case SYBINT4: + tds_swap_bytes(buf,4); break; + case SYBINT8: + tds_swap_bytes(buf,8); break; + case SYBREAL: + tds_swap_bytes(buf,4); break; + case SYBFLT8: + tds_swap_bytes(buf,8); break; + case SYBMONEY4: + tds_swap_bytes(buf,4); break; + case SYBMONEY: + tds_swap_bytes(buf,4); + tds_swap_bytes(&buf[4],4); break; + case SYBDATETIME4: + tds_swap_bytes(buf,2); + tds_swap_bytes(&buf[2],2); break; + case SYBDATETIME: + tds_swap_bytes(buf,4); + tds_swap_bytes(&buf[4],4); break; + case SYBNUMERIC: + case SYBDECIMAL: + num = (TDS_NUMERIC *) buf; + tds_swap_bytes(num->array,num->precision); break; + } +} diff --git a/src/tds/unittests/Makefile.am b/src/tds/unittests/Makefile.am new file mode 100644 index 000000000..7162a9862 --- /dev/null +++ b/src/tds/unittests/Makefile.am @@ -0,0 +1,13 @@ +TESTS = t0001 t0002 t0003 t0004 t0005 t0006 +check_PROGRAMS = t0001 t0002 t0003 t0004 t0005 t0006 + +t0001_SOURCES = t0001.c common.c +t0002_SOURCES = t0002.c common.c +t0003_SOURCES = t0003.c common.c +t0004_SOURCES = t0004.c common.c +t0005_SOURCES = t0005.c common.c +t0006_SOURCES = t0006.c common.c + +LIBS = ../libtds.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h diff --git a/src/tds/unittests/Makefile.in b/src/tds/unittests/Makefile.in new file mode 100644 index 000000000..bb0f6e41c --- /dev/null +++ b/src/tds/unittests/Makefile.in @@ -0,0 +1,389 @@ +# Makefile.in generated automatically by automake 1.4 from Makefile.am + +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + + +SHELL = @SHELL@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ +prefix = @prefix@ +exec_prefix = @exec_prefix@ + +bindir = @bindir@ +sbindir = @sbindir@ +libexecdir = @libexecdir@ +datadir = @datadir@ +sysconfdir = @sysconfdir@ +sharedstatedir = @sharedstatedir@ +localstatedir = @localstatedir@ +libdir = @libdir@ +infodir = @infodir@ +mandir = @mandir@ +includedir = @includedir@ +oldincludedir = /usr/include + +DESTDIR = + +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ + +top_builddir = ../../.. + +ACLOCAL = @ACLOCAL@ +AUTOCONF = @AUTOCONF@ +AUTOMAKE = @AUTOMAKE@ +AUTOHEADER = @AUTOHEADER@ + +INSTALL = @INSTALL@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS) +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +transform = @program_transform_name@ + +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +host_alias = @host_alias@ +host_triplet = @host@ +AS = @AS@ +CC = @CC@ +CPP = @CPP@ +DLLTOOL = @DLLTOOL@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +MAKEINFO = @MAKEINFO@ +NETWORK_LIBS = @NETWORK_LIBS@ +OBJDUMP = @OBJDUMP@ +ODBC = @ODBC@ +ODBC_INC = @ODBC_INC@ +PACKAGE = @PACKAGE@ +RANLIB = @RANLIB@ +VERSION = @VERSION@ +float = @float@ +int = @int@ +real = @real@ +smallint = @smallint@ + +TESTS = t0001 t0002 t0003 t0004 t0005 t0006 +check_PROGRAMS = t0001 t0002 t0003 t0004 t0005 t0006 + +t0001_SOURCES = t0001.c common.c +t0002_SOURCES = t0002.c common.c +t0003_SOURCES = t0003.c common.c +t0004_SOURCES = t0004.c common.c +t0005_SOURCES = t0005.c common.c +t0006_SOURCES = t0006.c common.c + +LIBS = ../libtds.la @NETWORK_LIBS@ +INCLUDES = -I$(top_srcdir)/include +include_HEADERS = common.h +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_CLEAN_FILES = + +DEFS = @DEFS@ -I. -I$(srcdir) +CPPFLAGS = @CPPFLAGS@ +LDFLAGS = @LDFLAGS@ +t0001_OBJECTS = t0001.o common.o +t0001_LDADD = $(LDADD) +t0001_DEPENDENCIES = +t0001_LDFLAGS = +t0002_OBJECTS = t0002.o common.o +t0002_LDADD = $(LDADD) +t0002_DEPENDENCIES = +t0002_LDFLAGS = +t0003_OBJECTS = t0003.o common.o +t0003_LDADD = $(LDADD) +t0003_DEPENDENCIES = +t0003_LDFLAGS = +t0004_OBJECTS = t0004.o common.o +t0004_LDADD = $(LDADD) +t0004_DEPENDENCIES = +t0004_LDFLAGS = +t0005_OBJECTS = t0005.o common.o +t0005_LDADD = $(LDADD) +t0005_DEPENDENCIES = +t0005_LDFLAGS = +t0006_OBJECTS = t0006.o common.o +t0006_LDADD = $(LDADD) +t0006_DEPENDENCIES = +t0006_LDFLAGS = +CFLAGS = @CFLAGS@ +COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ +HEADERS = $(include_HEADERS) + +DIST_COMMON = Makefile.am Makefile.in + + +DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) + +TAR = gtar +GZIP_ENV = --best +SOURCES = $(t0001_SOURCES) $(t0002_SOURCES) $(t0003_SOURCES) $(t0004_SOURCES) $(t0005_SOURCES) $(t0006_SOURCES) +OBJECTS = $(t0001_OBJECTS) $(t0002_OBJECTS) $(t0003_OBJECTS) $(t0004_OBJECTS) $(t0005_OBJECTS) $(t0006_OBJECTS) + +all: all-redirect +.SUFFIXES: +.SUFFIXES: .S .c .lo .o .s +$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) + cd $(top_srcdir) && $(AUTOMAKE) --gnu --include-deps src/tds/unittests/Makefile + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + + +mostlyclean-checkPROGRAMS: + +clean-checkPROGRAMS: + -test -z "$(check_PROGRAMS)" || rm -f $(check_PROGRAMS) + +distclean-checkPROGRAMS: + +maintainer-clean-checkPROGRAMS: + +.c.o: + $(COMPILE) -c $< + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean-compile: + -rm -f *.o core *.core + +clean-compile: + +distclean-compile: + -rm -f *.tab.c + +maintainer-clean-compile: + +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.s.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +.S.lo: + $(LIBTOOL) --mode=compile $(COMPILE) -c $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +distclean-libtool: + +maintainer-clean-libtool: + +t0001: $(t0001_OBJECTS) $(t0001_DEPENDENCIES) + @rm -f t0001 + $(LINK) $(t0001_LDFLAGS) $(t0001_OBJECTS) $(t0001_LDADD) $(LIBS) + +t0002: $(t0002_OBJECTS) $(t0002_DEPENDENCIES) + @rm -f t0002 + $(LINK) $(t0002_LDFLAGS) $(t0002_OBJECTS) $(t0002_LDADD) $(LIBS) + +t0003: $(t0003_OBJECTS) $(t0003_DEPENDENCIES) + @rm -f t0003 + $(LINK) $(t0003_LDFLAGS) $(t0003_OBJECTS) $(t0003_LDADD) $(LIBS) + +t0004: $(t0004_OBJECTS) $(t0004_DEPENDENCIES) + @rm -f t0004 + $(LINK) $(t0004_LDFLAGS) $(t0004_OBJECTS) $(t0004_LDADD) $(LIBS) + +t0005: $(t0005_OBJECTS) $(t0005_DEPENDENCIES) + @rm -f t0005 + $(LINK) $(t0005_LDFLAGS) $(t0005_OBJECTS) $(t0005_LDADD) $(LIBS) + +t0006: $(t0006_OBJECTS) $(t0006_DEPENDENCIES) + @rm -f t0006 + $(LINK) $(t0006_LDFLAGS) $(t0006_OBJECTS) $(t0006_LDADD) $(LIBS) + +install-includeHEADERS: $(include_HEADERS) + @$(NORMAL_INSTALL) + $(mkinstalldirs) $(DESTDIR)$(includedir) + @list='$(include_HEADERS)'; for p in $$list; do \ + if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \ + echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \ + $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \ + done + +uninstall-includeHEADERS: + @$(NORMAL_UNINSTALL) + list='$(include_HEADERS)'; for p in $$list; do \ + rm -f $(DESTDIR)$(includedir)/$$p; \ + done + +tags: TAGS + +ID: $(HEADERS) $(SOURCES) $(LISP) + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + here=`pwd` && cd $(srcdir) \ + && mkid -f$$here/ID $$unique $(LISP) + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS)'; \ + unique=`for i in $$list; do echo $$i; done | \ + awk ' { files[$$0] = 1; } \ + END { for (i in files) print i; }'`; \ + test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \ + || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS) + +mostlyclean-tags: + +clean-tags: + +distclean-tags: + -rm -f TAGS ID + +maintainer-clean-tags: + +distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir) + +subdir = src/tds/unittests + +distdir: $(DISTFILES) + @for file in $(DISTFILES); do \ + d=$(srcdir); \ + if test -d $$d/$$file; then \ + cp -pr $$d/$$file $(distdir)/$$file; \ + else \ + test -f $(distdir)/$$file \ + || ln $$d/$$file $(distdir)/$$file 2> /dev/null \ + || cp -p $$d/$$file $(distdir)/$$file || :; \ + fi; \ + done + +check-TESTS: $(TESTS) + @failed=0; all=0; \ + srcdir=$(srcdir); export srcdir; \ + for tst in $(TESTS); do \ + if test -f $$tst; then dir=.; \ + else dir="$(srcdir)"; fi; \ + if $(TESTS_ENVIRONMENT) $$dir/$$tst; then \ + all=`expr $$all + 1`; \ + echo "PASS: $$tst"; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + fi; \ + done; \ + if test "$$failed" -eq 0; then \ + banner="All $$all tests passed"; \ + else \ + banner="$$failed of $$all tests failed"; \ + fi; \ + dashes=`echo "$$banner" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0 +info-am: +info: info-am +dvi-am: +dvi: dvi-am +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS) + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +installcheck-am: +installcheck: installcheck-am +install-exec-am: +install-exec: install-exec-am + +install-data-am: install-includeHEADERS +install-data: install-data-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am +install: install-am +uninstall-am: uninstall-includeHEADERS +uninstall: uninstall-am +all-am: Makefile $(HEADERS) +all-redirect: all-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install +installdirs: + $(mkinstalldirs) $(DESTDIR)$(includedir) + + +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -rm -f Makefile $(CONFIG_CLEAN_FILES) + -rm -f config.cache config.log stamp-h stamp-h[0-9]* + +maintainer-clean-generic: +mostlyclean-am: mostlyclean-checkPROGRAMS mostlyclean-compile \ + mostlyclean-libtool mostlyclean-tags \ + mostlyclean-generic + +mostlyclean: mostlyclean-am + +clean-am: clean-checkPROGRAMS clean-compile clean-libtool clean-tags \ + clean-generic mostlyclean-am + +clean: clean-am + +distclean-am: distclean-checkPROGRAMS distclean-compile \ + distclean-libtool distclean-tags distclean-generic \ + clean-am + -rm -f libtool + +distclean: distclean-am + +maintainer-clean-am: maintainer-clean-checkPROGRAMS \ + maintainer-clean-compile maintainer-clean-libtool \ + maintainer-clean-tags maintainer-clean-generic \ + distclean-am + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + +maintainer-clean: maintainer-clean-am + +.PHONY: mostlyclean-checkPROGRAMS distclean-checkPROGRAMS \ +clean-checkPROGRAMS maintainer-clean-checkPROGRAMS mostlyclean-compile \ +distclean-compile clean-compile maintainer-clean-compile \ +mostlyclean-libtool distclean-libtool clean-libtool \ +maintainer-clean-libtool uninstall-includeHEADERS \ +install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \ +maintainer-clean-tags distdir check-TESTS info-am info dvi-am dvi check \ +check-am installcheck-am installcheck install-exec-am install-exec \ +install-data-am install-data install-am install uninstall-am uninstall \ +all-redirect all-am all installdirs mostlyclean-generic \ +distclean-generic clean-generic maintainer-clean-generic clean \ +mostlyclean distclean maintainer-clean + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c new file mode 100644 index 000000000..0595dfdfd --- /dev/null +++ b/src/tds/unittests/common.c @@ -0,0 +1,94 @@ +#include +#include +#include + +static char software_version[] = "$Id: common.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +char USER[512]; +char SERVER[512]; +char PASSWORD[512]; +char DATABASE[512]; + +int read_login_info() +{ + FILE *in; + char line[512]; + char *s1, *s2; + + in = fopen("../../../PWD","r"); + if (!in) { + fprintf(stderr,"Can not open PWD file\n\n"); + return TDS_FAIL; + } + + while (fgets(line, 512, in)) { + s1=strtok(line,"="); + s2=strtok(NULL,"\n"); + if (!s1 || !s2) { continue; } + if (!strcmp(s1,"UID")) { strcpy(USER,s2); } + else if (!strcmp(s1,"SRV")) { strcpy(SERVER,s2); } + else if (!strcmp(s1,"PWD")) { strcpy(PASSWORD,s2); } + else if (!strcmp(s1,"DB")) { strcpy(DATABASE,s2); } + } + return TDS_SUCCEED; +} + + +int try_tds_login( + TDSLOGIN **login, + TDSSOCKET **tds, + char *appname, + int verbose) +{ + if (verbose) { fprintf(stdout, "Entered tds_try_login()\n"); } + if (! login) { + fprintf(stderr, "Invalid TDSLOGIN**\n"); + return TDS_FAIL; + } + if (! tds) { + fprintf(stderr, "Invalid TDSSOCKET**\n"); + return TDS_FAIL; + } + + if (verbose) { fprintf(stdout, "Trying read_login_info()\n"); } + read_login_info(); + + if (verbose) { fprintf(stdout, "Setting login parameters\n"); } + *login = tds_alloc_login(); + if (! *login) { + fprintf(stderr, "tds_alloc_login() failed.\n"); + return TDS_FAIL; + } + tds_set_passwd(*login, PASSWORD); + tds_set_user(*login, USER); + tds_set_app(*login, appname); + tds_set_host(*login, "myhost"); + tds_set_library(*login, "TDS-Library"); + tds_set_server(*login, SERVER); + tds_set_charset(*login, "iso_1"); + tds_set_language(*login, "us_english"); + tds_set_packet(*login, 512); + + if (verbose) { fprintf(stdout, "Connecting to database\n"); } + *tds = tds_connect(*login); + if (! *tds) { + fprintf(stderr, "tds_connect() failed\n"); + return TDS_FAIL; + } + + return TDS_SUCCEED; +} + + +/* Note that this always suceeds */ +int try_tds_logout( + TDSLOGIN *login, + TDSSOCKET *tds, + int verbose) +{ + if (verbose) { fprintf(stdout, "Entered tds_try_logout()\n"); } + tds_free_socket(tds); + tds_free_login(login); + return TDS_SUCCEED; +} diff --git a/src/tds/unittests/common.h b/src/tds/unittests/common.h new file mode 100644 index 000000000..2614c5e3e --- /dev/null +++ b/src/tds/unittests/common.h @@ -0,0 +1,14 @@ + +#ifndef COMMON_h +#define COMMON_h + +static char rcsid_common_h [ ] = + "$Id: common.h,v 1.1 2001-10-12 23:29:04 brianb Exp $"; +static void *no_unused_common_h_warn[]={rcsid_common_h, no_unused_common_h_warn}; + +extern char PASSWORD[512]; +extern char USER[512]; +extern char SERVER[512]; +extern char DATABASE[512]; + +#endif diff --git a/src/tds/unittests/t0001.c b/src/tds/unittests/t0001.c new file mode 100644 index 000000000..4f53967ee --- /dev/null +++ b/src/tds/unittests/t0001.c @@ -0,0 +1,44 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + + +static char software_version[] = "$Id: t0001.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int ret; + int verbose = 0; + + fprintf(stdout, "%s: Testing login, logout\n", __FILE__); + ret = try_tds_login(&login, &tds, __FILE__, verbose); + if (ret != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + try_tds_logout(login, tds, verbose); + return 0; +} diff --git a/src/tds/unittests/t0002.c b/src/tds/unittests/t0002.c new file mode 100644 index 000000000..09f27f30b --- /dev/null +++ b/src/tds/unittests/t0002.c @@ -0,0 +1,116 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + + +static char software_version[] = "$Id: t0002.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +char *value_as_string( + TDSSOCKET *tds, + int col_idx) +{ + static char result[256]; + const int type = tds->res_info->columns[col_idx]->column_type; + const char *row = tds->res_info->current_row; + const int offset = tds->res_info->columns[col_idx]->column_offset; + const void *value = (row+offset); + + switch(type) { + case SYBVARCHAR: + strncpy(result, (char *)value, sizeof(result)-1); + result[sizeof(result)-1] = '\0'; + break; + case SYBINT4: + sprintf(result, "%d", *(int *)value); + break; + default: + sprintf(result, "Unexpected column_type %d", type); + break; + } + return result; +} /* value_as_string() */ + + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int verbose = 0; + int num_cols = 2; + int rc; + int i; + + fprintf(stdout, "%s: Test basic submit query, results\n", __FILE__); + rc = try_tds_login(&login, &tds, __FILE__, verbose); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + rc = tds_submit_query(tds,"select db_name() dbname, user_name() username"); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "tds_submit_query() failed\n"); + return 1; + } + + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + if (tds->res_info->num_cols != num_cols) { + fprintf(stderr, "Error: num_cols != %d in %s\n", num_cols); + return 1; + } + if (tds->res_info->columns[0]->column_type != SYBVARCHAR + || tds->res_info->columns[1]->column_type != SYBVARCHAR) { + fprintf(stderr, "Wrong column_type in %s\n", __FILE__); + return 1; + } + if (strcmp(tds->res_info->columns[0]->column_name,"dbname") + || strcmp(tds->res_info->columns[1]->column_name,"username")) { + fprintf(stderr, "Wrong column_name in %s\n", __FILE__); + return 1; + } + + while ((rc=tds_process_row_tokens(tds))==TDS_SUCCEED) { + if (verbose) { + for (i=0; i +#include + + +static char software_version[] = "$Id: t0003.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int verbose = 0; + int rc; + int i, marker, type; + char old[100], new[100]; /* WARNING: not properly allocated, possible buffer + overflow...for testing only, do not use in real + code */ + + fprintf(stdout, "%s: Testing DB change -- 'use tempdb'\n", __FILE__); + rc = try_tds_login(&login, &tds, __FILE__, verbose); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + rc = tds_submit_query(tds,"use tempdb"); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "tds_submit_query() failed\n"); + return 1; + } + + /* warning: this mucks with some internals to get the env chg message */ + do { + marker=tds_get_byte(tds); + tds_process_default_tokens(tds,marker); + } while (marker!=TDS_DONE_TOKEN); + + /* Test currently disabled during TDSENVINFO changes */ + if (tds && tds->env && tds->env->database) { + if (verbose) { + fprintf(stdout, "database changed to %s\n", tds->env->database); + } + if (strcmp(tds->env->database, "tempdb")) { + fprintf(stderr, "Wrong database, %s != tempdb\n", new); + return 1; + } + } + + try_tds_logout(login, tds, verbose); + return 0; +} diff --git a/src/tds/unittests/t0004.c b/src/tds/unittests/t0004.c new file mode 100644 index 000000000..657b45f24 --- /dev/null +++ b/src/tds/unittests/t0004.c @@ -0,0 +1,134 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +static char software_version[] = "$Id: t0004.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +char *varchar_as_string( + TDSSOCKET *tds, + int col_idx) +{ + static char result[256]; + const char *row = tds->res_info->current_row; + const int offset = tds->res_info->columns[col_idx]->column_offset; + const void *value = (row+offset); + + strncpy(result, (char *)value, sizeof(result)-1); + result[sizeof(result)-1] = '\0'; + return result; +} + + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int verbose = 0; + int rc; + int i; + + char *len200 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; + char long_query[1000]; + sprintf(long_query, "SELECT name FROM longquerytest WHERE (name = 'A%s' OR name = 'B%s' OR name = 'C%s' OR name = 'correct')", len200, len200, len200); + + fprintf(stdout, "%s: Test large (>512 bytes) queries\n", __FILE__); + rc = try_tds_login(&login, &tds, __FILE__, verbose); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + rc = run_query(tds, "DROP TABLE longquerytest"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "CREATE TABLE longquerytest (name varchar(255))"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "INSERT longquerytest (name) VALUES ('incorrect')"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "INSERT longquerytest (name) VALUES ('correct')"); + if (rc != TDS_SUCCEED) { return 1; } + + /* + * The heart of the test + */ + if (verbose) { fprintf(stdout, "block size %d\n", tds->env->block_size); } + rc = tds_submit_query(tds, long_query); + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + if (tds->res_info->columns[0]->column_type != SYBVARCHAR) { + fprintf(stderr, "Wrong column_type in %s\n", __FILE__); + return 1; + } + + while ((rc=tds_process_row_tokens(tds))==TDS_SUCCEED) { + if (verbose) { + printf("col %i is %s\n", i, varchar_as_string(tds, 0)); + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_row_tokens() returned TDS_FAIL\n"); + return 1; + } + else if (rc != TDS_NO_MORE_ROWS) { + fprintf(stderr, "tds_process_row_tokens() unexpected return\n"); + return 1; + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for long query\n"); + return 1; + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + } + + try_tds_logout(login, tds, verbose); + return 0; +} + + +/* Run query for which there should be no return results */ +int run_query(TDSSOCKET *tds, char *query) +{ + int rc; + + rc = tds_submit_query(tds, query); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "tds_submit_query() failed for query '%s'\n", query); + return TDS_FAIL; + } + + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + if (tds->res_info->rows_exist) { + fprintf(stderr, "Error: query should not return results\n"); + return TDS_FAIL; + } + } + if (rc == TDS_FAIL) { + /* probably okay - DROP TABLE might cause this */ + /* fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for '%s'\n", query); */ + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + return TDS_FAIL; + } + + return TDS_SUCCEED; +} diff --git a/src/tds/unittests/t0005.c b/src/tds/unittests/t0005.c new file mode 100644 index 000000000..749344a4d --- /dev/null +++ b/src/tds/unittests/t0005.c @@ -0,0 +1,149 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +static char software_version[] = "$Id: t0005.c,v 1.1 2001-10-12 23:29:03 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +int run_query(TDSSOCKET *tds, char *query); +char *value_as_string(TDSSOCKET *tds, int col_idx); + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int verbose = 0; + int rc; + int i; + + char *len200 = "01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789"; + char large_sql[1000]; + + fprintf(stdout, "%s: Test large (>512 bytes) replies\n", __FILE__); + rc = try_tds_login(&login, &tds, __FILE__, verbose); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + rc = run_query(tds, "DROP TABLE test_table"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "CREATE TABLE test_table (id int, name varchar(255))"); + if (rc != TDS_SUCCEED) { return 1; } + + sprintf(large_sql, "INSERT test_table (id, name) VALUES (0, 'A%s')", len200); + rc = run_query(tds, large_sql); + if (rc != TDS_SUCCEED) { return 1; } + sprintf(large_sql, "INSERT test_table (id, name) VALUES (1, 'B%s')", len200); + rc = run_query(tds, large_sql); + if (rc != TDS_SUCCEED) { return 1; } + sprintf(large_sql, "INSERT test_table (id, name) VALUES (2, 'C%s')", len200); + rc = run_query(tds, large_sql); + if (rc != TDS_SUCCEED) { return 1; } + + /* + * The heart of the test + */ + rc = tds_submit_query(tds, "SELECT * FROM test_table"); + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + while ((rc=tds_process_row_tokens(tds))==TDS_SUCCEED) { + for (i=0; ires_info->num_cols; i++) { + if (verbose) { + printf("col %i is %s\n", i, value_as_string(tds, i)); + } + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_row_tokens() returned TDS_FAIL\n"); + return 1; + } + else if (rc != TDS_NO_MORE_ROWS) { + fprintf(stderr, "tds_process_row_tokens() unexpected return\n"); + return 1; + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for SELECT\n"); + return 1; + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + } + + try_tds_logout(login, tds, verbose); + return 0; +} + + +/* Run query for which there should be no return results */ +int run_query(TDSSOCKET *tds, char *query) +{ + int rc; + + rc = tds_submit_query(tds, query); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "tds_submit_query() failed for query '%s'\n", query); + return TDS_FAIL; + } + + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + if (tds->res_info->rows_exist) { + fprintf(stderr, "Error: query should not return results\n"); + return TDS_FAIL; + } + } + if (rc == TDS_FAIL) { + /* probably okay - DROP TABLE might cause this */ + /* fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for '%s'\n", query); */ + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + return TDS_FAIL; + } + + return TDS_SUCCEED; +} + + +char *value_as_string( + TDSSOCKET *tds, + int col_idx) +{ + static char result[256]; + const int type = tds->res_info->columns[col_idx]->column_type; + const char *row = tds->res_info->current_row; + const int offset = tds->res_info->columns[col_idx]->column_offset; + const void *value = (row+offset); + + switch(type) { + case SYBVARCHAR: + strncpy(result, (char *)value, sizeof(result)-1); + result[sizeof(result)-1] = '\0'; + break; + case SYBINT4: + sprintf(result, "%d", *(int *)value); + break; + default: + sprintf(result, "Unexpected column_type %d", type); + break; + } + return result; +} diff --git a/src/tds/unittests/t0006.c b/src/tds/unittests/t0006.c new file mode 100644 index 000000000..e693036ba --- /dev/null +++ b/src/tds/unittests/t0006.c @@ -0,0 +1,238 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include + +static char software_version[] = "$Id: t0006.c,v 1.1 2001-10-12 23:29:04 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, no_unused_var_warn}; + +int run_query(TDSSOCKET *tds, char *query); + +int main() +{ + TDSLOGIN *login; + TDSSOCKET *tds; + int verbose = 0; + int rc; + int row_count, i; + + /* variables for conversions */ + TDSCOLINFO *curcol; + TDSRESULTINFO *resinfo; + char *src; + char dest[64]; + TDS_INT srctype, srclen, destlen; + + int src_id; + double src_val; + double src_err; + double tolerance = 0.000001; + + char sql[256]; + int num_sybreal = 5; + float sybreal[5]; + int num_sybflt8 = 7; + double sybflt8[7]; + + sybreal[0] = 1.1; + sybreal[1] = 12345678; + sybreal[2] = 0.012345678; + sybreal[3] = 1.234567890e+20; + sybreal[4] = 1.234567890e-20; + + sybflt8[0] = 1.1; + sybflt8[1] = 1234567890123456; + sybflt8[2] = 0.01234567890123456; + sybflt8[3] = 1.234567890123456e+20; + sybflt8[4] = 1.234567890123456e-20; + sybflt8[5] = 1.234567890123456e+200; + sybflt8[6] = 1.234567890123456e-200; + + printf("%s: Test SYBREAL, SYBFLT8 values\n", __FILE__); + rc = try_tds_login(&login, &tds, __FILE__, verbose); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "try_tds_login() failed\n"); + return 1; + } + + + /** + ** SYBREAL tests + **/ + if (verbose) printf("Starting SYBREAL tests\n"); + rc = run_query(tds, "DROP TABLE test_table"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "CREATE TABLE test_table (id int, val real)"); + if (rc != TDS_SUCCEED) { return 1; } + + for (i=0; ires_info; + for (i=0; inum_cols; i++) { + curcol = resinfo->columns[i]; + src = &(resinfo->current_row[curcol->column_offset]); + if (verbose) { + srctype = curcol->column_type; + srclen = curcol->column_size; + tds_convert(srctype, src, srclen, SYBCHAR, dest, 64); + printf("col %i is %s\n", i, dest); + } + if (i==0) { + src_id = *(int *)src; + } else { + src_val = *(float *)src; + src_err = src_val - sybreal[src_id]; + if (src_err != 0.0) { + src_err = src_err/src_val; + } + if (src_err < -tolerance || src_err > tolerance) { + fprintf(stderr, "SYBREAL expected %.8g got %.8g\n", + sybreal[src_id], src_val); + fprintf(stderr, "Error was %.4g%%\n", 100*src_err); + return 1; + } + } + } + row_count++; + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_row_tokens() returned TDS_FAIL\n"); + return 1; + } + else if (rc != TDS_NO_MORE_ROWS) { + fprintf(stderr, "tds_process_row_tokens() unexpected return\n"); + return 1; + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for SELECT\n"); + return 1; + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + } + + + /** + ** SYBFLT8 tests + **/ + if (verbose) printf("Starting SYBFLT8 tests\n"); + rc = run_query(tds, "DROP TABLE test_table"); + if (rc != TDS_SUCCEED) { return 1; } + rc = run_query(tds, "CREATE TABLE test_table (id int, val float(53))"); + if (rc != TDS_SUCCEED) { return 1; } + + for (i=0; ires_info; + for (i=0; inum_cols; i++) { + curcol = resinfo->columns[i]; + src = &(resinfo->current_row[curcol->column_offset]); + if (verbose) { + srctype = curcol->column_type; + srclen = curcol->column_size; + tds_convert(srctype, src, srclen, SYBCHAR, dest, 64); + printf("col %i is %s\n", i, dest); + } + if (i==0) { + src_id = *(int *)src; + } else { + memcpy(&src_val, src, 8); + src_err = src_val - sybflt8[src_id]; + if (src_err != 0.0){ + src_err = src_err/src_val; + } + if (src_err < -tolerance || src_err > tolerance) { + fprintf(stderr, "SYBFLT8 expected %.16g got %.16g\n", + sybflt8[src_id], src_val); + fprintf(stderr, "Error was %.4g%%\n", 100*src_err); + return 1; + } + } + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_row_tokens() returned TDS_FAIL\n"); + return 1; + } + else if (rc != TDS_NO_MORE_ROWS) { + fprintf(stderr, "tds_process_row_tokens() unexpected return\n"); + return 1; + } + } + if (rc == TDS_FAIL) { + fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for SELECT\n"); + return 1; + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + } + + try_tds_logout(login, tds, verbose); + return 0; +} + + +/* Run query for which there should be no return results */ +int run_query(TDSSOCKET *tds, char *query) +{ + int rc; + + rc = tds_submit_query(tds, query); + if (rc != TDS_SUCCEED) { + fprintf(stderr, "tds_submit_query() failed for query '%s'\n", query); + return TDS_FAIL; + } + + while ((rc=tds_process_result_tokens(tds))==TDS_SUCCEED) { + if (tds->res_info->rows_exist) { + fprintf(stderr, "Error: query should not return results\n"); + return TDS_FAIL; + } + } + if (rc == TDS_FAIL) { + /* probably okay - DROP TABLE might cause this */ + /* fprintf(stderr, "tds_process_result_tokens() returned TDS_FAIL for '%s'\n", query); */ + } + else if (rc != TDS_NO_MORE_RESULTS) { + fprintf(stderr, "tds_process_result_tokens() unexpected return\n"); + return TDS_FAIL; + } + + return TDS_SUCCEED; +} diff --git a/src/tds/util.c b/src/tds/util.c new file mode 100644 index 000000000..0703a65e0 --- /dev/null +++ b/src/tds/util.c @@ -0,0 +1,355 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#ifdef __DGUX__ +#include +#endif +#ifdef __FreeBSD__ +#include +#endif +#ifdef WIN32 +#include +#include +#define PATH_MAX 255 +#endif +#ifndef WIN32 +#include +#include +#include +#include +#endif +#include "tdsutil.h" + + +static char software_version[] = "$Id: util.c,v 1.1 2001-10-12 23:28:59 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + +/* for now all messages go to the log */ +int g_debug_lvl = 99; + +void tds_set_parent(TDSSOCKET* tds, void* the_parent) +{ + if (tds) + tds->parent = the_parent; +} + +void* tds_get_parent(TDSSOCKET* tds) +{ + return( tds->parent); +} + +int tds_swap_bytes(unsigned char *buf, int bytes) +{ +unsigned char tmp; +int i; + + /* if (bytes % 2) { return 0 }; */ + for (i=0;ig_debug_lvl) + return; + + if (write_dump && dumpfile!=NULL) + { + const char *ptr; + + va_list ap; + va_start(ap, fmt); + + for(ptr = fmt; *ptr != '\0'; ptr++) + { + if (*ptr == '%') + { + ptr++; + switch(*ptr) + { + case 's': + { + char *s = va_arg(ap, char *); + fputs(s, dumpfile); + break; + } + case 'd': + { + int i = va_arg(ap, int); + fprintf(dumpfile, "%d", i); + break; + } + case 'x': + { + int i = va_arg(ap, int); + fprintf(dumpfile, "%x", i); + break; + } + case 'D': + { + char *buf = va_arg(ap, char *); + int len = va_arg(ap, int); + tdsdump_dump_buf(buf, len); + break; + } + case 'L': /* current local time */ + { + char buf[1024]; + struct tm *tm; + time_t t; + +#ifdef __FreeBSD__ + struct timeval tv; +#endif + +#ifdef __FreeBSD__ + gettimeofday(&tv, NULL); + t = tv.tv_sec; +#else + /* + * XXX Need to get a better time resolution for + * non-FreeBSD systems. + */ + time(&t); +#endif + tm = localtime(&t); + strftime(buf, sizeof(buf)-1, "%Y-%m-%d %H:%M:%S", tm); + fputs(buf, dumpfile); +#ifdef __FreeBSD__ + fprintf(dumpfile, ".%06lu", tv.tv_usec); +#endif + } + default: + { + break; + } + } + } + else + { + fputc(*ptr, dumpfile); + } + } + } + fflush(dumpfile); +} /* tdsdump_log() */ + +/* Jeff's hack*** NEW CODE *** */ +int tds_msleep(long usec) /* returns 0 if ok, else -1 */ + { +#ifdef WIN32 + Sleep(0); + return 0; +#else + /* try to select stdin for writing just to create a delay */ + /* fd_set fd_in; */ + struct timeval delay; /* _select() timeout */ + + /* FD_ZERO (&fd_in); */ + /* FD_SET (fileno(stdin), &fd_in); */ + + delay.tv_sec = usec / 1000000L; + delay.tv_usec = usec % 1000000L; + + return(select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &delay)); +#endif + }; +/* Jeff's hack ***NEW CODE END**** */ + + diff --git a/src/tds/write.c b/src/tds/write.c new file mode 100644 index 000000000..a1109c3cf --- /dev/null +++ b/src/tds/write.c @@ -0,0 +1,189 @@ +/* FreeTDS - Library of routines accessing Sybase and Microsoft databases + * Copyright (C) 1998-1999 Brian Bruns + * + * 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., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "tds.h" +#include "tdsutil.h" +#include /* GW ADDED */ + +#ifdef WIN32 +#define WRITE(a,b,c) send((a),(b),(c), 0L) +#else +#define WRITE(a,b,c) write(a,b,c) +#endif + +static char software_version[] = "$Id: write.c,v 1.1 2001-10-12 23:29:01 brianb Exp $"; +static void *no_unused_var_warn[] = {software_version, + no_unused_var_warn}; + + +int tds_put_n(TDSSOCKET *tds, unsigned char *buf, int n) +{ +int i; + if (buf) { + for (i=0;i dsize ? dsize : ssize; + if (buf) memcpy(tempbuf,buf, cpsize); + tds_put_n(tds,tempbuf,dsize); + free(tempbuf); + tds_put_byte(tds,cpsize); +} +int tds_put_int(TDSSOCKET *tds, TDS_INT i) +{ +#if WORDS_BIGENDIAN + if (tds->emul_little_endian) { + tds_put_byte(tds, i & 0x000000FF); + tds_put_byte(tds, (i & 0x0000FF00) >> 8); + tds_put_byte(tds, (i & 0x00FF0000) >> 16); + tds_put_byte(tds, (i & 0xFF000000) >> 24); + return 0; + } +#endif + return tds_put_n(tds,(unsigned char *)&i,sizeof(TDS_INT)); +} +int tds_put_smallint(TDSSOCKET *tds, TDS_SMALLINT si) +{ +#if WORDS_BIGENDIAN + if (tds->emul_little_endian) { + tds_put_byte(tds, si & 0x000000FF); + tds_put_byte(tds, (si & 0x0000FF00) >> 8); + return 0; + } +#endif + return tds_put_n(tds,(unsigned char *)&si,sizeof(TDS_SMALLINT)); +} +int tds_put_tinyint(TDSSOCKET *tds, TDS_TINYINT ti) +{ + return tds_put_n(tds,(unsigned char *)&ti,sizeof(TDS_TINYINT)); +} +int tds_put_byte(TDSSOCKET *tds, unsigned char c) +{ + if (tds->out_pos >= tds->env->block_size) { + tds_write_packet(tds,0x0); + tds_init_write_buf(tds); + } + tds->out_buf[tds->out_pos++]=c; + return 0; +} +int tds_put_bulk_data(TDSSOCKET *tds, unsigned char * buf, TDS_INT bufsize) +{ + + tds->out_flag = 0x07; + return tds_put_n(tds,buf,bufsize); +} +int tds_init_write_buf(TDSSOCKET *tds) +{ + memset(tds->out_buf,'\0',tds->env->block_size); + tds->out_pos=8; + return 0; +} +int tds_write_packet(TDSSOCKET *tds,unsigned char final) +{ +static int retval; +void (*oldsig)(int); +fd_set fds; +struct timeval selecttimeout; +time_t start, now; +int retcode = 0; + + tds->out_buf[0]=tds->out_flag; + tds->out_buf[1]=final; + tds->out_buf[2]=(tds->out_pos)/256; + tds->out_buf[3]=(tds->out_pos)%256; + if (IS_TDS70(tds)) { + tds->out_buf[6]=0x01; + } + + tdsdump_log(TDS_DBG_NETWORK, "Sending packet @ %L\n%D\n", tds->out_buf, tds->out_pos); + oldsig=signal (SIGPIPE, SIG_IGN); + if (oldsig==SIG_ERR) { + fprintf(stderr, "TDS: Warning: Couldn't set SIGPIPE signal to be ignored\n"); + } + + /* Jeffs hack *** NEW CODE */ + /* If there's a timeout, we need to sit and wait for socket writability */ + if (tds->timeout) { + start = time(NULL); + + FD_ZERO (&fds); + + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + + now = time(NULL); + + while ((retcode == 0) && ((now-start) < tds->timeout)) { + tds_msleep(1); + FD_SET (tds->s, &fds); + selecttimeout.tv_sec = 0; + selecttimeout.tv_usec = 0; + retcode = select (tds->s + 1, NULL, &fds, NULL, &selecttimeout); + if (retcode < 0 && errno == EINTR) { + retcode = 0; + } + + now = time (NULL); + } + } +/* Jeffs hack *** END OF NEW CODE */ + retval=write(tds->s,tds->out_buf,tds->out_pos); + + if (signal(SIGPIPE, oldsig)==SIG_ERR) { + fprintf(stderr, "TDS: Warning: Couldn't reset SIGPIPE signal to previous value\n"); + } + if (retval < 0) { + fprintf(stderr, "TDS: Write failed in tds_write_packet\nError: %d (%s)\n", errno, strerror(errno)); + tds_client_msg(tds, 10018, 9, 0, 0, "The connection was closed"); + tds->in_pos=0; + tds->in_len=0; + close(tds->s); + tds->s=0; + return 0; + } +/* GW added in check for write() returning <0 and SIGPIPE checking */ + return 1; +} +int tds_flush_packet(TDSSOCKET *tds) +{ + if (tds->s) { + tds_write_packet(tds,0x01); + tds_init_write_buf(tds); + } + /* GW added check for tds->s */ + return 0; +}